54da33a1bcbb2ebf942e7db1d7a46c5e4f545745
[dragonfly.git] / sys / dev / netif / bwn / 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: head/sys/dev/bwn/if_bwn.c 260444 2014-01-08 08:06:56Z kevlo $");
32
33 /*
34  * The Broadcom Wireless LAN controller driver.
35  */
36
37 #include <opt_wlan.h>
38 #include <opt_bwn.h>
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/module.h>
43 #include <sys/kernel.h>
44 #include <sys/endian.h>
45 #include <sys/errno.h>
46 #include <sys/firmware.h>
47 #include <sys/bus_resource.h>
48 #include <sys/bus.h>
49 #include <sys/rman.h>
50 #include <sys/socket.h>
51 #include <sys/sockio.h>
52
53 #include <net/ethernet.h>
54 #include <net/if.h>
55 #include <net/if_var.h>
56 #include <net/if_arp.h>
57 #include <net/if_dl.h>
58 #include <net/if_llc.h>
59 #include <net/if_media.h>
60 #include <net/if_types.h>
61 #include <net/ifq_var.h>
62
63 #include <bus/pci/pcivar.h>
64 #include <bus/pci/pcireg.h>
65 #include <dev/netif/bwn/siba/siba_ids.h>
66 #include <dev/netif/bwn/siba/sibareg.h>
67 #include <dev/netif/bwn/siba/sibavar.h>
68
69 #include <netproto/802_11/ieee80211_var.h>
70 #include <netproto/802_11/ieee80211_radiotap.h>
71 #include <netproto/802_11/ieee80211_regdomain.h>
72 #include <netproto/802_11/ieee80211_phy.h>
73 #include <netproto/802_11/ieee80211_ratectl.h>
74
75 #include "if_bwnreg.h"
76 #include "if_bwnvar.h"
77
78 static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0,
79     "Broadcom driver parameters");
80
81 /*
82  * Tunable & sysctl variables.
83  */
84
85 #ifdef BWN_DEBUG
86 static  int bwn_debug = 0;
87 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RW, &bwn_debug, 0,
88     "Broadcom debugging printfs");
89 TUNABLE_INT("hw.bwn.debug", &bwn_debug);
90 enum {
91         BWN_DEBUG_XMIT          = 0x00000001,   /* basic xmit operation */
92         BWN_DEBUG_RECV          = 0x00000002,   /* basic recv operation */
93         BWN_DEBUG_STATE         = 0x00000004,   /* 802.11 state transitions */
94         BWN_DEBUG_TXPOW         = 0x00000008,   /* tx power processing */
95         BWN_DEBUG_RESET         = 0x00000010,   /* reset processing */
96         BWN_DEBUG_OPS           = 0x00000020,   /* bwn_ops processing */
97         BWN_DEBUG_BEACON        = 0x00000040,   /* beacon handling */
98         BWN_DEBUG_WATCHDOG      = 0x00000080,   /* watchdog timeout */
99         BWN_DEBUG_INTR          = 0x00000100,   /* ISR */
100         BWN_DEBUG_CALIBRATE     = 0x00000200,   /* periodic calibration */
101         BWN_DEBUG_NODE          = 0x00000400,   /* node management */
102         BWN_DEBUG_LED           = 0x00000800,   /* led management */
103         BWN_DEBUG_CMD           = 0x00001000,   /* cmd submission */
104         BWN_DEBUG_LO            = 0x00002000,   /* LO */
105         BWN_DEBUG_FW            = 0x00004000,   /* firmware */
106         BWN_DEBUG_WME           = 0x00008000,   /* WME */
107         BWN_DEBUG_RF            = 0x00010000,   /* RF */
108         BWN_DEBUG_FATAL         = 0x80000000,   /* fatal errors */
109         BWN_DEBUG_ANY           = 0xffffffff
110 };
111 #define DPRINTF(sc, m, fmt, ...) do {                   \
112         if (sc->sc_debug & (m))                         \
113                 kprintf(fmt, __VA_ARGS__);              \
114 } while (0)
115 #else
116 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
117 #endif
118
119 static int      bwn_bfp = 0;            /* use "Bad Frames Preemption" */
120 SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0,
121     "uses Bad Frames Preemption");
122 static int      bwn_bluetooth = 1;
123 SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0,
124     "turns on Bluetooth Coexistence");
125 static int      bwn_hwpctl = 0;
126 SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0,
127     "uses H/W power control");
128 static int      bwn_msi_enable = 1;
129 TUNABLE_INT("hw.bwn.msi.enable", &bwn_msi_enable);
130 static int      bwn_usedma = 1;
131 SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0,
132     "uses DMA");
133 TUNABLE_INT("hw.bwn.usedma", &bwn_usedma);
134 static int      bwn_wme = 1;
135 SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0,
136     "uses WME support");
137
138 static int      bwn_attach_pre(struct bwn_softc *);
139 static int      bwn_attach_post(struct bwn_softc *);
140 static void     bwn_sprom_bugfixes(device_t);
141 static void     bwn_init(void *);
142 static int      bwn_init_locked(struct bwn_softc *);
143 static int      bwn_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *);
144 static void     bwn_start(struct ifnet *, struct ifaltq_subque *);
145 static int      bwn_attach_core(struct bwn_mac *);
146 static void     bwn_reset_core(struct bwn_mac *, uint32_t);
147 static int      bwn_phy_getinfo(struct bwn_mac *, int);
148 static int      bwn_chiptest(struct bwn_mac *);
149 static int      bwn_setup_channels(struct bwn_mac *, int, int);
150 static int      bwn_phy_g_attach(struct bwn_mac *);
151 static void     bwn_phy_g_detach(struct bwn_mac *);
152 static void     bwn_phy_g_init_pre(struct bwn_mac *);
153 static int      bwn_phy_g_prepare_hw(struct bwn_mac *);
154 static int      bwn_phy_g_init(struct bwn_mac *);
155 static void     bwn_phy_g_exit(struct bwn_mac *);
156 static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t);
157 static void     bwn_phy_g_write(struct bwn_mac *, uint16_t,
158                     uint16_t);
159 static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t);
160 static void     bwn_phy_g_rf_write(struct bwn_mac *, uint16_t,
161                     uint16_t);
162 static int      bwn_phy_g_hwpctl(struct bwn_mac *);
163 static void     bwn_phy_g_rf_onoff(struct bwn_mac *, int);
164 static int      bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t);
165 static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *);
166 static void     bwn_phy_g_set_antenna(struct bwn_mac *, int);
167 static int      bwn_phy_g_im(struct bwn_mac *, int);
168 static int      bwn_phy_g_recalc_txpwr(struct bwn_mac *, int);
169 static void     bwn_phy_g_set_txpwr(struct bwn_mac *);
170 static void     bwn_phy_g_task_15s(struct bwn_mac *);
171 static void     bwn_phy_g_task_60s(struct bwn_mac *);
172 static uint16_t bwn_phy_g_txctl(struct bwn_mac *);
173 static void     bwn_phy_switch_analog(struct bwn_mac *, int);
174 static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t);
175 static void     bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t,
176                     uint16_t);
177 static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t);
178 static void     bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t,
179                     uint32_t);
180 static void     bwn_shm_ctlword(struct bwn_mac *, uint16_t,
181                     uint16_t);
182 static void     bwn_addchannels(struct ieee80211_channel [], int, int *,
183                     const struct bwn_channelinfo *, int);
184 static int      bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
185                     const struct ieee80211_bpf_params *);
186 static void     bwn_updateslot(struct ifnet *);
187 static void     bwn_update_promisc(struct ifnet *);
188 static void     bwn_wme_init(struct bwn_mac *);
189 static int      bwn_wme_update(struct ieee80211com *);
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_scan_start(struct ieee80211com *);
195 static void     bwn_scan_end(struct ieee80211com *);
196 static void     bwn_set_channel(struct ieee80211com *);
197 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *,
198                     const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
199                     const uint8_t [IEEE80211_ADDR_LEN],
200                     const uint8_t [IEEE80211_ADDR_LEN]);
201 static void     bwn_vap_delete(struct ieee80211vap *);
202 static void     bwn_stop(struct bwn_softc *, int);
203 static void     bwn_stop_locked(struct bwn_softc *, int);
204 static int      bwn_core_init(struct bwn_mac *);
205 static void     bwn_core_start(struct bwn_mac *);
206 static void     bwn_core_exit(struct bwn_mac *);
207 static void     bwn_bt_disable(struct bwn_mac *);
208 static int      bwn_chip_init(struct bwn_mac *);
209 static uint64_t bwn_hf_read(struct bwn_mac *);
210 static void     bwn_hf_write(struct bwn_mac *, uint64_t);
211 static void     bwn_set_txretry(struct bwn_mac *, int, int);
212 static void     bwn_rate_init(struct bwn_mac *);
213 static void     bwn_set_phytxctl(struct bwn_mac *);
214 static void     bwn_spu_setdelay(struct bwn_mac *, int);
215 static void     bwn_bt_enable(struct bwn_mac *);
216 static void     bwn_set_macaddr(struct bwn_mac *);
217 static void     bwn_crypt_init(struct bwn_mac *);
218 static void     bwn_chip_exit(struct bwn_mac *);
219 static int      bwn_fw_fillinfo(struct bwn_mac *);
220 static int      bwn_fw_loaducode(struct bwn_mac *);
221 static int      bwn_gpio_init(struct bwn_mac *);
222 static int      bwn_fw_loadinitvals(struct bwn_mac *);
223 static int      bwn_phy_init(struct bwn_mac *);
224 static void     bwn_set_txantenna(struct bwn_mac *, int);
225 static void     bwn_set_opmode(struct bwn_mac *);
226 static void     bwn_rate_write(struct bwn_mac *, uint16_t, int);
227 static uint8_t  bwn_plcp_getcck(const uint8_t);
228 static uint8_t  bwn_plcp_getofdm(const uint8_t);
229 static void     bwn_pio_init(struct bwn_mac *);
230 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int);
231 static void     bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *,
232                     int);
233 static void     bwn_pio_setupqueue_rx(struct bwn_mac *,
234                     struct bwn_pio_rxqueue *, int);
235 static void     bwn_destroy_queue_tx(struct bwn_pio_txqueue *);
236 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *,
237                     uint16_t);
238 static void     bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *);
239 static int      bwn_pio_rx(struct bwn_pio_rxqueue *);
240 static uint8_t  bwn_pio_rxeof(struct bwn_pio_rxqueue *);
241 static void     bwn_pio_handle_txeof(struct bwn_mac *,
242                     const struct bwn_txstatus *);
243 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t);
244 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t);
245 static void     bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t,
246                     uint16_t);
247 static void     bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t,
248                     uint32_t);
249 static int      bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *,
250                     struct mbuf *);
251 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t);
252 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *,
253                     struct bwn_pio_txqueue *, uint32_t, const void *, int);
254 static void     bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *,
255                     uint16_t, uint32_t);
256 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *,
257                     struct bwn_pio_txqueue *, uint16_t, const void *, int);
258 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *,
259                     struct bwn_pio_txqueue *, uint16_t, struct mbuf *);
260 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *,
261                     uint16_t, struct bwn_pio_txpkt **);
262 static void     bwn_dma_init(struct bwn_mac *);
263 static void     bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t);
264 static int      bwn_dma_mask2type(uint64_t);
265 static uint64_t bwn_dma_mask(struct bwn_mac *);
266 static uint16_t bwn_dma_base(int, int);
267 static void     bwn_dma_ringfree(struct bwn_dma_ring **);
268 static void     bwn_dma_32_getdesc(struct bwn_dma_ring *,
269                     int, struct bwn_dmadesc_generic **,
270                     struct bwn_dmadesc_meta **);
271 static void     bwn_dma_32_setdesc(struct bwn_dma_ring *,
272                     struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
273                     int, int);
274 static void     bwn_dma_32_start_transfer(struct bwn_dma_ring *, int);
275 static void     bwn_dma_32_suspend(struct bwn_dma_ring *);
276 static void     bwn_dma_32_resume(struct bwn_dma_ring *);
277 static int      bwn_dma_32_get_curslot(struct bwn_dma_ring *);
278 static void     bwn_dma_32_set_curslot(struct bwn_dma_ring *, int);
279 static void     bwn_dma_64_getdesc(struct bwn_dma_ring *,
280                     int, struct bwn_dmadesc_generic **,
281                     struct bwn_dmadesc_meta **);
282 static void     bwn_dma_64_setdesc(struct bwn_dma_ring *,
283                     struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
284                     int, int);
285 static void     bwn_dma_64_start_transfer(struct bwn_dma_ring *, int);
286 static void     bwn_dma_64_suspend(struct bwn_dma_ring *);
287 static void     bwn_dma_64_resume(struct bwn_dma_ring *);
288 static int      bwn_dma_64_get_curslot(struct bwn_dma_ring *);
289 static void     bwn_dma_64_set_curslot(struct bwn_dma_ring *, int);
290 static int      bwn_dma_allocringmemory(struct bwn_dma_ring *);
291 static void     bwn_dma_setup(struct bwn_dma_ring *);
292 static void     bwn_dma_free_ringmemory(struct bwn_dma_ring *);
293 static void     bwn_dma_cleanup(struct bwn_dma_ring *);
294 static void     bwn_dma_free_descbufs(struct bwn_dma_ring *);
295 static int      bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int);
296 static void     bwn_dma_rx_handle_overflow(struct bwn_dma_ring *);
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 void     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 const struct bwn_channelinfo bwn_chantable_bg = {
540         .channels = {
541                 { 2412,  1, 30 }, { 2417,  2, 30 }, { 2422,  3, 30 },
542                 { 2427,  4, 30 }, { 2432,  5, 30 }, { 2437,  6, 30 },
543                 { 2442,  7, 30 }, { 2447,  8, 30 }, { 2452,  9, 30 },
544                 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 },
545                 { 2472, 13, 30 }, { 2484, 14, 30 } },
546         .nchannels = 14
547 };
548
549 static const struct bwn_channelinfo bwn_chantable_a = {
550         .channels = {
551                 { 5170,  34, 30 }, { 5180,  36, 30 }, { 5190,  38, 30 },
552                 { 5200,  40, 30 }, { 5210,  42, 30 }, { 5220,  44, 30 },
553                 { 5230,  46, 30 }, { 5240,  48, 30 }, { 5260,  52, 30 },
554                 { 5280,  56, 30 }, { 5300,  60, 30 }, { 5320,  64, 30 },
555                 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 },
556                 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 },
557                 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 },
558                 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 },
559                 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 },
560                 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 },
561                 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 },
562                 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 },
563                 { 6080, 216, 30 } },
564         .nchannels = 37
565 };
566
567 static const struct bwn_channelinfo bwn_chantable_n = {
568         .channels = {
569                 { 5160,  32, 30 }, { 5170,  34, 30 }, { 5180,  36, 30 },
570                 { 5190,  38, 30 }, { 5200,  40, 30 }, { 5210,  42, 30 },
571                 { 5220,  44, 30 }, { 5230,  46, 30 }, { 5240,  48, 30 },
572                 { 5250,  50, 30 }, { 5260,  52, 30 }, { 5270,  54, 30 },
573                 { 5280,  56, 30 }, { 5290,  58, 30 }, { 5300,  60, 30 },
574                 { 5310,  62, 30 }, { 5320,  64, 30 }, { 5330,  66, 30 },
575                 { 5340,  68, 30 }, { 5350,  70, 30 }, { 5360,  72, 30 },
576                 { 5370,  74, 30 }, { 5380,  76, 30 }, { 5390,  78, 30 },
577                 { 5400,  80, 30 }, { 5410,  82, 30 }, { 5420,  84, 30 },
578                 { 5430,  86, 30 }, { 5440,  88, 30 }, { 5450,  90, 30 },
579                 { 5460,  92, 30 }, { 5470,  94, 30 }, { 5480,  96, 30 },
580                 { 5490,  98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 },
581                 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 },
582                 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 },
583                 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 },
584                 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 },
585                 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 },
586                 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 },
587                 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 },
588                 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 },
589                 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 },
590                 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 },
591                 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 },
592                 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 },
593                 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 },
594                 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 },
595                 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 },
596                 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 },
597                 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 },
598                 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 },
599                 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 },
600                 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 },
601                 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
602                 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
603                 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
604                 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
605                 { 6130, 226, 30 }, { 6140, 228, 30 } },
606         .nchannels = 110
607 };
608
609 static const uint8_t bwn_b2063_chantable_data[33][12] = {
610         { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
611         { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
612         { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
613         { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
614         { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
615         { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 },
616         { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 },
617         { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 },
618         { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 },
619         { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 },
620         { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 },
621         { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 },
622         { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 },
623         { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 },
624         { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
625         { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
626         { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 },
627         { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 },
628         { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 },
629         { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
630         { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
631         { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
632         { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
633         { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
634         { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 },
635         { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
636         { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
637         { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
638         { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
639         { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
640         { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
641         { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
642         { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }
643 };
644
645 static const struct bwn_b206x_chan bwn_b2063_chantable[] = {
646         { 1, 2412, bwn_b2063_chantable_data[0] },
647         { 2, 2417, bwn_b2063_chantable_data[0] },
648         { 3, 2422, bwn_b2063_chantable_data[0] },
649         { 4, 2427, bwn_b2063_chantable_data[1] },
650         { 5, 2432, bwn_b2063_chantable_data[1] },
651         { 6, 2437, bwn_b2063_chantable_data[1] },
652         { 7, 2442, bwn_b2063_chantable_data[1] },
653         { 8, 2447, bwn_b2063_chantable_data[1] },
654         { 9, 2452, bwn_b2063_chantable_data[2] },
655         { 10, 2457, bwn_b2063_chantable_data[2] },
656         { 11, 2462, bwn_b2063_chantable_data[3] },
657         { 12, 2467, bwn_b2063_chantable_data[3] },
658         { 13, 2472, bwn_b2063_chantable_data[3] },
659         { 14, 2484, bwn_b2063_chantable_data[4] },
660         { 34, 5170, bwn_b2063_chantable_data[5] },
661         { 36, 5180, bwn_b2063_chantable_data[6] },
662         { 38, 5190, bwn_b2063_chantable_data[7] },
663         { 40, 5200, bwn_b2063_chantable_data[8] },
664         { 42, 5210, bwn_b2063_chantable_data[9] },
665         { 44, 5220, bwn_b2063_chantable_data[10] },
666         { 46, 5230, bwn_b2063_chantable_data[11] },
667         { 48, 5240, bwn_b2063_chantable_data[12] },
668         { 52, 5260, bwn_b2063_chantable_data[13] },
669         { 56, 5280, bwn_b2063_chantable_data[14] },
670         { 60, 5300, bwn_b2063_chantable_data[14] },
671         { 64, 5320, bwn_b2063_chantable_data[15] },
672         { 100, 5500, bwn_b2063_chantable_data[16] },
673         { 104, 5520, bwn_b2063_chantable_data[17] },
674         { 108, 5540, bwn_b2063_chantable_data[18] },
675         { 112, 5560, bwn_b2063_chantable_data[19] },
676         { 116, 5580, bwn_b2063_chantable_data[20] },
677         { 120, 5600, bwn_b2063_chantable_data[21] },
678         { 124, 5620, bwn_b2063_chantable_data[21] },
679         { 128, 5640, bwn_b2063_chantable_data[22] },
680         { 132, 5660, bwn_b2063_chantable_data[22] },
681         { 136, 5680, bwn_b2063_chantable_data[22] },
682         { 140, 5700, bwn_b2063_chantable_data[23] },
683         { 149, 5745, bwn_b2063_chantable_data[23] },
684         { 153, 5765, bwn_b2063_chantable_data[23] },
685         { 157, 5785, bwn_b2063_chantable_data[23] },
686         { 161, 5805, bwn_b2063_chantable_data[23] },
687         { 165, 5825, bwn_b2063_chantable_data[23] },
688         { 184, 4920, bwn_b2063_chantable_data[24] },
689         { 188, 4940, bwn_b2063_chantable_data[25] },
690         { 192, 4960, bwn_b2063_chantable_data[26] },
691         { 196, 4980, bwn_b2063_chantable_data[27] },
692         { 200, 5000, bwn_b2063_chantable_data[28] },
693         { 204, 5020, bwn_b2063_chantable_data[29] },
694         { 208, 5040, bwn_b2063_chantable_data[30] },
695         { 212, 5060, bwn_b2063_chantable_data[31] },
696         { 216, 5080, bwn_b2063_chantable_data[32] }
697 };
698
699 static const uint8_t bwn_b2062_chantable_data[22][12] = {
700         { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 },
701         { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
702         { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
703         { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
704         { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
705         { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
706         { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
707         { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
708         { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
709         { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
710         { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
711         { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
712         { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
713         { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
714         { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
715         { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
716         { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
717         { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
718         { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
719         { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
720         { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
721         { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }
722 };
723
724 static const struct bwn_b206x_chan bwn_b2062_chantable[] = {
725         { 1, 2412, bwn_b2062_chantable_data[0] },
726         { 2, 2417, bwn_b2062_chantable_data[0] },
727         { 3, 2422, bwn_b2062_chantable_data[0] },
728         { 4, 2427, bwn_b2062_chantable_data[0] },
729         { 5, 2432, bwn_b2062_chantable_data[0] },
730         { 6, 2437, bwn_b2062_chantable_data[0] },
731         { 7, 2442, bwn_b2062_chantable_data[0] },
732         { 8, 2447, bwn_b2062_chantable_data[0] },
733         { 9, 2452, bwn_b2062_chantable_data[0] },
734         { 10, 2457, bwn_b2062_chantable_data[0] },
735         { 11, 2462, bwn_b2062_chantable_data[0] },
736         { 12, 2467, bwn_b2062_chantable_data[0] },
737         { 13, 2472, bwn_b2062_chantable_data[0] },
738         { 14, 2484, bwn_b2062_chantable_data[0] },
739         { 34, 5170, bwn_b2062_chantable_data[1] },
740         { 38, 5190, bwn_b2062_chantable_data[2] },
741         { 42, 5210, bwn_b2062_chantable_data[2] },
742         { 46, 5230, bwn_b2062_chantable_data[3] },
743         { 36, 5180, bwn_b2062_chantable_data[4] },
744         { 40, 5200, bwn_b2062_chantable_data[5] },
745         { 44, 5220, bwn_b2062_chantable_data[6] },
746         { 48, 5240, bwn_b2062_chantable_data[3] },
747         { 52, 5260, bwn_b2062_chantable_data[3] },
748         { 56, 5280, bwn_b2062_chantable_data[3] },
749         { 60, 5300, bwn_b2062_chantable_data[7] },
750         { 64, 5320, bwn_b2062_chantable_data[8] },
751         { 100, 5500, bwn_b2062_chantable_data[9] },
752         { 104, 5520, bwn_b2062_chantable_data[10] },
753         { 108, 5540, bwn_b2062_chantable_data[10] },
754         { 112, 5560, bwn_b2062_chantable_data[10] },
755         { 116, 5580, bwn_b2062_chantable_data[11] },
756         { 120, 5600, bwn_b2062_chantable_data[12] },
757         { 124, 5620, bwn_b2062_chantable_data[12] },
758         { 128, 5640, bwn_b2062_chantable_data[12] },
759         { 132, 5660, bwn_b2062_chantable_data[12] },
760         { 136, 5680, bwn_b2062_chantable_data[12] },
761         { 140, 5700, bwn_b2062_chantable_data[12] },
762         { 149, 5745, bwn_b2062_chantable_data[12] },
763         { 153, 5765, bwn_b2062_chantable_data[12] },
764         { 157, 5785, bwn_b2062_chantable_data[12] },
765         { 161, 5805, bwn_b2062_chantable_data[12] },
766         { 165, 5825, bwn_b2062_chantable_data[12] },
767         { 184, 4920, bwn_b2062_chantable_data[13] },
768         { 188, 4940, bwn_b2062_chantable_data[14] },
769         { 192, 4960, bwn_b2062_chantable_data[15] },
770         { 196, 4980, bwn_b2062_chantable_data[16] },
771         { 200, 5000, bwn_b2062_chantable_data[17] },
772         { 204, 5020, bwn_b2062_chantable_data[18] },
773         { 208, 5040, bwn_b2062_chantable_data[19] },
774         { 212, 5060, bwn_b2062_chantable_data[20] },
775         { 216, 5080, bwn_b2062_chantable_data[21] }
776 };
777
778 /* for LP PHY */
779 static const struct bwn_rxcompco bwn_rxcompco_5354[] = {
780         {  1, -66, 15 }, {  2, -66, 15 }, {  3, -66, 15 }, {  4, -66, 15 },
781         {  5, -66, 15 }, {  6, -66, 15 }, {  7, -66, 14 }, {  8, -66, 14 },
782         {  9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 },
783         { 13, -66, 13 }, { 14, -66, 13 },
784 };
785
786 /* for LP PHY */
787 static const struct bwn_rxcompco bwn_rxcompco_r12[] = {
788         {   1, -64, 13 }, {   2, -64, 13 }, {   3, -64, 13 }, {   4, -64, 13 },
789         {   5, -64, 12 }, {   6, -64, 12 }, {   7, -64, 12 }, {   8, -64, 12 },
790         {   9, -64, 12 }, {  10, -64, 11 }, {  11, -64, 11 }, {  12, -64, 11 },
791         {  13, -64, 11 }, {  14, -64, 10 }, {  34, -62, 24 }, {  38, -62, 24 },
792         {  42, -62, 24 }, {  46, -62, 23 }, {  36, -62, 24 }, {  40, -62, 24 },
793         {  44, -62, 23 }, {  48, -62, 23 }, {  52, -62, 23 }, {  56, -62, 22 },
794         {  60, -62, 22 }, {  64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 },
795         { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 },
796         { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 },
797         { 140, -62, 10 }, { 149, -61,  9 }, { 153, -61,  9 }, { 157, -61,  9 },
798         { 161, -61,  8 }, { 165, -61,  8 }, { 184, -62, 25 }, { 188, -62, 25 },
799         { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 },
800         { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 },
801 };
802
803 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 };
804
805 static const uint8_t bwn_tab_sigsq_tbl[] = {
806         0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd,
807         0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
808         0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00,
809         0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
810         0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
811         0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
812 };
813
814 static const uint8_t bwn_tab_pllfrac_tbl[] = {
815         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80,
816         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
817 };
818
819 static const uint16_t bwn_tabl_iqlocal_tbl[] = {
820         0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002,
821         0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
822         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
823         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
824         0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006,
825         0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
826         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
827         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
828         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
829         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
830         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
831         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
832 };
833
834 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
835 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
836 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
837 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
838 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
839 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
840
841 #define VENDOR_LED_ACT(vendor)                          \
842 {                                                       \
843         .vid = PCI_VENDOR_##vendor,                     \
844         .led_act = { BWN_VENDOR_LED_ACT_##vendor }      \
845 }
846
847 static const struct {
848         uint16_t        vid;
849         uint8_t         led_act[BWN_LED_MAX];
850 } bwn_vendor_led_act[] = {
851         VENDOR_LED_ACT(COMPAQ),
852         VENDOR_LED_ACT(ASUSTEK)
853 };
854
855 static const uint8_t bwn_default_led_act[BWN_LED_MAX] =
856         { BWN_VENDOR_LED_ACT_DEFAULT };
857
858 #undef VENDOR_LED_ACT
859
860 static const struct {
861         int             on_dur;
862         int             off_dur;
863 } bwn_led_duration[109] = {
864         [0]     = { 400, 100 },
865         [2]     = { 150, 75 },
866         [4]     = { 90, 45 },
867         [11]    = { 66, 34 },
868         [12]    = { 53, 26 },
869         [18]    = { 42, 21 },
870         [22]    = { 35, 17 },
871         [24]    = { 32, 16 },
872         [36]    = { 21, 10 },
873         [48]    = { 16, 8 },
874         [72]    = { 11, 5 },
875         [96]    = { 9, 4 },
876         [108]   = { 7, 3 }
877 };
878
879 static const uint16_t bwn_wme_shm_offsets[] = {
880         [0] = BWN_WME_BESTEFFORT,
881         [1] = BWN_WME_BACKGROUND,
882         [2] = BWN_WME_VOICE,
883         [3] = BWN_WME_VIDEO,
884 };
885
886 static const struct siba_devid bwn_devs[] = {
887         SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"),
888         SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"),
889         SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"),
890         SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"),
891         SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"),
892         SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"),
893         SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"),
894         SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"),
895         SIBA_DEV(BROADCOM, 80211, 16, "Revision 16")
896 };
897
898 static int
899 bwn_probe(device_t dev)
900 {
901         int i;
902
903         wlan_serialize_enter();
904
905         for (i = 0; i < NELEM(bwn_devs); i++) {
906                 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor &&
907                     siba_get_device(dev) == bwn_devs[i].sd_device &&
908                     siba_get_revid(dev) == bwn_devs[i].sd_rev) {
909                         wlan_serialize_exit();
910                         return (BUS_PROBE_DEFAULT);
911                 }
912         }
913         wlan_serialize_exit();
914         return (ENXIO);
915 }
916
917 static int
918 bwn_attach(device_t dev)
919 {
920         struct bwn_mac *mac;
921         struct bwn_softc *sc = device_get_softc(dev);
922         int error;
923         u_int irq_flags;
924
925         wlan_serialize_enter();
926
927         sc->sc_dev = dev;
928 #ifdef BWN_DEBUG
929         sc->sc_debug = bwn_debug;
930 #endif
931
932         if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
933                 error = bwn_attach_pre(sc);
934                 if (error != 0) {
935                         wlan_serialize_exit();
936                         return (error);
937                 }
938                 bwn_sprom_bugfixes(dev);
939                 sc->sc_flags |= BWN_FLAG_ATTACHED;
940         }
941
942         if (!TAILQ_EMPTY(&sc->sc_maclist)) {
943                 if (siba_get_pci_device(dev) != 0x4313 &&
944                     siba_get_pci_device(dev) != 0x431a &&
945                     siba_get_pci_device(dev) != 0x4321) {
946                         device_printf(sc->sc_dev,
947                             "skip 802.11 cores\n");
948                         wlan_serialize_exit();
949                         return (ENODEV);
950                 }
951         }
952
953         mac = (struct bwn_mac *)kmalloc(sizeof(*mac), M_DEVBUF,
954             M_INTWAIT | M_ZERO);
955         mac->mac_sc = sc;
956         mac->mac_status = BWN_MAC_STATUS_UNINIT;
957         if (bwn_bfp != 0)
958                 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
959
960         TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac);
961         TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac);
962         TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac);
963
964         error = bwn_attach_core(mac);
965         if (error)
966                 goto fail0;
967         bwn_led_attach(mac);
968
969         device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) "
970             "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
971             siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev),
972             mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev,
973             mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver,
974             mac->mac_phy.rf_rev);
975         if (mac->mac_flags & BWN_MAC_FLAG_DMA)
976                 device_printf(sc->sc_dev, "DMA (%d bits)\n",
977                     mac->mac_method.dma.dmatype);
978         else
979                 device_printf(sc->sc_dev, "PIO\n");
980
981         /* Allocate IRQ resource. */
982         sc->bwn_irq_rid = 0;
983         sc->bwn_irq_type = pci_alloc_1intr(sc->sc_dev, bwn_msi_enable,
984             &sc->bwn_irq_rid, &irq_flags);
985         if ((sc->bwn_irq = bus_alloc_resource_any(sc->sc_dev, SYS_RES_IRQ,
986             &sc->bwn_irq_rid, irq_flags)) == NULL) {
987                 device_printf(sc->sc_dev, "Cannot allocate interrupt\n");
988                 error = EINVAL;
989                 goto fail1;
990         }
991         if ((error = bus_setup_intr(sc->sc_dev, sc->bwn_irq, INTR_MPSAFE,
992                 bwn_intr, mac, &sc->bwn_intr, &wlan_global_serializer)) != 0) {
993                 device_printf(sc->sc_dev, "Cannot set up interrupt\n");
994                 goto fail1;
995         }
996
997         TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list);
998
999         /*
1000          * calls attach-post routine
1001          */
1002         if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0)
1003                 bwn_attach_post(sc);
1004
1005         wlan_serialize_exit();
1006         return (0);
1007 fail1:
1008         if (sc->bwn_irq_type == PCI_INTR_TYPE_MSI)
1009                 pci_release_msi(dev);
1010 fail0:
1011         kfree(mac, M_DEVBUF);
1012         wlan_serialize_exit();
1013         return (error);
1014 }
1015
1016 static int
1017 bwn_is_valid_ether_addr(uint8_t *addr)
1018 {
1019         char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
1020
1021         if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN)))
1022                 return (FALSE);
1023
1024         return (TRUE);
1025 }
1026
1027 static int
1028 bwn_attach_post(struct bwn_softc *sc)
1029 {
1030         struct ieee80211com *ic;
1031         struct ifnet *ifp = sc->sc_ifp;
1032
1033         ic = ifp->if_l2com;
1034         ic->ic_ifp = ifp;
1035         /* XXX not right but it's not used anywhere important */
1036         ic->ic_phytype = IEEE80211_T_OFDM;
1037         ic->ic_opmode = IEEE80211_M_STA;
1038         ic->ic_caps =
1039                   IEEE80211_C_STA               /* station mode supported */
1040                 | IEEE80211_C_MONITOR           /* monitor mode */
1041                 | IEEE80211_C_AHDEMO            /* adhoc demo mode */
1042                 | IEEE80211_C_SHPREAMBLE        /* short preamble supported */
1043                 | IEEE80211_C_SHSLOT            /* short slot time supported */
1044                 | IEEE80211_C_WME               /* WME/WMM supported */
1045                 | IEEE80211_C_WPA               /* capable of WPA1+WPA2 */
1046                 | IEEE80211_C_BGSCAN            /* capable of bg scanning */
1047                 | IEEE80211_C_TXPMGT            /* capable of txpow mgt */
1048                 ;
1049
1050         ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;     /* s/w bmiss */
1051
1052         /* call MI attach routine. */
1053         ieee80211_ifattach(ic,
1054             bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
1055             siba_sprom_get_mac_80211a(sc->sc_dev) :
1056             siba_sprom_get_mac_80211bg(sc->sc_dev));
1057
1058         ic->ic_headroom = sizeof(struct bwn_txhdr);
1059
1060         /* override default methods */
1061         ic->ic_raw_xmit = bwn_raw_xmit;
1062         ic->ic_updateslot = bwn_updateslot;
1063         ic->ic_update_promisc = bwn_update_promisc;
1064         ic->ic_wme.wme_update = bwn_wme_update;
1065
1066         ic->ic_scan_start = bwn_scan_start;
1067         ic->ic_scan_end = bwn_scan_end;
1068         ic->ic_set_channel = bwn_set_channel;
1069
1070         ic->ic_vap_create = bwn_vap_create;
1071         ic->ic_vap_delete = bwn_vap_delete;
1072
1073         ieee80211_radiotap_attach(ic,
1074             &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
1075             BWN_TX_RADIOTAP_PRESENT,
1076             &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
1077             BWN_RX_RADIOTAP_PRESENT);
1078
1079         bwn_sysctl_node(sc);
1080
1081         if (bootverbose)
1082                 ieee80211_announce(ic);
1083         return (0);
1084 }
1085
1086 static void
1087 bwn_phy_detach(struct bwn_mac *mac)
1088 {
1089
1090         if (mac->mac_phy.detach != NULL)
1091                 mac->mac_phy.detach(mac);
1092 }
1093
1094 static int
1095 bwn_detach(device_t dev)
1096 {
1097         struct bwn_softc *sc = device_get_softc(dev);
1098         struct bwn_mac *mac = sc->sc_curmac;
1099         struct ifnet *ifp = sc->sc_ifp;
1100         struct ieee80211com *ic = ifp->if_l2com;
1101
1102         wlan_serialize_enter();
1103
1104         sc->sc_flags |= BWN_FLAG_INVALID;
1105
1106         if (device_is_attached(sc->sc_dev)) {
1107                 bwn_stop(sc, 1);
1108                 bwn_dma_free(mac);
1109                 callout_stop_sync(&sc->sc_led_blink_ch);
1110                 callout_stop_sync(&sc->sc_rfswitch_ch);
1111                 callout_stop_sync(&sc->sc_task_ch);
1112                 callout_stop_sync(&sc->sc_watchdog_ch);
1113                 bwn_phy_detach(mac);
1114                 if (ifp != NULL) {
1115                         wlan_serialize_exit();
1116                         ieee80211_draintask(ic, &mac->mac_hwreset);
1117                         ieee80211_draintask(ic, &mac->mac_txpower);
1118                         wlan_serialize_enter();
1119                         ieee80211_ifdetach(ic);
1120                         if_free(ifp);
1121                 }
1122         }
1123         wlan_serialize_exit();
1124         taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
1125         taskqueue_free(sc->sc_tq);
1126         wlan_serialize_enter();
1127
1128         if (sc->bwn_intr)
1129                 bus_teardown_intr(dev, sc->bwn_irq, sc->bwn_intr);
1130         if (sc->bwn_irq != NULL)
1131                 bus_release_resource(dev, SYS_RES_IRQ, sc->bwn_irq_rid,
1132                     sc->bwn_irq);
1133
1134         if (sc->bwn_irq_type == PCI_INTR_TYPE_MSI)
1135                 pci_release_msi(dev);
1136
1137         wlan_serialize_exit();
1138         return (0);
1139 }
1140
1141 static int
1142 bwn_attach_pre(struct bwn_softc *sc)
1143 {
1144         struct ifnet *ifp;
1145         int error = 0;
1146
1147         TAILQ_INIT(&sc->sc_maclist);
1148         callout_init(&sc->sc_rfswitch_ch);
1149         callout_init(&sc->sc_task_ch);
1150         callout_init(&sc->sc_watchdog_ch);
1151
1152         sc->sc_tq = taskqueue_create("bwn_taskq", M_WAITOK,
1153                 taskqueue_thread_enqueue, &sc->sc_tq);
1154         taskqueue_start_threads(&sc->sc_tq, 1, TDPRI_KERN_DAEMON, -1,
1155                 "%s taskq", device_get_nameunit(sc->sc_dev));
1156
1157         ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
1158         if (ifp == NULL) {
1159                 device_printf(sc->sc_dev, "can not if_alloc()\n");
1160                 error = ENOSPC;
1161                 goto fail;
1162         }
1163
1164         /* set these up early for if_printf use */
1165         if_initname(ifp, device_get_name(sc->sc_dev),
1166             device_get_unit(sc->sc_dev));
1167
1168         ifp->if_softc = sc;
1169         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1170         ifp->if_init = bwn_init;
1171         ifp->if_ioctl = bwn_ioctl;
1172         ifp->if_start = bwn_start;
1173         ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
1174
1175         return (0);
1176
1177 fail:
1178         return (error);
1179 }
1180
1181 static void
1182 bwn_sprom_bugfixes(device_t dev)
1183 {
1184 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice)             \
1185         ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) &&          \
1186          (siba_get_pci_device(dev) == _device) &&                       \
1187          (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) &&    \
1188          (siba_get_pci_subdevice(dev) == _subdevice))
1189
1190         if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
1191             siba_get_pci_subdevice(dev) == 0x4e &&
1192             siba_get_pci_revid(dev) > 0x40)
1193                 siba_sprom_set_bf_lo(dev,
1194                     siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
1195         if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
1196             siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
1197                 siba_sprom_set_bf_lo(dev,
1198                     siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
1199         if (siba_get_type(dev) == SIBA_TYPE_PCI) {
1200                 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1201                     BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1202                     BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1203                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1204                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1205                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1206                     BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1207                         siba_sprom_set_bf_lo(dev,
1208                             siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
1209         }
1210 #undef  BWN_ISDEV
1211 }
1212
1213 static int
1214 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data,
1215           struct ucred *cr __unused)
1216 {
1217 #define IS_RUNNING(ifp) \
1218         ((ifp->if_flags & IFF_UP) && (ifp->if_flags & IFF_RUNNING))
1219         struct bwn_softc *sc = ifp->if_softc;
1220         struct ieee80211com *ic = ifp->if_l2com;
1221         struct ifreq *ifr = (struct ifreq *)data;
1222         int error = 0;
1223
1224         switch (cmd) {
1225         case SIOCSIFFLAGS:
1226                 if (IS_RUNNING(ifp)) {
1227                         bwn_update_promisc(ifp);
1228                 } else if (ifp->if_flags & IFF_UP) {
1229                         if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
1230                                 bwn_init(sc);
1231                         }
1232                 } else
1233                         bwn_stop(sc, 1);
1234                 break;
1235         case SIOCGIFMEDIA:
1236                 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1237                 break;
1238         case SIOCGIFADDR:
1239                 error = ether_ioctl(ifp, cmd, data);
1240                 break;
1241         default:
1242                 error = EINVAL;
1243                 break;
1244         }
1245         return (error);
1246 }
1247
1248 static void
1249 bwn_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
1250 {
1251         wlan_assert_serialized();
1252         bwn_start_locked(ifp);
1253 }
1254
1255 static void
1256 bwn_start_locked(struct ifnet *ifp)
1257 {
1258         struct bwn_softc *sc = ifp->if_softc;
1259         struct bwn_mac *mac = sc->sc_curmac;
1260         struct ieee80211_frame *wh;
1261         struct ieee80211_node *ni;
1262         struct ieee80211_key *k;
1263         struct mbuf *m;
1264
1265         wlan_assert_serialized();
1266
1267         if ((ifp->if_flags & IFF_RUNNING) == 0 || mac == NULL ||
1268             mac->mac_status < BWN_MAC_STATUS_STARTED)
1269                 return;
1270
1271         for (;;) {
1272                 m = ifq_dequeue(&ifp->if_snd);  /* XXX: LOCK */
1273                 if (m == NULL)
1274                         break;
1275
1276                 if (bwn_tx_isfull(sc, m))
1277                         break;
1278                 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1279                 if (ni == NULL) {
1280                         device_printf(sc->sc_dev, "unexpected NULL ni\n");
1281                         m_freem(m);
1282                         ifp->if_oerrors++;
1283                         continue;
1284                 }
1285                 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
1286                 wh = mtod(m, struct ieee80211_frame *);
1287                 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1288                         k = ieee80211_crypto_encap(ni, m);
1289                         if (k == NULL) {
1290                                 ieee80211_free_node(ni);
1291                                 m_freem(m);
1292                                 ifp->if_oerrors++;
1293                                 continue;
1294                         }
1295                 }
1296                 wh = NULL;      /* Catch any invalid use */
1297
1298                 if (bwn_tx_start(sc, ni, m) != 0) {
1299                         if (ni != NULL)
1300                                 ieee80211_free_node(ni);
1301                         ifp->if_oerrors++;
1302                         continue;
1303                 }
1304
1305                 sc->sc_watchdog_timer = 5;
1306         }
1307 }
1308
1309 static int
1310 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1311 {
1312         struct bwn_dma_ring *dr;
1313         struct bwn_mac *mac = sc->sc_curmac;
1314         struct bwn_pio_txqueue *tq;
1315         struct ifnet *ifp = sc->sc_ifp;
1316         int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1317
1318         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1319                 dr = bwn_dma_select(mac, M_WME_GETAC(m));
1320                 if (dr->dr_stop == 1 ||
1321                     bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1322                         dr->dr_stop = 1;
1323                         goto full;
1324                 }
1325         } else {
1326                 tq = bwn_pio_select(mac, M_WME_GETAC(m));
1327                 if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1328                     pktlen > (tq->tq_size - tq->tq_used)) {
1329                         tq->tq_stop = 1;
1330                         goto full;
1331                 }
1332         }
1333         return (0);
1334 full:
1335         ifq_prepend(&ifp->if_snd, m);
1336         ifq_set_oactive(&ifp->if_snd);
1337         return (1);
1338 }
1339
1340 static int
1341 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1342 {
1343         struct bwn_mac *mac = sc->sc_curmac;
1344         int error;
1345
1346         if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1347                 m_freem(m);
1348                 return (ENXIO);
1349         }
1350
1351         error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1352             bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1353         if (error) {
1354                 m_freem(m);
1355                 return (error);
1356         }
1357         return (0);
1358 }
1359
1360 static int
1361 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1362 {
1363         struct bwn_pio_txpkt *tp;
1364         struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1365         struct bwn_softc *sc = mac->mac_sc;
1366         struct bwn_txhdr txhdr;
1367         struct mbuf *m_new;
1368         uint32_t ctl32;
1369         int error;
1370         uint16_t ctl16;
1371
1372         /* XXX TODO send packets after DTIM */
1373
1374         KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1375         tp = TAILQ_FIRST(&tq->tq_pktlist);
1376         tp->tp_ni = ni;
1377         tp->tp_m = m;
1378
1379         error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1380         if (error) {
1381                 device_printf(sc->sc_dev, "tx fail\n");
1382                 return (error);
1383         }
1384
1385         TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1386         tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1387         tq->tq_free--;
1388
1389         if (siba_get_revid(sc->sc_dev) >= 8) {
1390                 /*
1391                  * XXX please removes m_defrag(9)
1392                  */
1393                 m_new = m_defrag(m, MB_DONTWAIT);
1394                 if (m_new == NULL) {
1395                         device_printf(sc->sc_dev,
1396                             "%s: can't defrag TX buffer\n",
1397                             __func__);
1398                         return (ENOBUFS);
1399                 }
1400                 if (m_new->m_next != NULL)
1401                         device_printf(sc->sc_dev,
1402                             "TODO: fragmented packets for PIO\n");
1403                 tp->tp_m = m_new;
1404
1405                 /* send HEADER */
1406                 ctl32 = bwn_pio_write_multi_4(mac, tq,
1407                     (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1408                         BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1409                     (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1410                 /* send BODY */
1411                 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1412                     mtod(m_new, const void *), m_new->m_pkthdr.len);
1413                 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1414                     ctl32 | BWN_PIO8_TXCTL_EOF);
1415         } else {
1416                 ctl16 = bwn_pio_write_multi_2(mac, tq,
1417                     (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1418                         BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1419                     (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1420                 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1421                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1422                     ctl16 | BWN_PIO_TXCTL_EOF);
1423         }
1424
1425         return (0);
1426 }
1427
1428 static struct bwn_pio_txqueue *
1429 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1430 {
1431
1432         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1433                 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1434
1435         switch (prio) {
1436         case 0:
1437                 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1438         case 1:
1439                 return (&mac->mac_method.pio.wme[WME_AC_BK]);
1440         case 2:
1441                 return (&mac->mac_method.pio.wme[WME_AC_VI]);
1442         case 3:
1443                 return (&mac->mac_method.pio.wme[WME_AC_VO]);
1444         }
1445         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1446         return (NULL);
1447 }
1448
1449 static int
1450 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1451 {
1452 #define BWN_GET_TXHDRCACHE(slot)                                        \
1453         &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_MAX_HDRSIZE(mac)])
1454         struct bwn_dma *dma = &mac->mac_method.dma;
1455         struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1456         struct bwn_dmadesc_generic *desc;
1457         struct bwn_dmadesc_meta *mt;
1458         struct bwn_softc *sc = mac->mac_sc;
1459         struct ifnet *ifp = sc->sc_ifp;
1460         uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1461         int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1462
1463         KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1464
1465         /* XXX send after DTIM */
1466
1467         slot = bwn_dma_getslot(dr);
1468         dr->getdesc(dr, slot, &desc, &mt);
1469         KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1470             ("%s:%d: fail", __func__, __LINE__));
1471
1472         error = bwn_set_txhdr(dr->dr_mac, ni, m,
1473             (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1474             BWN_DMA_COOKIE(dr, slot));
1475         if (error)
1476                 goto fail;
1477         bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1478             BUS_DMASYNC_PREWRITE);
1479         dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1480         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1481             BUS_DMASYNC_PREWRITE);
1482
1483         slot = bwn_dma_getslot(dr);
1484         dr->getdesc(dr, slot, &desc, &mt);
1485         KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1486             mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1487         mt->mt_m = m;
1488         mt->mt_ni = ni;
1489
1490         error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1491             bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1492         if (error && error != EFBIG) {
1493                 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1494                     __func__, error);
1495                 goto fail;
1496         }
1497         if (error) {    /* error == EFBIG */
1498                 struct mbuf *m_new;
1499
1500                 m_new = m_defrag(m, MB_DONTWAIT);
1501                 if (m_new == NULL) {
1502                         if_printf(ifp, "%s: can't defrag TX buffer\n",
1503                             __func__);
1504                         error = ENOBUFS;
1505                         goto fail;
1506                 } else {
1507                         m = m_new;
1508                 }
1509
1510                 mt->mt_m = m;
1511                 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1512                     m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1513                 if (error) {
1514                         if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
1515                             __func__, error);
1516                         goto fail;
1517                 }
1518         }
1519         bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1520         dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1521         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1522             BUS_DMASYNC_PREWRITE);
1523
1524         /* XXX send after DTIM */
1525
1526         dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1527         return (0);
1528 fail:
1529         dr->dr_curslot = backup[0];
1530         dr->dr_usedslot = backup[1];
1531         return (error);
1532 #undef BWN_GET_TXHDRCACHE
1533 }
1534
1535 static void
1536 bwn_watchdog(void *arg)
1537 {
1538         struct bwn_softc *sc = arg;
1539         struct ifnet *ifp = sc->sc_ifp;
1540
1541         wlan_serialize_enter();
1542
1543         if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1544                 if_printf(ifp, "device timeout\n");
1545                 ifp->if_oerrors++;
1546         }
1547         callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
1548         wlan_serialize_exit();
1549 }
1550
1551 static int
1552 bwn_attach_core(struct bwn_mac *mac)
1553 {
1554         struct bwn_softc *sc = mac->mac_sc;
1555         int error, have_bg = 0, have_a = 0;
1556         uint32_t high;
1557
1558         KASSERT(siba_get_revid(sc->sc_dev) >= 5,
1559             ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
1560
1561         siba_powerup(sc->sc_dev, 0);
1562
1563         high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
1564         bwn_reset_core(mac,
1565             (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1566         error = bwn_phy_getinfo(mac, high);
1567         if (error)
1568                 goto fail;
1569
1570         have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1571         have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1572         if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
1573             siba_get_pci_device(sc->sc_dev) != 0x4319 &&
1574             siba_get_pci_device(sc->sc_dev) != 0x4324) {
1575                 have_a = have_bg = 0;
1576                 if (mac->mac_phy.type == BWN_PHYTYPE_A)
1577                         have_a = 1;
1578                 else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1579                     mac->mac_phy.type == BWN_PHYTYPE_N ||
1580                     mac->mac_phy.type == BWN_PHYTYPE_LP)
1581                         have_bg = 1;
1582                 else
1583                         KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1584                             mac->mac_phy.type));
1585         }
1586         /* XXX turns off PHY A because it's not supported */
1587         if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1588             mac->mac_phy.type != BWN_PHYTYPE_N) {
1589                 have_a = 0;
1590                 have_bg = 1;
1591         }
1592
1593         if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1594                 mac->mac_phy.attach = bwn_phy_g_attach;
1595                 mac->mac_phy.detach = bwn_phy_g_detach;
1596                 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1597                 mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1598                 mac->mac_phy.init = bwn_phy_g_init;
1599                 mac->mac_phy.exit = bwn_phy_g_exit;
1600                 mac->mac_phy.phy_read = bwn_phy_g_read;
1601                 mac->mac_phy.phy_write = bwn_phy_g_write;
1602                 mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1603                 mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1604                 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1605                 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1606                 mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1607                 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1608                 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1609                 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1610                 mac->mac_phy.set_im = bwn_phy_g_im;
1611                 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1612                 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1613                 mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1614                 mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1615         } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1616                 mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1617                 mac->mac_phy.init = bwn_phy_lp_init;
1618                 mac->mac_phy.phy_read = bwn_phy_lp_read;
1619                 mac->mac_phy.phy_write = bwn_phy_lp_write;
1620                 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1621                 mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1622                 mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1623                 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1624                 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1625                 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1626                 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1627                 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1628                 mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1629         } else {
1630                 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1631                     mac->mac_phy.type);
1632                 error = ENXIO;
1633                 goto fail;
1634         }
1635
1636         mac->mac_phy.gmode = have_bg;
1637         if (mac->mac_phy.attach != NULL) {
1638                 error = mac->mac_phy.attach(mac);
1639                 if (error) {
1640                         device_printf(sc->sc_dev, "failed\n");
1641                         goto fail;
1642                 }
1643         }
1644
1645         bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1646
1647         error = bwn_chiptest(mac);
1648         if (error)
1649                 goto fail;
1650         error = bwn_setup_channels(mac, have_bg, have_a);
1651         if (error) {
1652                 device_printf(sc->sc_dev, "failed to setup channels\n");
1653                 goto fail;
1654         }
1655
1656         if (sc->sc_curmac == NULL)
1657                 sc->sc_curmac = mac;
1658
1659         wlan_assert_serialized();
1660         wlan_serialize_exit();
1661         error = bwn_dma_attach(mac);
1662         wlan_serialize_enter();
1663         if (error != 0) {
1664                 device_printf(sc->sc_dev, "failed to initialize DMA\n");
1665                 goto fail;
1666         }
1667
1668         mac->mac_phy.switch_analog(mac, 0);
1669
1670         siba_dev_down(sc->sc_dev, 0);
1671 fail:
1672         siba_powerdown(sc->sc_dev);
1673         return (error);
1674 }
1675
1676 static void
1677 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1678 {
1679         struct bwn_softc *sc = mac->mac_sc;
1680         uint32_t low, ctl;
1681
1682         flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1683
1684         siba_dev_up(sc->sc_dev, flags);
1685         DELAY(2000);
1686
1687         low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1688             ~BWN_TGSLOW_PHYRESET;
1689         siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
1690         siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1691         DELAY(1000);
1692         siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1693         siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1694         DELAY(1000);
1695
1696         if (mac->mac_phy.switch_analog != NULL)
1697                 mac->mac_phy.switch_analog(mac, 1);
1698
1699         ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1700         if (flags & BWN_TGSLOW_SUPPORT_G)
1701                 ctl |= BWN_MACCTL_GMODE;
1702         BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1703 }
1704
1705 static int
1706 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1707 {
1708         struct bwn_phy *phy = &mac->mac_phy;
1709         struct bwn_softc *sc = mac->mac_sc;
1710         uint32_t tmp;
1711
1712         /* PHY */
1713         tmp = BWN_READ_2(mac, BWN_PHYVER);
1714         phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1715         phy->rf_on = 1;
1716         phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1717         phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1718         phy->rev = (tmp & BWN_PHYVER_VERSION);
1719         if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1720             (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1721                 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1722             (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1723             (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1724             (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1725                 goto unsupphy;
1726
1727         /* RADIO */
1728         if (siba_get_chipid(sc->sc_dev) == 0x4317) {
1729                 if (siba_get_chiprev(sc->sc_dev) == 0)
1730                         tmp = 0x3205017f;
1731                 else if (siba_get_chiprev(sc->sc_dev) == 1)
1732                         tmp = 0x4205017f;
1733                 else
1734                         tmp = 0x5205017f;
1735         } else {
1736                 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1737                 tmp = BWN_READ_2(mac, BWN_RFDATALO);
1738                 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1739                 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1740         }
1741         phy->rf_rev = (tmp & 0xf0000000) >> 28;
1742         phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1743         phy->rf_manuf = (tmp & 0x00000fff);
1744         if (phy->rf_manuf != 0x17f)     /* 0x17f is broadcom */
1745                 goto unsupradio;
1746         if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1747              phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1748             (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1749             (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1750             (phy->type == BWN_PHYTYPE_N &&
1751              phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1752             (phy->type == BWN_PHYTYPE_LP &&
1753              phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1754                 goto unsupradio;
1755
1756         return (0);
1757 unsupphy:
1758         device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1759             "analog %#x)\n",
1760             phy->type, phy->rev, phy->analog);
1761         return (ENXIO);
1762 unsupradio:
1763         device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1764             "rev %#x)\n",
1765             phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1766         return (ENXIO);
1767 }
1768
1769 static int
1770 bwn_chiptest(struct bwn_mac *mac)
1771 {
1772 #define TESTVAL0        0x55aaaa55
1773 #define TESTVAL1        0xaa5555aa
1774         struct bwn_softc *sc = mac->mac_sc;
1775         uint32_t v, backup;
1776
1777         backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1778
1779         bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1780         if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1781                 goto error;
1782         bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1783         if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1784                 goto error;
1785
1786         bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1787
1788         if ((siba_get_revid(sc->sc_dev) >= 3) &&
1789             (siba_get_revid(sc->sc_dev) <= 10)) {
1790                 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1791                 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1792                 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1793                         goto error;
1794                 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1795                         goto error;
1796         }
1797         BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1798
1799         v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1800         if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1801                 goto error;
1802
1803         return (0);
1804 error:
1805         device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1806         return (ENODEV);
1807 }
1808
1809 #define IEEE80211_CHAN_HTG      (IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1810 #define IEEE80211_CHAN_HTA      (IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1811
1812 static int
1813 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1814 {
1815         struct bwn_softc *sc = mac->mac_sc;
1816         struct ifnet *ifp = sc->sc_ifp;
1817         struct ieee80211com *ic = ifp->if_l2com;
1818
1819         memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1820         ic->ic_nchans = 0;
1821
1822         if (have_bg)
1823                 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1824                     &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1825         if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1826                 if (have_a)
1827                         bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1828                             &ic->ic_nchans, &bwn_chantable_n,
1829                             IEEE80211_CHAN_HTA);
1830         } else {
1831                 if (have_a)
1832                         bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1833                             &ic->ic_nchans, &bwn_chantable_a,
1834                             IEEE80211_CHAN_A);
1835         }
1836
1837         mac->mac_phy.supports_2ghz = have_bg;
1838         mac->mac_phy.supports_5ghz = have_a;
1839
1840         return (ic->ic_nchans == 0 ? ENXIO : 0);
1841 }
1842
1843 static uint32_t
1844 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1845 {
1846         uint32_t ret;
1847
1848         if (way == BWN_SHARED) {
1849                 KASSERT((offset & 0x0001) == 0,
1850                     ("%s:%d warn", __func__, __LINE__));
1851                 if (offset & 0x0003) {
1852                         bwn_shm_ctlword(mac, way, offset >> 2);
1853                         ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1854                         ret <<= 16;
1855                         bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1856                         ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1857                         goto out;
1858                 }
1859                 offset >>= 2;
1860         }
1861         bwn_shm_ctlword(mac, way, offset);
1862         ret = BWN_READ_4(mac, BWN_SHM_DATA);
1863 out:
1864         return (ret);
1865 }
1866
1867 static uint16_t
1868 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1869 {
1870         uint16_t ret;
1871
1872         if (way == BWN_SHARED) {
1873                 KASSERT((offset & 0x0001) == 0,
1874                     ("%s:%d warn", __func__, __LINE__));
1875                 if (offset & 0x0003) {
1876                         bwn_shm_ctlword(mac, way, offset >> 2);
1877                         ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1878                         goto out;
1879                 }
1880                 offset >>= 2;
1881         }
1882         bwn_shm_ctlword(mac, way, offset);
1883         ret = BWN_READ_2(mac, BWN_SHM_DATA);
1884 out:
1885
1886         return (ret);
1887 }
1888
1889 static void
1890 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1891     uint16_t offset)
1892 {
1893         uint32_t control;
1894
1895         control = way;
1896         control <<= 16;
1897         control |= offset;
1898         BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1899 }
1900
1901 static void
1902 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1903     uint32_t value)
1904 {
1905         if (way == BWN_SHARED) {
1906                 KASSERT((offset & 0x0001) == 0,
1907                     ("%s:%d warn", __func__, __LINE__));
1908                 if (offset & 0x0003) {
1909                         bwn_shm_ctlword(mac, way, offset >> 2);
1910                         BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1911                                     (value >> 16) & 0xffff);
1912                         bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1913                         BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1914                         return;
1915                 }
1916                 offset >>= 2;
1917         }
1918         bwn_shm_ctlword(mac, way, offset);
1919         BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1920 }
1921
1922 static void
1923 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1924     uint16_t value)
1925 {
1926         if (way == BWN_SHARED) {
1927                 KASSERT((offset & 0x0001) == 0,
1928                     ("%s:%d warn", __func__, __LINE__));
1929                 if (offset & 0x0003) {
1930                         bwn_shm_ctlword(mac, way, offset >> 2);
1931                         BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1932                         return;
1933                 }
1934                 offset >>= 2;
1935         }
1936         bwn_shm_ctlword(mac, way, offset);
1937         BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1938 }
1939
1940 static void
1941 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
1942     int txpow)
1943 {
1944
1945         c->ic_freq = freq;
1946         c->ic_flags = flags;
1947         c->ic_ieee = ieee;
1948         c->ic_minpower = 0;
1949         c->ic_maxpower = 2 * txpow;
1950         c->ic_maxregpower = txpow;
1951 }
1952
1953 static void
1954 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
1955     const struct bwn_channelinfo *ci, int flags)
1956 {
1957         struct ieee80211_channel *c;
1958         int i;
1959
1960         c = &chans[*nchans];
1961
1962         for (i = 0; i < ci->nchannels; i++) {
1963                 const struct bwn_channel *hc;
1964
1965                 hc = &ci->channels[i];
1966                 if (*nchans >= maxchans)
1967                         break;
1968                 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
1969                 c++, (*nchans)++;
1970                 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
1971                         /* g channel have a separate b-only entry */
1972                         if (*nchans >= maxchans)
1973                                 break;
1974                         c[0] = c[-1];
1975                         c[-1].ic_flags = IEEE80211_CHAN_B;
1976                         c++, (*nchans)++;
1977                 }
1978                 if (flags == IEEE80211_CHAN_HTG) {
1979                         /* HT g channel have a separate g-only entry */
1980                         if (*nchans >= maxchans)
1981                                 break;
1982                         c[-1].ic_flags = IEEE80211_CHAN_G;
1983                         c[0] = c[-1];
1984                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
1985                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
1986                         c++, (*nchans)++;
1987                 }
1988                 if (flags == IEEE80211_CHAN_HTA) {
1989                         /* HT a channel have a separate a-only entry */
1990                         if (*nchans >= maxchans)
1991                                 break;
1992                         c[-1].ic_flags = IEEE80211_CHAN_A;
1993                         c[0] = c[-1];
1994                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
1995                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
1996                         c++, (*nchans)++;
1997                 }
1998         }
1999 }
2000
2001 static int
2002 bwn_phy_g_attach(struct bwn_mac *mac)
2003 {
2004         struct bwn_softc *sc = mac->mac_sc;
2005         struct bwn_phy *phy = &mac->mac_phy;
2006         struct bwn_phy_g *pg = &phy->phy_g;
2007         unsigned int i;
2008         int16_t pab0, pab1, pab2;
2009         static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2010         int8_t bg;
2011
2012         bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
2013         pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
2014         pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
2015         pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
2016
2017         if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
2018                 device_printf(sc->sc_dev, "not supported anymore\n");
2019
2020         pg->pg_flags = 0;
2021         if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2022             pab2 == -1) {
2023                 pg->pg_idletssi = 52;
2024                 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2025                 return (0);
2026         }
2027
2028         pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2029         pg->pg_tssi2dbm = (uint8_t *)kmalloc(64, M_DEVBUF, M_INTWAIT | M_ZERO);
2030         for (i = 0; i < 64; i++) {
2031                 int32_t m1, m2, f, q, delta;
2032                 int8_t j = 0;
2033
2034                 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2035                 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2036                 f = 256;
2037
2038                 do {
2039                         if (j > 15) {
2040                                 device_printf(sc->sc_dev,
2041                                     "failed to generate tssi2dBm\n");
2042                                 kfree(pg->pg_tssi2dbm, M_DEVBUF);
2043                                 return (ENOMEM);
2044                         }
2045                         q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2046                             f, 2048);
2047                         delta = abs(q - f);
2048                         f = q;
2049                         j++;
2050                 } while (delta >= 2);
2051
2052                 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2053                     128);
2054         }
2055
2056         pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2057         return (0);
2058 }
2059
2060 static void
2061 bwn_phy_g_detach(struct bwn_mac *mac)
2062 {
2063         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2064
2065         if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2066                 kfree(pg->pg_tssi2dbm, M_DEVBUF);
2067                 pg->pg_tssi2dbm = NULL;
2068         }
2069         pg->pg_flags = 0;
2070 }
2071
2072 static void
2073 bwn_phy_g_init_pre(struct bwn_mac *mac)
2074 {
2075         struct bwn_phy *phy = &mac->mac_phy;
2076         struct bwn_phy_g *pg = &phy->phy_g;
2077         void *tssi2dbm;
2078         int idletssi;
2079         unsigned int i;
2080
2081         tssi2dbm = pg->pg_tssi2dbm;
2082         idletssi = pg->pg_idletssi;
2083
2084         memset(pg, 0, sizeof(*pg));
2085
2086         pg->pg_tssi2dbm = tssi2dbm;
2087         pg->pg_idletssi = idletssi;
2088
2089         memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2090
2091         for (i = 0; i < N(pg->pg_nrssi); i++)
2092                 pg->pg_nrssi[i] = -1000;
2093         for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2094                 pg->pg_nrssi_lt[i] = i;
2095         pg->pg_lofcal = 0xffff;
2096         pg->pg_initval = 0xffff;
2097         pg->pg_immode = BWN_IMMODE_NONE;
2098         pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2099         pg->pg_avgtssi = 0xff;
2100
2101         pg->pg_loctl.tx_bias = 0xff;
2102         TAILQ_INIT(&pg->pg_loctl.calib_list);
2103 }
2104
2105 static int
2106 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2107 {
2108         struct bwn_phy *phy = &mac->mac_phy;
2109         struct bwn_phy_g *pg = &phy->phy_g;
2110         struct bwn_softc *sc = mac->mac_sc;
2111         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2112         static const struct bwn_rfatt rfatt0[] = {
2113                 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
2114                 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2115                 { 3, 1 }, { 4, 1 }
2116         };
2117         static const struct bwn_rfatt rfatt1[] = {
2118                 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2119                 { 14, 1 }
2120         };
2121         static const struct bwn_rfatt rfatt2[] = {
2122                 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2123                 { 9, 1 }
2124         };
2125         static const struct bwn_bbatt bbatt_0[] = {
2126                 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2127         };
2128
2129         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2130
2131         if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2132                 pg->pg_bbatt.att = 0;
2133         else
2134                 pg->pg_bbatt.att = 2;
2135
2136         /* prepare Radio Attenuation */
2137         pg->pg_rfatt.padmix = 0;
2138
2139         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
2140             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
2141                 if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
2142                         pg->pg_rfatt.att = 2;
2143                         goto done;
2144                 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
2145                         pg->pg_rfatt.att = 3;
2146                         goto done;
2147                 }
2148         }
2149
2150         if (phy->type == BWN_PHYTYPE_A) {
2151                 pg->pg_rfatt.att = 0x60;
2152                 goto done;
2153         }
2154
2155         switch (phy->rf_ver) {
2156         case 0x2050:
2157                 switch (phy->rf_rev) {
2158                 case 0:
2159                         pg->pg_rfatt.att = 5;
2160                         goto done;
2161                 case 1:
2162                         if (phy->type == BWN_PHYTYPE_G) {
2163                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2164                                     SIBA_BOARDVENDOR_BCM &&
2165                                     siba_get_pci_subdevice(sc->sc_dev) ==
2166                                     SIBA_BOARD_BCM4309G &&
2167                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2168                                         pg->pg_rfatt.att = 3;
2169                                 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2170                                     SIBA_BOARDVENDOR_BCM &&
2171                                     siba_get_pci_subdevice(sc->sc_dev) ==
2172                                     SIBA_BOARD_BU4306)
2173                                         pg->pg_rfatt.att = 3;
2174                                 else
2175                                         pg->pg_rfatt.att = 1;
2176                         } else {
2177                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2178                                     SIBA_BOARDVENDOR_BCM &&
2179                                     siba_get_pci_subdevice(sc->sc_dev) ==
2180                                     SIBA_BOARD_BCM4309G &&
2181                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2182                                         pg->pg_rfatt.att = 7;
2183                                 else
2184                                         pg->pg_rfatt.att = 6;
2185                         }
2186                         goto done;
2187                 case 2:
2188                         if (phy->type == BWN_PHYTYPE_G) {
2189                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2190                                     SIBA_BOARDVENDOR_BCM &&
2191                                     siba_get_pci_subdevice(sc->sc_dev) ==
2192                                     SIBA_BOARD_BCM4309G &&
2193                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2194                                         pg->pg_rfatt.att = 3;
2195                                 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2196                                     SIBA_BOARDVENDOR_BCM &&
2197                                     siba_get_pci_subdevice(sc->sc_dev) ==
2198                                     SIBA_BOARD_BU4306)
2199                                         pg->pg_rfatt.att = 5;
2200                                 else if (siba_get_chipid(sc->sc_dev) == 0x4320)
2201                                         pg->pg_rfatt.att = 4;
2202                                 else
2203                                         pg->pg_rfatt.att = 3;
2204                         } else
2205                                 pg->pg_rfatt.att = 6;
2206                         goto done;
2207                 case 3:
2208                         pg->pg_rfatt.att = 5;
2209                         goto done;
2210                 case 4:
2211                 case 5:
2212                         pg->pg_rfatt.att = 1;
2213                         goto done;
2214                 case 6:
2215                 case 7:
2216                         pg->pg_rfatt.att = 5;
2217                         goto done;
2218                 case 8:
2219                         pg->pg_rfatt.att = 0xa;
2220                         pg->pg_rfatt.padmix = 1;
2221                         goto done;
2222                 case 9:
2223                 default:
2224                         pg->pg_rfatt.att = 5;
2225                         goto done;
2226                 }
2227                 break;
2228         case 0x2053:
2229                 switch (phy->rf_rev) {
2230                 case 1:
2231                         pg->pg_rfatt.att = 6;
2232                         goto done;
2233                 }
2234                 break;
2235         }
2236         pg->pg_rfatt.att = 5;
2237 done:
2238         pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2239
2240         if (!bwn_has_hwpctl(mac)) {
2241                 lo->rfatt.array = rfatt0;
2242                 lo->rfatt.len = N(rfatt0);
2243                 lo->rfatt.min = 0;
2244                 lo->rfatt.max = 9;
2245                 goto genbbatt;
2246         }
2247         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2248                 lo->rfatt.array = rfatt1;
2249                 lo->rfatt.len = N(rfatt1);
2250                 lo->rfatt.min = 0;
2251                 lo->rfatt.max = 14;
2252                 goto genbbatt;
2253         }
2254         lo->rfatt.array = rfatt2;
2255         lo->rfatt.len = N(rfatt2);
2256         lo->rfatt.min = 0;
2257         lo->rfatt.max = 9;
2258 genbbatt:
2259         lo->bbatt.array = bbatt_0;
2260         lo->bbatt.len = N(bbatt_0);
2261         lo->bbatt.min = 0;
2262         lo->bbatt.max = 8;
2263
2264         BWN_READ_4(mac, BWN_MACCTL);
2265         if (phy->rev == 1) {
2266                 phy->gmode = 0;
2267                 bwn_reset_core(mac, 0);
2268                 bwn_phy_g_init_sub(mac);
2269                 phy->gmode = 1;
2270                 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2271         }
2272         return (0);
2273 }
2274
2275 static uint16_t
2276 bwn_phy_g_txctl(struct bwn_mac *mac)
2277 {
2278         struct bwn_phy *phy = &mac->mac_phy;
2279
2280         if (phy->rf_ver != 0x2050)
2281                 return (0);
2282         if (phy->rf_rev == 1)
2283                 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2284         if (phy->rf_rev < 6)
2285                 return (BWN_TXCTL_PA2DB);
2286         if (phy->rf_rev == 8)
2287                 return (BWN_TXCTL_TXMIX);
2288         return (0);
2289 }
2290
2291 static int
2292 bwn_phy_g_init(struct bwn_mac *mac)
2293 {
2294
2295         bwn_phy_g_init_sub(mac);
2296         return (0);
2297 }
2298
2299 static void
2300 bwn_phy_g_exit(struct bwn_mac *mac)
2301 {
2302         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2303         struct bwn_lo_calib *cal, *tmp;
2304
2305         if (lo == NULL)
2306                 return;
2307         TAILQ_FOREACH_MUTABLE(cal, &lo->calib_list, list, tmp) {
2308                 TAILQ_REMOVE(&lo->calib_list, cal, list);
2309                 kfree(cal, M_DEVBUF);
2310         }
2311 }
2312
2313 static uint16_t
2314 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2315 {
2316
2317         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2318         return (BWN_READ_2(mac, BWN_PHYDATA));
2319 }
2320
2321 static void
2322 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2323 {
2324
2325         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2326         BWN_WRITE_2(mac, BWN_PHYDATA, value);
2327 }
2328
2329 static uint16_t
2330 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2331 {
2332
2333         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2334         BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2335         return (BWN_READ_2(mac, BWN_RFDATALO));
2336 }
2337
2338 static void
2339 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2340 {
2341
2342         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2343         BWN_WRITE_2(mac, BWN_RFCTL, reg);
2344         BWN_WRITE_2(mac, BWN_RFDATALO, value);
2345 }
2346
2347 static int
2348 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2349 {
2350
2351         return (mac->mac_phy.rev >= 6);
2352 }
2353
2354 static void
2355 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2356 {
2357         struct bwn_phy *phy = &mac->mac_phy;
2358         struct bwn_phy_g *pg = &phy->phy_g;
2359         unsigned int channel;
2360         uint16_t rfover, rfoverval;
2361
2362         if (on) {
2363                 if (phy->rf_on)
2364                         return;
2365
2366                 BWN_PHY_WRITE(mac, 0x15, 0x8000);
2367                 BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2368                 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2369                 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2370                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2371                             pg->pg_radioctx_over);
2372                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2373                             pg->pg_radioctx_overval);
2374                         pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2375                 }
2376                 channel = phy->chan;
2377                 bwn_phy_g_switch_chan(mac, 6, 1);
2378                 bwn_phy_g_switch_chan(mac, channel, 0);
2379                 return;
2380         }
2381
2382         rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2383         rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2384         pg->pg_radioctx_over = rfover;
2385         pg->pg_radioctx_overval = rfoverval;
2386         pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2387         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2388         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2389 }
2390
2391 static int
2392 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2393 {
2394
2395         if ((newchan < 1) || (newchan > 14))
2396                 return (EINVAL);
2397         bwn_phy_g_switch_chan(mac, newchan, 0);
2398
2399         return (0);
2400 }
2401
2402 static uint32_t
2403 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2404 {
2405
2406         return (1);
2407 }
2408
2409 static void
2410 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2411 {
2412         struct bwn_phy *phy = &mac->mac_phy;
2413         uint64_t hf;
2414         int autodiv = 0;
2415         uint16_t tmp;
2416
2417         if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2418                 autodiv = 1;
2419
2420         hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2421         bwn_hf_write(mac, hf);
2422
2423         BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2424             (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2425             ((autodiv ? BWN_ANTAUTO1 : antenna)
2426                 << BWN_PHY_BBANDCFG_RXANT_SHIFT));
2427
2428         if (autodiv) {
2429                 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2430                 if (antenna == BWN_ANTAUTO1)
2431                         tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2432                 else
2433                         tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2434                 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2435         }
2436         tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2437         if (autodiv)
2438                 tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2439         else
2440                 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2441         BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2442         if (phy->rev >= 2) {
2443                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2444                     BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2445                 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2446                     (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2447                     0x15);
2448                 if (phy->rev == 2)
2449                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2450                 else
2451                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2452                             (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2453                             8);
2454         }
2455         if (phy->rev >= 6)
2456                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2457
2458         hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2459         bwn_hf_write(mac, hf);
2460 }
2461
2462 static int
2463 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2464 {
2465         struct bwn_phy *phy = &mac->mac_phy;
2466         struct bwn_phy_g *pg = &phy->phy_g;
2467
2468         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2469         KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2470
2471         if (phy->rev == 0 || !phy->gmode)
2472                 return (ENODEV);
2473
2474         pg->pg_aci_wlan_automatic = 0;
2475         return (0);
2476 }
2477
2478 static int
2479 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2480 {
2481         struct bwn_phy *phy = &mac->mac_phy;
2482         struct bwn_phy_g *pg = &phy->phy_g;
2483         struct bwn_softc *sc = mac->mac_sc;
2484         unsigned int tssi;
2485         int cck, ofdm;
2486         int power;
2487         int rfatt, bbatt;
2488         unsigned int max;
2489
2490         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2491
2492         cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2493         ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2494         if (cck < 0 && ofdm < 0) {
2495                 if (ignore_tssi == 0)
2496                         return (BWN_TXPWR_RES_DONE);
2497                 cck = 0;
2498                 ofdm = 0;
2499         }
2500         tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2501         if (pg->pg_avgtssi != 0xff)
2502                 tssi = (tssi + pg->pg_avgtssi) / 2;
2503         pg->pg_avgtssi = tssi;
2504         KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2505
2506         max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2507         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2508                 max -= 3;
2509         if (max >= 120) {
2510                 device_printf(sc->sc_dev, "invalid max TX-power value\n");
2511                 max = 80;
2512                 siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2513         }
2514
2515         power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2516             (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2517              tssi, 0x00), 0x3f)]);
2518         if (power == 0)
2519                 return (BWN_TXPWR_RES_DONE);
2520
2521         rfatt = -((power + 7) / 8);
2522         bbatt = (-(power / 2)) - (4 * rfatt);
2523         if ((rfatt == 0) && (bbatt == 0))
2524                 return (BWN_TXPWR_RES_DONE);
2525         pg->pg_bbatt_delta = bbatt;
2526         pg->pg_rfatt_delta = rfatt;
2527         return (BWN_TXPWR_RES_NEED_ADJUST);
2528 }
2529
2530 static void
2531 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2532 {
2533         struct bwn_phy *phy = &mac->mac_phy;
2534         struct bwn_phy_g *pg = &phy->phy_g;
2535         struct bwn_softc *sc = mac->mac_sc;
2536         int rfatt, bbatt;
2537         uint8_t txctl;
2538
2539         bwn_mac_suspend(mac);
2540
2541         bbatt = pg->pg_bbatt.att;
2542         bbatt += pg->pg_bbatt_delta;
2543         rfatt = pg->pg_rfatt.att;
2544         rfatt += pg->pg_rfatt_delta;
2545
2546         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2547         txctl = pg->pg_txctl;
2548         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2549                 if (rfatt <= 1) {
2550                         if (txctl == 0) {
2551                                 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2552                                 rfatt += 2;
2553                                 bbatt += 2;
2554                         } else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2555                             BWN_BFL_PACTRL) {
2556                                 bbatt += 4 * (rfatt - 2);
2557                                 rfatt = 2;
2558                         }
2559                 } else if (rfatt > 4 && txctl) {
2560                         txctl = 0;
2561                         if (bbatt < 3) {
2562                                 rfatt -= 3;
2563                                 bbatt += 2;
2564                         } else {
2565                                 rfatt -= 2;
2566                                 bbatt -= 2;
2567                         }
2568                 }
2569         }
2570         pg->pg_txctl = txctl;
2571         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2572         pg->pg_rfatt.att = rfatt;
2573         pg->pg_bbatt.att = bbatt;
2574
2575         DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2576
2577         bwn_phy_lock(mac);
2578         bwn_rf_lock(mac);
2579         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2580             pg->pg_txctl);
2581         bwn_rf_unlock(mac);
2582         bwn_phy_unlock(mac);
2583
2584         bwn_mac_enable(mac);
2585 }
2586
2587 static void
2588 bwn_phy_g_task_15s(struct bwn_mac *mac)
2589 {
2590         struct bwn_phy *phy = &mac->mac_phy;
2591         struct bwn_phy_g *pg = &phy->phy_g;
2592         struct bwn_softc *sc = mac->mac_sc;
2593         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2594         unsigned long expire, now;
2595         struct bwn_lo_calib *cal, *tmp;
2596         uint8_t expired = 0;
2597
2598         bwn_mac_suspend(mac);
2599
2600         if (lo == NULL)
2601                 goto fail;
2602
2603         BWN_GETTIME(now);
2604         if (bwn_has_hwpctl(mac)) {
2605                 expire = now - BWN_LO_PWRVEC_EXPIRE;
2606                 if (time_before(lo->pwr_vec_read_time, expire)) {
2607                         bwn_lo_get_powervector(mac);
2608                         bwn_phy_g_dc_lookup_init(mac, 0);
2609                 }
2610                 goto fail;
2611         }
2612
2613         expire = now - BWN_LO_CALIB_EXPIRE;
2614         TAILQ_FOREACH_MUTABLE(cal, &lo->calib_list, list, tmp) {
2615                 if (!time_before(cal->calib_time, expire))
2616                         continue;
2617                 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2618                     BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2619                         KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2620                         expired = 1;
2621                 }
2622
2623                 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2624                     cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2625                     cal->ctl.i, cal->ctl.q);
2626
2627                 TAILQ_REMOVE(&lo->calib_list, cal, list);
2628                 kfree(cal, M_DEVBUF);
2629         }
2630         if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2631                 cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2632                     &pg->pg_rfatt);
2633                 if (cal == NULL) {      /* XXX ivadasz: can't happen */
2634                         device_printf(sc->sc_dev,
2635                             "failed to recalibrate LO\n");
2636                         goto fail;
2637                 }
2638                 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2639                 bwn_lo_write(mac, &cal->ctl);
2640         }
2641
2642 fail:
2643         bwn_mac_enable(mac);
2644 }
2645
2646 static void
2647 bwn_phy_g_task_60s(struct bwn_mac *mac)
2648 {
2649         struct bwn_phy *phy = &mac->mac_phy;
2650         struct bwn_softc *sc = mac->mac_sc;
2651         uint8_t old = phy->chan;
2652
2653         if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2654                 return;
2655
2656         bwn_mac_suspend(mac);
2657         bwn_nrssi_slope_11g(mac);
2658         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2659                 bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2660                 bwn_switch_channel(mac, old);
2661         }
2662         bwn_mac_enable(mac);
2663 }
2664
2665 static void
2666 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2667 {
2668
2669         BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2670 }
2671
2672 static int
2673 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2674         const struct ieee80211_bpf_params *params)
2675 {
2676         struct ieee80211com *ic = ni->ni_ic;
2677         struct ifnet *ifp = ic->ic_ifp;
2678         struct bwn_softc *sc = ifp->if_softc;
2679         struct bwn_mac *mac = sc->sc_curmac;
2680
2681         if ((ifp->if_flags & IFF_RUNNING) == 0 ||
2682             mac->mac_status < BWN_MAC_STATUS_STARTED) {
2683                 ieee80211_free_node(ni);
2684                 m_freem(m);
2685                 return (ENETDOWN);
2686         }
2687
2688         if (bwn_tx_isfull(sc, m)) {
2689                 ieee80211_free_node(ni);
2690                 m_freem(m);
2691                 ifp->if_oerrors++;
2692                 return (ENOBUFS);
2693         }
2694
2695         if (bwn_tx_start(sc, ni, m) != 0) {
2696                 if (ni != NULL)
2697                         ieee80211_free_node(ni);
2698                 ifp->if_oerrors++;
2699         }
2700         sc->sc_watchdog_timer = 5;
2701         return (0);
2702 }
2703
2704 /*
2705  * Callback from the 802.11 layer to update the slot time
2706  * based on the current setting.  We use it to notify the
2707  * firmware of ERP changes and the f/w takes care of things
2708  * like slot time and preamble.
2709  */
2710 static void
2711 bwn_updateslot(struct ifnet *ifp)
2712 {
2713         struct bwn_softc *sc = ifp->if_softc;
2714         struct ieee80211com *ic = ifp->if_l2com;
2715         struct bwn_mac *mac;
2716
2717         if (ifp->if_flags & IFF_RUNNING) {
2718                 mac = (struct bwn_mac *)sc->sc_curmac;
2719                 bwn_set_slot_time(mac,
2720                     (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2721         }
2722 }
2723
2724 /*
2725  * Callback from the 802.11 layer after a promiscuous mode change.
2726  * Note this interface does not check the operating mode as this
2727  * is an internal callback and we are expected to honor the current
2728  * state (e.g. this is used for setting the interface in promiscuous
2729  * mode when operating in hostap mode to do ACS).
2730  */
2731 static void
2732 bwn_update_promisc(struct ifnet *ifp)
2733 {
2734         struct bwn_softc *sc = ifp->if_softc;
2735         struct bwn_mac *mac = sc->sc_curmac;
2736
2737         mac = sc->sc_curmac;
2738         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2739                 if (ifp->if_flags & IFF_PROMISC)
2740                         sc->sc_filters |= BWN_MACCTL_PROMISC;
2741                 else
2742                         sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2743                 bwn_set_opmode(mac);
2744         }
2745 }
2746
2747 /*
2748  * Callback from the 802.11 layer to update WME parameters.
2749  */
2750 static int
2751 bwn_wme_update(struct ieee80211com *ic)
2752 {
2753         struct bwn_softc *sc = ic->ic_ifp->if_softc;
2754         struct bwn_mac *mac = sc->sc_curmac;
2755         struct wmeParams *wmep;
2756         int i;
2757
2758         mac = sc->sc_curmac;
2759         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2760                 bwn_mac_suspend(mac);
2761                 for (i = 0; i < N(sc->sc_wmeParams); i++) {
2762                         wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2763                         bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2764                 }
2765                 bwn_mac_enable(mac);
2766         }
2767         return (0);
2768 }
2769
2770 static void
2771 bwn_scan_start(struct ieee80211com *ic)
2772 {
2773         struct ifnet *ifp = ic->ic_ifp;
2774         struct bwn_softc *sc = ifp->if_softc;
2775         struct bwn_mac *mac;
2776
2777         mac = sc->sc_curmac;
2778         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2779                 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2780                 bwn_set_opmode(mac);
2781                 /* disable CFP update during scan */
2782                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2783         }
2784 }
2785
2786 static void
2787 bwn_scan_end(struct ieee80211com *ic)
2788 {
2789         struct ifnet *ifp = ic->ic_ifp;
2790         struct bwn_softc *sc = ifp->if_softc;
2791         struct bwn_mac *mac;
2792
2793         mac = sc->sc_curmac;
2794         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2795                 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2796                 bwn_set_opmode(mac);
2797                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2798         }
2799 }
2800
2801 static void
2802 bwn_set_channel(struct ieee80211com *ic)
2803 {
2804         struct ifnet *ifp = ic->ic_ifp;
2805         struct bwn_softc *sc = ifp->if_softc;
2806         struct bwn_mac *mac = sc->sc_curmac;
2807         struct bwn_phy *phy = &mac->mac_phy;
2808         int chan, error;
2809
2810         error = bwn_switch_band(sc, ic->ic_curchan);
2811         if (error)
2812                 goto fail;
2813         bwn_mac_suspend(mac);
2814         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2815         chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2816         if (chan != phy->chan)
2817                 bwn_switch_channel(mac, chan);
2818
2819         /* TX power level */
2820         if (ic->ic_curchan->ic_maxpower != 0 &&
2821             ic->ic_curchan->ic_maxpower != phy->txpower) {
2822                 phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2823                 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2824                     BWN_TXPWR_IGNORE_TSSI);
2825         }
2826
2827         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2828         if (phy->set_antenna)
2829                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
2830
2831         if (sc->sc_rf_enabled != phy->rf_on) {
2832                 if (sc->sc_rf_enabled) {
2833                         bwn_rf_turnon(mac);
2834                         if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2835                                 device_printf(sc->sc_dev,
2836                                     "please turn on the RF switch\n");
2837                 } else
2838                         bwn_rf_turnoff(mac);
2839         }
2840
2841         bwn_mac_enable(mac);
2842
2843 fail:
2844         /*
2845          * Setup radio tap channel freq and flags
2846          */
2847         sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2848                 htole16(ic->ic_curchan->ic_freq);
2849         sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2850                 htole16(ic->ic_curchan->ic_flags & 0xffff);
2851 }
2852
2853 static struct ieee80211vap *
2854 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
2855     enum ieee80211_opmode opmode, int flags,
2856     const uint8_t bssid[IEEE80211_ADDR_LEN],
2857     const uint8_t mac0[IEEE80211_ADDR_LEN])
2858 {
2859         struct ifnet *ifp = ic->ic_ifp;
2860         struct bwn_softc *sc = ifp->if_softc;
2861         struct ieee80211vap *vap;
2862         struct bwn_vap *bvp;
2863         uint8_t mac[IEEE80211_ADDR_LEN];
2864
2865         if (!TAILQ_EMPTY(&ic->ic_vaps))         /* only one at a time */
2866                 return NULL;
2867
2868         IEEE80211_ADDR_COPY(mac, mac0);
2869         switch (opmode) {
2870         case IEEE80211_M_HOSTAP:
2871         case IEEE80211_M_MBSS:
2872         case IEEE80211_M_STA:
2873         case IEEE80211_M_WDS:
2874         case IEEE80211_M_MONITOR:
2875         case IEEE80211_M_IBSS:
2876         case IEEE80211_M_AHDEMO:
2877                 break;
2878         default:
2879                 return (NULL);
2880         }
2881
2882         IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
2883
2884         bvp = (struct bwn_vap *) kmalloc(sizeof(struct bwn_vap),
2885             M_80211_VAP, M_INTWAIT | M_ZERO);
2886         vap = &bvp->bv_vap;
2887         ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
2888         IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
2889         /* override with driver methods */
2890         bvp->bv_newstate = vap->iv_newstate;
2891         vap->iv_newstate = bwn_newstate;
2892
2893         /* override max aid so sta's cannot assoc when we're out of sta id's */
2894         vap->iv_max_aid = BWN_STAID_MAX;
2895
2896         ieee80211_ratectl_init(vap);
2897
2898         /* complete setup */
2899         ieee80211_vap_attach(vap, ieee80211_media_change,
2900             ieee80211_media_status);
2901         ic->ic_opmode = opmode;
2902         return (vap);
2903 }
2904
2905 static void
2906 bwn_vap_delete(struct ieee80211vap *vap)
2907 {
2908         struct bwn_vap *bvp = BWN_VAP(vap);
2909
2910         ieee80211_ratectl_deinit(vap);
2911         ieee80211_vap_detach(vap);
2912         kfree(bvp, M_80211_VAP);
2913 }
2914
2915 static void
2916 bwn_init(void *arg)
2917 {
2918         struct bwn_softc *sc = arg;
2919         struct ifnet *ifp = sc->sc_ifp;
2920         struct ieee80211com *ic = ifp->if_l2com;
2921         int error = 0;
2922
2923         DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
2924                 __func__, ifp->if_flags);
2925
2926         wlan_assert_serialized();
2927         error = bwn_init_locked(sc);
2928
2929         if (error == 0)
2930                 ieee80211_start_all(ic);        /* start all vap's */
2931 }
2932
2933 static int
2934 bwn_init_locked(struct bwn_softc *sc)
2935 {
2936         struct bwn_mac *mac;
2937         struct ifnet *ifp = sc->sc_ifp;
2938         int error;
2939
2940         bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
2941         sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
2942         sc->sc_filters = 0;
2943         bwn_wme_clear(sc);
2944         sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
2945         sc->sc_rf_enabled = 1;
2946
2947         mac = sc->sc_curmac;
2948         if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
2949                 error = bwn_core_init(mac);
2950                 if (error != 0)
2951                         return (error);
2952         }
2953         if (mac->mac_status == BWN_MAC_STATUS_INITED)
2954                 bwn_core_start(mac);
2955
2956         bwn_set_opmode(mac);
2957         bwn_set_pretbtt(mac);
2958         bwn_spu_setdelay(mac, 0);
2959         bwn_set_macaddr(mac);
2960
2961         ifp->if_flags |= IFF_RUNNING;
2962         callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
2963         callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
2964
2965         return (0);
2966 }
2967
2968 static void
2969 bwn_stop(struct bwn_softc *sc, int statechg)
2970 {
2971
2972         wlan_assert_serialized();
2973         bwn_stop_locked(sc, statechg);
2974 }
2975
2976 static void
2977 bwn_stop_locked(struct bwn_softc *sc, int statechg)
2978 {
2979         struct bwn_mac *mac = sc->sc_curmac;
2980         struct ifnet *ifp = sc->sc_ifp;
2981
2982         if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
2983                 /* XXX FIXME opmode not based on VAP */
2984                 bwn_set_opmode(mac);
2985                 bwn_set_macaddr(mac);
2986         }
2987
2988         if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
2989                 bwn_core_stop(mac);
2990
2991         callout_stop(&sc->sc_led_blink_ch);
2992         sc->sc_led_blinking = 0;
2993
2994         bwn_core_exit(mac);
2995         sc->sc_rf_enabled = 0;
2996
2997         ifp->if_flags &= ~IFF_RUNNING;
2998         ifq_clr_oactive(&ifp->if_snd);
2999 }
3000
3001 static void
3002 bwn_wme_clear(struct bwn_softc *sc)
3003 {
3004 #define MS(_v, _f)      (((_v) & _f) >> _f##_S)
3005         struct wmeParams *p;
3006         unsigned int i;
3007
3008         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
3009             ("%s:%d: fail", __func__, __LINE__));
3010
3011         for (i = 0; i < N(sc->sc_wmeParams); i++) {
3012                 p = &(sc->sc_wmeParams[i]);
3013
3014                 switch (bwn_wme_shm_offsets[i]) {
3015                 case BWN_WME_VOICE:
3016                         p->wmep_txopLimit = 0;
3017                         p->wmep_aifsn = 2;
3018                         /* XXX FIXME: log2(cwmin) */
3019                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3020                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3021                         break;
3022                 case BWN_WME_VIDEO:
3023                         p->wmep_txopLimit = 0;
3024                         p->wmep_aifsn = 2;
3025                         /* XXX FIXME: log2(cwmin) */
3026                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3027                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3028                         break;
3029                 case BWN_WME_BESTEFFORT:
3030                         p->wmep_txopLimit = 0;
3031                         p->wmep_aifsn = 3;
3032                         /* XXX FIXME: log2(cwmin) */
3033                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3034                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3035                         break;
3036                 case BWN_WME_BACKGROUND:
3037                         p->wmep_txopLimit = 0;
3038                         p->wmep_aifsn = 7;
3039                         /* XXX FIXME: log2(cwmin) */
3040                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3041                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3042                         break;
3043                 default:
3044                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3045                 }
3046         }
3047 }
3048
3049 static int
3050 bwn_core_init(struct bwn_mac *mac)
3051 {
3052         struct bwn_softc *sc = mac->mac_sc;
3053         uint64_t hf;
3054         int error;
3055
3056         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3057             ("%s:%d: fail", __func__, __LINE__));
3058
3059         siba_powerup(sc->sc_dev, 0);
3060         if (!siba_dev_isup(sc->sc_dev))
3061                 bwn_reset_core(mac,
3062                     mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3063
3064         mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3065         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3066         mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3067         BWN_GETTIME(mac->mac_phy.nexttime);
3068         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3069         bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3070         mac->mac_stats.link_noise = -95;
3071         mac->mac_reason_intr = 0;
3072         bzero(mac->mac_reason, sizeof(mac->mac_reason));
3073         mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3074 #ifdef BWN_DEBUG
3075         if (sc->sc_debug & BWN_DEBUG_XMIT)
3076                 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3077 #endif
3078         mac->mac_suspended = 1;
3079         mac->mac_task_state = 0;
3080         memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3081
3082         mac->mac_phy.init_pre(mac);
3083
3084         siba_pcicore_intr(sc->sc_dev);
3085
3086         siba_fix_imcfglobug(sc->sc_dev);
3087         bwn_bt_disable(mac);
3088         if (mac->mac_phy.prepare_hw) {
3089                 error = mac->mac_phy.prepare_hw(mac);
3090                 if (error)
3091                         goto fail0;
3092         }
3093         error = bwn_chip_init(mac);
3094         if (error)
3095                 goto fail0;
3096         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3097             siba_get_revid(sc->sc_dev));
3098         hf = bwn_hf_read(mac);
3099         if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3100                 hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3101                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3102                         hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3103                 if (mac->mac_phy.rev == 1)
3104                         hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3105         }
3106         if (mac->mac_phy.rf_ver == 0x2050) {
3107                 if (mac->mac_phy.rf_rev < 6)
3108                         hf |= BWN_HF_FORCE_VCO_RECALC;
3109                 if (mac->mac_phy.rf_rev == 6)
3110                         hf |= BWN_HF_4318_TSSI;
3111         }
3112         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3113                 hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3114         if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3115             (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3116                 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3117         hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3118         bwn_hf_write(mac, hf);
3119
3120         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3121         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3122         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3123         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3124
3125         bwn_rate_init(mac);
3126         bwn_set_phytxctl(mac);
3127
3128         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3129             (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3130         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3131
3132         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3133                 bwn_pio_init(mac);
3134         else
3135                 bwn_dma_init(mac);
3136         bwn_wme_init(mac);
3137         bwn_spu_setdelay(mac, 1);
3138         bwn_bt_enable(mac);
3139
3140         siba_powerup(sc->sc_dev,
3141             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3142         bwn_set_macaddr(mac);
3143         bwn_crypt_init(mac);
3144
3145         /* XXX LED initializatin */
3146
3147         mac->mac_status = BWN_MAC_STATUS_INITED;
3148
3149         return (error);
3150
3151 fail0:
3152         siba_powerdown(sc->sc_dev);
3153         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3154             ("%s:%d: fail", __func__, __LINE__));
3155         return (error);
3156 }
3157
3158 static void
3159 bwn_core_start(struct bwn_mac *mac)
3160 {
3161         struct bwn_softc *sc = mac->mac_sc;
3162         uint32_t tmp;
3163
3164         KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3165             ("%s:%d: fail", __func__, __LINE__));
3166
3167         if (siba_get_revid(sc->sc_dev) < 5)
3168                 return;
3169
3170         while (1) {
3171                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3172                 if (!(tmp & 0x00000001))
3173                         break;
3174                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3175         }
3176
3177         bwn_mac_enable(mac);
3178         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3179         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3180
3181         mac->mac_status = BWN_MAC_STATUS_STARTED;
3182 }
3183
3184 static void
3185 bwn_core_exit(struct bwn_mac *mac)
3186 {
3187         struct bwn_softc *sc = mac->mac_sc;
3188         uint32_t macctl;
3189
3190         wlan_assert_serialized();
3191
3192         KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3193             ("%s:%d: fail", __func__, __LINE__));
3194
3195         if (mac->mac_status != BWN_MAC_STATUS_INITED)
3196                 return;
3197         mac->mac_status = BWN_MAC_STATUS_UNINIT;
3198
3199         macctl = BWN_READ_4(mac, BWN_MACCTL);
3200         macctl &= ~BWN_MACCTL_MCODE_RUN;
3201         macctl |= BWN_MACCTL_MCODE_JMP0;
3202         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3203
3204         bwn_dma_stop(mac);
3205         bwn_pio_stop(mac);
3206         bwn_chip_exit(mac);
3207         mac->mac_phy.switch_analog(mac, 0);
3208         siba_dev_down(sc->sc_dev, 0);
3209         siba_powerdown(sc->sc_dev);
3210 }
3211
3212 static void
3213 bwn_bt_disable(struct bwn_mac *mac)
3214 {
3215         struct bwn_softc *sc = mac->mac_sc;
3216
3217         (void)sc;
3218         /* XXX do nothing yet */
3219 }
3220
3221 static int
3222 bwn_chip_init(struct bwn_mac *mac)
3223 {
3224         struct bwn_softc *sc = mac->mac_sc;
3225         struct bwn_phy *phy = &mac->mac_phy;
3226         uint32_t macctl;
3227         int error;
3228
3229         macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3230         if (phy->gmode)
3231                 macctl |= BWN_MACCTL_GMODE;
3232         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3233
3234         error = bwn_fw_fillinfo(mac);
3235         if (error)
3236                 return (error);
3237         error = bwn_fw_loaducode(mac);
3238         if (error)
3239                 return (error);
3240
3241         error = bwn_gpio_init(mac);
3242         if (error)
3243                 return (error);
3244
3245         error = bwn_fw_loadinitvals(mac);
3246         if (error) {
3247                 siba_gpio_set(sc->sc_dev, 0);
3248                 return (error);
3249         }
3250         phy->switch_analog(mac, 1);
3251         error = bwn_phy_init(mac);
3252         if (error) {
3253                 siba_gpio_set(sc->sc_dev, 0);
3254                 return (error);
3255         }
3256         if (phy->set_im)
3257                 phy->set_im(mac, BWN_IMMODE_NONE);
3258         if (phy->set_antenna)
3259                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
3260         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3261
3262         if (phy->type == BWN_PHYTYPE_B)
3263                 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3264         BWN_WRITE_4(mac, 0x0100, 0x01000000);
3265         if (siba_get_revid(sc->sc_dev) < 5)
3266                 BWN_WRITE_4(mac, 0x010c, 0x01000000);
3267
3268         BWN_WRITE_4(mac, BWN_MACCTL,
3269             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3270         BWN_WRITE_4(mac, BWN_MACCTL,
3271             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3272         bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3273
3274         bwn_set_opmode(mac);
3275         if (siba_get_revid(sc->sc_dev) < 3) {
3276                 BWN_WRITE_2(mac, 0x060e, 0x0000);
3277                 BWN_WRITE_2(mac, 0x0610, 0x8000);
3278                 BWN_WRITE_2(mac, 0x0604, 0x0000);
3279                 BWN_WRITE_2(mac, 0x0606, 0x0200);
3280         } else {
3281                 BWN_WRITE_4(mac, 0x0188, 0x80000000);
3282                 BWN_WRITE_4(mac, 0x018c, 0x02000000);
3283         }
3284         BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3285         BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001fc00);
3286         BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3287         BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3288         BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3289         BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3290         BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3291         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3292             siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3293         BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3294         return (error);
3295 }
3296
3297 /* read hostflags */
3298 static uint64_t
3299 bwn_hf_read(struct bwn_mac *mac)
3300 {
3301         uint64_t ret;
3302
3303         ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3304         ret <<= 16;
3305         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3306         ret <<= 16;
3307         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3308         return (ret);
3309 }
3310
3311 static void
3312 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3313 {
3314
3315         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3316             (value & 0x00000000ffffull));
3317         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3318             (value & 0x0000ffff0000ull) >> 16);
3319         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3320             (value & 0xffff00000000ULL) >> 32);
3321 }
3322
3323 static void
3324 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3325 {
3326
3327         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3328         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3329 }
3330
3331 static void
3332 bwn_rate_init(struct bwn_mac *mac)
3333 {
3334
3335         switch (mac->mac_phy.type) {
3336         case BWN_PHYTYPE_A:
3337         case BWN_PHYTYPE_G:
3338         case BWN_PHYTYPE_LP:
3339         case BWN_PHYTYPE_N:
3340                 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3341                 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3342                 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3343                 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3344                 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3345                 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3346                 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3347                 if (mac->mac_phy.type == BWN_PHYTYPE_A)
3348                         break;
3349                 /* FALLTHROUGH */
3350         case BWN_PHYTYPE_B:
3351                 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3352                 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3353                 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3354                 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3355                 break;
3356         default:
3357                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3358         }
3359 }
3360
3361 static void
3362 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3363 {
3364         uint16_t offset;
3365
3366         if (ofdm) {
3367                 offset = 0x480;
3368                 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3369         } else {
3370                 offset = 0x4c0;
3371                 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3372         }
3373         bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3374             bwn_shm_read_2(mac, BWN_SHARED, offset));
3375 }
3376
3377 static uint8_t
3378 bwn_plcp_getcck(const uint8_t bitrate)
3379 {
3380
3381         switch (bitrate) {
3382         case BWN_CCK_RATE_1MB:
3383                 return (0x0a);
3384         case BWN_CCK_RATE_2MB:
3385                 return (0x14);
3386         case BWN_CCK_RATE_5MB:
3387                 return (0x37);
3388         case BWN_CCK_RATE_11MB:
3389                 return (0x6e);
3390         }
3391         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3392         return (0);
3393 }
3394
3395 static uint8_t
3396 bwn_plcp_getofdm(const uint8_t bitrate)
3397 {
3398
3399         switch (bitrate) {
3400         case BWN_OFDM_RATE_6MB:
3401                 return (0xb);
3402         case BWN_OFDM_RATE_9MB:
3403                 return (0xf);
3404         case BWN_OFDM_RATE_12MB:
3405                 return (0xa);
3406         case BWN_OFDM_RATE_18MB:
3407                 return (0xe);
3408         case BWN_OFDM_RATE_24MB:
3409                 return (0x9);
3410         case BWN_OFDM_RATE_36MB:
3411                 return (0xd);
3412         case BWN_OFDM_RATE_48MB:
3413                 return (0x8);
3414         case BWN_OFDM_RATE_54MB:
3415                 return (0xc);
3416         }
3417         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3418         return (0);
3419 }
3420
3421 static void
3422 bwn_set_phytxctl(struct bwn_mac *mac)
3423 {
3424         uint16_t ctl;
3425
3426         ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3427             BWN_TX_PHY_TXPWR);
3428         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3429         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3430         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3431 }
3432
3433 static void
3434 bwn_pio_init(struct bwn_mac *mac)
3435 {
3436         struct bwn_pio *pio = &mac->mac_method.pio;
3437
3438         BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3439             & ~BWN_MACCTL_BIGENDIAN);
3440         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3441
3442         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3443         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3444         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3445         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3446         bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3447         bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3448 }
3449
3450 static void
3451 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3452     int index)
3453 {
3454         struct bwn_pio_txpkt *tp;
3455         struct bwn_softc *sc = mac->mac_sc;
3456         unsigned int i;
3457
3458         tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3459         tq->tq_index = index;
3460
3461         tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3462         if (siba_get_revid(sc->sc_dev) >= 8)
3463                 tq->tq_size = 1920;
3464         else {
3465                 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3466                 tq->tq_size -= 80;
3467         }
3468
3469         TAILQ_INIT(&tq->tq_pktlist);
3470         for (i = 0; i < N(tq->tq_pkts); i++) {
3471                 tp = &(tq->tq_pkts[i]);
3472                 tp->tp_index = i;
3473                 tp->tp_queue = tq;
3474                 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3475         }
3476 }
3477
3478 static uint16_t
3479 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3480 {
3481         struct bwn_softc *sc = mac->mac_sc;
3482         static const uint16_t bases[] = {
3483                 BWN_PIO_BASE0,
3484                 BWN_PIO_BASE1,
3485                 BWN_PIO_BASE2,
3486                 BWN_PIO_BASE3,
3487                 BWN_PIO_BASE4,
3488                 BWN_PIO_BASE5,
3489                 BWN_PIO_BASE6,
3490                 BWN_PIO_BASE7,
3491         };
3492         static const uint16_t bases_rev11[] = {
3493                 BWN_PIO11_BASE0,
3494                 BWN_PIO11_BASE1,
3495                 BWN_PIO11_BASE2,
3496                 BWN_PIO11_BASE3,
3497                 BWN_PIO11_BASE4,
3498                 BWN_PIO11_BASE5,
3499         };
3500
3501         if (siba_get_revid(sc->sc_dev) >= 11) {
3502                 if (index >= N(bases_rev11))
3503                         device_printf(sc->sc_dev, "%s: warning\n", __func__);
3504                 return (bases_rev11[index]);
3505         }
3506         if (index >= N(bases))
3507                 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3508         return (bases[index]);
3509 }
3510
3511 static void
3512 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3513     int index)
3514 {
3515         struct bwn_softc *sc = mac->mac_sc;
3516
3517         prq->prq_mac = mac;
3518         prq->prq_rev = siba_get_revid(sc->sc_dev);
3519         prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3520         bwn_dma_rxdirectfifo(mac, index, 1);
3521 }
3522
3523 static void
3524 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3525 {
3526         if (tq == NULL)
3527                 return;
3528         bwn_pio_cancel_tx_packets(tq);
3529 }
3530
3531 static void
3532 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3533 {
3534
3535         bwn_destroy_pioqueue_tx(pio);
3536 }
3537
3538 static uint16_t
3539 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3540     uint16_t offset)
3541 {
3542
3543         return (BWN_READ_2(mac, tq->tq_base + offset));
3544 }
3545
3546 static void
3547 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3548 {
3549         uint32_t ctl;
3550         int type;
3551         uint16_t base;
3552
3553         type = bwn_dma_mask2type(bwn_dma_mask(mac));
3554         base = bwn_dma_base(type, idx);
3555         if (type == BWN_DMA_64BIT) {
3556                 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3557                 ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3558                 if (enable)
3559                         ctl |= BWN_DMA64_RXDIRECTFIFO;
3560                 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3561         } else {
3562                 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3563                 ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3564                 if (enable)
3565                         ctl |= BWN_DMA32_RXDIRECTFIFO;
3566                 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3567         }
3568 }
3569
3570 static uint64_t
3571 bwn_dma_mask(struct bwn_mac *mac)
3572 {
3573         uint32_t tmp;
3574         uint16_t base;
3575
3576         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3577         if (tmp & SIBA_TGSHIGH_DMA64)
3578                 return (BWN_DMA_BIT_MASK(64));
3579         base = bwn_dma_base(0, 0);
3580         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3581         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3582         if (tmp & BWN_DMA32_TXADDREXT_MASK)
3583                 return (BWN_DMA_BIT_MASK(32));
3584
3585         return (BWN_DMA_BIT_MASK(30));
3586 }
3587
3588 static int
3589 bwn_dma_mask2type(uint64_t dmamask)
3590 {
3591
3592         if (dmamask == BWN_DMA_BIT_MASK(30))
3593                 return (BWN_DMA_30BIT);
3594         if (dmamask == BWN_DMA_BIT_MASK(32))
3595                 return (BWN_DMA_32BIT);
3596         if (dmamask == BWN_DMA_BIT_MASK(64))
3597                 return (BWN_DMA_64BIT);
3598         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3599         return (BWN_DMA_30BIT);
3600 }
3601
3602 static void
3603 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3604 {
3605         struct bwn_pio_txpkt *tp;
3606         unsigned int i;
3607
3608         for (i = 0; i < N(tq->tq_pkts); i++) {
3609                 tp = &(tq->tq_pkts[i]);
3610                 if (tp->tp_m) {
3611                         m_freem(tp->tp_m);
3612                         tp->tp_m = NULL;
3613                 }
3614         }
3615 }
3616
3617 static uint16_t
3618 bwn_dma_base(int type, int controller_idx)
3619 {
3620         static const uint16_t map64[] = {
3621                 BWN_DMA64_BASE0,
3622                 BWN_DMA64_BASE1,
3623                 BWN_DMA64_BASE2,
3624                 BWN_DMA64_BASE3,
3625                 BWN_DMA64_BASE4,
3626                 BWN_DMA64_BASE5,
3627         };
3628         static const uint16_t map32[] = {
3629                 BWN_DMA32_BASE0,
3630                 BWN_DMA32_BASE1,
3631                 BWN_DMA32_BASE2,
3632                 BWN_DMA32_BASE3,
3633                 BWN_DMA32_BASE4,
3634                 BWN_DMA32_BASE5,
3635         };
3636
3637         if (type == BWN_DMA_64BIT) {
3638                 KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3639                     ("%s:%d: fail", __func__, __LINE__));
3640                 return (map64[controller_idx]);
3641         }
3642         KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3643             ("%s:%d: fail", __func__, __LINE__));
3644         return (map32[controller_idx]);
3645 }
3646
3647 static void
3648 bwn_dma_init(struct bwn_mac *mac)
3649 {
3650         struct bwn_dma *dma = &mac->mac_method.dma;
3651
3652         /* setup TX DMA channels. */
3653         bwn_dma_setup(dma->wme[WME_AC_BK]);
3654         bwn_dma_setup(dma->wme[WME_AC_BE]);
3655         bwn_dma_setup(dma->wme[WME_AC_VI]);
3656         bwn_dma_setup(dma->wme[WME_AC_VO]);
3657         bwn_dma_setup(dma->mcast);
3658         /* setup RX DMA channel. */
3659         bwn_dma_setup(dma->rx);
3660 }
3661
3662 static struct bwn_dma_ring *
3663 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3664     int for_tx, int type)
3665 {
3666         struct bwn_dma *dma = &mac->mac_method.dma;
3667         struct bwn_dma_ring *dr;
3668         struct bwn_dmadesc_generic *desc;
3669         struct bwn_dmadesc_meta *mt;
3670         struct bwn_softc *sc = mac->mac_sc;
3671         int error, i;
3672
3673         dr = kmalloc(sizeof(*dr), M_DEVBUF, M_INTWAIT | M_ZERO);
3674         dr->dr_numslots = BWN_RXRING_SLOTS;
3675         if (for_tx)
3676                 dr->dr_numslots = BWN_TXRING_SLOTS;
3677
3678         dr->dr_meta = kmalloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3679             M_DEVBUF, M_INTWAIT | M_ZERO);
3680
3681         dr->dr_type = type;
3682         dr->dr_mac = mac;
3683         dr->dr_base = bwn_dma_base(type, controller_index);
3684         dr->dr_index = controller_index;
3685         if (type == BWN_DMA_64BIT) {
3686                 dr->getdesc = bwn_dma_64_getdesc;
3687                 dr->setdesc = bwn_dma_64_setdesc;
3688                 dr->start_transfer = bwn_dma_64_start_transfer;
3689                 dr->suspend = bwn_dma_64_suspend;
3690                 dr->resume = bwn_dma_64_resume;
3691                 dr->get_curslot = bwn_dma_64_get_curslot;
3692                 dr->set_curslot = bwn_dma_64_set_curslot;
3693         } else {
3694                 dr->getdesc = bwn_dma_32_getdesc;
3695                 dr->setdesc = bwn_dma_32_setdesc;
3696                 dr->start_transfer = bwn_dma_32_start_transfer;
3697                 dr->suspend = bwn_dma_32_suspend;
3698                 dr->resume = bwn_dma_32_resume;
3699                 dr->get_curslot = bwn_dma_32_get_curslot;
3700                 dr->set_curslot = bwn_dma_32_set_curslot;
3701         }
3702         if (for_tx) {
3703                 dr->dr_tx = 1;
3704                 dr->dr_curslot = -1;
3705         } else {
3706                 if (dr->dr_index == 0) {
3707                         dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3708                         dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3709                 } else
3710                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3711         }
3712
3713         error = bwn_dma_allocringmemory(dr);
3714         if (error)
3715                 goto fail1;
3716
3717         if (for_tx) {
3718                 /*
3719                  * Assumption: BWN_TXRING_SLOTS can be divided by
3720                  * BWN_TX_SLOTS_PER_FRAME
3721                  */
3722                 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3723                     ("%s:%d: fail", __func__, __LINE__));
3724
3725                 /*
3726                  * Create TX ring DMA stuffs
3727                  */
3728                 dr->dr_txhdr_cache = bus_dmamem_coherent_any(dma->parent_dtag,
3729                     4, (dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3730                     BWN_MAX_HDRSIZE(mac),
3731                     BUS_DMA_WAITOK | BUS_DMA_ZERO,
3732                     &dr->dr_txring_dtag, &dr->dr_txring_dmap,
3733                     &dr->dr_txring_paddr);
3734                 if (dr->dr_txhdr_cache == NULL) {
3735                         device_printf(sc->sc_dev,
3736                             "can't create TX ring DMA memory\n");
3737                         goto fail1;
3738                 }
3739
3740                 for (i = 0; i < dr->dr_numslots; i += 2) {
3741                         dr->getdesc(dr, i, &desc, &mt);
3742
3743                         mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3744                         mt->mt_m = NULL;
3745                         mt->mt_ni = NULL;
3746                         mt->mt_islast = 0;
3747                         mt->mt_dmap = dr->dr_txring_dmap;
3748                         mt->mt_paddr = dr->dr_txring_paddr +
3749                             (i / BWN_TX_SLOTS_PER_FRAME) *
3750                             BWN_MAX_HDRSIZE(mac);
3751
3752                         dr->getdesc(dr, i + 1, &desc, &mt);
3753
3754                         mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3755                         mt->mt_m = NULL;
3756                         mt->mt_ni = NULL;
3757                         mt->mt_islast = 1;
3758                         error = bus_dmamap_create(dma->txbuf_dtag, 0,
3759                             &mt->mt_dmap);
3760                         if (error) {
3761                                 device_printf(sc->sc_dev,
3762                                      "can't create RX buf DMA map\n");
3763                                 goto fail2;
3764                         }
3765                 }
3766         } else {
3767                 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3768                     &dr->dr_spare_dmap);
3769                 if (error) {
3770                         device_printf(sc->sc_dev,
3771                             "can't create RX buf DMA map\n");
3772                         goto out;               /* XXX wrong! */
3773                 }
3774
3775                 for (i = 0; i < dr->dr_numslots; i++) {
3776                         dr->getdesc(dr, i, &desc, &mt);
3777
3778                         error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3779                             &mt->mt_dmap);
3780                         if (error) {
3781                                 device_printf(sc->sc_dev,
3782                                     "can't create RX buf DMA map\n");
3783                                 goto out;       /* XXX wrong! */
3784                         }
3785                         error = bwn_dma_newbuf(dr, desc, mt, 1);
3786                         if (error) {
3787                                 device_printf(sc->sc_dev,
3788                                     "failed to allocate RX buf\n");
3789                                 goto out;       /* XXX wrong! */
3790                         }
3791                 }
3792
3793                 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3794                     BUS_DMASYNC_PREWRITE);
3795
3796                 dr->dr_usedslot = dr->dr_numslots;
3797         }
3798
3799       out:
3800         return (dr);
3801
3802 fail2:
3803         /* XXX free up dma allocations */
3804 fail1:
3805         kfree(dr->dr_meta, M_DEVBUF);
3806         kfree(dr, M_DEVBUF);
3807         return (NULL);
3808 }
3809
3810 static void
3811 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3812 {
3813
3814         if (dr == NULL)
3815                 return;
3816
3817         bwn_dma_free_descbufs(*dr);
3818         bwn_dma_free_ringmemory(*dr);
3819
3820         if ((*dr)->dr_meta != NULL)
3821                 kfree((*dr)->dr_meta, M_DEVBUF);
3822         kfree(*dr, M_DEVBUF);
3823
3824         *dr = NULL;
3825 }
3826
3827 static void
3828 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3829     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3830 {
3831         struct bwn_dmadesc32 *desc;
3832
3833         *meta = &(dr->dr_meta[slot]);
3834         desc = dr->dr_ring_descbase;
3835         desc = &(desc[slot]);
3836
3837         *gdesc = (struct bwn_dmadesc_generic *)desc;
3838 }
3839
3840 static void
3841 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3842     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3843     int start, int end, int irq)
3844 {
3845         struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3846         struct bwn_softc *sc = dr->dr_mac->mac_sc;
3847         uint32_t addr, addrext, ctl;
3848         int slot;
3849
3850         slot = (int)(&(desc->dma.dma32) - descbase);
3851         KASSERT(slot >= 0 && slot < dr->dr_numslots,
3852             ("%s:%d: fail", __func__, __LINE__));
3853
3854         addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
3855         addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
3856         addr |= siba_dma_translation(sc->sc_dev);
3857         ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3858         if (slot == dr->dr_numslots - 1)
3859                 ctl |= BWN_DMA32_DCTL_DTABLEEND;
3860         if (start)
3861                 ctl |= BWN_DMA32_DCTL_FRAMESTART;
3862         if (end)
3863                 ctl |= BWN_DMA32_DCTL_FRAMEEND;
3864         if (irq)
3865                 ctl |= BWN_DMA32_DCTL_IRQ;
3866         ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3867             & BWN_DMA32_DCTL_ADDREXT_MASK;
3868
3869         desc->dma.dma32.control = htole32(ctl);
3870         desc->dma.dma32.address = htole32(addr);
3871 }
3872
3873 static void
3874 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3875 {
3876
3877         BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3878             (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3879 }
3880
3881 static void
3882 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3883 {
3884
3885         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3886             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3887 }
3888
3889 static void
3890 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3891 {
3892
3893         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3894             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
3895 }
3896
3897 static int
3898 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
3899 {
3900         uint32_t val;
3901
3902         val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
3903         val &= BWN_DMA32_RXDPTR;
3904
3905         return (val / sizeof(struct bwn_dmadesc32));
3906 }
3907
3908 static void
3909 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
3910 {
3911
3912         BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
3913             (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
3914 }
3915
3916 static void
3917 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
3918     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3919 {
3920         struct bwn_dmadesc64 *desc;
3921
3922         *meta = &(dr->dr_meta[slot]);
3923         desc = dr->dr_ring_descbase;
3924         desc = &(desc[slot]);
3925
3926         *gdesc = (struct bwn_dmadesc_generic *)desc;
3927 }
3928
3929 static void
3930 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
3931     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3932     int start, int end, int irq)
3933 {
3934         struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
3935         struct bwn_softc *sc = dr->dr_mac->mac_sc;
3936         int slot;
3937         uint32_t ctl0 = 0, ctl1 = 0;
3938         uint32_t addrlo, addrhi;
3939         uint32_t addrext;
3940
3941         slot = (int)(&(desc->dma.dma64) - descbase);
3942         KASSERT(slot >= 0 && slot < dr->dr_numslots,
3943             ("%s:%d: fail", __func__, __LINE__));
3944
3945         addrlo = (uint32_t) (dmaaddr & 0xffffffff);
3946         addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
3947         addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
3948             30;
3949         addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
3950         if (slot == dr->dr_numslots - 1)
3951                 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
3952         if (start)
3953                 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
3954         if (end)
3955                 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
3956         if (irq)
3957                 ctl0 |= BWN_DMA64_DCTL0_IRQ;
3958         ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
3959         ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
3960             & BWN_DMA64_DCTL1_ADDREXT_MASK;
3961
3962         desc->dma.dma64.control0 = htole32(ctl0);
3963         desc->dma.dma64.control1 = htole32(ctl1);
3964         desc->dma.dma64.address_low = htole32(addrlo);
3965         desc->dma.dma64.address_high = htole32(addrhi);
3966 }
3967
3968 static void
3969 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
3970 {
3971
3972         BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
3973             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
3974 }
3975
3976 static void
3977 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
3978 {
3979
3980         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
3981             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
3982 }
3983
3984 static void
3985 bwn_dma_64_resume(struct bwn_dma_ring *dr)
3986 {
3987
3988         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
3989             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
3990 }
3991
3992 static int
3993 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
3994 {
3995         uint32_t val;
3996
3997         val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
3998         val &= BWN_DMA64_RXSTATDPTR;
3999
4000         return (val / sizeof(struct bwn_dmadesc64));
4001 }
4002
4003 static void
4004 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4005 {
4006
4007         BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4008             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4009 }
4010
4011 static int
4012 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4013 {
4014         struct bwn_mac *mac = dr->dr_mac;
4015         struct bwn_dma *dma = &mac->mac_method.dma;
4016         struct bwn_softc *sc = mac->mac_sc;
4017         int error;
4018
4019         error = bus_dma_tag_create(dma->parent_dtag,
4020                             BWN_ALIGN, 0,
4021                             BUS_SPACE_MAXADDR,
4022                             BUS_SPACE_MAXADDR,
4023                             NULL, NULL,
4024                             BWN_DMA_RINGMEMSIZE,
4025                             1,
4026                             BUS_SPACE_MAXSIZE_32BIT,
4027                             0,
4028                             &dr->dr_ring_dtag);
4029         if (error) {
4030                 device_printf(sc->sc_dev,
4031                     "can't create TX ring DMA tag: TODO frees\n");
4032                 return (-1);
4033         }
4034
4035         error = bus_dmamem_alloc(dr->dr_ring_dtag,
4036             &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4037             &dr->dr_ring_dmap);
4038         if (error) {
4039                 device_printf(sc->sc_dev,
4040                     "can't allocate DMA mem: TODO frees\n");
4041                 return (-1);
4042         }
4043         error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4044             dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4045             bwn_dma_ring_addr, &dr->dr_ring_dmabase, 0);
4046         if (error) {
4047                 device_printf(sc->sc_dev,
4048                     "can't load DMA mem: TODO free\n");
4049                 return (-1);
4050         }
4051
4052         return (0);
4053 }
4054
4055 static void
4056 bwn_dma_setup(struct bwn_dma_ring *dr)
4057 {
4058         struct bwn_softc *sc = dr->dr_mac->mac_sc;
4059         uint64_t ring64;
4060         uint32_t addrext, ring32, value;
4061         uint32_t trans = siba_dma_translation(sc->sc_dev);
4062
4063         if (dr->dr_tx) {
4064                 dr->dr_curslot = -1;
4065
4066                 if (dr->dr_type == BWN_DMA_64BIT) {
4067                         ring64 = (uint64_t)(dr->dr_ring_dmabase);
4068                         addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4069                             >> 30;
4070                         value = BWN_DMA64_TXENABLE;
4071                         value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4072                             & BWN_DMA64_TXADDREXT_MASK;
4073                         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4074                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4075                             (ring64 & 0xffffffff));
4076                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4077                             ((ring64 >> 32) &
4078                             ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4079                 } else {
4080                         ring32 = (uint32_t)(dr->dr_ring_dmabase);
4081                         addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4082                         value = BWN_DMA32_TXENABLE;
4083                         value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4084                             & BWN_DMA32_TXADDREXT_MASK;
4085                         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4086                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4087                             (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4088                 }
4089                 return;
4090         }
4091
4092         /*
4093          * set for RX
4094          */
4095         dr->dr_usedslot = dr->dr_numslots;
4096
4097         if (dr->dr_type == BWN_DMA_64BIT) {
4098                 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4099                 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4100                 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4101                 value |= BWN_DMA64_RXENABLE;
4102                 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4103                     & BWN_DMA64_RXADDREXT_MASK;
4104                 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4105                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4106                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4107                     ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4108                     | (trans << 1));
4109                 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4110                     sizeof(struct bwn_dmadesc64));
4111         } else {
4112                 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4113                 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4114                 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4115                 value |= BWN_DMA32_RXENABLE;
4116                 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4117                     & BWN_DMA32_RXADDREXT_MASK;
4118                 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4119                 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4120                     (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4121                 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4122                     sizeof(struct bwn_dmadesc32));
4123         }
4124 }
4125
4126 static void
4127 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4128 {
4129
4130         if (dr->dr_tx) {
4131                 bus_dmamap_unload(dr->dr_txring_dtag, dr->dr_txring_dmap);
4132                 if (dr->dr_txhdr_cache != NULL)
4133                         bus_dmamem_free(dr->dr_txring_dtag, dr->dr_txhdr_cache,
4134                             dr->dr_txring_dmap);
4135                 bus_dma_tag_destroy(dr->dr_txring_dtag);
4136         }
4137         bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4138         bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4139             dr->dr_ring_dmap);
4140         bus_dma_tag_destroy(dr->dr_ring_dtag);
4141 }
4142
4143 static void
4144 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4145 {
4146
4147         if (dr->dr_tx) {
4148                 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4149                 if (dr->dr_type == BWN_DMA_64BIT) {
4150                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4151                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4152                 } else
4153                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4154         } else {
4155                 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4156                 if (dr->dr_type == BWN_DMA_64BIT) {
4157                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4158                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4159                 } else
4160                         BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4161         }
4162 }
4163
4164 static void
4165 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4166 {
4167         struct bwn_dmadesc_generic *desc;
4168         struct bwn_dmadesc_meta *meta;
4169         struct bwn_mac *mac = dr->dr_mac;
4170         struct bwn_dma *dma = &mac->mac_method.dma;
4171         struct bwn_softc *sc = mac->mac_sc;
4172         int i;
4173
4174         if (!dr->dr_usedslot)
4175                 return;
4176         for (i = 0; i < dr->dr_numslots; i++) {
4177                 dr->getdesc(dr, i, &desc, &meta);
4178
4179                 if (meta->mt_m == NULL) {
4180                         if (!dr->dr_tx)
4181                                 device_printf(sc->sc_dev, "%s: not TX?\n",
4182                                     __func__);
4183                         continue;
4184                 }
4185                 if (dr->dr_tx) {
4186                         if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) {
4187                                 /* Nothing */
4188                         } else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) {
4189                                 bus_dmamap_unload(dma->txbuf_dtag,
4190                                     meta->mt_dmap);
4191                         }
4192                 } else
4193                         bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4194                 bwn_dma_free_descbuf(dr, meta);
4195         }
4196 }
4197
4198 static int
4199 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4200     int type)
4201 {
4202         struct bwn_softc *sc = mac->mac_sc;
4203         uint32_t value;
4204         int i;
4205         uint16_t offset;
4206
4207         for (i = 0; i < 10; i++) {
4208                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4209                     BWN_DMA32_TXSTATUS;
4210                 value = BWN_READ_4(mac, base + offset);
4211                 if (type == BWN_DMA_64BIT) {
4212                         value &= BWN_DMA64_TXSTAT;
4213                         if (value == BWN_DMA64_TXSTAT_DISABLED ||
4214                             value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4215                             value == BWN_DMA64_TXSTAT_STOPPED)
4216                                 break;
4217                 } else {
4218                         value &= BWN_DMA32_TXSTATE;
4219                         if (value == BWN_DMA32_TXSTAT_DISABLED ||
4220                             value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4221                             value == BWN_DMA32_TXSTAT_STOPPED)
4222                                 break;
4223                 }
4224                 DELAY(1000);
4225         }
4226         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4227         BWN_WRITE_4(mac, base + offset, 0);
4228         for (i = 0; i < 10; i++) {
4229                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4230                                                    BWN_DMA32_TXSTATUS;
4231                 value = BWN_READ_4(mac, base + offset);
4232                 if (type == BWN_DMA_64BIT) {
4233                         value &= BWN_DMA64_TXSTAT;
4234                         if (value == BWN_DMA64_TXSTAT_DISABLED) {
4235                                 i = -1;
4236                                 break;
4237                         }
4238                 } else {
4239                         value &= BWN_DMA32_TXSTATE;
4240                         if (value == BWN_DMA32_TXSTAT_DISABLED) {
4241                                 i = -1;
4242                                 break;
4243                         }
4244                 }
4245                 DELAY(1000);
4246         }
4247         if (i != -1) {
4248                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4249                 return (ENODEV);
4250         }
4251         DELAY(1000);
4252
4253         return (0);
4254 }
4255
4256 static int
4257 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4258     int type)
4259 {
4260         struct bwn_softc *sc = mac->mac_sc;
4261         uint32_t value;
4262         int i;
4263         uint16_t offset;
4264
4265         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4266         BWN_WRITE_4(mac, base + offset, 0);
4267         for (i = 0; i < 10; i++) {
4268                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4269                     BWN_DMA32_RXSTATUS;
4270                 value = BWN_READ_4(mac, base + offset);
4271                 if (type == BWN_DMA_64BIT) {
4272                         value &= BWN_DMA64_RXSTAT;
4273                         if (value == BWN_DMA64_RXSTAT_DISABLED) {
4274                                 i = -1;
4275                                 break;
4276                         }
4277                 } else {
4278                         value &= BWN_DMA32_RXSTATE;
4279                         if (value == BWN_DMA32_RXSTAT_DISABLED) {
4280                                 i = -1;
4281                                 break;
4282                         }
4283                 }
4284                 DELAY(1000);
4285         }
4286         if (i != -1) {
4287                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4288                 return (ENODEV);
4289         }
4290
4291         return (0);
4292 }
4293
4294 static void
4295 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4296     struct bwn_dmadesc_meta *meta)
4297 {
4298
4299         if (meta->mt_m != NULL) {
4300                 m_freem(meta->mt_m);
4301                 meta->mt_m = NULL;
4302         }
4303         if (meta->mt_ni != NULL) {
4304                 ieee80211_free_node(meta->mt_ni);
4305                 meta->mt_ni = NULL;
4306         }
4307 }
4308
4309 static void
4310 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4311 {
4312         struct bwn_rxhdr4 *rxhdr;
4313         unsigned char *frame;
4314
4315         rxhdr = mtod(m, struct bwn_rxhdr4 *);
4316         rxhdr->frame_len = 0;
4317
4318         KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4319             sizeof(struct bwn_plcp6) + 2,
4320             ("%s:%d: fail", __func__, __LINE__));
4321         frame = mtod(m, char *) + dr->dr_frameoffset;
4322         memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4323 }
4324
4325 static uint8_t
4326 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4327 {
4328         unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4329
4330         return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4331             == 0xff);
4332 }
4333
4334 static void
4335 bwn_wme_init(struct bwn_mac *mac)
4336 {
4337
4338         bwn_wme_load(mac);
4339
4340         /* enable WME support. */
4341         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4342         BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4343             BWN_IFSCTL_USE_EDCF);
4344 }
4345
4346 static void
4347 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4348 {
4349         struct bwn_softc *sc = mac->mac_sc;
4350         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
4351         uint16_t delay; /* microsec */
4352
4353         delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4354         if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4355                 delay = 500;
4356         if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4357                 delay = max(delay, (uint16_t)2400);
4358
4359         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4360 }
4361
4362 static void
4363 bwn_bt_enable(struct bwn_mac *mac)
4364 {
4365         struct bwn_softc *sc = mac->mac_sc;
4366         uint64_t hf;
4367
4368         if (bwn_bluetooth == 0)
4369                 return;
4370         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4371                 return;
4372         if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4373                 return;
4374
4375         hf = bwn_hf_read(mac);
4376         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4377                 hf |= BWN_HF_BT_COEXISTALT;
4378         else
4379                 hf |= BWN_HF_BT_COEXIST;
4380         bwn_hf_write(mac, hf);
4381 }
4382
4383 static void
4384 bwn_set_macaddr(struct bwn_mac *mac)
4385 {
4386
4387         bwn_mac_write_bssid(mac);
4388         bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
4389 }
4390
4391 static void
4392 bwn_clear_keys(struct bwn_mac *mac)
4393 {
4394         int i;
4395
4396         for (i = 0; i < mac->mac_max_nr_keys; i++) {
4397                 KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4398                     ("%s:%d: fail", __func__, __LINE__));
4399
4400                 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4401                     NULL, BWN_SEC_KEYSIZE, NULL);
4402                 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4403                         bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4404                             NULL, BWN_SEC_KEYSIZE, NULL);
4405                 }
4406                 mac->mac_key[i].keyconf = NULL;
4407         }
4408 }
4409
4410 static void
4411 bwn_crypt_init(struct bwn_mac *mac)
4412 {
4413         struct bwn_softc *sc = mac->mac_sc;
4414
4415         mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4416         KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4417             ("%s:%d: fail", __func__, __LINE__));
4418         mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4419         mac->mac_ktp *= 2;
4420         if (siba_get_revid(sc->sc_dev) >= 5)
4421                 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4422         bwn_clear_keys(mac);
4423 }
4424
4425 static void
4426 bwn_chip_exit(struct bwn_mac *mac)
4427 {
4428         struct bwn_softc *sc = mac->mac_sc;
4429
4430         bwn_phy_exit(mac);
4431         siba_gpio_set(sc->sc_dev, 0);
4432 }
4433
4434 static int
4435 bwn_fw_fillinfo(struct bwn_mac *mac)
4436 {
4437         int error;
4438
4439         error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4440         if (error == 0)
4441                 return (0);
4442         error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4443         if (error == 0)
4444                 return (0);
4445         return (error);
4446 }
4447
4448 static int
4449 bwn_gpio_init(struct bwn_mac *mac)
4450 {
4451         struct bwn_softc *sc = mac->mac_sc;
4452         uint32_t mask = 0x1f, set = 0xf, value;
4453
4454         BWN_WRITE_4(mac, BWN_MACCTL,
4455             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4456         BWN_WRITE_2(mac, BWN_GPIO_MASK,
4457             BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4458
4459         if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4460                 mask |= 0x0060;
4461                 set |= 0x0060;
4462         }
4463         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4464                 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4465                     BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4466                 mask |= 0x0200;
4467                 set |= 0x0200;
4468         }
4469         if (siba_get_revid(sc->sc_dev) >= 2)
4470                 mask |= 0x0010;
4471
4472         value = siba_gpio_get(sc->sc_dev);
4473         if (value == -1)
4474                 return (0);
4475         siba_gpio_set(sc->sc_dev, (value & mask) | set);
4476
4477         return (0);
4478 }
4479
4480 static int
4481 bwn_fw_loadinitvals(struct bwn_mac *mac)
4482 {
4483 #define GETFWOFFSET(fwp, offset)                                \
4484         ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4485         const size_t hdr_len = sizeof(struct bwn_fwhdr);
4486         const struct bwn_fwhdr *hdr;
4487         struct bwn_fw *fw = &mac->mac_fw;
4488         int error;
4489
4490         hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4491         error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4492             be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4493         if (error)
4494                 return (error);
4495         if (fw->initvals_band.fw) {
4496                 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4497                 error = bwn_fwinitvals_write(mac,
4498                     GETFWOFFSET(fw->initvals_band, hdr_len),
4499                     be32toh(hdr->size),
4500                     fw->initvals_band.fw->datasize - hdr_len);
4501         }
4502         return (error);
4503 #undef GETFWOFFSET
4504 }
4505
4506 static int
4507 bwn_phy_init(struct bwn_mac *mac)
4508 {
4509         struct bwn_softc *sc = mac->mac_sc;
4510         int error;
4511
4512         mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4513         mac->mac_phy.rf_onoff(mac, 1);
4514         error = mac->mac_phy.init(mac);
4515         if (error) {
4516                 device_printf(sc->sc_dev, "PHY init failed\n");
4517                 goto fail0;
4518         }
4519         error = bwn_switch_channel(mac,
4520             mac->mac_phy.get_default_chan(mac));
4521         if (error) {
4522                 device_printf(sc->sc_dev,
4523                     "failed to switch default channel\n");
4524                 goto fail1;
4525         }
4526         return (0);
4527 fail1:
4528         if (mac->mac_phy.exit)
4529                 mac->mac_phy.exit(mac);
4530 fail0:
4531         mac->mac_phy.rf_onoff(mac, 0);
4532
4533         return (error);
4534 }
4535
4536 static void
4537 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4538 {
4539         uint16_t ant;
4540         uint16_t tmp;
4541
4542         ant = bwn_ant2phy(antenna);
4543
4544         /* For ACK/CTS */
4545         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4546         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4547         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4548         /* For Probe Resposes */
4549         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4550         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4551         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4552 }
4553
4554 static void
4555 bwn_set_opmode(struct bwn_mac *mac)
4556 {
4557         struct bwn_softc *sc = mac->mac_sc;
4558         struct ifnet *ifp = sc->sc_ifp;
4559         struct ieee80211com *ic = ifp->if_l2com;
4560         uint32_t ctl;
4561         uint16_t cfp_pretbtt;
4562
4563         ctl = BWN_READ_4(mac, BWN_MACCTL);
4564         ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4565             BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4566             BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4567         ctl |= BWN_MACCTL_STA;
4568
4569         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4570             ic->ic_opmode == IEEE80211_M_MBSS)
4571                 ctl |= BWN_MACCTL_HOSTAP;
4572         else if (ic->ic_opmode == IEEE80211_M_IBSS)
4573                 ctl &= ~BWN_MACCTL_STA;
4574         ctl |= sc->sc_filters;
4575
4576         if (siba_get_revid(sc->sc_dev) <= 4)
4577                 ctl |= BWN_MACCTL_PROMISC;
4578
4579         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4580
4581         cfp_pretbtt = 2;
4582         if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4583                 if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4584                     siba_get_chiprev(sc->sc_dev) == 3)
4585                         cfp_pretbtt = 100;
4586                 else
4587                         cfp_pretbtt = 50;
4588         }
4589         BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4590 }
4591
4592 static int
4593 bwn_dma_gettype(struct bwn_mac *mac)
4594 {
4595         uint32_t tmp;
4596         uint16_t base;
4597
4598         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4599         if (tmp & SIBA_TGSHIGH_DMA64)
4600                 return (BWN_DMA_64BIT);
4601         base = bwn_dma_base(0, 0);
4602         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4603         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4604         if (tmp & BWN_DMA32_TXADDREXT_MASK)
4605                 return (BWN_DMA_32BIT);
4606
4607         return (BWN_DMA_30BIT);
4608 }
4609
4610 static void
4611 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4612 {
4613         if (!error) {
4614                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4615                 *((bus_addr_t *)arg) = seg->ds_addr;
4616         }
4617 }
4618
4619 static void
4620 bwn_phy_g_init_sub(struct bwn_mac *mac)
4621 {
4622         struct bwn_phy *phy = &mac->mac_phy;
4623         struct bwn_phy_g *pg = &phy->phy_g;
4624         struct bwn_softc *sc = mac->mac_sc;
4625         uint16_t i, tmp;
4626
4627         if (phy->rev == 1)
4628                 bwn_phy_init_b5(mac);
4629         else
4630                 bwn_phy_init_b6(mac);
4631
4632         if (phy->rev >= 2 || phy->gmode)
4633                 bwn_phy_init_a(mac);
4634
4635         if (phy->rev >= 2) {
4636                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4637                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4638         }
4639         if (phy->rev == 2) {
4640                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4641                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4642         }
4643         if (phy->rev > 5) {
4644                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4645                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4646         }
4647         if (phy->gmode || phy->rev >= 2) {
4648                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4649                 tmp &= BWN_PHYVER_VERSION;
4650                 if (tmp == 3 || tmp == 5) {
4651                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4652                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4653                 }
4654                 if (tmp == 5) {
4655                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4656                             0x1f00);
4657                 }
4658         }
4659         if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4660                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4661         if (phy->rf_rev == 8) {
4662                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4663                 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4664         }
4665         if (BWN_HAS_LOOPBACK(phy))
4666                 bwn_loopback_calcgain(mac);
4667
4668         if (phy->rf_rev != 8) {
4669                 if (pg->pg_initval == 0xffff)
4670                         pg->pg_initval = bwn_rf_init_bcm2050(mac);
4671                 else
4672                         BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4673         }
4674         bwn_lo_g_init(mac);
4675         if (BWN_HAS_TXMAG(phy)) {
4676                 BWN_RF_WRITE(mac, 0x52,
4677                     (BWN_RF_READ(mac, 0x52) & 0xff00)
4678                     | pg->pg_loctl.tx_bias |
4679                     pg->pg_loctl.tx_magn);
4680         } else {
4681                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4682         }
4683         if (phy->rev >= 6) {
4684                 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4685                     (pg->pg_loctl.tx_bias << 12));
4686         }
4687         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4688                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4689         else
4690                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4691         if (phy->rev < 2)
4692                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4693         else
4694                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4695         if (phy->gmode || phy->rev >= 2) {
4696                 bwn_lo_g_adjust(mac);
4697                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4698         }
4699
4700         if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4701                 for (i = 0; i < 64; i++) {
4702                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4703                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4704                             (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4705                             -32), 31));
4706                 }
4707                 bwn_nrssi_threshold(mac);
4708         } else if (phy->gmode || phy->rev >= 2) {
4709                 if (pg->pg_nrssi[0] == -1000) {
4710                         KASSERT(pg->pg_nrssi[1] == -1000,
4711                             ("%s:%d: fail", __func__, __LINE__));
4712                         bwn_nrssi_slope_11g(mac);
4713                 } else
4714                         bwn_nrssi_threshold(mac);
4715         }
4716         if (phy->rf_rev == 8)
4717                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4718         bwn_phy_hwpctl_init(mac);
4719         if ((siba_get_chipid(sc->sc_dev) == 0x4306
4720              && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4721                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4722                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4723         }
4724 }
4725
4726 static uint8_t
4727 bwn_has_hwpctl(struct bwn_mac *mac)
4728 {
4729
4730         if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4731                 return (0);
4732         return (mac->mac_phy.use_hwpctl(mac));
4733 }
4734
4735 static void
4736 bwn_phy_init_b5(struct bwn_mac *mac)
4737 {
4738         struct bwn_phy *phy = &mac->mac_phy;
4739         struct bwn_phy_g *pg = &phy->phy_g;
4740         struct bwn_softc *sc = mac->mac_sc;
4741         uint16_t offset, value;
4742         uint8_t old_channel;
4743
4744         if (phy->analog == 1)
4745                 BWN_RF_SET(mac, 0x007a, 0x0050);
4746         if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4747             (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4748                 value = 0x2120;
4749                 for (offset = 0x00a8; offset < 0x00c7; offset++) {
4750                         BWN_PHY_WRITE(mac, offset, value);
4751                         value += 0x202;
4752                 }
4753         }
4754         BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4755         if (phy->rf_ver == 0x2050)
4756                 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4757
4758         if (phy->gmode || phy->rev >= 2) {
4759                 if (phy->rf_ver == 0x2050) {
4760                         BWN_RF_SET(mac, 0x007a, 0x0020);
4761                         BWN_RF_SET(mac, 0x0051, 0x0004);
4762                 }
4763                 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4764
4765                 BWN_PHY_SET(mac, 0x0802, 0x0100);
4766                 BWN_PHY_SET(mac, 0x042b, 0x2000);
4767
4768                 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4769
4770                 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4771                 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4772                 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4773         }
4774
4775         if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4776                 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4777
4778         if (phy->analog == 1) {
4779                 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4780                 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4781                 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4782                 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4783                 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4784         } else
4785                 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4786         BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4787         BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4788
4789         if (phy->analog == 1)
4790                 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4791         else
4792                 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4793
4794         if (phy->analog == 0)
4795                 BWN_WRITE_2(mac, 0x03e4, 0x3000);
4796
4797         old_channel = phy->chan;
4798         bwn_phy_g_switch_chan(mac, 7, 0);
4799
4800         if (phy->rf_ver != 0x2050) {
4801                 BWN_RF_WRITE(mac, 0x0075, 0x0080);
4802                 BWN_RF_WRITE(mac, 0x0079, 0x0081);
4803         }
4804
4805         BWN_RF_WRITE(mac, 0x0050, 0x0020);
4806         BWN_RF_WRITE(mac, 0x0050, 0x0023);
4807
4808         if (phy->rf_ver == 0x2050) {
4809                 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4810                 BWN_RF_WRITE(mac, 0x005a, 0x0070);
4811         }
4812
4813         BWN_RF_WRITE(mac, 0x005b, 0x007b);
4814         BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4815         BWN_RF_SET(mac, 0x007a, 0x0007);
4816
4817         bwn_phy_g_switch_chan(mac, old_channel, 0);
4818         BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4819         BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4820         BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4821
4822         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4823             pg->pg_txctl);
4824
4825         if (phy->rf_ver == 0x2050)
4826                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
4827
4828         BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4829 }
4830
4831 static void
4832 bwn_loopback_calcgain(struct bwn_mac *mac)
4833 {
4834         struct bwn_phy *phy = &mac->mac_phy;
4835         struct bwn_phy_g *pg = &phy->phy_g;
4836         struct bwn_softc *sc = mac->mac_sc;
4837         uint16_t backup_phy[16] = { 0 };
4838         uint16_t backup_radio[3];
4839         uint16_t backup_bband;
4840         uint16_t i, j, loop_i_max;
4841         uint16_t trsw_rx;
4842         uint16_t loop1_outer_done, loop1_inner_done;
4843
4844         backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4845         backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4846         backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4847         backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4848         if (phy->rev != 1) {
4849                 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4850                 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4851         }
4852         backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4853         backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4854         backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4855         backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4856         backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4857         backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4858         backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4859         backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4860         backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4861         backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4862         backup_bband = pg->pg_bbatt.att;
4863         backup_radio[0] = BWN_RF_READ(mac, 0x52);
4864         backup_radio[1] = BWN_RF_READ(mac, 0x43);
4865         backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4866
4867         BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4868         BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4869         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4870         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4871         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4872         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4873         if (phy->rev != 1) {
4874                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4875                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4876                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4877                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4878         }
4879         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4880         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4881         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4882         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4883
4884         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4885         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4886         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4887
4888         BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4889         if (phy->rev != 1) {
4890                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4891                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4892         }
4893         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4894
4895         if (phy->rf_rev == 8)
4896                 BWN_RF_WRITE(mac, 0x43, 0x000f);
4897         else {
4898                 BWN_RF_WRITE(mac, 0x52, 0);
4899                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4900         }
4901         bwn_phy_g_set_bbatt(mac, 11);
4902
4903         if (phy->rev >= 3)
4904                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
4905         else
4906                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
4907         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
4908
4909         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
4910         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
4911
4912         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
4913         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
4914
4915         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
4916                 if (phy->rev >= 7) {
4917                         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
4918                         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
4919                 }
4920         }
4921         BWN_RF_MASK(mac, 0x7a, 0x00f7);
4922
4923         j = 0;
4924         loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
4925         for (i = 0; i < loop_i_max; i++) {
4926                 for (j = 0; j < 16; j++) {
4927                         BWN_RF_WRITE(mac, 0x43, i);
4928                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
4929                             (j << 8));
4930                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4931                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4932                         DELAY(20);
4933                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4934                                 goto done0;
4935                 }
4936         }
4937 done0:
4938         loop1_outer_done = i;
4939         loop1_inner_done = j;
4940         if (j >= 8) {
4941                 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
4942                 trsw_rx = 0x1b;
4943                 for (j = j - 8; j < 16; j++) {
4944                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
4945                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4946                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4947                         DELAY(20);
4948                         trsw_rx -= 3;
4949                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4950                                 goto done1;
4951                 }
4952         } else
4953                 trsw_rx = 0x18;
4954 done1:
4955
4956         if (phy->rev != 1) {
4957                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
4958                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
4959         }
4960         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
4961         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
4962         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
4963         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
4964         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
4965         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
4966         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
4967         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
4968         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
4969
4970         bwn_phy_g_set_bbatt(mac, backup_bband);
4971
4972         BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
4973         BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
4974         BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
4975
4976         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
4977         DELAY(10);
4978         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
4979         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
4980         BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
4981         BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
4982
4983         pg->pg_max_lb_gain =
4984             ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
4985         pg->pg_trsw_rx_gain = trsw_rx * 2;
4986 }
4987
4988 static uint16_t
4989 bwn_rf_init_bcm2050(struct bwn_mac *mac)
4990 {
4991         struct bwn_phy *phy = &mac->mac_phy;
4992         uint32_t tmp1 = 0, tmp2 = 0;
4993         uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
4994             analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
4995             radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
4996         static const uint8_t rcc_table[] = {
4997                 0x02, 0x03, 0x01, 0x0f,
4998                 0x06, 0x07, 0x05, 0x0f,
4999                 0x0a, 0x0b, 0x09, 0x0f,
5000                 0x0e, 0x0f, 0x0d, 0x0f,
5001         };
5002
5003         loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
5004             rfoverval = rfover = cck3 = 0;
5005         radio0 = BWN_RF_READ(mac, 0x43);
5006         radio1 = BWN_RF_READ(mac, 0x51);
5007         radio2 = BWN_RF_READ(mac, 0x52);
5008         pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5009         cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5010         cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5011         cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5012
5013         if (phy->type == BWN_PHYTYPE_B) {
5014                 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5015                 reg0 = BWN_READ_2(mac, 0x3ec);
5016
5017                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5018                 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5019         } else if (phy->gmode || phy->rev >= 2) {
5020                 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5021                 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5022                 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5023                 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5024                 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5025                 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5026
5027                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5028                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5029                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5030                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5031                 if (BWN_HAS_LOOPBACK(phy)) {
5032                         lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5033                         loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5034                         if (phy->rev >= 3)
5035                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5036                         else
5037                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5038                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5039                 }
5040
5041                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5042                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5043                         BWN_LPD(0, 1, 1)));
5044                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5045                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5046         }
5047         BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5048
5049         syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5050         BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5051         reg1 = BWN_READ_2(mac, 0x3e6);
5052         reg2 = BWN_READ_2(mac, 0x3f4);
5053
5054         if (phy->analog == 0)
5055                 BWN_WRITE_2(mac, 0x03e6, 0x0122);
5056         else {
5057                 if (phy->analog >= 2)
5058                         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5059                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5060                     (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5061         }
5062
5063         reg = BWN_RF_READ(mac, 0x60);
5064         index = (reg & 0x001e) >> 1;
5065         rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5066
5067         if (phy->type == BWN_PHYTYPE_B)
5068                 BWN_RF_WRITE(mac, 0x78, 0x26);
5069         if (phy->gmode || phy->rev >= 2) {
5070                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5071                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5072                         BWN_LPD(0, 1, 1)));
5073         }
5074         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5075         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5076         if (phy->gmode || phy->rev >= 2) {
5077                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5078                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5079                         BWN_LPD(0, 0, 1)));
5080         }
5081         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5082         BWN_RF_SET(mac, 0x51, 0x0004);
5083         if (phy->rf_rev == 8)
5084                 BWN_RF_WRITE(mac, 0x43, 0x1f);
5085         else {
5086                 BWN_RF_WRITE(mac, 0x52, 0);
5087                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5088         }
5089         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5090
5091         for (i = 0; i < 16; i++) {
5092                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5093                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5094                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5095                 if (phy->gmode || phy->rev >= 2) {
5096                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5097                             bwn_rf_2050_rfoverval(mac,
5098                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5099                 }
5100                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5101                 DELAY(10);
5102                 if (phy->gmode || phy->rev >= 2) {
5103                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5104                             bwn_rf_2050_rfoverval(mac,
5105                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5106                 }
5107                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5108                 DELAY(10);
5109                 if (phy->gmode || phy->rev >= 2) {
5110                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5111                             bwn_rf_2050_rfoverval(mac,
5112                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5113                 }
5114                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5115                 DELAY(20);
5116                 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5117                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5118                 if (phy->gmode || phy->rev >= 2) {
5119                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5120                             bwn_rf_2050_rfoverval(mac,
5121                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5122                 }
5123                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5124         }
5125         DELAY(10);
5126
5127         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5128         tmp1++;
5129         tmp1 >>= 9;
5130
5131         for (i = 0; i < 16; i++) {
5132                 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5133                 BWN_RF_WRITE(mac, 0x78, radio78);
5134                 DELAY(10);
5135                 for (j = 0; j < 16; j++) {
5136                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5137                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5138                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5139                         if (phy->gmode || phy->rev >= 2) {
5140                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5141                                     bwn_rf_2050_rfoverval(mac,
5142                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5143                         }
5144                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5145                         DELAY(10);
5146                         if (phy->gmode || phy->rev >= 2) {
5147                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5148                                     bwn_rf_2050_rfoverval(mac,
5149                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5150                         }
5151                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5152                         DELAY(10);
5153                         if (phy->gmode || phy->rev >= 2) {
5154                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5155                                     bwn_rf_2050_rfoverval(mac,
5156                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5157                         }
5158                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5159                         DELAY(10);
5160                         tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5161                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5162                         if (phy->gmode || phy->rev >= 2) {
5163                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5164                                     bwn_rf_2050_rfoverval(mac,
5165                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5166                         }
5167                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5168                 }
5169                 tmp2++;
5170                 tmp2 >>= 8;
5171                 if (tmp1 < tmp2)
5172                         break;
5173         }
5174
5175         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5176         BWN_RF_WRITE(mac, 0x51, radio1);
5177         BWN_RF_WRITE(mac, 0x52, radio2);
5178         BWN_RF_WRITE(mac, 0x43, radio0);
5179         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5180         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5181         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5182         BWN_WRITE_2(mac, 0x3e6, reg1);
5183         if (phy->analog != 0)
5184                 BWN_WRITE_2(mac, 0x3f4, reg2);
5185         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5186         bwn_spu_workaround(mac, phy->chan);
5187         if (phy->type == BWN_PHYTYPE_B) {
5188                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5189                 BWN_WRITE_2(mac, 0x3ec, reg0);
5190         } else if (phy->gmode) {
5191                 BWN_WRITE_2(mac, BWN_PHY_RADIO,
5192                             BWN_READ_2(mac, BWN_PHY_RADIO)
5193                             & 0x7fff);
5194                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5195                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5196                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5197                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5198                               analogoverval);
5199                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5200                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5201                 if (BWN_HAS_LOOPBACK(phy)) {
5202                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5203                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5204                 }
5205         }
5206
5207         return ((i > 15) ? radio78 : rcc);
5208 }
5209
5210 static void
5211 bwn_phy_init_b6(struct bwn_mac *mac)
5212 {
5213         struct bwn_phy *phy = &mac->mac_phy;
5214         struct bwn_phy_g *pg = &phy->phy_g;
5215         struct bwn_softc *sc = mac->mac_sc;
5216         uint16_t offset, val;
5217         uint8_t old_channel;
5218
5219         KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5220             ("%s:%d: fail", __func__, __LINE__));
5221
5222         BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5223         BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5224         if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5225                 BWN_RF_WRITE(mac, 0x51, 0x37);
5226                 BWN_RF_WRITE(mac, 0x52, 0x70);
5227                 BWN_RF_WRITE(mac, 0x53, 0xb3);
5228                 BWN_RF_WRITE(mac, 0x54, 0x9b);
5229                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5230                 BWN_RF_WRITE(mac, 0x5b, 0x88);
5231                 BWN_RF_WRITE(mac, 0x5d, 0x88);
5232                 BWN_RF_WRITE(mac, 0x5e, 0x88);
5233                 BWN_RF_WRITE(mac, 0x7d, 0x88);
5234                 bwn_hf_write(mac,
5235                     bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5236         }
5237         if (phy->rf_rev == 8) {
5238                 BWN_RF_WRITE(mac, 0x51, 0);
5239                 BWN_RF_WRITE(mac, 0x52, 0x40);
5240                 BWN_RF_WRITE(mac, 0x53, 0xb7);
5241                 BWN_RF_WRITE(mac, 0x54, 0x98);
5242                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5243                 BWN_RF_WRITE(mac, 0x5b, 0x6b);
5244                 BWN_RF_WRITE(mac, 0x5c, 0x0f);
5245                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5246                         BWN_RF_WRITE(mac, 0x5d, 0xfa);
5247                         BWN_RF_WRITE(mac, 0x5e, 0xd8);
5248                 } else {
5249                         BWN_RF_WRITE(mac, 0x5d, 0xf5);
5250                         BWN_RF_WRITE(mac, 0x5e, 0xb8);
5251                 }
5252                 BWN_RF_WRITE(mac, 0x0073, 0x0003);
5253                 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5254                 BWN_RF_WRITE(mac, 0x007c, 0x0001);
5255                 BWN_RF_WRITE(mac, 0x007e, 0x0008);
5256         }
5257         for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5258                 BWN_PHY_WRITE(mac, offset, val);
5259                 val -= 0x0202;
5260         }
5261         for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5262                 BWN_PHY_WRITE(mac, offset, val);
5263                 val -= 0x0202;
5264         }
5265         for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5266                 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5267                 val += 0x0202;
5268         }
5269         if (phy->type == BWN_PHYTYPE_G) {
5270                 BWN_RF_SET(mac, 0x007a, 0x0020);
5271                 BWN_RF_SET(mac, 0x0051, 0x0004);
5272                 BWN_PHY_SET(mac, 0x0802, 0x0100);
5273                 BWN_PHY_SET(mac, 0x042b, 0x2000);
5274                 BWN_PHY_WRITE(mac, 0x5b, 0);
5275                 BWN_PHY_WRITE(mac, 0x5c, 0);
5276         }
5277
5278         old_channel = phy->chan;
5279         bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5280
5281         BWN_RF_WRITE(mac, 0x0050, 0x0020);
5282         BWN_RF_WRITE(mac, 0x0050, 0x0023);
5283         DELAY(40);
5284         if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5285                 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5286                 BWN_RF_WRITE(mac, 0x50, 0x20);
5287         }
5288         if (phy->rf_rev <= 2) {
5289                 BWN_RF_WRITE(mac, 0x7c, 0x20);
5290                 BWN_RF_WRITE(mac, 0x5a, 0x70);
5291                 BWN_RF_WRITE(mac, 0x5b, 0x7b);
5292                 BWN_RF_WRITE(mac, 0x5c, 0xb0);
5293         }
5294         BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5295
5296         bwn_phy_g_switch_chan(mac, old_channel, 0);
5297
5298         BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5299         if (phy->rf_rev >= 6)
5300                 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5301         else
5302                 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5303         BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5304         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5305             pg->pg_txctl);
5306         if (phy->rf_rev <= 5)
5307                 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5308         if (phy->rf_rev <= 2)
5309                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
5310
5311         if (phy->analog == 4) {
5312                 BWN_WRITE_2(mac, 0x3e4, 9);
5313                 BWN_PHY_MASK(mac, 0x61, 0x0fff);
5314         } else
5315                 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5316         if (phy->type == BWN_PHYTYPE_B)
5317                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5318         else if (phy->type == BWN_PHYTYPE_G)
5319                 BWN_WRITE_2(mac, 0x03e6, 0x0);
5320 }
5321
5322 static void
5323 bwn_phy_init_a(struct bwn_mac *mac)
5324 {
5325         struct bwn_phy *phy = &mac->mac_phy;
5326         struct bwn_softc *sc = mac->mac_sc;
5327
5328         KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5329             ("%s:%d: fail", __func__, __LINE__));
5330
5331         if (phy->rev >= 6) {
5332                 if (phy->type == BWN_PHYTYPE_A)
5333                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5334                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5335                         BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5336                 else
5337                         BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5338         }
5339
5340         bwn_wa_init(mac);
5341
5342         if (phy->type == BWN_PHYTYPE_G &&
5343             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5344                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5345 }
5346
5347 static void
5348 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5349 {
5350         int i;
5351
5352         for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5353                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5354 }
5355
5356 static void
5357 bwn_wa_agc(struct bwn_mac *mac)
5358 {
5359         struct bwn_phy *phy = &mac->mac_phy;
5360
5361         if (phy->rev == 1) {
5362                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5363                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5364                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5365                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5366                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5367                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5368                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5369                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5370                 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5371         } else {
5372                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5373                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5374                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5375                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5376         }
5377
5378         BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5379             0x5700);
5380         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5381         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5382         BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5383         BWN_RF_SET(mac, 0x7a, 0x0008);
5384         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5385         BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5386         BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5387         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5388         if (phy->rev == 1)
5389                 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5390         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5391         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5392         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5393         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5394         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5395         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5396         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5397         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5398         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5399         if (phy->rev == 1) {
5400                 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5401                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5402         } else {
5403                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5404                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5405                 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5406                 if (phy->rev >= 6) {
5407                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5408                         BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5409                             (uint16_t)~0xf000, 0x3000);
5410                 }
5411         }
5412         BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5413         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5414         if (phy->rev == 1) {
5415                 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5416                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5417                 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5418                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5419                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5420                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5421                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5422                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5423         } else {
5424                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5425                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5426                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5427                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5428         }
5429         if (phy->rev >= 6) {
5430                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5431                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5432         }
5433         BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5434 }
5435
5436 static void
5437 bwn_wa_grev1(struct bwn_mac *mac)
5438 {
5439         struct bwn_phy *phy = &mac->mac_phy;
5440         int i;
5441         static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5442         static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5443         static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5444
5445         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5446
5447         /* init CRSTHRES and ANTDWELL */
5448         if (phy->rev == 1) {
5449                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5450         } else if (phy->rev == 2) {
5451                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5452                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5453                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5454         } else {
5455                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5456                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5457                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5458                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5459         }
5460         BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5461         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5462         BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5463
5464         /* XXX support PHY-A??? */
5465         for (i = 0; i < N(bwn_tab_finefreqg); i++)
5466                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5467                     bwn_tab_finefreqg[i]);
5468
5469         /* XXX support PHY-A??? */
5470         if (phy->rev == 1)
5471                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5472                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5473                             bwn_tab_noise_g1[i]);
5474         else
5475                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5476                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5477                             bwn_tab_noise_g2[i]);
5478
5479
5480         for (i = 0; i < N(bwn_tab_rotor); i++)
5481                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5482                     bwn_tab_rotor[i]);
5483
5484         /* XXX support PHY-A??? */
5485         if (phy->rev >= 6) {
5486                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5487                     BWN_PHY_ENCORE_EN)
5488                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5489                 else
5490                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5491         } else
5492                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5493
5494         for (i = 0; i < N(bwn_tab_retard); i++)
5495                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5496                     bwn_tab_retard[i]);
5497
5498         if (phy->rev == 1) {
5499                 for (i = 0; i < 16; i++)
5500                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5501                             i, 0x0020);
5502         } else {
5503                 for (i = 0; i < 32; i++)
5504                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5505         }
5506
5507         bwn_wa_agc(mac);
5508 }
5509
5510 static void
5511 bwn_wa_grev26789(struct bwn_mac *mac)
5512 {
5513         struct bwn_phy *phy = &mac->mac_phy;
5514         int i;
5515         static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5516         uint16_t ofdmrev;
5517
5518         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5519
5520         bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5521
5522         /* init CRSTHRES and ANTDWELL */
5523         if (phy->rev == 1)
5524                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5525         else if (phy->rev == 2) {
5526                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5527                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5528                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5529         } else {
5530                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5531                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5532                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5533                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5534         }
5535
5536         for (i = 0; i < 64; i++)
5537                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5538
5539         /* XXX support PHY-A??? */
5540         if (phy->rev == 1)
5541                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5542                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5543                             bwn_tab_noise_g1[i]);
5544         else
5545                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5546                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5547                             bwn_tab_noise_g2[i]);
5548
5549         /* XXX support PHY-A??? */
5550         if (phy->rev >= 6) {
5551                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5552                     BWN_PHY_ENCORE_EN)
5553                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5554                 else
5555                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5556         } else
5557                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5558
5559         for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5560                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5561                     bwn_tab_sigmasqr2[i]);
5562
5563         if (phy->rev == 1) {
5564                 for (i = 0; i < 16; i++)
5565                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5566                             0x0020);
5567         } else {
5568                 for (i = 0; i < 32; i++)
5569                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5570         }
5571
5572         bwn_wa_agc(mac);
5573
5574         ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5575         if (ofdmrev > 2) {
5576                 if (phy->type == BWN_PHYTYPE_A)
5577                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5578                 else
5579                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5580         } else {
5581                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5582                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5583                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5584         }
5585
5586         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5587         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5588 }
5589
5590 static void
5591 bwn_wa_init(struct bwn_mac *mac)
5592 {
5593         struct bwn_phy *phy = &mac->mac_phy;
5594         struct bwn_softc *sc = mac->mac_sc;
5595
5596         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5597
5598         switch (phy->rev) {
5599         case 1:
5600                 bwn_wa_grev1(mac);
5601                 break;
5602         case 2:
5603         case 6:
5604         case 7:
5605         case 8:
5606         case 9:
5607                 bwn_wa_grev26789(mac);
5608                 break;
5609         default:
5610                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5611         }
5612
5613         if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5614             siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5615             siba_get_pci_revid(sc->sc_dev) != 0x17) {
5616                 if (phy->rev < 2) {
5617                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5618                             0x0002);
5619                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5620                             0x0001);
5621                 } else {
5622                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5623                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5624                         if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5625                              BWN_BFL_EXTLNA) &&
5626                             (phy->rev >= 7)) {
5627                                 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5628                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5629                                     0x0020, 0x0001);
5630                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5631                                     0x0021, 0x0001);
5632                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5633                                     0x0022, 0x0001);
5634                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5635                                     0x0023, 0x0000);
5636                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5637                                     0x0000, 0x0000);
5638                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5639                                     0x0003, 0x0002);
5640                         }
5641                 }
5642         }
5643         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5644                 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5645                 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5646         }
5647
5648         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5649         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5650 }
5651
5652 static void
5653 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5654     uint16_t value)
5655 {
5656         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5657         uint16_t addr;
5658
5659         addr = table + offset;
5660         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5661             (addr - 1 != pg->pg_ofdmtab_addr)) {
5662                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5663                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5664         }
5665         pg->pg_ofdmtab_addr = addr;
5666         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5667 }
5668
5669 static void
5670 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5671     uint32_t value)
5672 {
5673         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5674         uint16_t addr;
5675
5676         addr = table + offset;
5677         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5678             (addr - 1 != pg->pg_ofdmtab_addr)) {
5679                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5680                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5681         }
5682         pg->pg_ofdmtab_addr = addr;
5683
5684         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5685         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5686 }
5687
5688 static void
5689 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5690     uint16_t value)
5691 {
5692
5693         BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5694         BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5695 }
5696
5697 static void
5698 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5699 {
5700         struct bwn_phy *phy = &mac->mac_phy;
5701         struct bwn_softc *sc = mac->mac_sc;
5702         unsigned int i, max_loop;
5703         uint16_t value;
5704         uint32_t buffer[5] = {
5705                 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5706         };
5707
5708         if (ofdm) {
5709                 max_loop = 0x1e;
5710                 buffer[0] = 0x000201cc;
5711         } else {
5712                 max_loop = 0xfa;
5713                 buffer[0] = 0x000b846e;
5714         }
5715
5716         for (i = 0; i < 5; i++)
5717                 bwn_ram_write(mac, i * 4, buffer[i]);
5718
5719         BWN_WRITE_2(mac, 0x0568, 0x0000);
5720         BWN_WRITE_2(mac, 0x07c0,
5721             (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5722         value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5723         BWN_WRITE_2(mac, 0x050c, value);
5724         if (phy->type == BWN_PHYTYPE_LP)
5725                 BWN_WRITE_2(mac, 0x0514, 0x1a02);
5726         BWN_WRITE_2(mac, 0x0508, 0x0000);
5727         BWN_WRITE_2(mac, 0x050a, 0x0000);
5728         BWN_WRITE_2(mac, 0x054c, 0x0000);
5729         BWN_WRITE_2(mac, 0x056a, 0x0014);
5730         BWN_WRITE_2(mac, 0x0568, 0x0826);
5731         BWN_WRITE_2(mac, 0x0500, 0x0000);
5732         if (phy->type == BWN_PHYTYPE_LP)
5733                 BWN_WRITE_2(mac, 0x0502, 0x0050);
5734         else
5735                 BWN_WRITE_2(mac, 0x0502, 0x0030);
5736
5737         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5738                 BWN_RF_WRITE(mac, 0x0051, 0x0017);
5739         for (i = 0x00; i < max_loop; i++) {
5740                 value = BWN_READ_2(mac, 0x050e);
5741                 if (value & 0x0080)
5742                         break;
5743                 DELAY(10);
5744         }
5745         for (i = 0x00; i < 0x0a; i++) {
5746                 value = BWN_READ_2(mac, 0x050e);
5747                 if (value & 0x0400)
5748                         break;
5749                 DELAY(10);
5750         }
5751         for (i = 0x00; i < 0x19; i++) {
5752                 value = BWN_READ_2(mac, 0x0690);
5753                 if (!(value & 0x0100))
5754                         break;
5755                 DELAY(10);
5756         }
5757         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5758                 BWN_RF_WRITE(mac, 0x0051, 0x0037);
5759 }
5760
5761 static void
5762 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5763 {
5764         uint32_t macctl;
5765
5766         KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5767
5768         macctl = BWN_READ_4(mac, BWN_MACCTL);
5769         if (macctl & BWN_MACCTL_BIGENDIAN)
5770                 kprintf("TODO: need swap\n");
5771
5772         BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5773         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5774         BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5775 }
5776
5777 static void
5778 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5779 {
5780         uint16_t value;
5781
5782         KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5783             ("%s:%d: fail", __func__, __LINE__));
5784
5785         value = (uint8_t) (ctl->q);
5786         value |= ((uint8_t) (ctl->i)) << 8;
5787         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5788 }
5789
5790 static uint16_t
5791 bwn_lo_calcfeed(struct bwn_mac *mac,
5792     uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5793 {
5794         struct bwn_phy *phy = &mac->mac_phy;
5795         struct bwn_softc *sc = mac->mac_sc;
5796         uint16_t rfover;
5797         uint16_t feedthrough;
5798
5799         if (phy->gmode) {
5800                 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5801                 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5802
5803                 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5804                     ("%s:%d: fail", __func__, __LINE__));
5805                 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5806                     ("%s:%d: fail", __func__, __LINE__));
5807
5808                 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5809
5810                 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5811                 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5812                     phy->rev > 6)
5813                         rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5814
5815                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5816                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5817                 DELAY(10);
5818                 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5819                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5820                 DELAY(10);
5821                 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5822                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5823                 DELAY(10);
5824                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5825         } else {
5826                 pga |= BWN_PHY_PGACTL_UNKNOWN;
5827                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5828                 DELAY(10);
5829                 pga |= BWN_PHY_PGACTL_LOWBANDW;
5830                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5831                 DELAY(10);
5832                 pga |= BWN_PHY_PGACTL_LPF;
5833                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5834         }
5835         DELAY(21);
5836         feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5837
5838         return (feedthrough);
5839 }
5840
5841 static uint16_t
5842 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5843     uint16_t *value, uint16_t *pad_mix_gain)
5844 {
5845         struct bwn_phy *phy = &mac->mac_phy;
5846         uint16_t reg, v, padmix;
5847
5848         if (phy->type == BWN_PHYTYPE_B) {
5849                 v = 0x30;
5850                 if (phy->rf_rev <= 5) {
5851                         reg = 0x43;
5852                         padmix = 0;
5853                 } else {
5854                         reg = 0x52;
5855                         padmix = 5;
5856                 }
5857         } else {
5858                 if (phy->rev >= 2 && phy->rf_rev == 8) {
5859                         reg = 0x43;
5860                         v = 0x10;
5861                         padmix = 2;
5862                 } else {
5863                         reg = 0x52;
5864                         v = 0x30;
5865                         padmix = 5;
5866                 }
5867         }
5868         if (value)
5869                 *value = v;
5870         if (pad_mix_gain)
5871                 *pad_mix_gain = padmix;
5872
5873         return (reg);
5874 }
5875
5876 static void
5877 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5878 {
5879         struct bwn_phy *phy = &mac->mac_phy;
5880         struct bwn_phy_g *pg = &phy->phy_g;
5881         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5882         uint16_t reg, mask;
5883         uint16_t trsw_rx, pga;
5884         uint16_t rf_pctl_reg;
5885
5886         static const uint8_t tx_bias_values[] = {
5887                 0x09, 0x08, 0x0a, 0x01, 0x00,
5888                 0x02, 0x05, 0x04, 0x06,
5889         };
5890         static const uint8_t tx_magn_values[] = {
5891                 0x70, 0x40,
5892         };
5893
5894         if (!BWN_HAS_LOOPBACK(phy)) {
5895                 rf_pctl_reg = 6;
5896                 trsw_rx = 2;
5897                 pga = 0;
5898         } else {
5899                 int lb_gain;
5900
5901                 trsw_rx = 0;
5902                 lb_gain = pg->pg_max_lb_gain / 2;
5903                 if (lb_gain > 10) {
5904                         rf_pctl_reg = 0;
5905                         pga = abs(10 - lb_gain) / 6;
5906                         pga = MIN(MAX(pga, 0), 15);
5907                 } else {
5908                         int cmp_val;
5909                         int tmp;
5910
5911                         pga = 0;
5912                         cmp_val = 0x24;
5913                         if ((phy->rev >= 2) &&
5914                             (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
5915                                 cmp_val = 0x3c;
5916                         tmp = lb_gain;
5917                         if ((10 - lb_gain) < cmp_val)
5918                                 tmp = (10 - lb_gain);
5919                         if (tmp < 0)
5920                                 tmp += 6;
5921                         else
5922                                 tmp += 3;
5923                         cmp_val /= 4;
5924                         tmp /= 4;
5925                         if (tmp >= cmp_val)
5926                                 rf_pctl_reg = cmp_val;
5927                         else
5928                                 rf_pctl_reg = tmp;
5929                 }
5930         }
5931         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
5932         bwn_phy_g_set_bbatt(mac, 2);
5933
5934         reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
5935         mask = ~mask;
5936         BWN_RF_MASK(mac, reg, mask);
5937
5938         if (BWN_HAS_TXMAG(phy)) {
5939                 int i, j;
5940                 int feedthrough;
5941                 int min_feedth = 0xffff;
5942                 uint8_t tx_magn, tx_bias;
5943
5944                 for (i = 0; i < N(tx_magn_values); i++) {
5945                         tx_magn = tx_magn_values[i];
5946                         BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
5947                         for (j = 0; j < N(tx_bias_values); j++) {
5948                                 tx_bias = tx_bias_values[j];
5949                                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
5950                                 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
5951                                     trsw_rx);
5952                                 if (feedthrough < min_feedth) {
5953                                         lo->tx_bias = tx_bias;
5954                                         lo->tx_magn = tx_magn;
5955                                         min_feedth = feedthrough;
5956                                 }
5957                                 if (lo->tx_bias == 0)
5958                                         break;
5959                         }
5960                         BWN_RF_WRITE(mac, 0x52,
5961                                           (BWN_RF_READ(mac, 0x52)
5962                                            & 0xff00) | lo->tx_bias | lo->
5963                                           tx_magn);
5964                 }
5965         } else {
5966                 lo->tx_magn = 0;
5967                 lo->tx_bias = 0;
5968                 BWN_RF_MASK(mac, 0x52, 0xfff0);
5969         }
5970
5971         BWN_GETTIME(lo->txctl_measured_time);
5972 }
5973
5974 static void
5975 bwn_lo_get_powervector(struct bwn_mac *mac)
5976 {
5977         struct bwn_phy *phy = &mac->mac_phy;
5978         struct bwn_phy_g *pg = &phy->phy_g;
5979         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5980         int i;
5981         uint64_t tmp;
5982         uint64_t power_vector = 0;
5983
5984         for (i = 0; i < 8; i += 2) {
5985                 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
5986                 power_vector |= (tmp << (i * 8));
5987                 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
5988         }
5989         if (power_vector)
5990                 lo->power_vector = power_vector;
5991
5992         BWN_GETTIME(lo->pwr_vec_read_time);
5993 }
5994
5995 static void
5996 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
5997     int use_trsw_rx)
5998 {
5999         struct bwn_phy *phy = &mac->mac_phy;
6000         struct bwn_phy_g *pg = &phy->phy_g;
6001         uint16_t tmp;
6002
6003         if (max_rx_gain < 0)
6004                 max_rx_gain = 0;
6005
6006         if (BWN_HAS_LOOPBACK(phy)) {
6007                 int trsw_rx = 0;
6008                 int trsw_rx_gain;
6009
6010                 if (use_trsw_rx) {
6011                         trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6012                         if (max_rx_gain >= trsw_rx_gain) {
6013                                 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6014                                 trsw_rx = 0x20;
6015                         }
6016                 } else
6017                         trsw_rx_gain = max_rx_gain;
6018                 if (trsw_rx_gain < 9) {
6019                         pg->pg_lna_lod_gain = 0;
6020                 } else {
6021                         pg->pg_lna_lod_gain = 1;
6022                         trsw_rx_gain -= 8;
6023                 }
6024                 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6025                 pg->pg_pga_gain = trsw_rx_gain / 3;
6026                 if (pg->pg_pga_gain >= 5) {
6027                         pg->pg_pga_gain -= 5;
6028                         pg->pg_lna_gain = 2;
6029                 } else
6030                         pg->pg_lna_gain = 0;
6031         } else {
6032                 pg->pg_lna_gain = 0;
6033                 pg->pg_trsw_rx_gain = 0x20;
6034                 if (max_rx_gain >= 0x14) {
6035                         pg->pg_lna_lod_gain = 1;
6036                         pg->pg_pga_gain = 2;
6037                 } else if (max_rx_gain >= 0x12) {
6038                         pg->pg_lna_lod_gain = 1;
6039                         pg->pg_pga_gain = 1;
6040                 } else if (max_rx_gain >= 0xf) {
6041                         pg->pg_lna_lod_gain = 1;
6042                         pg->pg_pga_gain = 0;
6043                 } else {
6044                         pg->pg_lna_lod_gain = 0;
6045                         pg->pg_pga_gain = 0;
6046                 }
6047         }
6048
6049         tmp = BWN_RF_READ(mac, 0x7a);
6050         if (pg->pg_lna_lod_gain == 0)
6051                 tmp &= ~0x0008;
6052         else
6053                 tmp |= 0x0008;
6054         BWN_RF_WRITE(mac, 0x7a, tmp);
6055 }
6056
6057 static void
6058 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6059 {
6060         struct bwn_phy *phy = &mac->mac_phy;
6061         struct bwn_phy_g *pg = &phy->phy_g;
6062         struct bwn_softc *sc = mac->mac_sc;
6063         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6064         struct timespec ts;
6065         uint16_t tmp;
6066
6067         if (bwn_has_hwpctl(mac)) {
6068                 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6069                 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6070                 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6071                 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6072                 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6073
6074                 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6075                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6076                 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6077                 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6078         }
6079         if (phy->type == BWN_PHYTYPE_B &&
6080             phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6081                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6082                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6083         }
6084         if (phy->rev >= 2) {
6085                 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6086                 sav->phy_analogoverval =
6087                     BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6088                 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6089                 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6090                 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6091                 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6092                 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6093
6094                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6095                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6096                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6097                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6098                 if (phy->type == BWN_PHYTYPE_G) {
6099                         if ((phy->rev >= 7) &&
6100                             (siba_sprom_get_bf_lo(sc->sc_dev) &
6101                              BWN_BFL_EXTLNA)) {
6102                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6103                         } else {
6104                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6105                         }
6106                 } else {
6107                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6108                 }
6109                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6110         }
6111         sav->reg0 = BWN_READ_2(mac, 0x3f4);
6112         sav->reg1 = BWN_READ_2(mac, 0x3e2);
6113         sav->rf0 = BWN_RF_READ(mac, 0x43);
6114         sav->rf1 = BWN_RF_READ(mac, 0x7a);
6115         sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6116         sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6117         sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6118         sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6119
6120         if (!BWN_HAS_TXMAG(phy)) {
6121                 sav->rf2 = BWN_RF_READ(mac, 0x52);
6122                 sav->rf2 &= 0x00f0;
6123         }
6124         if (phy->type == BWN_PHYTYPE_B) {
6125                 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6126                 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6127                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6128                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6129         } else {
6130                 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6131                             | 0x8000);
6132         }
6133         BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6134                     & 0xf000);
6135
6136         tmp =
6137             (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6138         BWN_PHY_WRITE(mac, tmp, 0x007f);
6139
6140         tmp = sav->phy_syncctl;
6141         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6142         tmp = sav->rf1;
6143         BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6144
6145         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6146         if (phy->type == BWN_PHYTYPE_G ||
6147             (phy->type == BWN_PHYTYPE_B &&
6148              phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6149                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6150         } else
6151                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6152         if (phy->rev >= 2)
6153                 bwn_dummy_transmission(mac, 0, 1);
6154         bwn_phy_g_switch_chan(mac, 6, 0);
6155         BWN_RF_READ(mac, 0x51);
6156         if (phy->type == BWN_PHYTYPE_G)
6157                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6158
6159         nanouptime(&ts);
6160         if (time_before(lo->txctl_measured_time,
6161             (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6162                 bwn_lo_measure_txctl_values(mac);
6163
6164         if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6165                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6166         else {
6167                 if (phy->type == BWN_PHYTYPE_B)
6168                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6169                 else
6170                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6171         }
6172 }
6173
6174 static void
6175 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6176 {
6177         struct bwn_phy *phy = &mac->mac_phy;
6178         struct bwn_phy_g *pg = &phy->phy_g;
6179         uint16_t tmp;
6180
6181         if (phy->rev >= 2) {
6182                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6183                 tmp = (pg->pg_pga_gain << 8);
6184                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6185                 DELAY(5);
6186                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6187                 DELAY(2);
6188                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6189         } else {
6190                 tmp = (pg->pg_pga_gain | 0xefa0);
6191                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6192         }
6193         if (phy->type == BWN_PHYTYPE_G) {
6194                 if (phy->rev >= 3)
6195                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6196                 else
6197                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6198                 if (phy->rev >= 2)
6199                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6200                 else
6201                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6202         }
6203         BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6204         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6205         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6206         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6207         BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6208         BWN_RF_WRITE(mac, 0x43, sav->rf0);
6209         BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6210         if (!BWN_HAS_TXMAG(phy)) {
6211                 tmp = sav->rf2;
6212                 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6213         }
6214         BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6215         if (phy->type == BWN_PHYTYPE_B &&
6216             phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6217                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6218                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6219         }
6220         if (phy->rev >= 2) {
6221                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6222                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6223                               sav->phy_analogoverval);
6224                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6225                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6226                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6227                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6228                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6229         }
6230         if (bwn_has_hwpctl(mac)) {
6231                 tmp = (sav->phy_lomask & 0xbfff);
6232                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6233                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6234                 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6235                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6236                 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6237         }
6238         bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6239 }
6240
6241 static int
6242 bwn_lo_probe_loctl(struct bwn_mac *mac,
6243     struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6244 {
6245         struct bwn_phy *phy = &mac->mac_phy;
6246         struct bwn_phy_g *pg = &phy->phy_g;
6247         struct bwn_loctl orig, test;
6248         struct bwn_loctl prev = { -100, -100 };
6249         static const struct bwn_loctl modifiers[] = {
6250                 {  1,  1,}, {  1,  0,}, {  1, -1,}, {  0, -1,},
6251                 { -1, -1,}, { -1,  0,}, { -1,  1,}, {  0,  1,}
6252         };
6253         int begin, end, lower = 0, i;
6254         uint16_t feedth;
6255
6256         if (d->curstate == 0) {
6257                 begin = 1;
6258                 end = 8;
6259         } else if (d->curstate % 2 == 0) {
6260                 begin = d->curstate - 1;
6261                 end = d->curstate + 1;
6262         } else {
6263                 begin = d->curstate - 2;
6264                 end = d->curstate + 2;
6265         }
6266         if (begin < 1)
6267                 begin += 8;
6268         if (end > 8)
6269                 end -= 8;
6270
6271         memcpy(&orig, probe, sizeof(struct bwn_loctl));
6272         i = begin;
6273         d->curstate = i;
6274         while (1) {
6275                 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6276                 memcpy(&test, &orig, sizeof(struct bwn_loctl));
6277                 test.i += modifiers[i - 1].i * d->multipler;
6278                 test.q += modifiers[i - 1].q * d->multipler;
6279                 if ((test.i != prev.i || test.q != prev.q) &&
6280                     (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6281                         bwn_lo_write(mac, &test);
6282                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6283                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6284                         if (feedth < d->feedth) {
6285                                 memcpy(probe, &test,
6286                                     sizeof(struct bwn_loctl));
6287                                 lower = 1;
6288                                 d->feedth = feedth;
6289                                 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6290                                         break;
6291                         }
6292                 }
6293                 memcpy(&prev, &test, sizeof(prev));
6294                 if (i == end)
6295                         break;
6296                 if (i == 8)
6297                         i = 1;
6298                 else
6299                         i++;
6300                 d->curstate = i;
6301         }
6302
6303         return (lower);
6304 }
6305
6306 static void
6307 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6308 {
6309         struct bwn_phy *phy = &mac->mac_phy;
6310         struct bwn_phy_g *pg = &phy->phy_g;
6311         struct bwn_lo_g_sm d;
6312         struct bwn_loctl probe;
6313         int lower, repeat, cnt = 0;
6314         uint16_t feedth;
6315
6316         d.nmeasure = 0;
6317         d.multipler = 1;
6318         if (BWN_HAS_LOOPBACK(phy))
6319                 d.multipler = 3;
6320
6321         memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6322         repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6323
6324         do {
6325                 bwn_lo_write(mac, &d.loctl);
6326                 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6327                     pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6328                 if (feedth < 0x258) {
6329                         if (feedth >= 0x12c)
6330                                 *rxgain += 6;
6331                         else
6332                                 *rxgain += 3;
6333                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6334                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6335                 }
6336                 d.feedth = feedth;
6337                 d.curstate = 0;
6338                 do {
6339                         KASSERT(d.curstate >= 0 && d.curstate <= 8,
6340                             ("%s:%d: fail", __func__, __LINE__));
6341                         memcpy(&probe, &d.loctl,
6342                                sizeof(struct bwn_loctl));
6343                         lower = bwn_lo_probe_loctl(mac, &probe, &d);
6344                         if (!lower)
6345                                 break;
6346                         if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6347                                 break;
6348                         memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6349                         d.nmeasure++;
6350                 } while (d.nmeasure < 24);
6351                 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6352
6353                 if (BWN_HAS_LOOPBACK(phy)) {
6354                         if (d.feedth > 0x1194)
6355                                 *rxgain -= 6;
6356                         else if (d.feedth < 0x5dc)
6357                                 *rxgain += 3;
6358                         if (cnt == 0) {
6359                                 if (d.feedth <= 0x5dc) {
6360                                         d.multipler = 1;
6361                                         cnt++;
6362                                 } else
6363                                         d.multipler = 2;
6364                         } else if (cnt == 2)
6365                                 d.multipler = 1;
6366                 }
6367                 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6368         } while (++cnt < repeat);
6369 }
6370
6371 static struct bwn_lo_calib *
6372 bwn_lo_calibset(struct bwn_mac *mac,
6373     const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6374 {
6375         struct bwn_phy *phy = &mac->mac_phy;
6376         struct bwn_phy_g *pg = &phy->phy_g;
6377         struct bwn_loctl loctl = { 0, 0 };
6378         struct bwn_lo_calib *cal;
6379         struct bwn_lo_g_value sval = { 0 };
6380         int rxgain;
6381         uint16_t pad, reg, value;
6382
6383         sval.old_channel = phy->chan;
6384         bwn_mac_suspend(mac);
6385         bwn_lo_save(mac, &sval);
6386
6387         reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6388         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6389         BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6390
6391         rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6392         if (rfatt->padmix)
6393                 rxgain -= pad;
6394         if (BWN_HAS_LOOPBACK(phy))
6395                 rxgain += pg->pg_max_lb_gain;
6396         bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6397         bwn_phy_g_set_bbatt(mac, bbatt->att);
6398         bwn_lo_probe_sm(mac, &loctl, &rxgain);
6399
6400         bwn_lo_restore(mac, &sval);
6401         bwn_mac_enable(mac);
6402
6403         cal = kmalloc(sizeof(*cal), M_DEVBUF, M_INTWAIT | M_ZERO);
6404         memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6405         memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6406         memcpy(&cal->ctl, &loctl, sizeof(loctl));
6407
6408         BWN_GETTIME(cal->calib_time);
6409
6410         return (cal);
6411 }
6412
6413 static struct bwn_lo_calib *
6414 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6415     const struct bwn_rfatt *rfatt)
6416 {
6417         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6418         struct bwn_lo_calib *c;
6419
6420         TAILQ_FOREACH(c, &lo->calib_list, list) {
6421                 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6422                         continue;
6423                 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6424                         continue;
6425                 return (c);
6426         }
6427
6428         c = bwn_lo_calibset(mac, bbatt, rfatt);
6429         if (c == NULL)  /* XXX ivadasz: can't happen */
6430                 return (NULL);
6431         TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6432
6433         return (c);
6434 }
6435
6436 static void
6437 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6438 {
6439         struct bwn_phy *phy = &mac->mac_phy;
6440         struct bwn_phy_g *pg = &phy->phy_g;
6441         struct bwn_softc *sc = mac->mac_sc;
6442         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6443         const struct bwn_rfatt *rfatt;
6444         const struct bwn_bbatt *bbatt;
6445         uint64_t pvector;
6446         int i;
6447         int rf_offset, bb_offset;
6448         uint8_t changed = 0;
6449
6450         KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6451         KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6452             ("%s:%d: fail", __func__, __LINE__));
6453
6454         pvector = lo->power_vector;
6455         if (!update && !pvector)
6456                 return;
6457
6458         bwn_mac_suspend(mac);
6459
6460         for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6461                 struct bwn_lo_calib *cal;
6462                 int idx;
6463                 uint16_t val;
6464
6465                 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6466                         continue;
6467                 bb_offset = i / lo->rfatt.len;
6468                 rf_offset = i % lo->rfatt.len;
6469                 bbatt = &(lo->bbatt.array[bb_offset]);
6470                 rfatt = &(lo->rfatt.array[rf_offset]);
6471
6472                 cal = bwn_lo_calibset(mac, bbatt, rfatt);
6473                 if (cal == NULL) {      /* XXX ivadasz: can't happen */
6474                         device_printf(sc->sc_dev, "LO: Could not "
6475                             "calibrate DC table entry\n");
6476                         continue;
6477                 }
6478                 val = (uint8_t)(cal->ctl.q);
6479                 val |= ((uint8_t)(cal->ctl.i)) << 4;
6480                 kfree(cal, M_DEVBUF);
6481
6482                 idx = i / 2;
6483                 if (i % 2)
6484                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6485                             | ((val & 0x00ff) << 8);
6486                 else
6487                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6488                             | (val & 0x00ff);
6489                 changed = 1;
6490         }
6491         if (changed) {
6492                 for (i = 0; i < BWN_DC_LT_SIZE; i++)
6493                         BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6494         }
6495         bwn_mac_enable(mac);
6496 }
6497
6498 static void
6499 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6500 {
6501
6502         if (!rf->padmix)
6503                 return;
6504         if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6505                 rf->att = 4;
6506 }
6507
6508 static void
6509 bwn_lo_g_adjust(struct bwn_mac *mac)
6510 {
6511         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6512         struct bwn_lo_calib *cal;
6513         struct bwn_rfatt rf;
6514
6515         memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6516         bwn_lo_fixup_rfatt(&rf);
6517
6518         cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6519         if (cal == NULL)        /* XXX ivadasz: can't happen */
6520                 return;
6521         bwn_lo_write(mac, &cal->ctl);
6522 }
6523
6524 static void
6525 bwn_lo_g_init(struct bwn_mac *mac)
6526 {
6527
6528         if (!bwn_has_hwpctl(mac))
6529                 return;
6530
6531         bwn_lo_get_powervector(mac);
6532         bwn_phy_g_dc_lookup_init(mac, 1);
6533 }
6534
6535 static void
6536 bwn_mac_suspend(struct bwn_mac *mac)
6537 {
6538         struct bwn_softc *sc = mac->mac_sc;
6539         int i;
6540         uint32_t tmp;
6541
6542         KASSERT(mac->mac_suspended >= 0,
6543             ("%s:%d: fail", __func__, __LINE__));
6544
6545         if (mac->mac_suspended == 0) {
6546                 bwn_psctl(mac, BWN_PS_AWAKE);
6547                 BWN_WRITE_4(mac, BWN_MACCTL,
6548                             BWN_READ_4(mac, BWN_MACCTL)
6549                             & ~BWN_MACCTL_ON);
6550                 BWN_READ_4(mac, BWN_MACCTL);
6551                 for (i = 35; i; i--) {
6552                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6553                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6554                                 goto out;
6555                         DELAY(10);
6556                 }
6557                 for (i = 40; i; i--) {
6558                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6559                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6560                                 goto out;
6561                         DELAY(1000);
6562                 }
6563                 device_printf(sc->sc_dev, "MAC suspend failed\n");
6564         }
6565 out:
6566         mac->mac_suspended++;
6567 }
6568
6569 static void
6570 bwn_mac_enable(struct bwn_mac *mac)
6571 {
6572         struct bwn_softc *sc = mac->mac_sc;
6573         uint16_t state;
6574
6575         state = bwn_shm_read_2(mac, BWN_SHARED,
6576             BWN_SHARED_UCODESTAT);
6577         if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6578             state != BWN_SHARED_UCODESTAT_SLEEP)
6579                 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6580
6581         mac->mac_suspended--;
6582         KASSERT(mac->mac_suspended >= 0,
6583             ("%s:%d: fail", __func__, __LINE__));
6584         if (mac->mac_suspended == 0) {
6585                 BWN_WRITE_4(mac, BWN_MACCTL,
6586                     BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6587                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6588                 BWN_READ_4(mac, BWN_MACCTL);
6589                 BWN_READ_4(mac, BWN_INTR_REASON);
6590                 bwn_psctl(mac, 0);
6591         }
6592 }
6593
6594 static void
6595 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6596 {
6597         struct bwn_softc *sc = mac->mac_sc;
6598         int i;
6599         uint16_t ucstat;
6600
6601         KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6602             ("%s:%d: fail", __func__, __LINE__));
6603         KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6604             ("%s:%d: fail", __func__, __LINE__));
6605
6606         /* XXX forcibly awake and hwps-off */
6607
6608         BWN_WRITE_4(mac, BWN_MACCTL,
6609             (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6610             ~BWN_MACCTL_HWPS);
6611         BWN_READ_4(mac, BWN_MACCTL);
6612         if (siba_get_revid(sc->sc_dev) >= 5) {
6613                 for (i = 0; i < 100; i++) {
6614                         ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6615                             BWN_SHARED_UCODESTAT);
6616                         if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6617                                 break;
6618                         DELAY(10);
6619                 }
6620         }
6621 }
6622
6623 static int16_t
6624 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6625 {
6626
6627         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6628         return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6629 }
6630
6631 static void
6632 bwn_nrssi_threshold(struct bwn_mac *mac)
6633 {
6634         struct bwn_phy *phy = &mac->mac_phy;
6635         struct bwn_phy_g *pg = &phy->phy_g;
6636         struct bwn_softc *sc = mac->mac_sc;
6637         int32_t a, b;
6638         int16_t tmp16;
6639         uint16_t tmpu16;
6640
6641         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6642
6643         if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6644                 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6645                         a = 0x13;
6646                         b = 0x12;
6647                 } else {
6648                         a = 0xe;
6649                         b = 0x11;
6650                 }
6651
6652                 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6653                 a += (pg->pg_nrssi[0] << 6);
6654                 a += (a < 32) ? 31 : 32;
6655                 a = a >> 6;
6656                 a = MIN(MAX(a, -31), 31);
6657
6658                 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6659                 b += (pg->pg_nrssi[0] << 6);
6660                 if (b < 32)
6661                         b += 31;
6662                 else
6663                         b += 32;
6664                 b = b >> 6;
6665                 b = MIN(MAX(b, -31), 31);
6666
6667                 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6668                 tmpu16 |= ((uint32_t)b & 0x0000003f);
6669                 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6670                 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6671                 return;
6672         }
6673
6674         tmp16 = bwn_nrssi_read(mac, 0x20);
6675         if (tmp16 >= 0x20)
6676                 tmp16 -= 0x40;
6677         BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6678 }
6679
6680 static void
6681 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6682 {
6683 #define SAVE_RF_MAX             3
6684 #define SAVE_PHY_COMM_MAX       4
6685 #define SAVE_PHY3_MAX           8
6686         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6687                 { 0x7a, 0x52, 0x43 };
6688         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6689                 { 0x15, 0x5a, 0x59, 0x58 };
6690         static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6691                 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6692                 0x0801, 0x0060, 0x0014, 0x0478
6693         };
6694         struct bwn_phy *phy = &mac->mac_phy;
6695         struct bwn_phy_g *pg = &phy->phy_g;
6696         int32_t i, tmp32, phy3_idx = 0;
6697         uint16_t delta, tmp;
6698         uint16_t save_rf[SAVE_RF_MAX];
6699         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6700         uint16_t save_phy3[SAVE_PHY3_MAX];
6701         uint16_t ant_div, phy0, chan_ex;
6702         int16_t nrssi0, nrssi1;
6703
6704         KASSERT(phy->type == BWN_PHYTYPE_G,
6705             ("%s:%d: fail", __func__, __LINE__));
6706
6707         if (phy->rf_rev >= 9)
6708                 return;
6709         if (phy->rf_rev == 8)
6710                 bwn_nrssi_offset(mac);
6711
6712         BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6713         BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6714
6715         /*
6716          * Save RF/PHY registers for later restoration
6717          */
6718         ant_div = BWN_READ_2(mac, 0x03e2);
6719         BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6720         for (i = 0; i < SAVE_RF_MAX; ++i)
6721                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6722         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6723                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6724
6725         phy0 = BWN_READ_2(mac, BWN_PHY0);
6726         chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6727         if (phy->rev >= 3) {
6728                 for (i = 0; i < SAVE_PHY3_MAX; ++i)
6729                         save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6730                 BWN_PHY_WRITE(mac, 0x002e, 0);
6731                 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6732                 switch (phy->rev) {
6733                 case 4:
6734                 case 6:
6735                 case 7:
6736                         BWN_PHY_SET(mac, 0x0478, 0x0100);
6737                         BWN_PHY_SET(mac, 0x0801, 0x0040);
6738                         break;
6739                 case 3:
6740                 case 5:
6741                         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6742                         break;
6743                 }
6744                 BWN_PHY_SET(mac, 0x0060, 0x0040);
6745                 BWN_PHY_SET(mac, 0x0014, 0x0200);
6746         }
6747         /*
6748          * Calculate nrssi0
6749          */
6750         BWN_RF_SET(mac, 0x007a, 0x0070);
6751         bwn_set_all_gains(mac, 0, 8, 0);
6752         BWN_RF_MASK(mac, 0x007a, 0x00f7);
6753         if (phy->rev >= 2) {
6754                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6755                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6756         }
6757         BWN_RF_SET(mac, 0x007a, 0x0080);
6758         DELAY(20);
6759
6760         nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6761         if (nrssi0 >= 0x0020)
6762                 nrssi0 -= 0x0040;
6763
6764         /*
6765          * Calculate nrssi1
6766          */
6767         BWN_RF_MASK(mac, 0x007a, 0x007f);
6768         if (phy->rev >= 2)
6769                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6770
6771         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6772             BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6773         BWN_RF_SET(mac, 0x007a, 0x000f);
6774         BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6775         if (phy->rev >= 2) {
6776                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6777                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6778         }
6779
6780         bwn_set_all_gains(mac, 3, 0, 1);
6781         if (phy->rf_rev == 8) {
6782                 BWN_RF_WRITE(mac, 0x0043, 0x001f);
6783         } else {
6784                 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6785                 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6786                 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6787                 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6788         }
6789         BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6790         BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6791         BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6792         DELAY(20);
6793         nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6794
6795         /*
6796          * Install calculated narrow RSSI values
6797          */
6798         if (nrssi1 >= 0x0020)
6799                 nrssi1 -= 0x0040;
6800         if (nrssi0 == nrssi1)
6801                 pg->pg_nrssi_slope = 0x00010000;
6802         else
6803                 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6804         if (nrssi0 >= -4) {
6805                 pg->pg_nrssi[0] = nrssi1;
6806                 pg->pg_nrssi[1] = nrssi0;
6807         }
6808
6809         /*
6810          * Restore saved RF/PHY registers
6811          */
6812         if (phy->rev >= 3) {
6813                 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6814                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6815                             save_phy3[phy3_idx]);
6816                 }
6817         }
6818         if (phy->rev >= 2) {
6819                 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6820                 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6821         }
6822
6823         for (i = 0; i < SAVE_RF_MAX; ++i)
6824                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6825
6826         BWN_WRITE_2(mac, 0x03e2, ant_div);
6827         BWN_WRITE_2(mac, 0x03e6, phy0);
6828         BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6829
6830         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6831                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6832
6833         bwn_spu_workaround(mac, phy->chan);
6834         BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6835         bwn_set_original_gains(mac);
6836         BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6837         if (phy->rev >= 3) {
6838                 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6839                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6840                             save_phy3[phy3_idx]);
6841                 }
6842         }
6843
6844         delta = 0x1f - pg->pg_nrssi[0];
6845         for (i = 0; i < 64; i++) {
6846                 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6847                 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6848                 pg->pg_nrssi_lt[i] = tmp32;
6849         }
6850
6851         bwn_nrssi_threshold(mac);
6852 #undef SAVE_RF_MAX
6853 #undef SAVE_PHY_COMM_MAX
6854 #undef SAVE_PHY3_MAX
6855 }
6856
6857 static void
6858 bwn_nrssi_offset(struct bwn_mac *mac)
6859 {
6860 #define SAVE_RF_MAX             2
6861 #define SAVE_PHY_COMM_MAX       10
6862 #define SAVE_PHY6_MAX           8
6863         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6864                 { 0x7a, 0x43 };
6865         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6866                 0x0001, 0x0811, 0x0812, 0x0814,
6867                 0x0815, 0x005a, 0x0059, 0x0058,
6868                 0x000a, 0x0003
6869         };
6870         static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6871                 0x002e, 0x002f, 0x080f, 0x0810,
6872                 0x0801, 0x0060, 0x0014, 0x0478
6873         };
6874         struct bwn_phy *phy = &mac->mac_phy;
6875         int i, phy6_idx = 0;
6876         uint16_t save_rf[SAVE_RF_MAX];
6877         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6878         uint16_t save_phy6[SAVE_PHY6_MAX];
6879         int16_t nrssi;
6880         uint16_t saved = 0xffff;
6881
6882         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6883                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6884         for (i = 0; i < SAVE_RF_MAX; ++i)
6885                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6886
6887         BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6888         BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6889         BWN_PHY_SET(mac, 0x0811, 0x000c);
6890         BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6891         BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6892         if (phy->rev >= 6) {
6893                 for (i = 0; i < SAVE_PHY6_MAX; ++i)
6894                         save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6895
6896                 BWN_PHY_WRITE(mac, 0x002e, 0);
6897                 BWN_PHY_WRITE(mac, 0x002f, 0);
6898                 BWN_PHY_WRITE(mac, 0x080f, 0);
6899                 BWN_PHY_WRITE(mac, 0x0810, 0);
6900                 BWN_PHY_SET(mac, 0x0478, 0x0100);
6901                 BWN_PHY_SET(mac, 0x0801, 0x0040);
6902                 BWN_PHY_SET(mac, 0x0060, 0x0040);
6903                 BWN_PHY_SET(mac, 0x0014, 0x0200);
6904         }
6905         BWN_RF_SET(mac, 0x007a, 0x0070);
6906         BWN_RF_SET(mac, 0x007a, 0x0080);
6907         DELAY(30);
6908
6909         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6910         if (nrssi >= 0x20)
6911                 nrssi -= 0x40;
6912         if (nrssi == 31) {
6913                 for (i = 7; i >= 4; i--) {
6914                         BWN_RF_WRITE(mac, 0x007b, i);
6915                         DELAY(20);
6916                         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
6917                             0x003f);
6918                         if (nrssi >= 0x20)
6919                                 nrssi -= 0x40;
6920                         if (nrssi < 31 && saved == 0xffff)
6921                                 saved = i;
6922                 }
6923                 if (saved == 0xffff)
6924                         saved = 4;
6925         } else {
6926                 BWN_RF_MASK(mac, 0x007a, 0x007f);
6927                 if (phy->rev != 1) {
6928                         BWN_PHY_SET(mac, 0x0814, 0x0001);
6929                         BWN_PHY_MASK(mac, 0x0815, 0xfffe);
6930                 }
6931                 BWN_PHY_SET(mac, 0x0811, 0x000c);
6932                 BWN_PHY_SET(mac, 0x0812, 0x000c);
6933                 BWN_PHY_SET(mac, 0x0811, 0x0030);
6934                 BWN_PHY_SET(mac, 0x0812, 0x0030);
6935                 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6936                 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6937                 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6938                 if (phy->rev == 0)
6939                         BWN_PHY_WRITE(mac, 0x0003, 0x0122);
6940                 else
6941                         BWN_PHY_SET(mac, 0x000a, 0x2000);
6942                 if (phy->rev != 1) {
6943                         BWN_PHY_SET(mac, 0x0814, 0x0004);
6944                         BWN_PHY_MASK(mac, 0x0815, 0xfffb);
6945                 }
6946                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6947                 BWN_RF_SET(mac, 0x007a, 0x000f);
6948                 bwn_set_all_gains(mac, 3, 0, 1);
6949                 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
6950                 DELAY(30);
6951                 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6952                 if (nrssi >= 0x20)
6953                         nrssi -= 0x40;
6954                 if (nrssi == -32) {
6955                         for (i = 0; i < 4; i++) {
6956                                 BWN_RF_WRITE(mac, 0x007b, i);
6957                                 DELAY(20);
6958                                 nrssi = (int16_t)((BWN_PHY_READ(mac,
6959                                     0x047f) >> 8) & 0x003f);
6960                                 if (nrssi >= 0x20)
6961                                         nrssi -= 0x40;
6962                                 if (nrssi > -31 && saved == 0xffff)
6963                                         saved = i;
6964                         }
6965                         if (saved == 0xffff)
6966                                 saved = 3;
6967                 } else
6968                         saved = 0;
6969         }
6970         BWN_RF_WRITE(mac, 0x007b, saved);
6971
6972         /*
6973          * Restore saved RF/PHY registers
6974          */
6975         if (phy->rev >= 6) {
6976                 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
6977                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
6978                             save_phy6[phy6_idx]);
6979                 }
6980         }
6981         if (phy->rev != 1) {
6982                 for (i = 3; i < 5; i++)
6983                         BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
6984                             save_phy_comm[i]);
6985         }
6986         for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
6987                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6988
6989         for (i = SAVE_RF_MAX - 1; i >= 0; --i)
6990                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6991
6992         BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
6993         BWN_PHY_SET(mac, 0x0429, 0x8000);
6994         bwn_set_original_gains(mac);
6995         if (phy->rev >= 6) {
6996                 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
6997                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
6998                             save_phy6[phy6_idx]);
6999                 }
7000         }
7001
7002         BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7003         BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7004         BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7005 }
7006
7007 static void
7008 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7009     int16_t third)
7010 {
7011         struct bwn_phy *phy = &mac->mac_phy;
7012         uint16_t i;
7013         uint16_t start = 0x08, end = 0x18;
7014         uint16_t tmp;
7015         uint16_t table;
7016
7017         if (phy->rev <= 1) {
7018                 start = 0x10;
7019                 end = 0x20;
7020         }
7021
7022         table = BWN_OFDMTAB_GAINX;
7023         if (phy->rev <= 1)
7024                 table = BWN_OFDMTAB_GAINX_R1;
7025         for (i = 0; i < 4; i++)
7026                 bwn_ofdmtab_write_2(mac, table, i, first);
7027
7028         for (i = start; i < end; i++)
7029                 bwn_ofdmtab_write_2(mac, table, i, second);
7030
7031         if (third != -1) {
7032                 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7033                 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7034                 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7035                 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7036         }
7037         bwn_dummy_transmission(mac, 0, 1);
7038 }
7039
7040 static void
7041 bwn_set_original_gains(struct bwn_mac *mac)
7042 {
7043         struct bwn_phy *phy = &mac->mac_phy;
7044         uint16_t i, tmp;
7045         uint16_t table;
7046         uint16_t start = 0x0008, end = 0x0018;
7047
7048         if (phy->rev <= 1) {
7049                 start = 0x0010;
7050                 end = 0x0020;
7051         }
7052
7053         table = BWN_OFDMTAB_GAINX;
7054         if (phy->rev <= 1)
7055                 table = BWN_OFDMTAB_GAINX_R1;
7056         for (i = 0; i < 4; i++) {
7057                 tmp = (i & 0xfffc);
7058                 tmp |= (i & 0x0001) << 1;
7059                 tmp |= (i & 0x0002) >> 1;
7060
7061                 bwn_ofdmtab_write_2(mac, table, i, tmp);
7062         }
7063
7064         for (i = start; i < end; i++)
7065                 bwn_ofdmtab_write_2(mac, table, i, i - start);
7066
7067         BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7068         BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7069         BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7070         bwn_dummy_transmission(mac, 0, 1);
7071 }
7072
7073 static void
7074 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7075 {
7076         struct bwn_phy *phy = &mac->mac_phy;
7077         struct bwn_phy_g *pg = &phy->phy_g;
7078         struct bwn_rfatt old_rfatt, rfatt;
7079         struct bwn_bbatt old_bbatt, bbatt;
7080         struct bwn_softc *sc = mac->mac_sc;
7081         uint8_t old_txctl = 0;
7082
7083         KASSERT(phy->type == BWN_PHYTYPE_G,
7084             ("%s:%d: fail", __func__, __LINE__));
7085
7086         if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7087             (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7088                 return;
7089
7090         BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7091
7092         BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7093
7094         if (!phy->gmode)
7095                 return;
7096         bwn_hwpctl_early_init(mac);
7097         if (pg->pg_curtssi == 0) {
7098                 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7099                         BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7100                 } else {
7101                         memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7102                         memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7103                         old_txctl = pg->pg_txctl;
7104
7105                         bbatt.att = 11;
7106                         if (phy->rf_rev == 8) {
7107                                 rfatt.att = 15;
7108                                 rfatt.padmix = 1;
7109                         } else {
7110                                 rfatt.att = 9;
7111                                 rfatt.padmix = 0;
7112                         }
7113                         bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7114                 }
7115                 bwn_dummy_transmission(mac, 0, 1);
7116                 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7117                 if (phy->rf_ver == 0x2050 && phy->analog == 0)
7118                         BWN_RF_MASK(mac, 0x0076, 0xff7b);
7119                 else
7120                         bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7121                             &old_rfatt, old_txctl);
7122         }
7123         bwn_hwpctl_init_gphy(mac);
7124
7125         /* clear TSSI */
7126         bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7127         bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7128         bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7129         bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7130 }
7131
7132 static void
7133 bwn_hwpctl_early_init(struct bwn_mac *mac)
7134 {
7135         struct bwn_phy *phy = &mac->mac_phy;
7136
7137         if (!bwn_has_hwpctl(mac)) {
7138                 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7139                 return;
7140         }
7141
7142         BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7143         BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7144         BWN_PHY_SET(mac, 0x047c, 0x0002);
7145         BWN_PHY_SET(mac, 0x047a, 0xf000);
7146         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7147                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7148                 BWN_PHY_SET(mac, 0x005d, 0x8000);
7149                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7150                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7151                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7152         } else {
7153                 BWN_PHY_SET(mac, 0x0036, 0x0200);
7154                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7155                 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7156                 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7157                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7158                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7159                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7160         }
7161 }
7162
7163 static void
7164 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7165 {
7166         struct bwn_phy *phy = &mac->mac_phy;
7167         struct bwn_phy_g *pg = &phy->phy_g;
7168         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7169         int i;
7170         uint16_t nr_written = 0, tmp, value;
7171         uint8_t rf, bb;
7172
7173         if (!bwn_has_hwpctl(mac)) {
7174                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7175                 return;
7176         }
7177
7178         BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7179             (pg->pg_idletssi - pg->pg_curtssi));
7180         BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7181             (pg->pg_idletssi - pg->pg_curtssi));
7182
7183         for (i = 0; i < 32; i++)
7184                 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7185         for (i = 32; i < 64; i++)
7186                 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7187         for (i = 0; i < 64; i += 2) {
7188                 value = (uint16_t) pg->pg_tssi2dbm[i];
7189                 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7190                 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7191         }
7192
7193         for (rf = 0; rf < lo->rfatt.len; rf++) {
7194                 for (bb = 0; bb < lo->bbatt.len; bb++) {
7195                         if (nr_written >= 0x40)
7196                                 return;
7197                         tmp = lo->bbatt.array[bb].att;
7198                         tmp <<= 8;
7199                         if (phy->rf_rev == 8)
7200                                 tmp |= 0x50;
7201                         else
7202                                 tmp |= 0x40;
7203                         tmp |= lo->rfatt.array[rf].att;
7204                         BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7205                         nr_written++;
7206                 }
7207         }
7208
7209         BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7210         BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7211
7212         KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7213         BWN_PHY_SET(mac, 0x0478, 0x0800);
7214         BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7215         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7216
7217         bwn_phy_g_dc_lookup_init(mac, 1);
7218         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7219 }
7220
7221 static void
7222 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7223 {
7224         struct bwn_softc *sc = mac->mac_sc;
7225
7226         if (spu != 0)
7227                 bwn_spu_workaround(mac, channel);
7228
7229         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7230
7231         if (channel == 14) {
7232                 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7233                         bwn_hf_write(mac,
7234                             bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7235                 else
7236                         bwn_hf_write(mac,
7237                             bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7238                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7239                     BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7240                 return;
7241         }
7242
7243         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7244             BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7245 }
7246
7247 static uint16_t
7248 bwn_phy_g_chan2freq(uint8_t channel)
7249 {
7250         static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7251
7252         KASSERT(channel >= 1 && channel <= 14,
7253             ("%s:%d: fail", __func__, __LINE__));
7254
7255         return (bwn_phy_g_rf_channels[channel - 1]);
7256 }
7257
7258 static void
7259 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7260     const struct bwn_rfatt *rfatt, uint8_t txctl)
7261 {
7262         struct bwn_phy *phy = &mac->mac_phy;
7263         struct bwn_phy_g *pg = &phy->phy_g;
7264         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7265         uint16_t bb, rf;
7266         uint16_t tx_bias, tx_magn;
7267
7268         bb = bbatt->att;
7269         rf = rfatt->att;
7270         tx_bias = lo->tx_bias;
7271         tx_magn = lo->tx_magn;
7272         if (tx_bias == 0xff)
7273                 tx_bias = 0;
7274
7275         pg->pg_txctl = txctl;
7276         memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7277         pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7278         memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7279         bwn_phy_g_set_bbatt(mac, bb);
7280         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7281         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7282                 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7283         else {
7284                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7285                 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7286         }
7287         if (BWN_HAS_TXMAG(phy))
7288                 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7289         else
7290                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7291         bwn_lo_g_adjust(mac);
7292 }
7293
7294 static void
7295 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7296     uint16_t bbatt)
7297 {
7298         struct bwn_phy *phy = &mac->mac_phy;
7299
7300         if (phy->analog == 0) {
7301                 BWN_WRITE_2(mac, BWN_PHY0,
7302                     (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7303                 return;
7304         }
7305         if (phy->analog > 1) {
7306                 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7307                 return;
7308         }
7309         BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7310 }
7311
7312 static uint16_t
7313 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7314 {
7315         struct bwn_phy *phy = &mac->mac_phy;
7316         struct bwn_phy_g *pg = &phy->phy_g;
7317         struct bwn_softc *sc = mac->mac_sc;
7318         int max_lb_gain;
7319         uint16_t extlna;
7320         uint16_t i;
7321
7322         if (phy->gmode == 0)
7323                 return (0);
7324
7325         if (BWN_HAS_LOOPBACK(phy)) {
7326                 max_lb_gain = pg->pg_max_lb_gain;
7327                 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7328                 if (max_lb_gain >= 0x46) {
7329                         extlna = 0x3000;
7330                         max_lb_gain -= 0x46;
7331                 } else if (max_lb_gain >= 0x3a) {
7332                         extlna = 0x1000;
7333                         max_lb_gain -= 0x3a;
7334                 } else if (max_lb_gain >= 0x2e) {
7335                         extlna = 0x2000;
7336                         max_lb_gain -= 0x2e;
7337                 } else {
7338                         extlna = 0;
7339                         max_lb_gain -= 0x10;
7340                 }
7341
7342                 for (i = 0; i < 16; i++) {
7343                         max_lb_gain -= (i * 6);
7344                         if (max_lb_gain < 6)
7345                                 break;
7346                 }
7347
7348                 if ((phy->rev < 7) ||
7349                     !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7350                         if (reg == BWN_PHY_RFOVER) {
7351                                 return (0x1b3);
7352                         } else if (reg == BWN_PHY_RFOVERVAL) {
7353                                 extlna |= (i << 8);
7354                                 switch (lpd) {
7355                                 case BWN_LPD(0, 1, 1):
7356                                         return (0x0f92);
7357                                 case BWN_LPD(0, 0, 1):
7358                                 case BWN_LPD(1, 0, 1):
7359                                         return (0x0092 | extlna);
7360                                 case BWN_LPD(1, 0, 0):
7361                                         return (0x0093 | extlna);
7362                                 }
7363                                 KASSERT(0 == 1,
7364                                     ("%s:%d: fail", __func__, __LINE__));
7365                         }
7366                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7367                 } else {
7368                         if (reg == BWN_PHY_RFOVER)
7369                                 return (0x9b3);
7370                         if (reg == BWN_PHY_RFOVERVAL) {
7371                                 if (extlna)
7372                                         extlna |= 0x8000;
7373                                 extlna |= (i << 8);
7374                                 switch (lpd) {
7375                                 case BWN_LPD(0, 1, 1):
7376                                         return (0x8f92);
7377                                 case BWN_LPD(0, 0, 1):
7378                                         return (0x8092 | extlna);
7379                                 case BWN_LPD(1, 0, 1):
7380                                         return (0x2092 | extlna);
7381                                 case BWN_LPD(1, 0, 0):
7382                                         return (0x2093 | extlna);
7383                                 }
7384                                 KASSERT(0 == 1,
7385                                     ("%s:%d: fail", __func__, __LINE__));
7386                         }
7387                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7388                 }
7389                 return (0);
7390         }
7391
7392         if ((phy->rev < 7) ||
7393             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7394                 if (reg == BWN_PHY_RFOVER) {
7395                         return (0x1b3);
7396                 } else if (reg == BWN_PHY_RFOVERVAL) {
7397                         switch (lpd) {
7398                         case BWN_LPD(0, 1, 1):
7399                                 return (0x0fb2);
7400                         case BWN_LPD(0, 0, 1):
7401                                 return (0x00b2);
7402                         case BWN_LPD(1, 0, 1):
7403                                 return (0x30b2);
7404                         case BWN_LPD(1, 0, 0):
7405                                 return (0x30b3);
7406                         }
7407                         KASSERT(0 == 1,
7408                             ("%s:%d: fail", __func__, __LINE__));
7409                 }
7410                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7411         } else {
7412                 if (reg == BWN_PHY_RFOVER) {
7413                         return (0x9b3);
7414                 } else if (reg == BWN_PHY_RFOVERVAL) {
7415                         switch (lpd) {
7416                         case BWN_LPD(0, 1, 1):
7417                                 return (0x8fb2);
7418                         case BWN_LPD(0, 0, 1):
7419                                 return (0x80b2);
7420                         case BWN_LPD(1, 0, 1):
7421                                 return (0x20b2);
7422                         case BWN_LPD(1, 0, 0):
7423                                 return (0x20b3);
7424                         }
7425                         KASSERT(0 == 1,
7426                             ("%s:%d: fail", __func__, __LINE__));
7427                 }
7428                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7429         }
7430         return (0);
7431 }
7432
7433 static void
7434 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7435 {
7436
7437         if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7438                 return;
7439         BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7440             bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7441         DELAY(1000);
7442         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7443 }
7444
7445 static int
7446 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7447 {
7448         struct bwn_softc *sc = mac->mac_sc;
7449         struct bwn_fw *fw = &mac->mac_fw;
7450         const uint8_t rev = siba_get_revid(sc->sc_dev);
7451         const char *filename;
7452         uint32_t high;
7453         int error;
7454
7455         /* microcode */
7456         if (rev >= 5 && rev <= 10)
7457                 filename = "ucode5";
7458         else if (rev >= 11 && rev <= 12)
7459                 filename = "ucode11";
7460         else if (rev == 13)
7461                 filename = "ucode13";
7462         else if (rev == 14)
7463                 filename = "ucode14";
7464         else if (rev >= 15)
7465                 filename = "ucode15";
7466         else {
7467                 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7468                 bwn_release_firmware(mac);
7469                 return (EOPNOTSUPP);
7470         }
7471         error = bwn_fw_get(mac, type, filename, &fw->ucode);
7472         if (error) {
7473                 bwn_release_firmware(mac);
7474                 return (error);
7475         }
7476
7477         /* PCM */
7478         KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7479         if (rev >= 5 && rev <= 10) {
7480                 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7481                 if (error == ENOENT)
7482                         fw->no_pcmfile = 1;
7483                 else if (error) {
7484                         bwn_release_firmware(mac);
7485                         return (error);
7486                 }
7487         } else if (rev < 11) {
7488                 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7489                 return (EOPNOTSUPP);
7490         }
7491
7492         /* initvals */
7493         high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7494         switch (mac->mac_phy.type) {
7495         case BWN_PHYTYPE_A:
7496                 if (rev < 5 || rev > 10)
7497                         goto fail1;
7498                 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7499                         filename = "a0g1initvals5";
7500                 else
7501                         filename = "a0g0initvals5";
7502                 break;
7503         case BWN_PHYTYPE_G:
7504                 if (rev >= 5 && rev <= 10)
7505                         filename = "b0g0initvals5";
7506                 else if (rev >= 13)
7507                         filename = "b0g0initvals13";
7508                 else
7509                         goto fail1;
7510                 break;
7511         case BWN_PHYTYPE_LP:
7512                 if (rev == 13)
7513                         filename = "lp0initvals13";
7514                 else if (rev == 14)
7515                         filename = "lp0initvals14";
7516                 else if (rev >= 15)
7517                         filename = "lp0initvals15";
7518                 else
7519                         goto fail1;
7520                 break;
7521         case BWN_PHYTYPE_N:
7522                 if (rev >= 11 && rev <= 12)
7523                         filename = "n0initvals11";
7524                 else
7525                         goto fail1;
7526                 break;
7527         default:
7528                 goto fail1;
7529         }
7530         error = bwn_fw_get(mac, type, filename, &fw->initvals);
7531         if (error) {
7532                 bwn_release_firmware(mac);
7533                 return (error);
7534         }
7535
7536         /* bandswitch initvals */
7537         switch (mac->mac_phy.type) {
7538         case BWN_PHYTYPE_A:
7539                 if (rev >= 5 && rev <= 10) {
7540                         if (high & BWN_TGSHIGH_HAVE_2GHZ)
7541                                 filename = "a0g1bsinitvals5";
7542                         else
7543                                 filename = "a0g0bsinitvals5";
7544                 } else if (rev >= 11)
7545                         filename = NULL;
7546                 else
7547                         goto fail1;
7548                 break;
7549         case BWN_PHYTYPE_G:
7550                 if (rev >= 5 && rev <= 10)
7551                         filename = "b0g0bsinitvals5";
7552                 else if (rev >= 11)
7553                         filename = NULL;
7554                 else
7555                         goto fail1;
7556                 break;
7557         case BWN_PHYTYPE_LP:
7558                 if (rev == 13)
7559                         filename = "lp0bsinitvals13";
7560                 else if (rev == 14)
7561                         filename = "lp0bsinitvals14";
7562                 else if (rev >= 15)
7563                         filename = "lp0bsinitvals15";
7564                 else
7565                         goto fail1;
7566                 break;
7567         case BWN_PHYTYPE_N:
7568                 if (rev >= 11 && rev <= 12)
7569                         filename = "n0bsinitvals11";
7570                 else
7571                         goto fail1;
7572                 break;
7573         default:
7574                 goto fail1;
7575         }
7576         error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7577         if (error) {
7578                 bwn_release_firmware(mac);
7579                 return (error);
7580         }
7581         return (0);
7582 fail1:
7583         device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7584         bwn_release_firmware(mac);
7585         return (EOPNOTSUPP);
7586 }
7587
7588 static int
7589 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7590     const char *name, struct bwn_fwfile *bfw)
7591 {
7592         const struct bwn_fwhdr *hdr;
7593         struct bwn_softc *sc = mac->mac_sc;
7594         const struct firmware *fw;
7595         char namebuf[64];
7596
7597         if (name == NULL) {
7598                 bwn_do_release_fw(bfw);
7599                 return (0);
7600         }
7601         if (bfw->filename != NULL) {
7602                 if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7603                         return (0);
7604                 bwn_do_release_fw(bfw);
7605         }
7606
7607         ksnprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7608             (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7609             (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7610         wlan_assert_serialized();
7611         wlan_serialize_exit();
7612         fw = firmware_get(namebuf);
7613         wlan_serialize_enter();
7614         if (fw == NULL) {
7615                 device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7616                     namebuf);
7617                 return (ENOENT);
7618         }
7619         if (fw->datasize < sizeof(struct bwn_fwhdr))
7620                 goto fail;
7621         hdr = (const struct bwn_fwhdr *)(fw->data);
7622         switch (hdr->type) {
7623         case BWN_FWTYPE_UCODE:
7624         case BWN_FWTYPE_PCM:
7625                 if (be32toh(hdr->size) !=
7626                     (fw->datasize - sizeof(struct bwn_fwhdr)))
7627                         goto fail;
7628                 /* FALLTHROUGH */
7629         case BWN_FWTYPE_IV:
7630                 if (hdr->ver != 1)
7631                         goto fail;
7632                 break;
7633         default:
7634                 goto fail;
7635         }
7636         bfw->filename = name;
7637         bfw->fw = fw;
7638         bfw->type = type;
7639         return (0);
7640 fail:
7641         device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7642         if (fw != NULL)
7643                 firmware_put(fw, FIRMWARE_UNLOAD);
7644         return (EPROTO);
7645 }
7646
7647 static void
7648 bwn_release_firmware(struct bwn_mac *mac)
7649 {
7650
7651         bwn_do_release_fw(&mac->mac_fw.ucode);
7652         bwn_do_release_fw(&mac->mac_fw.pcm);
7653         bwn_do_release_fw(&mac->mac_fw.initvals);
7654         bwn_do_release_fw(&mac->mac_fw.initvals_band);
7655 }
7656
7657 static void
7658 bwn_do_release_fw(struct bwn_fwfile *bfw)
7659 {
7660
7661         if (bfw->fw != NULL)
7662                 firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7663         bfw->fw = NULL;
7664         bfw->filename = NULL;
7665 }
7666
7667 static int
7668 bwn_fw_loaducode(struct bwn_mac *mac)
7669 {
7670 #define GETFWOFFSET(fwp, offset)        \
7671         ((const uint32_t *)((const char *)fwp.fw->data + offset))
7672 #define GETFWSIZE(fwp, offset)  \
7673         ((fwp.fw->datasize - offset) / sizeof(uint32_t))
7674         struct bwn_softc *sc = mac->mac_sc;
7675         const uint32_t *data;
7676         unsigned int i;
7677         uint32_t ctl;
7678         uint16_t date, fwcaps, time;
7679         int error = 0;
7680
7681         ctl = BWN_READ_4(mac, BWN_MACCTL);
7682         ctl |= BWN_MACCTL_MCODE_JMP0;
7683         KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7684             __LINE__));
7685         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7686         for (i = 0; i < 64; i++)
7687                 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7688         for (i = 0; i < 4096; i += 2)
7689                 bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7690
7691         data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7692         bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7693         for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7694              i++) {
7695                 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7696                 DELAY(10);
7697         }
7698
7699         if (mac->mac_fw.pcm.fw) {
7700                 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7701                 bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7702                 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7703                 bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7704                 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7705                     sizeof(struct bwn_fwhdr)); i++) {
7706                         BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7707                         DELAY(10);
7708                 }
7709         }
7710
7711         BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7712         BWN_WRITE_4(mac, BWN_MACCTL,
7713             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7714             BWN_MACCTL_MCODE_RUN);
7715
7716         for (i = 0; i < 21; i++) {
7717                 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7718                         break;
7719                 if (i >= 20) {
7720                         device_printf(sc->sc_dev, "ucode timeout\n");
7721                         error = ENXIO;
7722                         goto error;
7723                 }
7724                 DELAY(50000);
7725         }
7726         BWN_READ_4(mac, BWN_INTR_REASON);
7727
7728         mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7729         if (mac->mac_fw.rev <= 0x128) {
7730                 device_printf(sc->sc_dev, "the firmware is too old\n");
7731                 error = EOPNOTSUPP;
7732                 goto error;
7733         }
7734         mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7735             BWN_SHARED_UCODE_PATCH);
7736         date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7737         mac->mac_fw.opensource = (date == 0xffff);
7738         if (bwn_wme != 0)
7739                 mac->mac_flags |= BWN_MAC_FLAG_WME;
7740         mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7741
7742         time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7743         if (mac->mac_fw.opensource == 0) {
7744                 device_printf(sc->sc_dev,
7745                     "firmware version (rev %u patch %u date %#x time %#x)\n",
7746                     mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7747                 if (mac->mac_fw.no_pcmfile)
7748                         device_printf(sc->sc_dev,
7749                             "no HW crypto acceleration due to pcm5\n");
7750         } else {
7751                 mac->mac_fw.patch = time;
7752                 fwcaps = bwn_fwcaps_read(mac);
7753                 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7754                         device_printf(sc->sc_dev,
7755                             "disabling HW crypto acceleration\n");
7756                         mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7757                 }
7758                 if (!(fwcaps & BWN_FWCAPS_WME)) {
7759                         device_printf(sc->sc_dev, "disabling WME support\n");
7760                         mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7761                 }
7762         }
7763
7764         if (BWN_ISOLDFMT(mac))
7765                 device_printf(sc->sc_dev, "using old firmware image\n");
7766
7767         return (0);
7768
7769 error:
7770         BWN_WRITE_4(mac, BWN_MACCTL,
7771             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7772             BWN_MACCTL_MCODE_JMP0);
7773
7774         return (error);
7775 #undef GETFWSIZE
7776 #undef GETFWOFFSET
7777 }
7778
7779 /* OpenFirmware only */
7780 static uint16_t
7781 bwn_fwcaps_read(struct bwn_mac *mac)
7782 {
7783
7784         KASSERT(mac->mac_fw.opensource == 1,
7785             ("%s:%d: fail", __func__, __LINE__));
7786         return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7787 }
7788
7789 static int
7790 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7791     size_t count, size_t array_size)
7792 {
7793 #define GET_NEXTIV16(iv)                                                \
7794         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7795             sizeof(uint16_t) + sizeof(uint16_t)))
7796 #define GET_NEXTIV32(iv)                                                \
7797         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7798             sizeof(uint16_t) + sizeof(uint32_t)))
7799         struct bwn_softc *sc = mac->mac_sc;
7800         const struct bwn_fwinitvals *iv;
7801         uint16_t offset;
7802         size_t i;
7803         uint8_t bit32;
7804
7805         KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7806             ("%s:%d: fail", __func__, __LINE__));
7807         iv = ivals;
7808         for (i = 0; i < count; i++) {
7809                 if (array_size < sizeof(iv->offset_size))
7810                         goto fail;
7811                 array_size -= sizeof(iv->offset_size);
7812                 offset = be16toh(iv->offset_size);
7813                 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7814                 offset &= BWN_FWINITVALS_OFFSET_MASK;
7815                 if (offset >= 0x1000)
7816                         goto fail;
7817                 if (bit32) {
7818                         if (array_size < sizeof(iv->data.d32))
7819                                 goto fail;
7820                         array_size -= sizeof(iv->data.d32);
7821                         BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7822                         iv = GET_NEXTIV32(iv);
7823                 } else {
7824
7825                         if (array_size < sizeof(iv->data.d16))
7826                                 goto fail;
7827                         array_size -= sizeof(iv->data.d16);
7828                         BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7829
7830                         iv = GET_NEXTIV16(iv);
7831                 }
7832         }
7833         if (array_size != 0)
7834                 goto fail;
7835         return (0);
7836 fail:
7837         device_printf(sc->sc_dev, "initvals: invalid format\n");
7838         return (EPROTO);
7839 #undef GET_NEXTIV16
7840 #undef GET_NEXTIV32
7841 }
7842
7843 static int
7844 bwn_switch_channel(struct bwn_mac *mac, int chan)
7845 {
7846         struct bwn_phy *phy = &(mac->mac_phy);
7847         struct bwn_softc *sc = mac->mac_sc;
7848         struct ifnet *ifp = sc->sc_ifp;
7849         struct ieee80211com *ic = ifp->if_l2com;
7850         uint16_t channelcookie, savedcookie;
7851         int error;
7852
7853         if (chan == 0xffff)
7854                 chan = phy->get_default_chan(mac);
7855
7856         channelcookie = chan;
7857         if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
7858                 channelcookie |= 0x100;
7859         savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
7860         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
7861         error = phy->switch_channel(mac, chan);
7862         if (error)
7863                 goto fail;
7864
7865         mac->mac_phy.chan = chan;
7866         DELAY(8000);
7867         return (0);
7868 fail:
7869         device_printf(sc->sc_dev, "failed to switch channel\n");
7870         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
7871         return (error);
7872 }
7873
7874 static uint16_t
7875 bwn_ant2phy(int antenna)
7876 {
7877
7878         switch (antenna) {
7879         case BWN_ANT0:
7880                 return (BWN_TX_PHY_ANT0);
7881         case BWN_ANT1:
7882                 return (BWN_TX_PHY_ANT1);
7883         case BWN_ANT2:
7884                 return (BWN_TX_PHY_ANT2);
7885         case BWN_ANT3:
7886                 return (BWN_TX_PHY_ANT3);
7887         case BWN_ANTAUTO:
7888                 return (BWN_TX_PHY_ANT01AUTO);
7889         }
7890         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7891         return (0);
7892 }
7893
7894 static void
7895 bwn_wme_load(struct bwn_mac *mac)
7896 {
7897         struct bwn_softc *sc = mac->mac_sc;
7898         int i;
7899
7900         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
7901             ("%s:%d: fail", __func__, __LINE__));
7902
7903         bwn_mac_suspend(mac);
7904         for (i = 0; i < N(sc->sc_wmeParams); i++)
7905                 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
7906                     bwn_wme_shm_offsets[i]);
7907         bwn_mac_enable(mac);
7908 }
7909
7910 static void
7911 bwn_wme_loadparams(struct bwn_mac *mac,
7912     const struct wmeParams *p, uint16_t shm_offset)
7913 {
7914 #define SM(_v, _f)      (((_v) << _f##_S) & _f)
7915         struct bwn_softc *sc = mac->mac_sc;
7916         uint16_t params[BWN_NR_WMEPARAMS];
7917         int slot, tmp;
7918         unsigned int i;
7919
7920         slot = BWN_READ_2(mac, BWN_RNG) &
7921             SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7922
7923         memset(&params, 0, sizeof(params));
7924
7925         DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
7926             "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
7927             p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
7928
7929         params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
7930         params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7931         params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
7932         params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7933         params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
7934         params[BWN_WMEPARAM_BSLOTS] = slot;
7935         params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
7936
7937         for (i = 0; i < N(params); i++) {
7938                 if (i == BWN_WMEPARAM_STATUS) {
7939                         tmp = bwn_shm_read_2(mac, BWN_SHARED,
7940                             shm_offset + (i * 2));
7941                         tmp |= 0x100;
7942                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
7943                             tmp);
7944                 } else {
7945                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
7946                             params[i]);
7947                 }
7948         }
7949 }
7950
7951 static void
7952 bwn_mac_write_bssid(struct bwn_mac *mac)
7953 {
7954         struct bwn_softc *sc = mac->mac_sc;
7955         uint32_t tmp;
7956         int i;
7957         uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
7958
7959         bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
7960         memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
7961         memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
7962             IEEE80211_ADDR_LEN);
7963
7964         for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
7965                 tmp = (uint32_t) (mac_bssid[i + 0]);
7966                 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
7967                 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
7968                 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
7969                 bwn_ram_write(mac, 0x20 + i, tmp);
7970         }
7971 }
7972
7973 static void
7974 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
7975     const uint8_t *macaddr)
7976 {
7977         static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
7978         uint16_t data;
7979
7980         if (mac == NULL)
7981                 macaddr = zero;
7982
7983         offset |= 0x0020;
7984         BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
7985
7986         data = macaddr[0];
7987         data |= macaddr[1] << 8;
7988         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7989         data = macaddr[2];
7990         data |= macaddr[3] << 8;
7991         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7992         data = macaddr[4];
7993         data |= macaddr[5] << 8;
7994         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7995 }
7996
7997 static void
7998 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
7999     const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
8000 {
8001         uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
8002         uint8_t per_sta_keys_start = 8;
8003
8004         if (BWN_SEC_NEWAPI(mac))
8005                 per_sta_keys_start = 4;
8006
8007         KASSERT(index < mac->mac_max_nr_keys,
8008             ("%s:%d: fail", __func__, __LINE__));
8009         KASSERT(key_len <= BWN_SEC_KEYSIZE,
8010             ("%s:%d: fail", __func__, __LINE__));
8011
8012         if (index >= per_sta_keys_start)
8013                 bwn_key_macwrite(mac, index, NULL);
8014         if (key)
8015                 memcpy(buf, key, key_len);
8016         bwn_key_write(mac, index, algorithm, buf);
8017         if (index >= per_sta_keys_start)
8018                 bwn_key_macwrite(mac, index, mac_addr);
8019
8020         mac->mac_key[index].algorithm = algorithm;
8021 }
8022
8023 static void
8024 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8025 {
8026         struct bwn_softc *sc = mac->mac_sc;
8027         uint32_t addrtmp[2] = { 0, 0 };
8028         uint8_t start = 8;
8029
8030         if (BWN_SEC_NEWAPI(mac))
8031                 start = 4;
8032
8033         KASSERT(index >= start,
8034             ("%s:%d: fail", __func__, __LINE__));
8035         index -= start;
8036
8037         if (addr) {
8038                 addrtmp[0] = addr[0];
8039                 addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8040                 addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8041                 addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8042                 addrtmp[1] = addr[4];
8043                 addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8044         }
8045
8046         if (siba_get_revid(sc->sc_dev) >= 5) {
8047                 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8048                 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8049         } else {
8050                 if (index >= 8) {
8051                         bwn_shm_write_4(mac, BWN_SHARED,
8052                             BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8053                         bwn_shm_write_2(mac, BWN_SHARED,
8054                             BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8055                 }
8056         }
8057 }
8058
8059 static void
8060 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8061     const uint8_t *key)
8062 {
8063         unsigned int i;
8064         uint32_t offset;
8065         uint16_t kidx, value;
8066
8067         kidx = BWN_SEC_KEY2FW(mac, index);
8068         bwn_shm_write_2(mac, BWN_SHARED,
8069             BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8070
8071         offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8072         for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8073                 value = key[i];
8074                 value |= (uint16_t)(key[i + 1]) << 8;
8075                 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8076         }
8077 }
8078
8079 static void
8080 bwn_phy_exit(struct bwn_mac *mac)
8081 {
8082
8083         mac->mac_phy.rf_onoff(mac, 0);
8084         if (mac->mac_phy.exit != NULL)
8085                 mac->mac_phy.exit(mac);
8086 }
8087
8088 static void
8089 bwn_dma_free(struct bwn_mac *mac)
8090 {
8091         struct bwn_dma *dma;
8092
8093         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8094                 return;
8095         dma = &mac->mac_method.dma;
8096
8097         bwn_dma_ringfree(&dma->rx);
8098         bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8099         bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8100         bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8101         bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8102         bwn_dma_ringfree(&dma->mcast);
8103 }
8104
8105 static void
8106 bwn_core_stop(struct bwn_mac *mac)
8107 {
8108         struct bwn_softc *sc = mac->mac_sc;
8109
8110         wlan_assert_serialized();
8111
8112         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8113                 return;
8114
8115         callout_stop(&sc->sc_rfswitch_ch);
8116         callout_stop(&sc->sc_task_ch);
8117         callout_stop(&sc->sc_watchdog_ch);
8118         sc->sc_watchdog_timer = 0;
8119         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8120         BWN_READ_4(mac, BWN_INTR_MASK);
8121         bwn_mac_suspend(mac);
8122
8123         mac->mac_status = BWN_MAC_STATUS_INITED;
8124 }
8125
8126 static int
8127 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8128 {
8129         struct bwn_mac *up_dev = NULL;
8130         struct bwn_mac *down_dev;
8131         struct bwn_mac *mac;
8132         int err, status;
8133         uint8_t gmode;
8134
8135         TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8136                 if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8137                     mac->mac_phy.supports_2ghz) {
8138                         up_dev = mac;
8139                         gmode = 1;
8140                 } else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8141                     mac->mac_phy.supports_5ghz) {
8142                         up_dev = mac;
8143                         gmode = 0;
8144                 } else {
8145                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8146                         return (EINVAL);
8147                 }
8148                 if (up_dev != NULL)
8149                         break;
8150         }
8151         if (up_dev == NULL) {
8152                 device_printf(sc->sc_dev, "Could not find a device\n");
8153                 return (ENODEV);
8154         }
8155         if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8156                 return (0);
8157
8158         device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8159             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8160
8161         down_dev = sc->sc_curmac;
8162         status = down_dev->mac_status;
8163         if (status >= BWN_MAC_STATUS_STARTED)
8164                 bwn_core_stop(down_dev);
8165         if (status >= BWN_MAC_STATUS_INITED)
8166                 bwn_core_exit(down_dev);
8167
8168         if (down_dev != up_dev)
8169                 bwn_phy_reset(down_dev);
8170
8171         up_dev->mac_phy.gmode = gmode;
8172         if (status >= BWN_MAC_STATUS_INITED) {
8173                 err = bwn_core_init(up_dev);
8174                 if (err) {
8175                         device_printf(sc->sc_dev,
8176                             "fatal: failed to initialize for %s-GHz\n",
8177                             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8178                         goto fail;
8179                 }
8180         }
8181         if (status >= BWN_MAC_STATUS_STARTED)
8182                 bwn_core_start(up_dev);
8183         KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8184         sc->sc_curmac = up_dev;
8185
8186         return (0);
8187 fail:
8188         sc->sc_curmac = NULL;
8189         return (err);
8190 }
8191
8192 static void
8193 bwn_rf_turnon(struct bwn_mac *mac)
8194 {
8195
8196         bwn_mac_suspend(mac);
8197         mac->mac_phy.rf_onoff(mac, 1);
8198         mac->mac_phy.rf_on = 1;
8199         bwn_mac_enable(mac);
8200 }
8201
8202 static void
8203 bwn_rf_turnoff(struct bwn_mac *mac)
8204 {
8205
8206         bwn_mac_suspend(mac);
8207         mac->mac_phy.rf_onoff(mac, 0);
8208         mac->mac_phy.rf_on = 0;
8209         bwn_mac_enable(mac);
8210 }
8211
8212 static void
8213 bwn_phy_reset(struct bwn_mac *mac)
8214 {
8215         struct bwn_softc *sc = mac->mac_sc;
8216
8217         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8218             ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8219              BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8220         DELAY(1000);
8221         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8222             (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8223             BWN_TGSLOW_PHYRESET);
8224         DELAY(1000);
8225 }
8226
8227 static int
8228 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8229 {
8230         struct bwn_vap *bvp = BWN_VAP(vap);
8231         struct ieee80211com *ic= vap->iv_ic;
8232         struct ifnet *ifp = ic->ic_ifp;
8233         enum ieee80211_state ostate = vap->iv_state;
8234         struct bwn_softc *sc = ifp->if_softc;
8235         struct bwn_mac *mac = sc->sc_curmac;
8236         int error;
8237
8238         DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8239             ieee80211_state_name[vap->iv_state],
8240             ieee80211_state_name[nstate]);
8241
8242         error = bvp->bv_newstate(vap, nstate, arg);
8243         if (error != 0)
8244                 return (error);
8245
8246         bwn_led_newstate(mac, nstate);
8247
8248         /*
8249          * Clear the BSSID when we stop a STA
8250          */
8251         if (vap->iv_opmode == IEEE80211_M_STA) {
8252                 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8253                         /*
8254                          * Clear out the BSSID.  If we reassociate to
8255                          * the same AP, this will reinialize things
8256                          * correctly...
8257                          */
8258                         if (ic->ic_opmode == IEEE80211_M_STA &&
8259                             (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8260                                 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8261                                 bwn_set_macaddr(mac);
8262                         }
8263                 }
8264         }
8265
8266         if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8267             vap->iv_opmode == IEEE80211_M_AHDEMO) {
8268                 /* XXX nothing to do? */
8269         } else if (nstate == IEEE80211_S_RUN) {
8270                 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8271                 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
8272                 bwn_set_opmode(mac);
8273                 bwn_set_pretbtt(mac);
8274                 bwn_spu_setdelay(mac, 0);
8275                 bwn_set_macaddr(mac);
8276         }
8277
8278         return (error);
8279 }
8280
8281 static void
8282 bwn_set_pretbtt(struct bwn_mac *mac)
8283 {
8284         struct bwn_softc *sc = mac->mac_sc;
8285         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8286         uint16_t pretbtt;
8287
8288         if (ic->ic_opmode == IEEE80211_M_IBSS)
8289                 pretbtt = 2;
8290         else
8291                 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8292         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8293         BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8294 }
8295
8296 static void
8297 bwn_intr(void *arg)
8298 {
8299         struct bwn_mac *mac = arg;
8300         struct bwn_softc *sc = mac->mac_sc;
8301         uint32_t reason;
8302
8303         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8304             (sc->sc_flags & BWN_FLAG_INVALID))
8305                 return;
8306
8307         reason = BWN_READ_4(mac, BWN_INTR_REASON);
8308         if (reason == 0xffffffff)       /* shared IRQ */
8309                 return;
8310         reason &= mac->mac_intr_mask;
8311         if (reason == 0)
8312                 return;
8313
8314         mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001fc00;
8315         mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8316         mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8317         mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8318         mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8319         BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8320         BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8321         BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8322         BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8323         BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8324         BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8325
8326         /* Disable interrupts. */
8327         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8328
8329         mac->mac_reason_intr = reason;
8330
8331         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8332         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8333
8334         taskqueue_enqueue(sc->sc_tq, &mac->mac_intrtask);
8335         return;
8336 }
8337
8338 static void
8339 bwn_intrtask(void *arg, int npending)
8340 {
8341         struct bwn_mac *mac = arg;
8342         struct bwn_softc *sc = mac->mac_sc;
8343         struct ifnet *ifp = sc->sc_ifp;
8344         uint32_t merged = 0;
8345         int i, tx = 0, rx = 0;
8346
8347         wlan_serialize_enter();
8348         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8349             (sc->sc_flags & BWN_FLAG_INVALID)) {
8350                 wlan_serialize_exit();
8351                 return;
8352         }
8353
8354         for (i = 0; i < N(mac->mac_reason); i++)
8355                 merged |= mac->mac_reason[i];
8356
8357         if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8358                 device_printf(sc->sc_dev, "MAC trans error\n");
8359
8360         if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8361                 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8362                 mac->mac_phy.txerrors--;
8363                 if (mac->mac_phy.txerrors == 0) {
8364                         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8365                         bwn_restart(mac, "PHY TX errors");
8366                 }
8367         }
8368
8369         if (merged & BWN_DMAINTR_FATALMASK) {
8370                 device_printf(sc->sc_dev,
8371                     "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8372                     mac->mac_reason[0], mac->mac_reason[1],
8373                     mac->mac_reason[2], mac->mac_reason[3],
8374                     mac->mac_reason[4], mac->mac_reason[5]);
8375                 bwn_restart(mac, "DMA error");
8376                 wlan_serialize_exit();
8377                 return;
8378         }
8379
8380         if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8381                 bwn_intr_ucode_debug(mac);
8382         if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8383                 bwn_intr_tbtt_indication(mac);
8384         if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8385                 bwn_intr_atim_end(mac);
8386         if (mac->mac_reason_intr & BWN_INTR_BEACON)
8387                 bwn_intr_beacon(mac);
8388         if (mac->mac_reason_intr & BWN_INTR_PMQ)
8389                 bwn_intr_pmq(mac);
8390         if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8391                 bwn_intr_noise(mac);
8392
8393         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8394                 if (mac->mac_reason[0] & BWN_DMAINTR_RDESC_UFLOW) {
8395                         device_printf(sc->sc_dev, "RX descriptor overflow\n");
8396                         bwn_dma_rx_handle_overflow(mac->mac_method.dma.rx);
8397                 }
8398                 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8399                         bwn_dma_rx(mac->mac_method.dma.rx);
8400                         rx = 1;
8401                 }
8402         } else
8403                 rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8404
8405         KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8406         KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8407         KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8408         KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8409         KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8410
8411         if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8412                 bwn_intr_txeof(mac);
8413                 tx = 1;
8414         }
8415
8416         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8417
8418         if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8419                 int evt = BWN_LED_EVENT_NONE;
8420
8421                 if (tx && rx) {
8422                         if (sc->sc_rx_rate > sc->sc_tx_rate)
8423                                 evt = BWN_LED_EVENT_RX;
8424                         else
8425                                 evt = BWN_LED_EVENT_TX;
8426                 } else if (tx) {
8427                         evt = BWN_LED_EVENT_TX;
8428                 } else if (rx) {
8429                         evt = BWN_LED_EVENT_RX;
8430                 } else if (rx == 0) {
8431                         evt = BWN_LED_EVENT_POLL;
8432                 }
8433
8434                 if (evt != BWN_LED_EVENT_NONE)
8435                         bwn_led_event(mac, evt);
8436        }
8437
8438         if (!ifq_is_oactive(&ifp->if_snd)) {
8439                 if (!ifq_is_empty(&ifp->if_snd))
8440                         bwn_start_locked(ifp);
8441         }
8442
8443         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8444         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8445
8446         wlan_serialize_exit();
8447 }
8448
8449 static void
8450 bwn_restart(struct bwn_mac *mac, const char *msg)
8451 {
8452         struct bwn_softc *sc = mac->mac_sc;
8453         struct ifnet *ifp = sc->sc_ifp;
8454         struct ieee80211com *ic = ifp->if_l2com;
8455
8456         if (mac->mac_status < BWN_MAC_STATUS_INITED)
8457                 return;
8458
8459         device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8460         ieee80211_runtask(ic, &mac->mac_hwreset);
8461 }
8462
8463 static void
8464 bwn_intr_ucode_debug(struct bwn_mac *mac)
8465 {
8466         struct bwn_softc *sc = mac->mac_sc;
8467         uint16_t reason;
8468
8469         if (mac->mac_fw.opensource == 0)
8470                 return;
8471
8472         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8473         switch (reason) {
8474         case BWN_DEBUGINTR_PANIC:
8475                 bwn_handle_fwpanic(mac);
8476                 break;
8477         case BWN_DEBUGINTR_DUMP_SHM:
8478                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8479                 break;
8480         case BWN_DEBUGINTR_DUMP_REGS:
8481                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8482                 break;
8483         case BWN_DEBUGINTR_MARKER:
8484                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8485                 break;
8486         default:
8487                 device_printf(sc->sc_dev,
8488                     "ucode debug unknown reason: %#x\n", reason);
8489         }
8490
8491         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8492             BWN_DEBUGINTR_ACK);
8493 }
8494
8495 static void
8496 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8497 {
8498         struct bwn_softc *sc = mac->mac_sc;
8499         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8500
8501         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8502                 bwn_psctl(mac, 0);
8503         if (ic->ic_opmode == IEEE80211_M_IBSS)
8504                 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8505 }
8506
8507 static void
8508 bwn_intr_atim_end(struct bwn_mac *mac)
8509 {
8510
8511         if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8512                 BWN_WRITE_4(mac, BWN_MACCMD,
8513                     BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8514                 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8515         }
8516 }
8517
8518 static void
8519 bwn_intr_beacon(struct bwn_mac *mac)
8520 {
8521         struct bwn_softc *sc = mac->mac_sc;
8522         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8523         uint32_t cmd, beacon0, beacon1;
8524
8525         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8526             ic->ic_opmode == IEEE80211_M_MBSS)
8527                 return;
8528
8529         mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8530
8531         cmd = BWN_READ_4(mac, BWN_MACCMD);
8532         beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8533         beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8534
8535         if (beacon0 && beacon1) {
8536                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8537                 mac->mac_intr_mask |= BWN_INTR_BEACON;
8538                 return;
8539         }
8540
8541         if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8542                 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8543                 bwn_load_beacon0(mac);
8544                 bwn_load_beacon1(mac);
8545                 cmd = BWN_READ_4(mac, BWN_MACCMD);
8546                 cmd |= BWN_MACCMD_BEACON0_VALID;
8547                 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8548         } else {
8549                 if (!beacon0) {
8550                         bwn_load_beacon0(mac);
8551                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8552                         cmd |= BWN_MACCMD_BEACON0_VALID;
8553                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8554                 } else if (!beacon1) {
8555                         bwn_load_beacon1(mac);
8556                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8557                         cmd |= BWN_MACCMD_BEACON1_VALID;
8558                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8559                 }
8560         }
8561 }
8562
8563 static void
8564 bwn_intr_pmq(struct bwn_mac *mac)
8565 {
8566         uint32_t tmp;
8567
8568         while (1) {
8569                 tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8570                 if (!(tmp & 0x00000008))
8571                         break;
8572         }
8573         BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8574 }
8575
8576 static void
8577 bwn_intr_noise(struct bwn_mac *mac)
8578 {
8579         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8580         uint16_t tmp;
8581         uint8_t noise[4];
8582         uint8_t i, j;
8583         int32_t average;
8584
8585         if (mac->mac_phy.type != BWN_PHYTYPE_G)
8586                 return;
8587
8588         KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8589         *((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8590         if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8591             noise[3] == 0x7f)
8592                 goto new;
8593
8594         KASSERT(mac->mac_noise.noi_nsamples < 8,
8595             ("%s:%d: fail", __func__, __LINE__));
8596         i = mac->mac_noise.noi_nsamples;
8597         noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8598         noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8599         noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8600         noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8601         mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8602         mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8603         mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8604         mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8605         mac->mac_noise.noi_nsamples++;
8606         if (mac->mac_noise.noi_nsamples == 8) {
8607                 average = 0;
8608                 for (i = 0; i < 8; i++) {
8609                         for (j = 0; j < 4; j++)
8610                                 average += mac->mac_noise.noi_samples[i][j];
8611                 }
8612                 average = (((average / 32) * 125) + 64) / 128;
8613                 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8614                 if (tmp >= 8)
8615                         average += 2;
8616                 else
8617                         average -= 25;
8618                 average -= (tmp == 8) ? 72 : 48;
8619
8620                 mac->mac_stats.link_noise = average;
8621                 mac->mac_noise.noi_running = 0;
8622                 return;
8623         }
8624 new:
8625         bwn_noise_gensample(mac);
8626 }
8627
8628 static int
8629 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8630 {
8631         struct bwn_mac *mac = prq->prq_mac;
8632         struct bwn_softc *sc = mac->mac_sc;
8633         unsigned int i;
8634
8635         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8636                 return (0);
8637
8638         for (i = 0; i < 5000; i++) {
8639                 if (bwn_pio_rxeof(prq) == 0)
8640                         break;
8641         }
8642         if (i >= 5000)
8643                 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8644         return ((i > 0) ? 1 : 0);
8645 }
8646
8647 static void
8648 bwn_dma_rx_handle_overflow(struct bwn_dma_ring *dr)
8649 {
8650         int curslot, prevslot;
8651
8652         curslot = dr->get_curslot(dr);
8653         if (curslot == 0)
8654                 prevslot = dr->dr_numslots - 1;
8655         else
8656                 prevslot = curslot - 1;
8657         dr->set_curslot(dr, prevslot);
8658 }
8659
8660 static void
8661 bwn_dma_rx(struct bwn_dma_ring *dr)
8662 {
8663         int slot, curslot;
8664
8665         KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8666         curslot = dr->get_curslot(dr);
8667         KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8668             ("%s:%d: fail", __func__, __LINE__));
8669
8670         slot = dr->dr_curslot;
8671         for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8672                 bwn_dma_rxeof(dr, &slot);
8673
8674         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8675             BUS_DMASYNC_PREWRITE);
8676
8677         dr->set_curslot(dr, slot);
8678         dr->dr_curslot = slot;
8679 }
8680
8681 static void
8682 bwn_intr_txeof(struct bwn_mac *mac)
8683 {
8684         struct bwn_txstatus stat;
8685         uint32_t stat0, stat1;
8686         uint16_t tmp;
8687
8688         while (1) {
8689                 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8690                 if (!(stat0 & 0x00000001))
8691                         break;
8692                 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8693
8694                 stat.cookie = (stat0 >> 16);
8695                 stat.seq = (stat1 & 0x0000ffff);
8696                 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8697                 tmp = (stat0 & 0x0000ffff);
8698                 stat.framecnt = ((tmp & 0xf000) >> 12);
8699                 stat.rtscnt = ((tmp & 0x0f00) >> 8);
8700                 stat.sreason = ((tmp & 0x001c) >> 2);
8701                 stat.pm = (tmp & 0x0080) ? 1 : 0;
8702                 stat.im = (tmp & 0x0040) ? 1 : 0;
8703                 stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8704                 stat.ack = (tmp & 0x0002) ? 1 : 0;
8705
8706                 bwn_handle_txeof(mac, &stat);
8707         }
8708 }
8709
8710 static void
8711 bwn_hwreset(void *arg, int npending)
8712 {
8713         struct bwn_mac *mac = arg;
8714         struct bwn_softc *sc = mac->mac_sc;
8715         int error = 0;
8716         int prev_status;
8717
8718         wlan_serialize_enter();
8719
8720         prev_status = mac->mac_status;
8721         if (prev_status >= BWN_MAC_STATUS_STARTED)
8722                 bwn_core_stop(mac);
8723         if (prev_status >= BWN_MAC_STATUS_INITED)
8724                 bwn_core_exit(mac);
8725
8726         if (prev_status >= BWN_MAC_STATUS_INITED) {
8727                 error = bwn_core_init(mac);
8728                 if (error)
8729                         goto out;
8730         }
8731         if (prev_status >= BWN_MAC_STATUS_STARTED)
8732                 bwn_core_start(mac);
8733 out:
8734         if (error) {
8735                 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8736                 sc->sc_curmac = NULL;
8737         }
8738         wlan_serialize_exit();
8739 }
8740
8741 static void
8742 bwn_handle_fwpanic(struct bwn_mac *mac)
8743 {
8744         struct bwn_softc *sc = mac->mac_sc;
8745         uint16_t reason;
8746
8747         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8748         device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8749
8750         if (reason == BWN_FWPANIC_RESTART)
8751                 bwn_restart(mac, "ucode panic");
8752 }
8753
8754 static void
8755 bwn_load_beacon0(struct bwn_mac *mac)
8756 {
8757
8758         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8759 }
8760
8761 static void
8762 bwn_load_beacon1(struct bwn_mac *mac)
8763 {
8764
8765         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8766 }
8767
8768 static uint32_t
8769 bwn_jssi_read(struct bwn_mac *mac)
8770 {
8771         uint32_t val = 0;
8772
8773         val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8774         val <<= 16;
8775         val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8776
8777         return (val);
8778 }
8779
8780 static void
8781 bwn_noise_gensample(struct bwn_mac *mac)
8782 {
8783         uint32_t jssi = 0x7f7f7f7f;
8784
8785         bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8786         bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8787         BWN_WRITE_4(mac, BWN_MACCMD,
8788             BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8789 }
8790
8791 static int
8792 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8793 {
8794         return (dr->dr_numslots - dr->dr_usedslot);
8795 }
8796
8797 static int
8798 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8799 {
8800         KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8801             ("%s:%d: fail", __func__, __LINE__));
8802         if (slot == dr->dr_numslots - 1)
8803                 return (0);
8804         return (slot + 1);
8805 }
8806
8807 static void
8808 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8809 {
8810         struct bwn_mac *mac = dr->dr_mac;
8811         struct bwn_softc *sc = mac->mac_sc;
8812         struct bwn_dma *dma = &mac->mac_method.dma;
8813         struct bwn_dmadesc_generic *desc;
8814         struct bwn_dmadesc_meta *meta;
8815         struct bwn_rxhdr4 *rxhdr;
8816         struct ifnet *ifp = sc->sc_ifp;
8817         struct mbuf *m;
8818         uint32_t macstat;
8819         int32_t tmp;
8820         int cnt = 0;
8821         uint16_t len;
8822
8823         dr->getdesc(dr, *slot, &desc, &meta);
8824
8825         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8826         m = meta->mt_m;
8827
8828         if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8829                 ifp->if_ierrors++;
8830                 return;
8831         }
8832
8833         rxhdr = mtod(m, struct bwn_rxhdr4 *);
8834         len = le16toh(rxhdr->frame_len);
8835         if (len <= 0) {
8836                 ifp->if_ierrors++;
8837                 return;
8838         }
8839         if (bwn_dma_check_redzone(dr, m)) {
8840                 device_printf(sc->sc_dev, "redzone error.\n");
8841                 bwn_dma_set_redzone(dr, m);
8842                 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8843                     BUS_DMASYNC_PREWRITE);
8844                 return;
8845         }
8846         if (len > dr->dr_rx_bufsize) {
8847                 tmp = len;
8848                 while (1) {
8849                         dr->getdesc(dr, *slot, &desc, &meta);
8850                         bwn_dma_set_redzone(dr, meta->mt_m);
8851                         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8852                             BUS_DMASYNC_PREWRITE);
8853                         *slot = bwn_dma_nextslot(dr, *slot);
8854                         cnt++;
8855                         tmp -= dr->dr_rx_bufsize;
8856                         if (tmp <= 0)
8857                                 break;
8858                 }
8859                 device_printf(sc->sc_dev, "too small buffer "
8860                        "(len %u buffer %u dropped %d)\n",
8861                        len, dr->dr_rx_bufsize, cnt);
8862                 return;
8863         }
8864         macstat = le32toh(rxhdr->mac_status);
8865         if (macstat & BWN_RX_MAC_FCSERR) {
8866                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8867                         device_printf(sc->sc_dev, "RX drop\n");
8868                         return;
8869                 }
8870         }
8871
8872         m->m_pkthdr.rcvif = ifp;
8873         m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8874         m_adj(m, dr->dr_frameoffset);
8875
8876         bwn_rxeof(dr->dr_mac, m, rxhdr);
8877 }
8878
8879 static void
8880 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8881 {
8882         struct bwn_dma_ring *dr;
8883         struct bwn_dmadesc_generic *desc;
8884         struct bwn_dmadesc_meta *meta;
8885         struct bwn_pio_txqueue *tq;
8886         struct bwn_pio_txpkt *tp = NULL;
8887         struct bwn_softc *sc = mac->mac_sc;
8888         struct bwn_stats *stats = &mac->mac_stats;
8889         struct ieee80211_node *ni;
8890         struct ieee80211vap *vap;
8891         int retrycnt = 0, slot;
8892
8893         if (status->im)
8894                 device_printf(sc->sc_dev, "TODO: STATUS IM\n");
8895         if (status->ampdu)
8896                 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
8897         if (status->rtscnt) {
8898                 if (status->rtscnt == 0xf)
8899                         stats->rtsfail++;
8900                 else
8901                         stats->rts++;
8902         }
8903
8904         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8905                 if (status->ack) {
8906                         dr = bwn_dma_parse_cookie(mac, status,
8907                             status->cookie, &slot);
8908                         if (dr == NULL) {
8909                                 device_printf(sc->sc_dev,
8910                                     "failed to parse cookie\n");
8911                                 return;
8912                         }
8913                         while (1) {
8914                                 dr->getdesc(dr, slot, &desc, &meta);
8915                                 if (meta->mt_islast) {
8916                                         ni = meta->mt_ni;
8917                                         vap = ni->ni_vap;
8918                                         ieee80211_ratectl_tx_complete(vap, ni,
8919                                             status->ack ?
8920                                               IEEE80211_RATECTL_TX_SUCCESS :
8921                                               IEEE80211_RATECTL_TX_FAILURE,
8922                                             &retrycnt, 0);
8923                                         break;
8924                                 }
8925                                 slot = bwn_dma_nextslot(dr, slot);
8926                         }
8927                 }
8928                 bwn_dma_handle_txeof(mac, status);
8929         } else {
8930                 if (status->ack) {
8931                         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
8932                         if (tq == NULL) {
8933                                 device_printf(sc->sc_dev,
8934                                     "failed to parse cookie\n");
8935                                 return;
8936                         }
8937                         ni = tp->tp_ni;
8938                         vap = ni->ni_vap;
8939                         ieee80211_ratectl_tx_complete(vap, ni,
8940                             status->ack ?
8941                               IEEE80211_RATECTL_TX_SUCCESS :
8942                               IEEE80211_RATECTL_TX_FAILURE,
8943                             &retrycnt, 0);
8944                 }
8945                 bwn_pio_handle_txeof(mac, status);
8946         }
8947
8948         bwn_phy_txpower_check(mac, 0);
8949 }
8950
8951 static uint8_t
8952 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
8953 {
8954         struct bwn_mac *mac = prq->prq_mac;
8955         struct bwn_softc *sc = mac->mac_sc;
8956         struct bwn_rxhdr4 rxhdr;
8957         struct ifnet *ifp = sc->sc_ifp;
8958         struct mbuf *m;
8959         uint32_t ctl32, macstat, v32;
8960         unsigned int i, padding;
8961         uint16_t ctl16, len, totlen, v16;
8962         unsigned char *mp;
8963         char *data;
8964
8965         memset(&rxhdr, 0, sizeof(rxhdr));
8966
8967         if (prq->prq_rev >= 8) {
8968                 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
8969                 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
8970                         return (0);
8971                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
8972                     BWN_PIO8_RXCTL_FRAMEREADY);
8973                 for (i = 0; i < 10; i++) {
8974                         ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
8975                         if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
8976                                 goto ready;
8977                         DELAY(10);
8978                 }
8979         } else {
8980                 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
8981                 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
8982                         return (0);
8983                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
8984                     BWN_PIO_RXCTL_FRAMEREADY);
8985                 for (i = 0; i < 10; i++) {
8986                         ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
8987                         if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
8988                                 goto ready;
8989                         DELAY(10);
8990                 }
8991         }
8992         device_printf(sc->sc_dev, "%s: timed out\n", __func__);
8993         return (1);
8994 ready:
8995         if (prq->prq_rev >= 8)
8996                 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
8997                     prq->prq_base + BWN_PIO8_RXDATA);
8998         else
8999                 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9000                     prq->prq_base + BWN_PIO_RXDATA);
9001         len = le16toh(rxhdr.frame_len);
9002         if (len > 0x700) {
9003                 device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9004                 goto error;
9005         }
9006         if (len == 0) {
9007                 device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9008                 goto error;
9009         }
9010
9011         macstat = le32toh(rxhdr.mac_status);
9012         if (macstat & BWN_RX_MAC_FCSERR) {
9013                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9014                         device_printf(sc->sc_dev, "%s: FCS error", __func__);
9015                         goto error;
9016                 }
9017         }
9018
9019         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9020         totlen = len + padding;
9021         KASSERT(totlen <= MCLBYTES, ("too big..\n"));
9022         m = m_getcl(MB_DONTWAIT, MT_DATA, M_PKTHDR);
9023         if (m == NULL) {
9024                 device_printf(sc->sc_dev, "%s: out of memory", __func__);
9025                 goto error;
9026         }
9027         mp = mtod(m, unsigned char *);
9028         if (prq->prq_rev >= 8) {
9029                 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3),
9030                     prq->prq_base + BWN_PIO8_RXDATA);
9031                 if (totlen & 3) {
9032                         v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9033                         data = &(mp[totlen - 1]);
9034                         switch (totlen & 3) {
9035                         case 3:
9036                                 *data = (v32 >> 16);
9037                                 data--;
9038                         case 2:
9039                                 *data = (v32 >> 8);
9040                                 data--;
9041                         case 1:
9042                                 *data = v32;
9043                         }
9044                 }
9045         } else {
9046                 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1),
9047                     prq->prq_base + BWN_PIO_RXDATA);
9048                 if (totlen & 1) {
9049                         v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9050                         mp[totlen - 1] = v16;
9051                 }
9052         }
9053
9054         m->m_pkthdr.rcvif = ifp;
9055         m->m_len = m->m_pkthdr.len = totlen;
9056
9057         bwn_rxeof(prq->prq_mac, m, &rxhdr);
9058
9059         return (1);
9060 error:
9061         if (prq->prq_rev >= 8)
9062                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9063                     BWN_PIO8_RXCTL_DATAREADY);
9064         else
9065                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9066         return (1);
9067 }
9068
9069 static int
9070 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9071     struct bwn_dmadesc_meta *meta, int init)
9072 {
9073         struct bwn_mac *mac = dr->dr_mac;
9074         struct bwn_dma *dma = &mac->mac_method.dma;
9075         struct bwn_rxhdr4 *hdr;
9076         bus_dmamap_t map;
9077         bus_addr_t paddr;
9078         struct mbuf *m;
9079         int error;
9080
9081         m = m_getcl(MB_DONTWAIT, MT_DATA, M_PKTHDR);
9082         if (m == NULL) {
9083                 error = ENOBUFS;
9084
9085                 /*
9086                  * If the NIC is up and running, we need to:
9087                  * - Clear RX buffer's header.
9088                  * - Restore RX descriptor settings.
9089                  */
9090                 if (init)
9091                         return (error);
9092                 else
9093                         goto back;
9094         }
9095         m->m_len = m->m_pkthdr.len = MCLBYTES;
9096
9097         bwn_dma_set_redzone(dr, m);
9098
9099         /*
9100          * Try to load RX buf into temporary DMA map
9101          */
9102         error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9103             bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9104         if (error) {
9105                 m_freem(m);
9106
9107                 /*
9108                  * See the comment above
9109                  */
9110                 if (init)
9111                         return (error);
9112                 else
9113                         goto back;
9114         }
9115
9116         if (!init)
9117                 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9118         meta->mt_m = m;
9119         meta->mt_paddr = paddr;
9120
9121         /*
9122          * Swap RX buf's DMA map with the loaded temporary one
9123          */
9124         map = meta->mt_dmap;
9125         meta->mt_dmap = dr->dr_spare_dmap;
9126         dr->dr_spare_dmap = map;
9127
9128 back:
9129         /*
9130          * Clear RX buf header
9131          */
9132         hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9133         bzero(hdr, sizeof(*hdr));
9134         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9135             BUS_DMASYNC_PREWRITE);
9136
9137         /*
9138          * Setup RX buf descriptor
9139          */
9140         dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len -
9141             sizeof(*hdr), 0, 0, 0);
9142         return (error);
9143 }
9144
9145 static void
9146 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9147                  bus_size_t mapsz __unused, int error)
9148 {
9149
9150         if (!error) {
9151                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9152                 *((bus_addr_t *)arg) = seg->ds_addr;
9153         }
9154 }
9155
9156 static int
9157 bwn_hwrate2ieeerate(int rate)
9158 {
9159
9160         switch (rate) {
9161         case BWN_CCK_RATE_1MB:
9162                 return (2);
9163         case BWN_CCK_RATE_2MB:
9164                 return (4);
9165         case BWN_CCK_RATE_5MB:
9166                 return (11);
9167         case BWN_CCK_RATE_11MB:
9168                 return (22);
9169         case BWN_OFDM_RATE_6MB:
9170                 return (12);
9171         case BWN_OFDM_RATE_9MB:
9172                 return (18);
9173         case BWN_OFDM_RATE_12MB:
9174                 return (24);
9175         case BWN_OFDM_RATE_18MB:
9176                 return (36);
9177         case BWN_OFDM_RATE_24MB:
9178                 return (48);
9179         case BWN_OFDM_RATE_36MB:
9180                 return (72);
9181         case BWN_OFDM_RATE_48MB:
9182                 return (96);
9183         case BWN_OFDM_RATE_54MB:
9184                 return (108);
9185         default:
9186                 kprintf("Ooops\n");
9187                 return (0);
9188         }
9189 }
9190
9191 static void
9192 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9193 {
9194         const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9195         struct bwn_plcp6 *plcp;
9196         struct bwn_softc *sc = mac->mac_sc;
9197         struct ieee80211_frame_min *wh;
9198         struct ieee80211_node *ni;
9199         struct ifnet *ifp = sc->sc_ifp;
9200         struct ieee80211com *ic = ifp->if_l2com;
9201         uint32_t macstat;
9202         int padding, rate, rssi = 0, noise = 0, type;
9203         uint16_t phytype, phystat0, phystat3, chanstat;
9204         unsigned char *mp = mtod(m, unsigned char *);
9205         static int rx_mac_dec_rpt = 0;
9206
9207         phystat0 = le16toh(rxhdr->phy_status0);
9208         phystat3 = le16toh(rxhdr->phy_status3);
9209         macstat = le32toh(rxhdr->mac_status);
9210         chanstat = le16toh(rxhdr->channel);
9211         phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9212
9213         if (macstat & BWN_RX_MAC_FCSERR)
9214                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9215         if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9216                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9217         if (macstat & BWN_RX_MAC_DECERR)
9218                 goto drop;
9219
9220         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9221         if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9222                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9223                     m->m_pkthdr.len);
9224                 goto drop;
9225         }
9226         plcp = (struct bwn_plcp6 *)(mp + padding);
9227         m_adj(m, sizeof(struct bwn_plcp6) + padding);
9228         if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9229                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9230                     m->m_pkthdr.len);
9231                 goto drop;
9232         }
9233         wh = mtod(m, struct ieee80211_frame_min *);
9234
9235         if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9236                 device_printf(sc->sc_dev,
9237                     "RX decryption attempted (old %d keyidx %#x)\n",
9238                     BWN_ISOLDFMT(mac),
9239                     (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9240
9241         /* XXX calculating RSSI & noise & antenna */
9242
9243         if (phystat0 & BWN_RX_PHYST0_OFDM)
9244                 rate = bwn_plcp_get_ofdmrate(mac, plcp,
9245                     phytype == BWN_PHYTYPE_A);
9246         else
9247                 rate = bwn_plcp_get_cckrate(mac, plcp);
9248         if (rate == -1) {
9249                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9250                         goto drop;
9251         }
9252         sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9253
9254         /* RX radio tap */
9255         if (ieee80211_radiotap_active(ic))
9256                 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9257         m_adj(m, -IEEE80211_CRC_LEN);
9258
9259         rssi = rxhdr->phy.abg.rssi;     /* XXX incorrect RSSI calculation? */
9260         noise = mac->mac_stats.link_noise;
9261
9262         ifp->if_ipackets++;
9263
9264         ni = ieee80211_find_rxnode(ic, wh);
9265         if (ni != NULL) {
9266                 type = ieee80211_input(ni, m, rssi, noise);
9267                 ieee80211_free_node(ni);
9268         } else
9269                 type = ieee80211_input_all(ic, m, rssi, noise);
9270
9271         return;
9272 drop:
9273         device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9274 }
9275
9276 static void
9277 bwn_dma_handle_txeof(struct bwn_mac *mac,
9278     const struct bwn_txstatus *status)
9279 {
9280         struct bwn_dma *dma = &mac->mac_method.dma;
9281         struct bwn_dma_ring *dr;
9282         struct bwn_dmadesc_generic *desc;
9283         struct bwn_dmadesc_meta *meta;
9284         struct bwn_softc *sc = mac->mac_sc;
9285         struct ieee80211_node *ni;
9286         struct ifnet *ifp = sc->sc_ifp;
9287         struct mbuf *m;
9288         int slot;
9289
9290         dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9291         if (dr == NULL) {
9292                 device_printf(sc->sc_dev, "failed to parse cookie\n");
9293                 return;
9294         }
9295         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9296
9297         while (1) {
9298                 KASSERT(slot >= 0 && slot < dr->dr_numslots,
9299                     ("%s:%d: fail", __func__, __LINE__));
9300                 dr->getdesc(dr, slot, &desc, &meta);
9301
9302                 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) {
9303                         bus_dmamap_sync(dr->dr_txring_dtag, meta->mt_dmap,
9304                             BUS_DMASYNC_POSTWRITE);
9305                 } else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) {
9306                         bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9307                 }
9308
9309                 if (meta->mt_islast) {
9310                         KASSERT(meta->mt_m != NULL,
9311                             ("%s:%d: fail", __func__, __LINE__));
9312
9313                         ni = meta->mt_ni;
9314                         m = meta->mt_m;
9315                         if (ni != NULL) {
9316                                 /*
9317                                  * Do any tx complete callback. Note this must
9318                                  * be done before releasing the node reference.
9319                                  */
9320                                 if (m->m_flags & M_TXCB)
9321                                         ieee80211_process_callback(ni, m, 0);
9322                                 ieee80211_free_node(ni);
9323                                 meta->mt_ni = NULL;
9324                         }
9325                         m_freem(m);
9326                         meta->mt_m = NULL;
9327                 } else {
9328                         KASSERT(meta->mt_m == NULL,
9329                             ("%s:%d: fail", __func__, __LINE__));
9330                 }
9331
9332                 dr->dr_usedslot--;
9333                 if (meta->mt_islast) {
9334                         ifp->if_opackets++;
9335                         break;
9336                 }
9337                 slot = bwn_dma_nextslot(dr, slot);
9338         }
9339         sc->sc_watchdog_timer = 0;
9340         if (dr->dr_stop) {
9341                 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9342                     ("%s:%d: fail", __func__, __LINE__));
9343                 ifq_clr_oactive(&ifp->if_snd);
9344                 dr->dr_stop = 0;
9345         }
9346 }
9347
9348 static void
9349 bwn_pio_handle_txeof(struct bwn_mac *mac,
9350     const struct bwn_txstatus *status)
9351 {
9352         struct bwn_pio_txqueue *tq;
9353         struct bwn_pio_txpkt *tp = NULL;
9354         struct bwn_softc *sc = mac->mac_sc;
9355         struct ifnet *ifp = sc->sc_ifp;
9356
9357         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9358         if (tq == NULL)
9359                 return;
9360
9361         tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9362         tq->tq_free++;
9363
9364         if (tp->tp_ni != NULL) {
9365                 /*
9366                  * Do any tx complete callback.  Note this must
9367                  * be done before releasing the node reference.
9368                  */
9369                 if (tp->tp_m->m_flags & M_TXCB)
9370                         ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9371                 ieee80211_free_node(tp->tp_ni);
9372                 tp->tp_ni = NULL;
9373         }
9374         m_freem(tp->tp_m);
9375         tp->tp_m = NULL;
9376         TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9377
9378         ifp->if_opackets++;
9379
9380         sc->sc_watchdog_timer = 0;
9381         if (tq->tq_stop) {
9382                 ifq_clr_oactive(&ifp->if_snd);
9383                 tq->tq_stop = 0;
9384         }
9385 }
9386
9387 static void
9388 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9389 {
9390         struct bwn_softc *sc = mac->mac_sc;
9391         struct bwn_phy *phy = &mac->mac_phy;
9392         struct ifnet *ifp = sc->sc_ifp;
9393         struct ieee80211com *ic = ifp->if_l2com;
9394         unsigned long now;
9395         int result;
9396
9397         BWN_GETTIME(now);
9398
9399         if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9400                 return;
9401         phy->nexttime = now + 2 * 1000;
9402
9403         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9404             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9405                 return;
9406
9407         if (phy->recalc_txpwr != NULL) {
9408                 result = phy->recalc_txpwr(mac,
9409                     (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9410                 if (result == BWN_TXPWR_RES_DONE)
9411                         return;
9412                 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9413                     ("%s: fail", __func__));
9414                 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9415
9416                 ieee80211_runtask(ic, &mac->mac_txpower);
9417         }
9418 }
9419
9420 static uint16_t
9421 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9422 {
9423
9424         return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9425 }
9426
9427 static uint32_t
9428 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9429 {
9430
9431         return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9432 }
9433
9434 static void
9435 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9436 {
9437
9438         BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9439 }
9440
9441 static void
9442 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9443 {
9444
9445         BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9446 }
9447
9448 static int
9449 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9450 {
9451
9452         switch (rate) {
9453         /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9454         case 12:
9455                 return (BWN_OFDM_RATE_6MB);
9456         case 18:
9457                 return (BWN_OFDM_RATE_9MB);
9458         case 24:
9459                 return (BWN_OFDM_RATE_12MB);
9460         case 36:
9461                 return (BWN_OFDM_RATE_18MB);
9462         case 48:
9463                 return (BWN_OFDM_RATE_24MB);
9464         case 72:
9465                 return (BWN_OFDM_RATE_36MB);
9466         case 96:
9467                 return (BWN_OFDM_RATE_48MB);
9468         case 108:
9469                 return (BWN_OFDM_RATE_54MB);
9470         /* CCK rates (NB: not IEEE std, device-specific) */
9471         case 2:
9472                 return (BWN_CCK_RATE_1MB);
9473         case 4:
9474                 return (BWN_CCK_RATE_2MB);
9475         case 11:
9476                 return (BWN_CCK_RATE_5MB);
9477         case 22:
9478                 return (BWN_CCK_RATE_11MB);
9479         }
9480
9481         device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9482         return (BWN_CCK_RATE_1MB);
9483 }
9484
9485 static int
9486 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9487     struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9488 {
9489         const struct bwn_phy *phy = &mac->mac_phy;
9490         struct bwn_softc *sc = mac->mac_sc;
9491         struct ieee80211_frame *wh;
9492         struct ieee80211_frame *protwh;
9493         struct ieee80211_frame_cts *cts;
9494         struct ieee80211_frame_rts *rts;
9495         const struct ieee80211_txparam *tp;
9496         struct ieee80211vap *vap = ni->ni_vap;
9497         struct ifnet *ifp = sc->sc_ifp;
9498         struct ieee80211com *ic = ifp->if_l2com;
9499         struct mbuf *mprot;
9500         unsigned int len;
9501         uint32_t macctl = 0;
9502         int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9503         uint16_t phyctl = 0;
9504         uint8_t rate, rate_fb;
9505
9506         wh = mtod(m, struct ieee80211_frame *);
9507         memset(txhdr, 0, sizeof(*txhdr));
9508
9509         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9510         ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9511         isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9512
9513         /*
9514          * Find TX rate
9515          */
9516         tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9517         if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9518                 rate = rate_fb = tp->mgmtrate;
9519         else if (ismcast)
9520                 rate = rate_fb = tp->mcastrate;
9521         else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9522                 rate = rate_fb = tp->ucastrate;
9523         else {
9524                 rix = ieee80211_ratectl_rate(ni, NULL, 0);
9525                 rate = ni->ni_txrate;
9526
9527                 if (rix > 0)
9528                         rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9529                             IEEE80211_RATE_VAL;
9530                 else
9531                         rate_fb = rate;
9532         }
9533
9534         sc->sc_tx_rate = rate;
9535
9536         rate = bwn_ieeerate2hwrate(sc, rate);
9537         rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9538
9539         txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9540             bwn_plcp_getcck(rate);
9541         bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9542         bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9543
9544         if ((rate_fb == rate) ||
9545             (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9546             (*(u_int16_t *)wh->i_dur == htole16(0)))
9547                 txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9548         else
9549                 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9550                     m->m_pkthdr.len, rate, isshort);
9551
9552         /* XXX TX encryption */
9553         bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9554             (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9555             (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9556             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9557         bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9558             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9559
9560         txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9561             BWN_TX_EFT_FB_CCK;
9562         txhdr->chan = phy->chan;
9563         phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9564             BWN_TX_PHY_ENC_CCK;
9565         if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9566              rate == BWN_CCK_RATE_11MB))
9567                 phyctl |= BWN_TX_PHY_SHORTPRMBL;
9568
9569         /* XXX TX antenna selection */
9570
9571         switch (bwn_antenna_sanitize(mac, 0)) {
9572         case 0:
9573                 phyctl |= BWN_TX_PHY_ANT01AUTO;
9574                 break;
9575         case 1:
9576                 phyctl |= BWN_TX_PHY_ANT0;
9577                 break;
9578         case 2:
9579                 phyctl |= BWN_TX_PHY_ANT1;
9580                 break;
9581         case 3:
9582                 phyctl |= BWN_TX_PHY_ANT2;
9583                 break;
9584         case 4:
9585                 phyctl |= BWN_TX_PHY_ANT3;
9586                 break;
9587         default:
9588                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9589         }
9590
9591         if (!ismcast)
9592                 macctl |= BWN_TX_MAC_ACK;
9593
9594         macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9595         if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9596             m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9597                 macctl |= BWN_TX_MAC_LONGFRAME;
9598
9599         if (ic->ic_flags & IEEE80211_F_USEPROT) {
9600                 /* XXX RTS rate is always 1MB??? */
9601                 rts_rate = BWN_CCK_RATE_1MB;
9602                 rts_rate_fb = bwn_get_fbrate(rts_rate);
9603
9604                 protdur = ieee80211_compute_duration(ic->ic_rt,
9605                     m->m_pkthdr.len, rate, isshort) +
9606                     + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9607
9608                 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9609                         cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9610                             (txhdr->body.old.rts_frame) :
9611                             (txhdr->body.new.rts_frame));
9612                         mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9613                             protdur);
9614                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9615                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9616                             mprot->m_pkthdr.len);
9617                         m_freem(mprot);
9618                         macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9619                         len = sizeof(struct ieee80211_frame_cts);
9620                 } else {
9621                         rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9622                             (txhdr->body.old.rts_frame) :
9623                             (txhdr->body.new.rts_frame));
9624                         protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9625                             isshort);
9626                         mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9627                             wh->i_addr2, protdur);
9628                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9629                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9630                             mprot->m_pkthdr.len);
9631                         m_freem(mprot);
9632                         macctl |= BWN_TX_MAC_SEND_RTSCTS;
9633                         len = sizeof(struct ieee80211_frame_rts);
9634                 }
9635                 len += IEEE80211_CRC_LEN;
9636                 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9637                     &txhdr->body.old.rts_plcp :
9638                     &txhdr->body.new.rts_plcp), len, rts_rate);
9639                 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9640                     rts_rate_fb);
9641
9642                 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9643                     (&txhdr->body.old.rts_frame) :
9644                     (&txhdr->body.new.rts_frame));
9645                 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9646
9647                 if (BWN_ISOFDMRATE(rts_rate)) {
9648                         txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9649                         txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9650                 } else {
9651                         txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9652                         txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9653                 }
9654                 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9655                     BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9656         }
9657
9658         if (BWN_ISOLDFMT(mac))
9659                 txhdr->body.old.cookie = htole16(cookie);
9660         else
9661                 txhdr->body.new.cookie = htole16(cookie);
9662
9663         txhdr->macctl = htole32(macctl);
9664         txhdr->phyctl = htole16(phyctl);
9665
9666         /*
9667          * TX radio tap
9668          */
9669         if (ieee80211_radiotap_active_vap(vap)) {
9670                 sc->sc_tx_th.wt_flags = 0;
9671                 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
9672                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9673                 if (isshort &&
9674                     (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9675                      rate == BWN_CCK_RATE_11MB))
9676                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9677                 sc->sc_tx_th.wt_rate = rate;
9678
9679                 ieee80211_radiotap_tx(vap, m);
9680         }
9681
9682         return (0);
9683 }
9684
9685 static void
9686 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9687     const uint8_t rate)
9688 {
9689         uint32_t d, plen;
9690         uint8_t *raw = plcp->o.raw;
9691
9692         if (BWN_ISOFDMRATE(rate)) {
9693                 d = bwn_plcp_getofdm(rate);
9694                 KASSERT(!(octets & 0xf000),
9695                     ("%s:%d: fail", __func__, __LINE__));
9696                 d |= (octets << 5);
9697                 plcp->o.data = htole32(d);
9698         } else {
9699                 plen = octets * 16 / rate;
9700                 if ((octets * 16 % rate) > 0) {
9701                         plen++;
9702                         if ((rate == BWN_CCK_RATE_11MB)
9703                             && ((octets * 8 % 11) < 4)) {
9704                                 raw[1] = 0x84;
9705                         } else
9706                                 raw[1] = 0x04;
9707                 } else
9708                         raw[1] = 0x04;
9709                 plcp->o.data |= htole32(plen << 16);
9710                 raw[0] = bwn_plcp_getcck(rate);
9711         }
9712 }
9713
9714 static uint8_t
9715 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9716 {
9717         struct bwn_softc *sc = mac->mac_sc;
9718         uint8_t mask;
9719
9720         if (n == 0)
9721                 return (0);
9722         if (mac->mac_phy.gmode)
9723                 mask = siba_sprom_get_ant_bg(sc->sc_dev);
9724         else
9725                 mask = siba_sprom_get_ant_a(sc->sc_dev);
9726         if (!(mask & (1 << (n - 1))))
9727                 return (0);
9728         return (n);
9729 }
9730
9731 static uint8_t
9732 bwn_get_fbrate(uint8_t bitrate)
9733 {
9734         switch (bitrate) {
9735         case BWN_CCK_RATE_1MB:
9736                 return (BWN_CCK_RATE_1MB);
9737         case BWN_CCK_RATE_2MB:
9738                 return (BWN_CCK_RATE_1MB);
9739         case BWN_CCK_RATE_5MB:
9740                 return (BWN_CCK_RATE_2MB);
9741         case BWN_CCK_RATE_11MB:
9742                 return (BWN_CCK_RATE_5MB);
9743         case BWN_OFDM_RATE_6MB:
9744                 return (BWN_CCK_RATE_5MB);
9745         case BWN_OFDM_RATE_9MB:
9746                 return (BWN_OFDM_RATE_6MB);
9747         case BWN_OFDM_RATE_12MB:
9748                 return (BWN_OFDM_RATE_9MB);
9749         case BWN_OFDM_RATE_18MB:
9750                 return (BWN_OFDM_RATE_12MB);
9751         case BWN_OFDM_RATE_24MB:
9752                 return (BWN_OFDM_RATE_18MB);
9753         case BWN_OFDM_RATE_36MB:
9754                 return (BWN_OFDM_RATE_24MB);
9755         case BWN_OFDM_RATE_48MB:
9756                 return (BWN_OFDM_RATE_36MB);
9757         case BWN_OFDM_RATE_54MB:
9758                 return (BWN_OFDM_RATE_48MB);
9759         }
9760         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9761         return (0);
9762 }
9763
9764 static uint32_t
9765 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9766     uint32_t ctl, const void *_data, int len)
9767 {
9768         struct bwn_softc *sc = mac->mac_sc;
9769         uint32_t value = 0;
9770         const uint8_t *data = _data;
9771
9772         ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9773             BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9774         bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9775
9776         siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9777             tq->tq_base + BWN_PIO8_TXDATA);
9778         if (len & 3) {
9779                 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9780                     BWN_PIO8_TXCTL_24_31);
9781                 data = &(data[len - 1]);
9782                 switch (len & 3) {
9783                 case 3:
9784                         ctl |= BWN_PIO8_TXCTL_16_23;
9785                         value |= (uint32_t)(*data) << 16;
9786                         data--;
9787                 case 2:
9788                         ctl |= BWN_PIO8_TXCTL_8_15;
9789                         value |= (uint32_t)(*data) << 8;
9790                         data--;
9791                 case 1:
9792                         value |= (uint32_t)(*data);
9793                 }
9794                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9795                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9796         }
9797
9798         return (ctl);
9799 }
9800
9801 static void
9802 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9803     uint16_t offset, uint32_t value)
9804 {
9805
9806         BWN_WRITE_4(mac, tq->tq_base + offset, value);
9807 }
9808
9809 static uint16_t
9810 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9811     uint16_t ctl, const void *_data, int len)
9812 {
9813         struct bwn_softc *sc = mac->mac_sc;
9814         const uint8_t *data = _data;
9815
9816         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9817         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9818
9819         siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9820             tq->tq_base + BWN_PIO_TXDATA);
9821         if (len & 1) {
9822                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9823                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9824                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9825         }
9826
9827         return (ctl);
9828 }
9829
9830 static uint16_t
9831 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9832     uint16_t ctl, struct mbuf *m0)
9833 {
9834         int i, j = 0;
9835         uint16_t data = 0;
9836         const uint8_t *buf;
9837         struct mbuf *m = m0;
9838
9839         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9840         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9841
9842         for (; m != NULL; m = m->m_next) {
9843                 buf = mtod(m, const uint8_t *);
9844                 for (i = 0; i < m->m_len; i++) {
9845                         if (!((j++) % 2))
9846                                 data |= buf[i];
9847                         else {
9848                                 data |= (buf[i] << 8);
9849                                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9850                                 data = 0;
9851                         }
9852                 }
9853         }
9854         if (m0->m_pkthdr.len % 2) {
9855                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9856                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9857                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9858         }
9859
9860         return (ctl);
9861 }
9862
9863 static void
9864 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9865 {
9866
9867         if (mac->mac_phy.type != BWN_PHYTYPE_G)
9868                 return;
9869         BWN_WRITE_2(mac, 0x684, 510 + time);
9870
9871         /*
9872          * XXX ivadasz: Linux's b43 comments this. Enabling this causes a
9873          *              a severe performance penalty (especially when sending).
9874          */
9875 #if 0
9876         bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9877 #endif
9878 }
9879
9880 static struct bwn_dma_ring *
9881 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9882 {
9883
9884         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9885                 return (mac->mac_method.dma.wme[WME_AC_BE]);
9886
9887         switch (prio) {
9888         case 3:
9889                 return (mac->mac_method.dma.wme[WME_AC_VO]);
9890         case 2:
9891                 return (mac->mac_method.dma.wme[WME_AC_VI]);
9892         case 0:
9893                 return (mac->mac_method.dma.wme[WME_AC_BE]);
9894         case 1:
9895                 return (mac->mac_method.dma.wme[WME_AC_BK]);
9896         }
9897         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9898         return (NULL);
9899 }
9900
9901 static int
9902 bwn_dma_getslot(struct bwn_dma_ring *dr)
9903 {
9904         int slot;
9905
9906         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9907         KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
9908         KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
9909
9910         slot = bwn_dma_nextslot(dr, dr->dr_curslot);
9911         KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
9912         dr->dr_curslot = slot;
9913         dr->dr_usedslot++;
9914
9915         return (slot);
9916 }
9917
9918 static int
9919 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
9920 {
9921         const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
9922         unsigned int a, b, c, d;
9923         unsigned int avg;
9924         uint32_t tmp;
9925
9926         tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
9927         a = tmp & 0xff;
9928         b = (tmp >> 8) & 0xff;
9929         c = (tmp >> 16) & 0xff;
9930         d = (tmp >> 24) & 0xff;
9931         if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
9932             c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
9933                 return (ENOENT);
9934         bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
9935             BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
9936             (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
9937
9938         if (ofdm) {
9939                 a = (a + 32) & 0x3f;
9940                 b = (b + 32) & 0x3f;
9941                 c = (c + 32) & 0x3f;
9942                 d = (d + 32) & 0x3f;
9943         }
9944
9945         avg = (a + b + c + d + 2) / 4;
9946         if (ofdm) {
9947                 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
9948                     & BWN_HF_4DB_CCK_POWERBOOST)
9949                         avg = (avg >= 13) ? (avg - 13) : 0;
9950         }
9951         return (avg);
9952 }
9953
9954 static void
9955 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
9956 {
9957         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
9958         int rfatt = *rfattp;
9959         int bbatt = *bbattp;
9960
9961         while (1) {
9962                 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
9963                         break;
9964                 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
9965                         break;
9966                 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
9967                         break;
9968                 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
9969                         break;
9970                 if (bbatt > lo->bbatt.max) {
9971                         bbatt -= 4;
9972                         rfatt += 1;
9973                         continue;
9974                 }
9975                 if (bbatt < lo->bbatt.min) {
9976                         bbatt += 4;
9977                         rfatt -= 1;
9978                         continue;
9979                 }
9980                 if (rfatt > lo->rfatt.max) {
9981                         rfatt -= 1;
9982                         bbatt += 4;
9983                         continue;
9984                 }
9985                 if (rfatt < lo->rfatt.min) {
9986                         rfatt += 1;
9987                         bbatt -= 4;
9988                         continue;
9989                 }
9990                 break;
9991         }
9992
9993         *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
9994         *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
9995 }
9996
9997 static void
9998 bwn_phy_lock(struct bwn_mac *mac)
9999 {
10000         struct bwn_softc *sc = mac->mac_sc;
10001         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10002
10003         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10004             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10005
10006         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10007                 bwn_psctl(mac, BWN_PS_AWAKE);
10008 }
10009
10010 static void
10011 bwn_phy_unlock(struct bwn_mac *mac)
10012 {
10013         struct bwn_softc *sc = mac->mac_sc;
10014         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10015
10016         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10017             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10018
10019         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10020                 bwn_psctl(mac, 0);
10021 }
10022
10023 static void
10024 bwn_rf_lock(struct bwn_mac *mac)
10025 {
10026
10027         BWN_WRITE_4(mac, BWN_MACCTL,
10028             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
10029         BWN_READ_4(mac, BWN_MACCTL);
10030         DELAY(10);
10031 }
10032
10033 static void
10034 bwn_rf_unlock(struct bwn_mac *mac)
10035 {
10036
10037         BWN_READ_2(mac, BWN_PHYVER);
10038         BWN_WRITE_4(mac, BWN_MACCTL,
10039             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10040 }
10041
10042 static struct bwn_pio_txqueue *
10043 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10044     struct bwn_pio_txpkt **pack)
10045 {
10046         struct bwn_pio *pio = &mac->mac_method.pio;
10047         struct bwn_pio_txqueue *tq = NULL;
10048         unsigned int index;
10049
10050         switch (cookie & 0xf000) {
10051         case 0x1000:
10052                 tq = &pio->wme[WME_AC_BK];
10053                 break;
10054         case 0x2000:
10055                 tq = &pio->wme[WME_AC_BE];
10056                 break;
10057         case 0x3000:
10058                 tq = &pio->wme[WME_AC_VI];
10059                 break;
10060         case 0x4000:
10061                 tq = &pio->wme[WME_AC_VO];
10062                 break;
10063         case 0x5000:
10064                 tq = &pio->mcast;
10065                 break;
10066         }
10067         KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10068         if (tq == NULL)
10069                 return (NULL);
10070         index = (cookie & 0x0fff);
10071         KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10072         if (index >= N(tq->tq_pkts))
10073                 return (NULL);
10074         *pack = &tq->tq_pkts[index];
10075         KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10076         return (tq);
10077 }
10078
10079 static void
10080 bwn_txpwr(void *arg, int npending)
10081 {
10082         struct bwn_mac *mac = arg;
10083
10084         wlan_serialize_enter();
10085         if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10086             mac->mac_phy.set_txpwr != NULL)
10087                 mac->mac_phy.set_txpwr(mac);
10088         wlan_serialize_exit();
10089 }
10090
10091 static void
10092 bwn_task_15s(struct bwn_mac *mac)
10093 {
10094         uint16_t reg;
10095
10096         if (mac->mac_fw.opensource) {
10097                 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10098                 if (reg) {
10099                         bwn_restart(mac, "fw watchdog");
10100                         return;
10101                 }
10102                 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10103         }
10104         if (mac->mac_phy.task_15s)
10105                 mac->mac_phy.task_15s(mac);
10106
10107         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10108 }
10109
10110 static void
10111 bwn_task_30s(struct bwn_mac *mac)
10112 {
10113
10114         if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10115                 return;
10116         mac->mac_noise.noi_running = 1;
10117         mac->mac_noise.noi_nsamples = 0;
10118
10119         bwn_noise_gensample(mac);
10120 }
10121
10122 static void
10123 bwn_task_60s(struct bwn_mac *mac)
10124 {
10125
10126         if (mac->mac_phy.task_60s)
10127                 mac->mac_phy.task_60s(mac);
10128         bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10129 }
10130
10131 static void
10132 bwn_tasks(void *arg)
10133 {
10134         struct bwn_mac *mac = arg;
10135         struct bwn_softc *sc = mac->mac_sc;
10136
10137         wlan_serialize_enter();
10138
10139         if (mac->mac_status != BWN_MAC_STATUS_STARTED) {
10140                 wlan_serialize_exit();
10141                 return;
10142         }
10143
10144         if (mac->mac_task_state % 4 == 0)
10145                 bwn_task_60s(mac);
10146         if (mac->mac_task_state % 2 == 0)
10147                 bwn_task_30s(mac);
10148         bwn_task_15s(mac);
10149
10150         mac->mac_task_state++;
10151         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10152         wlan_serialize_exit();
10153 }
10154
10155 static int
10156 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10157 {
10158         struct bwn_softc *sc = mac->mac_sc;
10159
10160         KASSERT(a == 0, ("not support APHY\n"));
10161
10162         switch (plcp->o.raw[0] & 0xf) {
10163         case 0xb:
10164                 return (BWN_OFDM_RATE_6MB);
10165         case 0xf:
10166                 return (BWN_OFDM_RATE_9MB);
10167         case 0xa:
10168                 return (BWN_OFDM_RATE_12MB);
10169         case 0xe:
10170                 return (BWN_OFDM_RATE_18MB);
10171         case 0x9:
10172                 return (BWN_OFDM_RATE_24MB);
10173         case 0xd:
10174                 return (BWN_OFDM_RATE_36MB);
10175         case 0x8:
10176                 return (BWN_OFDM_RATE_48MB);
10177         case 0xc:
10178                 return (BWN_OFDM_RATE_54MB);
10179         }
10180         device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10181             plcp->o.raw[0] & 0xf);
10182         return (-1);
10183 }
10184
10185 static int
10186 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10187 {
10188         struct bwn_softc *sc = mac->mac_sc;
10189
10190         switch (plcp->o.raw[0]) {
10191         case 0x0a:
10192                 return (BWN_CCK_RATE_1MB);
10193         case 0x14:
10194                 return (BWN_CCK_RATE_2MB);
10195         case 0x37:
10196                 return (BWN_CCK_RATE_5MB);
10197         case 0x6e:
10198                 return (BWN_CCK_RATE_11MB);
10199         }
10200         device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10201         return (-1);
10202 }
10203
10204 static void
10205 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10206     const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10207     int rssi, int noise)
10208 {
10209         struct bwn_softc *sc = mac->mac_sc;
10210         const struct ieee80211_frame_min *wh;
10211         uint64_t tsf;
10212         uint16_t low_mactime_now;
10213
10214         if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10215                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10216
10217         wh = mtod(m, const struct ieee80211_frame_min *);
10218         if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
10219                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10220
10221         bwn_tsf_read(mac, &tsf);
10222         low_mactime_now = tsf;
10223         tsf = tsf & ~0xffffULL;
10224         tsf += le16toh(rxhdr->mac_time);
10225         if (low_mactime_now < le16toh(rxhdr->mac_time))
10226                 tsf -= 0x10000;
10227
10228         sc->sc_rx_th.wr_tsf = tsf;
10229         sc->sc_rx_th.wr_rate = rate;
10230         sc->sc_rx_th.wr_antsignal = rssi;
10231         sc->sc_rx_th.wr_antnoise = noise;
10232 }
10233
10234 static void
10235 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10236 {
10237         uint32_t low, high;
10238
10239         KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10240             ("%s:%d: fail", __func__, __LINE__));
10241
10242         low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10243         high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10244         *tsf = high;
10245         *tsf <<= 32;
10246         *tsf |= low;
10247 }
10248
10249 static int
10250 bwn_dma_attach(struct bwn_mac *mac)
10251 {
10252         struct bwn_dma *dma = &mac->mac_method.dma;
10253         struct bwn_softc *sc = mac->mac_sc;
10254         bus_addr_t lowaddr = 0;
10255         int error;
10256
10257         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10258                 return (0);
10259
10260         KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10261
10262         mac->mac_flags |= BWN_MAC_FLAG_DMA;
10263
10264         dma->dmatype = bwn_dma_gettype(mac);
10265         if (dma->dmatype == BWN_DMA_30BIT)
10266                 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10267         else if (dma->dmatype == BWN_DMA_32BIT)
10268                 lowaddr = BUS_SPACE_MAXADDR_32BIT;
10269         else
10270                 lowaddr = BUS_SPACE_MAXADDR;
10271
10272         /*
10273          * Create top level DMA tag
10274          */
10275         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
10276                                BWN_ALIGN, 0,            /* alignment, bounds */
10277                                lowaddr,                 /* lowaddr */
10278                                BUS_SPACE_MAXADDR,       /* highaddr */
10279                                NULL, NULL,              /* filter, filterarg */
10280                                MAXBSIZE,                /* maxsize */
10281                                BUS_SPACE_UNRESTRICTED,  /* nsegments */
10282                                BUS_SPACE_MAXSIZE,       /* maxsegsize */
10283                                0,                       /* flags */
10284                                &dma->parent_dtag);
10285         if (error) {
10286                 device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10287                 return (error);
10288         }
10289
10290         /*
10291          * Create TX/RX mbuf DMA tag
10292          */
10293         error = bus_dma_tag_create(dma->parent_dtag,
10294                                 4,
10295                                 0,
10296                                 BUS_SPACE_MAXADDR,
10297                                 BUS_SPACE_MAXADDR,
10298                                 NULL, NULL,
10299                                 MCLBYTES,
10300                                 1,
10301                                 BUS_SPACE_MAXSIZE_32BIT,
10302                                 0,
10303                                 &dma->rxbuf_dtag);
10304         if (error) {
10305                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10306                 goto fail0;
10307         }
10308         error = bus_dma_tag_create(dma->parent_dtag,
10309                                 4,
10310                                 0,
10311                                 BUS_SPACE_MAXADDR,
10312                                 BUS_SPACE_MAXADDR,
10313                                 NULL, NULL,
10314                                 MCLBYTES,
10315                                 1,
10316                                 BUS_SPACE_MAXSIZE_32BIT,
10317                                 0,
10318                                 &dma->txbuf_dtag);
10319         if (error) {
10320                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10321                 goto fail1;
10322         }
10323
10324         dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10325         if (dma->wme[WME_AC_BK] == NULL)
10326                 goto fail2;
10327
10328         dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10329         if (dma->wme[WME_AC_BE] == NULL)
10330                 goto fail3;
10331
10332         dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10333         if (dma->wme[WME_AC_VI] == NULL)
10334                 goto fail4;
10335
10336         dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10337         if (dma->wme[WME_AC_VO] == NULL)
10338                 goto fail5;
10339
10340         dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10341         if (dma->mcast == NULL)
10342                 goto fail6;
10343         dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10344         if (dma->rx == NULL)
10345                 goto fail7;
10346
10347         return (error);
10348
10349 fail7:  bwn_dma_ringfree(&dma->mcast);
10350 fail6:  bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10351 fail5:  bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10352 fail4:  bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10353 fail3:  bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10354 fail2:  bus_dma_tag_destroy(dma->txbuf_dtag);
10355 fail1:  bus_dma_tag_destroy(dma->rxbuf_dtag);
10356 fail0:  bus_dma_tag_destroy(dma->parent_dtag);
10357         return (error);
10358 }
10359
10360 static struct bwn_dma_ring *
10361 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10362     uint16_t cookie, int *slot)
10363 {
10364         struct bwn_dma *dma = &mac->mac_method.dma;
10365         struct bwn_dma_ring *dr;
10366         struct bwn_softc *sc = mac->mac_sc;
10367
10368         switch (cookie & 0xf000) {
10369         case 0x1000:
10370                 dr = dma->wme[WME_AC_BK];
10371                 break;
10372         case 0x2000:
10373                 dr = dma->wme[WME_AC_BE];
10374                 break;
10375         case 0x3000:
10376                 dr = dma->wme[WME_AC_VI];
10377                 break;
10378         case 0x4000:
10379                 dr = dma->wme[WME_AC_VO];
10380                 break;
10381         case 0x5000:
10382                 dr = dma->mcast;
10383                 break;
10384         default:
10385                 dr = NULL;
10386                 KASSERT(0 == 1,
10387                     ("invalid cookie value %d", cookie & 0xf000));
10388         }
10389         *slot = (cookie & 0x0fff);
10390         if (*slot < 0 || *slot >= dr->dr_numslots) {
10391                 /*
10392                  * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10393                  * that it occurs events which have same H/W sequence numbers.
10394                  * When it's occurred just prints a WARNING msgs and ignores.
10395                  */
10396                 KASSERT(status->seq == dma->lastseq,
10397                     ("%s:%d: fail", __func__, __LINE__));
10398                 device_printf(sc->sc_dev,
10399                     "out of slot ranges (0 < %d < %d)\n", *slot,
10400                     dr->dr_numslots);
10401                 return (NULL);
10402         }
10403         dma->lastseq = status->seq;
10404         return (dr);
10405 }
10406
10407 static void
10408 bwn_dma_stop(struct bwn_mac *mac)
10409 {
10410         struct bwn_dma *dma;
10411
10412         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10413                 return;
10414         dma = &mac->mac_method.dma;
10415
10416         bwn_dma_ringstop(&dma->rx);
10417         bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10418         bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10419         bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10420         bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10421         bwn_dma_ringstop(&dma->mcast);
10422 }
10423
10424 static void
10425 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10426 {
10427
10428         if (dr == NULL)
10429                 return;
10430
10431         bwn_dma_cleanup(*dr);
10432 }
10433
10434 static void
10435 bwn_pio_stop(struct bwn_mac *mac)
10436 {
10437         struct bwn_pio *pio;
10438
10439         if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10440                 return;
10441         pio = &mac->mac_method.pio;
10442
10443         bwn_destroy_queue_tx(&pio->mcast);
10444         bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10445         bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10446         bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10447         bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10448 }
10449
10450 static void
10451 bwn_led_attach(struct bwn_mac *mac)
10452 {
10453         struct bwn_softc *sc = mac->mac_sc;
10454         const uint8_t *led_act = NULL;
10455         uint16_t val[BWN_LED_MAX];
10456         int i;
10457
10458         sc->sc_led_idle = (2350 * hz) / 1000;
10459         sc->sc_led_blink = 1;
10460
10461         for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10462                 if (siba_get_pci_subvendor(sc->sc_dev) ==
10463                     bwn_vendor_led_act[i].vid) {
10464                         led_act = bwn_vendor_led_act[i].led_act;
10465                         break;
10466                 }
10467         }
10468         if (led_act == NULL)
10469                 led_act = bwn_default_led_act;
10470
10471         val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10472         val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10473         val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10474         val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10475
10476         for (i = 0; i < BWN_LED_MAX; ++i) {
10477                 struct bwn_led *led = &sc->sc_leds[i];
10478
10479                 if (val[i] == 0xff) {
10480                         led->led_act = led_act[i];
10481                 } else {
10482                         if (val[i] & BWN_LED_ACT_LOW)
10483                                 led->led_flags |= BWN_LED_F_ACTLOW;
10484                         led->led_act = val[i] & BWN_LED_ACT_MASK;
10485                 }
10486                 led->led_mask = (1 << i);
10487
10488                 if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10489                     led->led_act == BWN_LED_ACT_BLINK_POLL ||
10490                     led->led_act == BWN_LED_ACT_BLINK) {
10491                         led->led_flags |= BWN_LED_F_BLINK;
10492                         if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10493                                 led->led_flags |= BWN_LED_F_POLLABLE;
10494                         else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10495                                 led->led_flags |= BWN_LED_F_SLOW;
10496
10497                         if (sc->sc_blink_led == NULL) {
10498                                 sc->sc_blink_led = led;
10499                                 if (led->led_flags & BWN_LED_F_SLOW)
10500                                         BWN_LED_SLOWDOWN(sc->sc_led_idle);
10501                         }
10502                 }
10503
10504                 DPRINTF(sc, BWN_DEBUG_LED,
10505                     "%dth led, act %d, lowact %d\n", i,
10506                     led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10507         }
10508         callout_init(&sc->sc_led_blink_ch);
10509 }
10510
10511 static __inline uint16_t
10512 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10513 {
10514
10515         if (led->led_flags & BWN_LED_F_ACTLOW)
10516                 on = !on;
10517         if (on)
10518                 val |= led->led_mask;
10519         else
10520                 val &= ~led->led_mask;
10521         return val;
10522 }
10523
10524 static void
10525 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10526 {
10527         struct bwn_softc *sc = mac->mac_sc;
10528         struct ifnet *ifp = sc->sc_ifp;
10529         struct ieee80211com *ic = ifp->if_l2com;
10530         uint16_t val;
10531         int i;
10532
10533         if (nstate == IEEE80211_S_INIT) {
10534                 callout_stop(&sc->sc_led_blink_ch);
10535                 sc->sc_led_blinking = 0;
10536         }
10537
10538         if ((ic->ic_ifp->if_flags & IFF_RUNNING) == 0)
10539                 return;
10540
10541         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10542         for (i = 0; i < BWN_LED_MAX; ++i) {
10543                 struct bwn_led *led = &sc->sc_leds[i];
10544                 int on;
10545
10546                 if (led->led_act == BWN_LED_ACT_UNKN ||
10547                     led->led_act == BWN_LED_ACT_NULL)
10548                         continue;
10549
10550                 if ((led->led_flags & BWN_LED_F_BLINK) &&
10551                     nstate != IEEE80211_S_INIT)
10552                         continue;
10553
10554                 switch (led->led_act) {
10555                 case BWN_LED_ACT_ON:    /* Always on */
10556                         on = 1;
10557                         break;
10558                 case BWN_LED_ACT_OFF:   /* Always off */
10559                 case BWN_LED_ACT_5GHZ:  /* TODO: 11A */
10560                         on = 0;
10561                         break;
10562                 default:
10563                         on = 1;
10564                         switch (nstate) {
10565                         case IEEE80211_S_INIT:
10566                                 on = 0;
10567                                 break;
10568                         case IEEE80211_S_RUN:
10569                                 if (led->led_act == BWN_LED_ACT_11G &&
10570                                     ic->ic_curmode != IEEE80211_MODE_11G)
10571                                         on = 0;
10572                                 break;
10573                         default:
10574                                 if (led->led_act == BWN_LED_ACT_ASSOC)
10575                                         on = 0;
10576                                 break;
10577                         }
10578                         break;
10579                 }
10580
10581                 val = bwn_led_onoff(led, val, on);
10582         }
10583         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10584 }
10585
10586 static void
10587 bwn_led_event(struct bwn_mac *mac, int event)
10588 {
10589         struct bwn_softc *sc = mac->mac_sc;
10590         struct bwn_led *led = sc->sc_blink_led;
10591         int rate;
10592
10593         if (event == BWN_LED_EVENT_POLL) {
10594                 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10595                         return;
10596                 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10597                         return;
10598         }
10599
10600         sc->sc_led_ticks = ticks;
10601         if (sc->sc_led_blinking)
10602                 return;
10603
10604         switch (event) {
10605         case BWN_LED_EVENT_RX:
10606                 rate = sc->sc_rx_rate;
10607                 break;
10608         case BWN_LED_EVENT_TX:
10609                 rate = sc->sc_tx_rate;
10610                 break;
10611         case BWN_LED_EVENT_POLL:
10612                 rate = 0;
10613                 break;
10614         default:
10615                 panic("unknown LED event %d\n", event);
10616                 break;
10617         }
10618         bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10619             bwn_led_duration[rate].off_dur);
10620 }
10621
10622 static void
10623 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10624 {
10625         struct bwn_softc *sc = mac->mac_sc;
10626         struct bwn_led *led = sc->sc_blink_led;
10627         uint16_t val;
10628
10629         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10630         val = bwn_led_onoff(led, val, 1);
10631         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10632
10633         if (led->led_flags & BWN_LED_F_SLOW) {
10634                 BWN_LED_SLOWDOWN(on_dur);
10635                 BWN_LED_SLOWDOWN(off_dur);
10636         }
10637
10638         sc->sc_led_blinking = 1;
10639         sc->sc_led_blink_offdur = off_dur;
10640
10641         callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10642 }
10643
10644 static void
10645 bwn_led_blink_next(void *arg)
10646 {
10647         struct bwn_mac *mac = arg;
10648         struct bwn_softc *sc = mac->mac_sc;
10649         uint16_t val;
10650
10651         wlan_serialize_enter();
10652
10653         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10654         val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10655         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10656
10657         callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10658             bwn_led_blink_end, mac);
10659         wlan_serialize_exit();
10660 }
10661
10662 static void
10663 bwn_led_blink_end(void *arg)
10664 {
10665         struct bwn_mac *mac = arg;
10666         struct bwn_softc *sc = mac->mac_sc;
10667
10668         sc->sc_led_blinking = 0;
10669 }
10670
10671 static int
10672 bwn_suspend(device_t dev)
10673 {
10674         struct bwn_softc *sc = device_get_softc(dev);
10675
10676         wlan_serialize_enter();
10677         bwn_stop(sc, 1);
10678         wlan_serialize_exit();
10679
10680         return (0);
10681 }
10682
10683 static int
10684 bwn_resume(device_t dev)
10685 {
10686         struct bwn_softc *sc = device_get_softc(dev);
10687         struct ifnet *ifp = sc->sc_ifp;
10688
10689         wlan_serialize_enter();
10690         if (ifp->if_flags & IFF_UP)
10691                 bwn_init(sc);
10692         wlan_serialize_exit();
10693         return (0);
10694 }
10695
10696 static void
10697 bwn_rfswitch(void *arg)
10698 {
10699         struct bwn_softc *sc = arg;
10700         struct bwn_mac *mac = sc->sc_curmac;
10701         int cur = 0, prev = 0;
10702
10703         wlan_serialize_enter();
10704
10705         KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10706             ("%s: invalid MAC status %d", __func__, mac->mac_status));
10707
10708         if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10709                 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10710                         & BWN_RF_HWENABLED_HI_MASK))
10711                         cur = 1;
10712         } else {
10713                 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10714                     & BWN_RF_HWENABLED_LO_MASK)
10715                         cur = 1;
10716         }
10717
10718         if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10719                 prev = 1;
10720
10721         if (cur != prev) {
10722                 if (cur)
10723                         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10724                 else
10725                         mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10726
10727                 device_printf(sc->sc_dev,
10728                     "status of RF switch is changed to %s\n",
10729                     cur ? "ON" : "OFF");
10730                 if (cur != mac->mac_phy.rf_on) {
10731                         if (cur)
10732                                 bwn_rf_turnon(mac);
10733                         else
10734                                 bwn_rf_turnoff(mac);
10735                 }
10736         }
10737
10738         callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
10739         wlan_serialize_exit();
10740 }
10741
10742 static void
10743 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10744 {
10745         struct bwn_phy *phy = &mac->mac_phy;
10746         struct bwn_phy_lp *plp = &phy->phy_lp;
10747
10748         plp->plp_antenna = BWN_ANT_DEFAULT;
10749 }
10750
10751 static int
10752 bwn_phy_lp_init(struct bwn_mac *mac)
10753 {
10754         static const struct bwn_stxtable tables[] = {
10755                 { 2,  6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10756                 { 1,  8, 0x50, 0, 0x7f }, { 0,  8, 0x44, 0, 0xff },
10757                 { 1,  0, 0x4a, 0, 0xff }, { 0,  4, 0x4d, 0, 0xff },
10758                 { 1,  4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10759                 { 1,  0, 0x4f, 4, 0x0f }, { 3,  0, 0x49, 0, 0x0f },
10760                 { 4,  3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10761                 { 4,  0, 0x46, 1, 0x07 }, { 3,  8, 0x48, 4, 0x07 },
10762                 { 3, 11, 0x48, 0, 0x0f }, { 3,  4, 0x49, 4, 0x0f },
10763                 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10764                 { 6,  0, 0x52, 7, 0x01 }, { 5,  3, 0x41, 5, 0x07 },
10765                 { 5,  6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10766                 { 4, 15, 0x42, 0, 0x01 }, { 5,  0, 0x42, 1, 0x07 },
10767                 { 4, 11, 0x43, 4, 0x0f }, { 4,  7, 0x43, 0, 0x0f },
10768                 { 4,  6, 0x45, 1, 0x01 }, { 2,  7, 0x40, 4, 0x0f },
10769                 { 2, 11, 0x40, 0, 0x0f }
10770         };
10771         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10772         struct bwn_softc *sc = mac->mac_sc;
10773         const struct bwn_stxtable *st;
10774         struct ifnet *ifp = sc->sc_ifp;
10775         struct ieee80211com *ic = ifp->if_l2com;
10776         int i, error;
10777         uint16_t tmp;
10778
10779         bwn_phy_lp_readsprom(mac);      /* XXX bad place */
10780         bwn_phy_lp_bbinit(mac);
10781
10782         /* initialize RF */
10783         BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10784         DELAY(1);
10785         BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10786         DELAY(1);
10787
10788         if (mac->mac_phy.rf_ver == 0x2062)
10789                 bwn_phy_lp_b2062_init(mac);
10790         else {
10791                 bwn_phy_lp_b2063_init(mac);
10792
10793                 /* synchronize stx table. */
10794                 for (i = 0; i < N(tables); i++) {
10795                         st = &tables[i];
10796                         tmp = BWN_RF_READ(mac, st->st_rfaddr);
10797                         tmp >>= st->st_rfshift;
10798                         tmp <<= st->st_physhift;
10799                         BWN_PHY_SETMASK(mac,
10800                             BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10801                             ~(st->st_mask << st->st_physhift), tmp);
10802                 }
10803
10804                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10805                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10806         }
10807
10808         /* calibrate RC */
10809         if (mac->mac_phy.rev >= 2)
10810                 bwn_phy_lp_rxcal_r2(mac);
10811         else if (!plp->plp_rccap) {
10812                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10813                         bwn_phy_lp_rccal_r12(mac);
10814         } else
10815                 bwn_phy_lp_set_rccap(mac);
10816
10817         error = bwn_phy_lp_switch_channel(mac, 7);
10818         if (error)
10819                 device_printf(sc->sc_dev,
10820                     "failed to change channel 7 (%d)\n", error);
10821         bwn_phy_lp_txpctl_init(mac);
10822         bwn_phy_lp_calib(mac);
10823         return (0);
10824 }
10825
10826 static uint16_t
10827 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10828 {
10829
10830         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10831         return (BWN_READ_2(mac, BWN_PHYDATA));
10832 }
10833
10834 static void
10835 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10836 {
10837
10838         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10839         BWN_WRITE_2(mac, BWN_PHYDATA, value);
10840 }
10841
10842 static void
10843 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10844     uint16_t set)
10845 {
10846
10847         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10848         BWN_WRITE_2(mac, BWN_PHYDATA,
10849             (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10850 }
10851
10852 static uint16_t
10853 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10854 {
10855
10856         KASSERT(reg != 1, ("unaccessible register %d", reg));
10857         if (mac->mac_phy.rev < 2 && reg != 0x4001)
10858                 reg |= 0x100;
10859         if (mac->mac_phy.rev >= 2)
10860                 reg |= 0x200;
10861         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10862         return BWN_READ_2(mac, BWN_RFDATALO);
10863 }
10864
10865 static void
10866 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10867 {
10868
10869         KASSERT(reg != 1, ("unaccessible register %d", reg));
10870         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10871         BWN_WRITE_2(mac, BWN_RFDATALO, value);
10872 }
10873
10874 static void
10875 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10876 {
10877
10878         if (on) {
10879                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10880                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10881                     (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10882                 return;
10883         }
10884
10885         if (mac->mac_phy.rev >= 2) {
10886                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10887                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10888                 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10889                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10890                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
10891                 return;
10892         }
10893
10894         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
10895         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10896         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
10897         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
10898 }
10899
10900 static int
10901 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
10902 {
10903         struct bwn_phy *phy = &mac->mac_phy;
10904         struct bwn_phy_lp *plp = &phy->phy_lp;
10905         int error;
10906
10907         if (phy->rf_ver == 0x2063) {
10908                 error = bwn_phy_lp_b2063_switch_channel(mac, chan);
10909                 if (error)
10910                         return (error);
10911         } else {
10912                 error = bwn_phy_lp_b2062_switch_channel(mac, chan);
10913                 if (error)
10914                         return (error);
10915                 bwn_phy_lp_set_anafilter(mac, chan);
10916                 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
10917         }
10918
10919         plp->plp_chan = chan;
10920         BWN_WRITE_2(mac, BWN_CHANNEL, chan);
10921         return (0);
10922 }
10923
10924 static uint32_t
10925 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
10926 {
10927         struct bwn_softc *sc = mac->mac_sc;
10928         struct ifnet *ifp = sc->sc_ifp;
10929         struct ieee80211com *ic = ifp->if_l2com;
10930
10931         return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
10932 }
10933
10934 static void
10935 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
10936 {
10937         struct bwn_phy *phy = &mac->mac_phy;
10938         struct bwn_phy_lp *plp = &phy->phy_lp;
10939
10940         if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
10941                 return;
10942
10943         bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
10944         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
10945         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
10946         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
10947         plp->plp_antenna = antenna;
10948 }
10949
10950 static void
10951 bwn_phy_lp_task_60s(struct bwn_mac *mac)
10952 {
10953
10954         bwn_phy_lp_calib(mac);
10955 }
10956
10957 static void
10958 bwn_phy_lp_readsprom(struct bwn_mac *mac)
10959 {
10960         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10961         struct bwn_softc *sc = mac->mac_sc;
10962         struct ifnet *ifp = sc->sc_ifp;
10963         struct ieee80211com *ic = ifp->if_l2com;
10964
10965         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
10966                 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
10967                 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
10968                 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
10969                 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
10970                 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
10971                 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
10972                 return;
10973         }
10974
10975         plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
10976         plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
10977         plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
10978         plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
10979         plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
10980         plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
10981         plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
10982         plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
10983 }
10984
10985 static void
10986 bwn_phy_lp_bbinit(struct bwn_mac *mac)
10987 {
10988
10989         bwn_phy_lp_tblinit(mac);
10990         if (mac->mac_phy.rev >= 2)
10991                 bwn_phy_lp_bbinit_r2(mac);
10992         else
10993                 bwn_phy_lp_bbinit_r01(mac);
10994 }
10995
10996 static void
10997 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
10998 {
10999         struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
11000         struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
11001         struct bwn_softc *sc = mac->mac_sc;
11002         struct ifnet *ifp = sc->sc_ifp;
11003         struct ieee80211com *ic = ifp->if_l2com;
11004
11005         bwn_phy_lp_set_txgain(mac,
11006             IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
11007         bwn_phy_lp_set_bbmult(mac, 150);
11008 }
11009
11010 static void
11011 bwn_phy_lp_calib(struct bwn_mac *mac)
11012 {
11013         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11014         struct bwn_softc *sc = mac->mac_sc;
11015         struct ifnet *ifp = sc->sc_ifp;
11016         struct ieee80211com *ic = ifp->if_l2com;
11017         const struct bwn_rxcompco *rc = NULL;
11018         struct bwn_txgain ogain;
11019         int i, omode, oafeovr, orf, obbmult;
11020         uint8_t mode, fc = 0;
11021
11022         if (plp->plp_chanfullcal != plp->plp_chan) {
11023                 plp->plp_chanfullcal = plp->plp_chan;
11024                 fc = 1;
11025         }
11026
11027         bwn_mac_suspend(mac);
11028
11029         /* BlueTooth Coexistance Override */
11030         BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
11031         BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
11032
11033         if (mac->mac_phy.rev >= 2)
11034                 bwn_phy_lp_digflt_save(mac);
11035         bwn_phy_lp_get_txpctlmode(mac);
11036         mode = plp->plp_txpctlmode;
11037         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11038         if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
11039                 bwn_phy_lp_bugfix(mac);
11040         if (mac->mac_phy.rev >= 2 && fc == 1) {
11041                 bwn_phy_lp_get_txpctlmode(mac);
11042                 omode = plp->plp_txpctlmode;
11043                 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11044                 if (oafeovr)
11045                         ogain = bwn_phy_lp_get_txgain(mac);
11046                 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11047                 obbmult = bwn_phy_lp_get_bbmult(mac);
11048                 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11049                 if (oafeovr)
11050                         bwn_phy_lp_set_txgain(mac, &ogain);
11051                 bwn_phy_lp_set_bbmult(mac, obbmult);
11052                 bwn_phy_lp_set_txpctlmode(mac, omode);
11053                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11054         }
11055         bwn_phy_lp_set_txpctlmode(mac, mode);
11056         if (mac->mac_phy.rev >= 2)
11057                 bwn_phy_lp_digflt_restore(mac);
11058
11059         /* do RX IQ Calculation; assumes that noise is true. */
11060         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11061                 for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11062                         if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11063                                 rc = &bwn_rxcompco_5354[i];
11064                 }
11065         } else if (mac->mac_phy.rev >= 2)
11066                 rc = &bwn_rxcompco_r2;
11067         else {
11068                 for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11069                         if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11070                                 rc = &bwn_rxcompco_r12[i];
11071                 }
11072         }
11073         if (rc == NULL)
11074                 goto fail;
11075
11076         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11077         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11078
11079         bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11080
11081         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11082                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11083                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11084         } else {
11085                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11086                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11087         }
11088
11089         bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11090         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11091         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11092         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11093         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11094         bwn_phy_lp_set_deaf(mac, 0);
11095         /* XXX no checking return value? */
11096         (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11097         bwn_phy_lp_clear_deaf(mac, 0);
11098         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11099         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11100         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11101
11102         /* disable RX GAIN override. */
11103         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11104         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11105         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11106         if (mac->mac_phy.rev >= 2) {
11107                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11108                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11109                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11110                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11111                 }
11112         } else {
11113                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11114         }
11115
11116         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11117         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11118 fail:
11119         bwn_mac_enable(mac);
11120 }
11121
11122 static void
11123 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11124 {
11125
11126         if (on) {
11127                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11128                 return;
11129         }
11130
11131         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11132         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11133 }
11134
11135 static int
11136 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11137 {
11138         static const struct bwn_b206x_chan *bc = NULL;
11139         struct bwn_softc *sc = mac->mac_sc;
11140         uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11141             tmp[6];
11142         uint16_t old, scale, tmp16;
11143         int i, div;
11144
11145         for (i = 0; i < N(bwn_b2063_chantable); i++) {
11146                 if (bwn_b2063_chantable[i].bc_chan == chan) {
11147                         bc = &bwn_b2063_chantable[i];
11148                         break;
11149                 }
11150         }
11151         if (bc == NULL)
11152                 return (EINVAL);
11153
11154         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11155         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11156         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11157         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11158         BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11159         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11160         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11161         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11162         BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11163         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11164         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11165         BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11166
11167         old = BWN_RF_READ(mac, BWN_B2063_COM15);
11168         BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11169
11170         freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11171         freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11172         freqref = freqxtal * 3;
11173         div = (freqxtal <= 26000000 ? 1 : 2);
11174         timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11175         timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11176                 999999) / 1000000) + 1;
11177
11178         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11179         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11180             0xfff8, timeout >> 2);
11181         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11182             0xff9f,timeout << 5);
11183         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11184
11185         val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11186         val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11187         val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11188
11189         count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11190             (timeoutref + 1)) - 1;
11191         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11192             0xf0, count >> 8);
11193         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11194
11195         tmp[0] = ((val[2] * 62500) / freqref) << 4;
11196         tmp[1] = ((val[2] * 62500) % freqref) << 4;
11197         while (tmp[1] >= freqref) {
11198                 tmp[0]++;
11199                 tmp[1] -= freqref;
11200         }
11201         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11202         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11203         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11204         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11205         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11206
11207         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11208         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11209         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11210         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11211
11212         tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11213         tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11214
11215         if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11216                 scale = 1;
11217                 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11218         } else {
11219                 scale = 0;
11220                 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11221         }
11222         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11223         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11224
11225         tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11226             (scale + 1);
11227         if (tmp[5] > 150)
11228                 tmp[5] = 0;
11229
11230         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11231         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11232
11233         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11234         if (freqxtal > 26000000)
11235                 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11236         else
11237                 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11238
11239         if (val[0] == 45)
11240                 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11241         else
11242                 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11243
11244         BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11245         DELAY(1);
11246         BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11247
11248         /* VCO Calibration */
11249         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11250         tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11251         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11252         DELAY(1);
11253         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11254         DELAY(1);
11255         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11256         DELAY(1);
11257         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11258         DELAY(300);
11259         BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11260
11261         BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11262         return (0);
11263 }
11264
11265 static int
11266 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11267 {
11268         struct bwn_softc *sc = mac->mac_sc;
11269         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11270         const struct bwn_b206x_chan *bc = NULL;
11271         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11272         uint32_t tmp[9];
11273         int i;
11274
11275         for (i = 0; i < N(bwn_b2062_chantable); i++) {
11276                 if (bwn_b2062_chantable[i].bc_chan == chan) {
11277                         bc = &bwn_b2062_chantable[i];
11278                         break;
11279                 }
11280         }
11281
11282         if (bc == NULL)
11283                 return (EINVAL);
11284
11285         BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11286         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11287         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11288         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11289         BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11290         BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11291         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11292         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11293         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11294         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11295
11296         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11297         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11298         bwn_phy_lp_b2062_reset_pllbias(mac);
11299         tmp[0] = freqxtal / 1000;
11300         tmp[1] = plp->plp_div * 1000;
11301         tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11302         if (ieee80211_ieee2mhz(chan, 0) < 4000)
11303                 tmp[2] *= 2;
11304         tmp[3] = 48 * tmp[0];
11305         tmp[5] = tmp[2] / tmp[3];
11306         tmp[6] = tmp[2] % tmp[3];
11307         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11308         tmp[4] = tmp[6] * 0x100;
11309         tmp[5] = tmp[4] / tmp[3];
11310         tmp[6] = tmp[4] % tmp[3];
11311         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11312         tmp[4] = tmp[6] * 0x100;
11313         tmp[5] = tmp[4] / tmp[3];
11314         tmp[6] = tmp[4] % tmp[3];
11315         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11316         tmp[4] = tmp[6] * 0x100;
11317         tmp[5] = tmp[4] / tmp[3];
11318         tmp[6] = tmp[4] % tmp[3];
11319         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11320             tmp[5] + ((2 * tmp[6]) / tmp[3]));
11321         tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11322         tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11323         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11324         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11325
11326         bwn_phy_lp_b2062_vco_calib(mac);
11327         if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11328                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11329                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11330                 bwn_phy_lp_b2062_reset_pllbias(mac);
11331                 bwn_phy_lp_b2062_vco_calib(mac);
11332                 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11333                         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11334                         return (EIO);
11335                 }
11336         }
11337         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11338         return (0);
11339 }
11340
11341 static void
11342 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11343 {
11344         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11345         uint16_t tmp = (channel == 14);
11346
11347         if (mac->mac_phy.rev < 2) {
11348                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11349                 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11350                         bwn_phy_lp_set_rccap(mac);
11351                 return;
11352         }
11353
11354         BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11355 }
11356
11357 static void
11358 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11359 {
11360         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11361         struct bwn_softc *sc = mac->mac_sc;
11362         struct ifnet *ifp = sc->sc_ifp;
11363         struct ieee80211com *ic = ifp->if_l2com;
11364         uint16_t iso, tmp[3];
11365
11366         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11367
11368         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11369                 iso = plp->plp_txisoband_m;
11370         else if (freq <= 5320)
11371                 iso = plp->plp_txisoband_l;
11372         else if (freq <= 5700)
11373                 iso = plp->plp_txisoband_m;
11374         else
11375                 iso = plp->plp_txisoband_h;
11376
11377         tmp[0] = ((iso - 26) / 12) << 12;
11378         tmp[1] = tmp[0] + 0x1000;
11379         tmp[2] = tmp[0] + 0x2000;
11380
11381         bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11382         bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11383 }
11384
11385 static void
11386 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11387 {
11388         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11389         int i;
11390         static const uint16_t addr[] = {
11391                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11392                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11393                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11394                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11395                 BWN_PHY_OFDM(0xcf),
11396         };
11397         static const uint16_t val[] = {
11398                 0xde5e, 0xe832, 0xe331, 0x4d26,
11399                 0x0026, 0x1420, 0x0020, 0xfe08,
11400                 0x0008,
11401         };
11402
11403         for (i = 0; i < N(addr); i++) {
11404                 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11405                 BWN_PHY_WRITE(mac, addr[i], val[i]);
11406         }
11407 }
11408
11409 static void
11410 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11411 {
11412         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11413         struct bwn_softc *sc = mac->mac_sc;
11414         uint16_t ctl;
11415
11416         ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11417         switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11418         case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11419                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11420                 break;
11421         case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11422                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11423                 break;
11424         case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11425                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11426                 break;
11427         default:
11428                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11429                 device_printf(sc->sc_dev, "unknown command mode\n");
11430                 break;
11431         }
11432 }
11433
11434 static void
11435 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11436 {
11437         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11438         uint16_t ctl;
11439         uint8_t old;
11440
11441         bwn_phy_lp_get_txpctlmode(mac);
11442         old = plp->plp_txpctlmode;
11443         if (old == mode)
11444                 return;
11445         plp->plp_txpctlmode = mode;
11446
11447         if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11448                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11449                     plp->plp_tssiidx);
11450                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11451                     0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11452
11453                 /* disable TX GAIN override */
11454                 if (mac->mac_phy.rev < 2)
11455                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11456                 else {
11457                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11458                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11459                 }
11460                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11461
11462                 plp->plp_txpwridx = -1;
11463         }
11464         if (mac->mac_phy.rev >= 2) {
11465                 if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11466                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11467                 else
11468                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11469         }
11470
11471         /* writes TX Power Control mode */
11472         switch (plp->plp_txpctlmode) {
11473         case BWN_PHYLP_TXPCTL_OFF:
11474                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11475                 break;
11476         case BWN_PHYLP_TXPCTL_ON_HW:
11477                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11478                 break;
11479         case BWN_PHYLP_TXPCTL_ON_SW:
11480                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11481                 break;
11482         default:
11483                 ctl = 0;
11484                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11485         }
11486         BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11487             (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11488 }
11489
11490 static void
11491 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11492 {
11493         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11494         const unsigned int size = 256;
11495         struct bwn_txgain tg;
11496         uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11497         uint16_t tssinpt, tssiidx, value[2];
11498         uint8_t mode;
11499         int8_t txpwridx;
11500
11501         tabs = (uint32_t *)kmalloc(sizeof(uint32_t) * size, M_DEVBUF,
11502             M_INTWAIT | M_ZERO);
11503
11504         bwn_phy_lp_get_txpctlmode(mac);
11505         mode = plp->plp_txpctlmode;
11506         txpwridx = plp->plp_txpwridx;
11507         tssinpt = plp->plp_tssinpt;
11508         tssiidx = plp->plp_tssiidx;
11509
11510         bwn_tab_read_multi(mac,
11511             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11512             BWN_TAB_4(7, 0x140), size, tabs);
11513
11514         bwn_phy_lp_tblinit(mac);
11515         bwn_phy_lp_bbinit(mac);
11516         bwn_phy_lp_txpctl_init(mac);
11517         bwn_phy_lp_rf_onoff(mac, 1);
11518         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11519
11520         bwn_tab_write_multi(mac,
11521             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11522             BWN_TAB_4(7, 0x140), size, tabs);
11523
11524         BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11525         plp->plp_tssinpt = tssinpt;
11526         plp->plp_tssiidx = tssiidx;
11527         bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11528         if (txpwridx != -1) {
11529                 /* set TX power by index */
11530                 plp->plp_txpwridx = txpwridx;
11531                 bwn_phy_lp_get_txpctlmode(mac);
11532                 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11533                         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11534                 if (mac->mac_phy.rev >= 2) {
11535                         rxcomp = bwn_tab_read(mac,
11536                             BWN_TAB_4(7, txpwridx + 320));
11537                         txgain = bwn_tab_read(mac,
11538                             BWN_TAB_4(7, txpwridx + 192));
11539                         tg.tg_pad = (txgain >> 16) & 0xff;
11540                         tg.tg_gm = txgain & 0xff;
11541                         tg.tg_pga = (txgain >> 8) & 0xff;
11542                         tg.tg_dac = (rxcomp >> 28) & 0xff;
11543                         bwn_phy_lp_set_txgain(mac, &tg);
11544                 } else {
11545                         rxcomp = bwn_tab_read(mac,
11546                             BWN_TAB_4(10, txpwridx + 320));
11547                         txgain = bwn_tab_read(mac,
11548                             BWN_TAB_4(10, txpwridx + 192));
11549                         BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11550                             0xf800, (txgain >> 4) & 0x7fff);
11551                         bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11552                         bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11553                 }
11554                 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11555
11556                 /* set TX IQCC */
11557                 value[0] = (rxcomp >> 10) & 0x3ff;
11558                 value[1] = rxcomp & 0x3ff;
11559                 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11560
11561                 coeff = bwn_tab_read(mac,
11562                     (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11563                     BWN_TAB_4(10, txpwridx + 448));
11564                 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11565                 if (mac->mac_phy.rev >= 2) {
11566                         rfpwr = bwn_tab_read(mac,
11567                             BWN_TAB_4(7, txpwridx + 576));
11568                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11569                             rfpwr & 0xffff);
11570                 }
11571                 bwn_phy_lp_set_txgain_override(mac);
11572         }
11573         if (plp->plp_rccap)
11574                 bwn_phy_lp_set_rccap(mac);
11575         bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11576         bwn_phy_lp_set_txpctlmode(mac, mode);
11577         kfree(tabs, M_DEVBUF);
11578 }
11579
11580 static void
11581 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11582 {
11583         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11584         int i;
11585         static const uint16_t addr[] = {
11586                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11587                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11588                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11589                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11590                 BWN_PHY_OFDM(0xcf),
11591         };
11592
11593         for (i = 0; i < N(addr); i++)
11594                 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11595 }
11596
11597 static void
11598 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11599 {
11600         uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11601
11602         if (mac->mac_phy.rev < 2) {
11603                 bwn_phy_lp_tblinit_r01(mac);
11604                 bwn_phy_lp_tblinit_txgain(mac);
11605                 bwn_phy_lp_set_gaintbl(mac, freq);
11606                 return;
11607         }
11608
11609         bwn_phy_lp_tblinit_r2(mac);
11610         bwn_phy_lp_tblinit_txgain(mac);
11611 }
11612
11613 struct bwn_wpair {
11614         uint16_t                reg;
11615         uint16_t                value;
11616 };
11617
11618 struct bwn_smpair {
11619         uint16_t                offset;
11620         uint16_t                mask;
11621         uint16_t                set;
11622 };
11623
11624 static void
11625 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11626 {
11627         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11628         struct bwn_softc *sc = mac->mac_sc;
11629         struct ifnet *ifp = sc->sc_ifp;
11630         struct ieee80211com *ic = ifp->if_l2com;
11631         static const struct bwn_wpair v1[] = {
11632                 { BWN_PHY_AFE_DAC_CTL, 0x50 },
11633                 { BWN_PHY_AFE_CTL, 0x8800 },
11634                 { BWN_PHY_AFE_CTL_OVR, 0 },
11635                 { BWN_PHY_AFE_CTL_OVRVAL, 0 },
11636                 { BWN_PHY_RF_OVERRIDE_0, 0 },
11637                 { BWN_PHY_RF_OVERRIDE_2, 0 },
11638                 { BWN_PHY_OFDM(0xf9), 0 },
11639                 { BWN_PHY_TR_LOOKUP_1, 0 }
11640         };
11641         static const struct bwn_smpair v2[] = {
11642                 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11643                 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11644                 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11645                 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11646                 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11647         };
11648         static const struct bwn_smpair v3[] = {
11649                 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11650                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11651                 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11652                 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11653                 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11654                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11655                 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11656                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11657                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11658                 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11659
11660         };
11661         int i;
11662
11663         for (i = 0; i < N(v1); i++)
11664                 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11665         BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11666         for (i = 0; i < N(v2); i++)
11667                 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11668
11669         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11670         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11671         BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11672         if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11673                 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11674                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11675         } else {
11676                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11677         }
11678         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11679         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11680         BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11681         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11682         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11683         BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11684         BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11685         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11686         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11687         BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11688         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11689         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11690             (siba_get_chiprev(sc->sc_dev) == 0)) {
11691                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11692                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11693         } else {
11694                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11695                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11696         }
11697         for (i = 0; i < N(v3); i++)
11698                 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11699         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11700             (siba_get_chiprev(sc->sc_dev) == 0)) {
11701                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11702                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11703         }
11704
11705         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11706                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11707                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11708                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11709                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11710                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11711                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11712         } else
11713                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11714
11715         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11716         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11717         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11718         BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11719         BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11720         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11721         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11722             0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11723             ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11724
11725         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11726             (siba_get_chiprev(sc->sc_dev) == 0)) {
11727                 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11728                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11729                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11730         }
11731
11732         bwn_phy_lp_digflt_save(mac);
11733 }
11734
11735 static void
11736 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11737 {
11738         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11739         struct bwn_softc *sc = mac->mac_sc;
11740         struct ifnet *ifp = sc->sc_ifp;
11741         struct ieee80211com *ic = ifp->if_l2com;
11742         static const struct bwn_smpair v1[] = {
11743                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11744                 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11745                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11746                 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11747                 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11748                 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11749                 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11750         };
11751         static const struct bwn_smpair v2[] = {
11752                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11753                 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11754                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11755                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11756                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11757                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11758                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11759                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11760                 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11761                 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11762                 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11763                 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11764                 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11765                 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11766                 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11767                 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11768         };
11769         static const struct bwn_smpair v3[] = {
11770                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11771                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11772                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11773                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11774                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11775                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11776                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11777                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11778         };
11779         static const struct bwn_smpair v4[] = {
11780                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11781                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11782                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11783                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11784                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11785                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11786                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11787                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11788         };
11789         static const struct bwn_smpair v5[] = {
11790                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11791                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11792                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11793                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11794                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11795                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11796                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11797                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11798         };
11799         int i;
11800         uint16_t tmp, tmp2;
11801
11802         BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11803         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11804         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11805         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11806         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11807         BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11808         BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11809         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11810         BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11811         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11812         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11813         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11814         BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11815         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11816         BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11817         for (i = 0; i < N(v1); i++)
11818                 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11819         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11820             0xff00, plp->plp_rxpwroffset);
11821         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11822             ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11823            (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11824                 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11825                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11826                 if (mac->mac_phy.rev == 0)
11827                         BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11828                             0xffcf, 0x0010);
11829                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11830         } else {
11831                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11832                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11833                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11834         }
11835         tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11836         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11837         if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11838                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11839         else
11840                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11841         bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11842         BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11843             0xfff9, (plp->plp_bxarch << 1));
11844         if (mac->mac_phy.rev == 1 &&
11845             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11846                 for (i = 0; i < N(v2); i++)
11847                         BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11848                             v2[i].set);
11849         } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11850             (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11851             ((mac->mac_phy.rev == 0) &&
11852              (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11853                 for (i = 0; i < N(v3); i++)
11854                         BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11855                             v3[i].set);
11856         } else if (mac->mac_phy.rev == 1 ||
11857                   (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11858                 for (i = 0; i < N(v4); i++)
11859                         BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11860                             v4[i].set);
11861         } else {
11862                 for (i = 0; i < N(v5); i++)
11863                         BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11864                             v5[i].set);
11865         }
11866         if (mac->mac_phy.rev == 1 &&
11867             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11868                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11869                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11870                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11871                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11872         }
11873         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11874             (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11875             (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11876                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11877                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11878                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11879                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11880         }
11881         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11882                 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11883                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11884                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11885                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11886                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11887                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
11888                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
11889                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11890         } else {
11891                 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
11892                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
11893         }
11894         if (mac->mac_phy.rev == 1) {
11895                 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
11896                 tmp2 = (tmp & 0x03e0) >> 5;
11897                 tmp2 |= tmp2 << 5;
11898                 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
11899                 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
11900                 tmp2 = (tmp & 0x1f00) >> 8;
11901                 tmp2 |= tmp2 << 5;
11902                 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
11903                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
11904                 tmp2 = tmp & 0x00ff;
11905                 tmp2 |= tmp << 8;
11906                 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
11907         }
11908 }
11909
11910 struct bwn_b2062_freq {
11911         uint16_t                freq;
11912         uint8_t                 value[6];
11913 };
11914
11915 static void
11916 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
11917 {
11918 #define CALC_CTL7(freq, div)                                            \
11919         (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
11920 #define CALC_CTL18(freq, div)                                           \
11921         ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
11922 #define CALC_CTL19(freq, div)                                           \
11923         ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
11924         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11925         struct bwn_softc *sc = mac->mac_sc;
11926         struct ifnet *ifp = sc->sc_ifp;
11927         struct ieee80211com *ic = ifp->if_l2com;
11928         static const struct bwn_b2062_freq freqdata_tab[] = {
11929                 { 12000, { 6, 6, 6, 6, 10, 6 } },
11930                 { 13000, { 4, 4, 4, 4, 11, 7 } },
11931                 { 14400, { 3, 3, 3, 3, 12, 7 } },
11932                 { 16200, { 3, 3, 3, 3, 13, 8 } },
11933                 { 18000, { 2, 2, 2, 2, 14, 8 } },
11934                 { 19200, { 1, 1, 1, 1, 14, 9 } }
11935         };
11936         static const struct bwn_wpair v1[] = {
11937                 { BWN_B2062_N_TXCTL3, 0 },
11938                 { BWN_B2062_N_TXCTL4, 0 },
11939                 { BWN_B2062_N_TXCTL5, 0 },
11940                 { BWN_B2062_N_TXCTL6, 0 },
11941                 { BWN_B2062_N_PDNCTL0, 0x40 },
11942                 { BWN_B2062_N_PDNCTL0, 0 },
11943                 { BWN_B2062_N_CALIB_TS, 0x10 },
11944                 { BWN_B2062_N_CALIB_TS, 0 }
11945         };
11946         const struct bwn_b2062_freq *f = NULL;
11947         uint32_t xtalfreq, ref;
11948         unsigned int i;
11949
11950         bwn_phy_lp_b2062_tblinit(mac);
11951
11952         for (i = 0; i < N(v1); i++)
11953                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
11954         if (mac->mac_phy.rev > 0)
11955                 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
11956                     (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
11957         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11958                 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
11959         else
11960                 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
11961
11962         KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
11963             ("%s:%d: fail", __func__, __LINE__));
11964         xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11965         KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
11966
11967         if (xtalfreq <= 30000000) {
11968                 plp->plp_div = 1;
11969                 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
11970         } else {
11971                 plp->plp_div = 2;
11972                 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
11973         }
11974
11975         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
11976             CALC_CTL7(xtalfreq, plp->plp_div));
11977         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
11978             CALC_CTL18(xtalfreq, plp->plp_div));
11979         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
11980             CALC_CTL19(xtalfreq, plp->plp_div));
11981
11982         ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
11983         ref &= 0xffff;
11984         for (i = 0; i < N(freqdata_tab); i++) {
11985                 if (ref < freqdata_tab[i].freq) {
11986                         f = &freqdata_tab[i];
11987                         break;
11988                 }
11989         }
11990         if (f == NULL)
11991                 f = &freqdata_tab[N(freqdata_tab) - 1];
11992         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
11993             ((uint16_t)(f->value[1]) << 4) | f->value[0]);
11994         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
11995             ((uint16_t)(f->value[3]) << 4) | f->value[2]);
11996         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
11997         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
11998 #undef CALC_CTL7
11999 #undef CALC_CTL18
12000 #undef CALC_CTL19
12001 }
12002
12003 static void
12004 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
12005 {
12006
12007         bwn_phy_lp_b2063_tblinit(mac);
12008         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
12009         BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
12010         BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
12011         BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
12012         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
12013         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
12014         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
12015         if (mac->mac_phy.rev == 2) {
12016                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
12017                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
12018                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
12019         } else {
12020                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
12021                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
12022         }
12023 }
12024
12025 static void
12026 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
12027 {
12028         struct bwn_softc *sc = mac->mac_sc;
12029         static const struct bwn_wpair v1[] = {
12030                 { BWN_B2063_RX_BB_SP8, 0x0 },
12031                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12032                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12033                 { BWN_B2063_RC_CALIB_CTL2, 0x15 },
12034                 { BWN_B2063_RC_CALIB_CTL3, 0x70 },
12035                 { BWN_B2063_RC_CALIB_CTL4, 0x52 },
12036                 { BWN_B2063_RC_CALIB_CTL5, 0x1 },
12037                 { BWN_B2063_RC_CALIB_CTL1, 0x7d }
12038         };
12039         static const struct bwn_wpair v2[] = {
12040                 { BWN_B2063_TX_BB_SP3, 0x0 },
12041                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12042                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12043                 { BWN_B2063_RC_CALIB_CTL2, 0x55 },
12044                 { BWN_B2063_RC_CALIB_CTL3, 0x76 }
12045         };
12046         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12047         int i;
12048         uint8_t tmp;
12049
12050         tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12051
12052         for (i = 0; i < 2; i++)
12053                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12054         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12055         for (i = 2; i < N(v1); i++)
12056                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12057         for (i = 0; i < 10000; i++) {
12058                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12059                         break;
12060                 DELAY(1000);
12061         }
12062
12063         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12064                 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12065
12066         tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12067
12068         for (i = 0; i < N(v2); i++)
12069                 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12070         if (freqxtal == 24000000) {
12071                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12072                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12073         } else {
12074                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12075                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12076         }
12077         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12078         for (i = 0; i < 10000; i++) {
12079                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12080                         break;
12081                 DELAY(1000);
12082         }
12083         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12084                 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12085         BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12086 }
12087
12088 static void
12089 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12090 {
12091         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12092         struct bwn_softc *sc = mac->mac_sc;
12093         struct bwn_phy_lp_iq_est ie;
12094         struct bwn_txgain tx_gains;
12095         static const uint32_t pwrtbl[21] = {
12096                 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12097                 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12098                 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12099                 0x0004c, 0x0002c, 0x0001a,
12100         };
12101         uint32_t npwr, ipwr, sqpwr, tmp;
12102         int loopback, i, j, sum, error;
12103         uint16_t save[7];
12104         uint8_t txo, bbmult, txpctlmode;
12105
12106         error = bwn_phy_lp_switch_channel(mac, 7);
12107         if (error)
12108                 device_printf(sc->sc_dev,
12109                     "failed to change channel to 7 (%d)\n", error);
12110         txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12111         bbmult = bwn_phy_lp_get_bbmult(mac);
12112         if (txo)
12113                 tx_gains = bwn_phy_lp_get_txgain(mac);
12114
12115         save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12116         save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12117         save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12118         save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12119         save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12120         save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12121         save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12122
12123         bwn_phy_lp_get_txpctlmode(mac);
12124         txpctlmode = plp->plp_txpctlmode;
12125         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12126
12127         /* disable CRS */
12128         bwn_phy_lp_set_deaf(mac, 1);
12129         bwn_phy_lp_set_trsw_over(mac, 0, 1);
12130         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12131         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12132         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12133         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12134         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12135         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12136         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12137         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12138         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12139         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12140         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12141         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12142         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12143         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12144         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12145         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12146         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12147         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12148         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12149         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12150         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12151         BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12152         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12153
12154         loopback = bwn_phy_lp_loopback(mac);
12155         if (loopback == -1)
12156                 goto done;
12157         bwn_phy_lp_set_rxgain_idx(mac, loopback);
12158         BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12159         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12160         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12161         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12162
12163         tmp = 0;
12164         memset(&ie, 0, sizeof(ie));
12165         for (i = 128; i <= 159; i++) {
12166                 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12167                 sum = 0;
12168                 for (j = 5; j <= 25; j++) {
12169                         bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12170                         if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12171                                 goto done;
12172                         sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12173                         ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12174                         npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12175                             12);
12176                         sum += ((ipwr - npwr) * (ipwr - npwr));
12177                         if ((i == 128) || (sum < tmp)) {
12178                                 plp->plp_rccap = i;
12179                                 tmp = sum;
12180                         }
12181                 }
12182         }
12183         bwn_phy_lp_ddfs_turnoff(mac);
12184 done:
12185         /* restore CRS */
12186         bwn_phy_lp_clear_deaf(mac, 1);
12187         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12188         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12189
12190         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12191         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12192         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12193         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12194         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12195         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12196         BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12197
12198         bwn_phy_lp_set_bbmult(mac, bbmult);
12199         if (txo)
12200                 bwn_phy_lp_set_txgain(mac, &tx_gains);
12201         bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12202         if (plp->plp_rccap)
12203                 bwn_phy_lp_set_rccap(mac);
12204 }
12205
12206 static void
12207 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12208 {
12209         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12210         uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12211
12212         if (mac->mac_phy.rev == 1)
12213                 rc_cap = MIN(rc_cap + 5, 15);
12214
12215         BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12216             MAX(plp->plp_rccap - 4, 0x80));
12217         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12218         BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12219             ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12220 }
12221
12222 static uint32_t
12223 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12224 {
12225         uint32_t i, q, r;
12226
12227         if (div == 0)
12228                 return (0);
12229
12230         for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12231                 q <<= 1;
12232                 if (r << 1 >= div) {
12233                         q++;
12234                         r = (r << 1) - div;
12235                 }
12236         }
12237         if (r << 1 >= div)
12238                 q++;
12239         return (q);
12240 }
12241
12242 static void
12243 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12244 {
12245         struct bwn_softc *sc = mac->mac_sc;
12246
12247         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12248         DELAY(20);
12249         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12250                 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12251                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12252         } else {
12253                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12254         }
12255         DELAY(5);
12256 }
12257
12258 static void
12259 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12260 {
12261
12262         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12263         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12264         DELAY(200);
12265 }
12266
12267 static void
12268 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12269 {
12270 #define FLAG_A  0x01
12271 #define FLAG_G  0x02
12272         struct bwn_softc *sc = mac->mac_sc;
12273         struct ifnet *ifp = sc->sc_ifp;
12274         struct ieee80211com *ic = ifp->if_l2com;
12275         static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12276                 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12277                 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12278                 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12279                 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12280                 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12281                 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12282                 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12283                 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12284                 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12285                 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12286                 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12287                 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12288                 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12289                 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12290                 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12291                 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12292                 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12293                 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12294                 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12295                 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12296                 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12297                 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12298                 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12299                 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12300                 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12301                 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12302                 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12303                 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12304                 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12305                 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12306                 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12307                 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12308                 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12309                 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12310                 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12311                 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12312                 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12313                 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12314                 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12315                 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12316                 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12317                 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12318                 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12319                 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12320                 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12321                 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12322                 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12323         };
12324         const struct bwn_b206x_rfinit_entry *br;
12325         unsigned int i;
12326
12327         for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12328                 br = &bwn_b2062_init_tab[i];
12329                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12330                         if (br->br_flags & FLAG_G)
12331                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12332                 } else {
12333                         if (br->br_flags & FLAG_A)
12334                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12335                 }
12336         }
12337 #undef FLAG_A
12338 #undef FLAG_B
12339 }
12340
12341 static void
12342 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12343 {
12344 #define FLAG_A  0x01
12345 #define FLAG_G  0x02
12346         struct bwn_softc *sc = mac->mac_sc;
12347         struct ifnet *ifp = sc->sc_ifp;
12348         struct ieee80211com *ic = ifp->if_l2com;
12349         static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12350                 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12351                 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12352                 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12353                 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12354                 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12355                 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12356                 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12357                 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12358                 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12359                 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12360                 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12361                 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12362                 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12363                 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12364                 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12365                 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12366                 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12367                 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12368                 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12369                 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12370                 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12371                 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12372                 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12373                 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12374                 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12375                 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12376                 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12377                 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12378                 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12379                 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12380                 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12381                 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12382                 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12383                 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12384                 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12385                 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12386                 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12387                 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12388                 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12389                 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12390                 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12391                 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12392         };
12393         const struct bwn_b206x_rfinit_entry *br;
12394         unsigned int i;
12395
12396         for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12397                 br = &bwn_b2063_init_tab[i];
12398                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12399                         if (br->br_flags & FLAG_G)
12400                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12401                 } else {
12402                         if (br->br_flags & FLAG_A)
12403                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12404                 }
12405         }
12406 #undef FLAG_A
12407 #undef FLAG_B
12408 }
12409
12410 static void
12411 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12412     int count, void *_data)
12413 {
12414         unsigned int i;
12415         uint32_t offset, type;
12416         uint8_t *data = _data;
12417
12418         type = BWN_TAB_GETTYPE(typenoffset);
12419         offset = BWN_TAB_GETOFFSET(typenoffset);
12420         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12421
12422         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12423
12424         for (i = 0; i < count; i++) {
12425                 switch (type) {
12426                 case BWN_TAB_8BIT:
12427                         *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12428                         data++;
12429                         break;
12430                 case BWN_TAB_16BIT:
12431                         *((uint16_t *)data) = BWN_PHY_READ(mac,
12432                             BWN_PHY_TABLEDATALO);
12433                         data += 2;
12434                         break;
12435                 case BWN_TAB_32BIT:
12436                         *((uint32_t *)data) = BWN_PHY_READ(mac,
12437                             BWN_PHY_TABLEDATAHI);
12438                         *((uint32_t *)data) <<= 16;
12439                         *((uint32_t *)data) |= BWN_PHY_READ(mac,
12440                             BWN_PHY_TABLEDATALO);
12441                         data += 4;
12442                         break;
12443                 default:
12444                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12445                 }
12446         }
12447 }
12448
12449 static void
12450 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12451     int count, const void *_data)
12452 {
12453         uint32_t offset, type, value;
12454         const uint8_t *data = _data;
12455         unsigned int i;
12456
12457         type = BWN_TAB_GETTYPE(typenoffset);
12458         offset = BWN_TAB_GETOFFSET(typenoffset);
12459         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12460
12461         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12462
12463         for (i = 0; i < count; i++) {
12464                 switch (type) {
12465                 case BWN_TAB_8BIT:
12466                         value = *data;
12467                         data++;
12468                         KASSERT(!(value & ~0xff),
12469                             ("%s:%d: fail", __func__, __LINE__));
12470                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12471                         break;
12472                 case BWN_TAB_16BIT:
12473                         value = *((const uint16_t *)data);
12474                         data += 2;
12475                         KASSERT(!(value & ~0xffff),
12476                             ("%s:%d: fail", __func__, __LINE__));
12477                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12478                         break;
12479                 case BWN_TAB_32BIT:
12480                         value = *((const uint32_t *)data);
12481                         data += 4;
12482                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12483                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12484                         break;
12485                 default:
12486                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12487                 }
12488         }
12489 }
12490
12491 static struct bwn_txgain
12492 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12493 {
12494         struct bwn_txgain tg;
12495         uint16_t tmp;
12496
12497         tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12498         if (mac->mac_phy.rev < 2) {
12499                 tmp = BWN_PHY_READ(mac,
12500                     BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12501                 tg.tg_gm = tmp & 0x0007;
12502                 tg.tg_pga = (tmp & 0x0078) >> 3;
12503                 tg.tg_pad = (tmp & 0x780) >> 7;
12504                 return (tg);
12505         }
12506
12507         tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12508         tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12509         tg.tg_gm = tmp & 0xff;
12510         tg.tg_pga = (tmp >> 8) & 0xff;
12511         return (tg);
12512 }
12513
12514 static uint8_t
12515 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12516 {
12517
12518         return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12519 }
12520
12521 static void
12522 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12523 {
12524         uint16_t pa;
12525
12526         if (mac->mac_phy.rev < 2) {
12527                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12528                     (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12529                 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12530                 bwn_phy_lp_set_txgain_override(mac);
12531                 return;
12532         }
12533
12534         pa = bwn_phy_lp_get_pa_gain(mac);
12535         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12536             (tg->tg_pga << 8) | tg->tg_gm);
12537         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12538             tg->tg_pad | (pa << 6));
12539         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12540         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12541             tg->tg_pad | (pa << 8));
12542         bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12543         bwn_phy_lp_set_txgain_override(mac);
12544 }
12545
12546 static void
12547 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12548 {
12549
12550         bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12551 }
12552
12553 static void
12554 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12555 {
12556         uint16_t trsw = (tx << 1) | rx;
12557
12558         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12559         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12560 }
12561
12562 static void
12563 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12564 {
12565         struct bwn_softc *sc = mac->mac_sc;
12566         struct ifnet *ifp = sc->sc_ifp;
12567         struct ieee80211com *ic = ifp->if_l2com;
12568         uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12569
12570         if (mac->mac_phy.rev < 2) {
12571                 trsw = gain & 0x1;
12572                 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12573                 ext_lna = (gain & 2) >> 1;
12574
12575                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12576                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12577                     0xfbff, ext_lna << 10);
12578                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12579                     0xf7ff, ext_lna << 11);
12580                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12581         } else {
12582                 low_gain = gain & 0xffff;
12583                 high_gain = (gain >> 16) & 0xf;
12584                 ext_lna = (gain >> 21) & 0x1;
12585                 trsw = ~(gain >> 20) & 0x1;
12586
12587                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12588                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12589                     0xfdff, ext_lna << 9);
12590                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12591                     0xfbff, ext_lna << 10);
12592                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12593                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12594                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12595                         tmp = (gain >> 2) & 0x3;
12596                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12597                             0xe7ff, tmp<<11);
12598                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12599                             tmp << 3);
12600                 }
12601         }
12602
12603         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12604         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12605         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12606         if (mac->mac_phy.rev >= 2) {
12607                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12608                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12609                         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12610                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12611                 }
12612                 return;
12613         }
12614         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12615 }
12616
12617 static void
12618 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12619 {
12620         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12621
12622         if (user)
12623                 plp->plp_crsusr_off = 1;
12624         else
12625                 plp->plp_crssys_off = 1;
12626
12627         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12628 }
12629
12630 static void
12631 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12632 {
12633         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12634         struct bwn_softc *sc = mac->mac_sc;
12635         struct ifnet *ifp = sc->sc_ifp;
12636         struct ieee80211com *ic = ifp->if_l2com;
12637
12638         if (user)
12639                 plp->plp_crsusr_off = 0;
12640         else
12641                 plp->plp_crssys_off = 0;
12642
12643         if (plp->plp_crsusr_off || plp->plp_crssys_off)
12644                 return;
12645
12646         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12647                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12648         else
12649                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12650 }
12651
12652 static unsigned int
12653 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12654 {
12655         /* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12656         static uint8_t sqrt_table[256] = {
12657                 10, 14, 17, 20, 22, 24, 26, 28,
12658                 30, 31, 33, 34, 36, 37, 38, 40,
12659                 41, 42, 43, 44, 45, 46, 47, 48,
12660                 50, 50, 51, 52, 53, 54, 55, 56,
12661                 57, 58, 59, 60, 60, 61, 62, 63,
12662                 64, 64, 65, 66, 67, 67, 68, 69,
12663                 70, 70, 71, 72, 72, 73, 74, 74,
12664                 75, 76, 76, 77, 78, 78, 79, 80,
12665                 80, 81, 81, 82, 83, 83, 84, 84,
12666                 85, 86, 86, 87, 87, 88, 88, 89,
12667                 90, 90, 91, 91, 92, 92, 93, 93,
12668                 94, 94, 95, 95, 96, 96, 97, 97,
12669                 98, 98, 99, 100, 100, 100, 101, 101,
12670                 102, 102, 103, 103, 104, 104, 105, 105,
12671                 106, 106, 107, 107, 108, 108, 109, 109,
12672                 110, 110, 110, 111, 111, 112, 112, 113,
12673                 113, 114, 114, 114, 115, 115, 116, 116,
12674                 117, 117, 117, 118, 118, 119, 119, 120,
12675                 120, 120, 121, 121, 122, 122, 122, 123,
12676                 123, 124, 124, 124, 125, 125, 126, 126,
12677                 126, 127, 127, 128, 128, 128, 129, 129,
12678                 130, 130, 130, 131, 131, 131, 132, 132,
12679                 133, 133, 133, 134, 134, 134, 135, 135,
12680                 136, 136, 136, 137, 137, 137, 138, 138,
12681                 138, 139, 139, 140, 140, 140, 141, 141,
12682                 141, 142, 142, 142, 143, 143, 143, 144,
12683                 144, 144, 145, 145, 145, 146, 146, 146,
12684                 147, 147, 147, 148, 148, 148, 149, 149,
12685                 150, 150, 150, 150, 151, 151, 151, 152,
12686                 152, 152, 153, 153, 153, 154, 154, 154,
12687                 155, 155, 155, 156, 156, 156, 157, 157,
12688                 157, 158, 158, 158, 159, 159, 159, 160
12689         };
12690
12691         if (x == 0)
12692                 return (0);
12693         if (x >= 256) {
12694                 unsigned int tmp;
12695
12696                 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12697                         /* do nothing */ ;
12698                 return (tmp);
12699         }
12700         return (sqrt_table[x - 1] / 10);
12701 }
12702
12703 static int
12704 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12705 {
12706 #define CALC_COEFF(_v, _x, _y, _z)      do {                            \
12707         int _t;                                                         \
12708         _t = _x - 20;                                                   \
12709         if (_t >= 0) {                                                  \
12710                 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12711         } else {                                                        \
12712                 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12713         }                                                               \
12714 } while (0)
12715 #define CALC_COEFF2(_v, _x, _y, _z)     do {                            \
12716         int _t;                                                         \
12717         _t = _x - 11;                                                   \
12718         if (_t >= 0)                                                    \
12719                 _v = (_y << (31 - _x)) / (_z >> _t);                    \
12720         else                                                            \
12721                 _v = (_y << (31 - _x)) / (_z << -_t);                   \
12722 } while (0)
12723         struct bwn_phy_lp_iq_est ie;
12724         uint16_t v0, v1;
12725         int tmp[2], ret;
12726
12727         v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12728         v0 = v1 >> 8;
12729         v1 |= 0xff;
12730
12731         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12732         BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12733
12734         ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12735         if (ret == 0)
12736                 goto done;
12737
12738         if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12739                 ret = 0;
12740                 goto done;
12741         }
12742
12743         CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12744         CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12745
12746         tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12747         v0 = tmp[0] >> 3;
12748         v1 = tmp[1] >> 4;
12749 done:
12750         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12751         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12752         return ret;
12753 #undef CALC_COEFF
12754 #undef CALC_COEFF2
12755 }
12756
12757 static void
12758 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12759 {
12760         static const uint16_t noisescale[] = {
12761                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12762                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12763                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12764                 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12765                 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12766         };
12767         static const uint16_t crsgainnft[] = {
12768                 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12769                 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12770                 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12771                 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12772                 0x013d,
12773         };
12774         static const uint16_t filterctl[] = {
12775                 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12776                 0xff53, 0x0127,
12777         };
12778         static const uint32_t psctl[] = {
12779                 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12780                 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12781                 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12782                 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12783                 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12784                 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12785                 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12786                 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12787         };
12788         static const uint16_t ofdmcckgain_r0[] = {
12789                 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12790                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12791                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12792                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12793                 0x755d,
12794         };
12795         static const uint16_t ofdmcckgain_r1[] = {
12796                 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12797                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12798                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12799                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12800                 0x755d,
12801         };
12802         static const uint16_t gaindelta[] = {
12803                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12804                 0x0000,
12805         };
12806         static const uint32_t txpwrctl[] = {
12807                 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12808                 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12809                 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12810                 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12811                 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12812                 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12813                 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12814                 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12815                 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12816                 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12817                 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12818                 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12819                 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
12820                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12821                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12822                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12823                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12824                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12825                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12826                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12827                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12828                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12829                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12830                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12831                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12832                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12833                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12834                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12835                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12836                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12837                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12838                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12839                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12840                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12841                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12842                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12843                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12844                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12845                 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12846                 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12847                 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12848                 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12849                 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12850                 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12851                 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12852                 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12853                 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12854                 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12855                 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12856                 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12857                 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12858                 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12859                 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12860                 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12861                 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12862                 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12863                 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12864                 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12865                 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12866                 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12867                 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12868                 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12869                 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12870                 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12871                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12872                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12873                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12874                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12875                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12876                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12877                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12878                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12879                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12880                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12881                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12882                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12883                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12884                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12885                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12886                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12887                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12888                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12889                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12890                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12891                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12892                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12893                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12894                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12895                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12896                 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
12897                 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
12898                 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
12899                 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
12900                 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
12901                 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
12902                 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
12903                 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
12904                 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
12905                 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
12906                 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
12907                 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
12908                 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
12909                 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
12910                 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
12911                 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
12912                 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
12913                 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
12914                 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
12915                 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
12916                 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
12917                 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
12918                 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
12919                 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
12920                 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
12921                 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
12922                 0x00000702,
12923         };
12924
12925         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
12926
12927         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
12928             bwn_tab_sigsq_tbl);
12929         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
12930         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
12931         bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
12932         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
12933         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
12934             bwn_tab_pllfrac_tbl);
12935         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
12936             bwn_tabl_iqlocal_tbl);
12937         if (mac->mac_phy.rev == 0) {
12938                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
12939                     ofdmcckgain_r0);
12940                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
12941                     ofdmcckgain_r0);
12942         } else {
12943                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
12944                     ofdmcckgain_r1);
12945                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
12946                     ofdmcckgain_r1);
12947         }
12948         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
12949         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
12950 }
12951
12952 static void
12953 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
12954 {
12955         struct bwn_softc *sc = mac->mac_sc;
12956         int i;
12957         static const uint16_t noisescale[] = {
12958                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12959                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12960                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12961                 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12962                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12963                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12964                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
12965         };
12966         static const uint32_t filterctl[] = {
12967                 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
12968                 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
12969         };
12970         static const uint32_t psctl[] = {
12971                 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
12972                 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
12973                 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
12974                 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
12975         };
12976         static const uint32_t gainidx[] = {
12977                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12978                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12979                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12980                 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
12981                 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
12982                 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
12983                 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
12984                 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
12985                 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
12986                 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
12987                 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
12988                 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
12989                 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
12990                 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
12991                 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
12992                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12993                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12994                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12995                 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
12996                 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
12997                 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
12998                 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
12999                 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
13000                 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
13001                 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
13002                 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
13003                 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
13004                 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
13005                 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
13006                 0x0000001a, 0x64ca55ad, 0x0000001a
13007         };
13008         static const uint16_t auxgainidx[] = {
13009                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13010                 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
13011                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
13012                 0x0004, 0x0016
13013         };
13014         static const uint16_t swctl[] = {
13015                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13016                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13017                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13018                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
13019                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13020                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13021                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13022                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
13023         };
13024         static const uint8_t hf[] = {
13025                 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
13026                 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
13027         };
13028         static const uint32_t gainval[] = {
13029                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13030                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13031                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13032                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13033                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13034                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13035                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13036                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13037                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13038                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13039                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13040                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13041                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
13042                 0x000000f1, 0x00000000, 0x00000000
13043         };
13044         static const uint16_t gain[] = {
13045                 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13046                 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13047                 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13048                 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13049                 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13050                 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
13051                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13052                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13053                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13054                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13055                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13056                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13057         };
13058         static const uint32_t papdeps[] = {
13059                 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13060                 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13061                 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13062                 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13063                 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13064                 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13065                 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13066                 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13067                 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13068                 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13069                 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13070                 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13071                 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13072         };
13073         static const uint32_t papdmult[] = {
13074                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13075                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13076                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13077                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13078                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13079                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13080                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13081                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13082                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13083                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13084                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13085                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13086                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13087         };
13088         static const uint32_t gainidx_a0[] = {
13089                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13090                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13091                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13092                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13093                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13094                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13095                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13096                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13097                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13098                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13099                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13100                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13101                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13102         };
13103         static const uint16_t auxgainidx_a0[] = {
13104                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13105                 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13106                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13107                 0x0002, 0x0014
13108         };
13109         static const uint32_t gainval_a0[] = {
13110                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13111                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13112                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13113                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13114                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13115                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13116                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13117                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13118                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13119                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13120                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13121                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13122                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13123                 0x000000f7, 0x00000000, 0x00000000
13124         };
13125         static const uint16_t gain_a0[] = {
13126                 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13127                 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13128                 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13129                 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13130                 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13131                 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
13132                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13133                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13134                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13135                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13136                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13137                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13138         };
13139
13140         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13141
13142         for (i = 0; i < 704; i++)
13143                 bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13144
13145         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13146             bwn_tab_sigsq_tbl);
13147         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13148         bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13149         bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13150         bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13151         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13152         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13153         bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13154         bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13155         bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13156         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13157             bwn_tab_pllfrac_tbl);
13158         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13159             bwn_tabl_iqlocal_tbl);
13160         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13161         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13162
13163         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13164             (siba_get_chiprev(sc->sc_dev) == 0)) {
13165                 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13166                     gainidx_a0);
13167                 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13168                     auxgainidx_a0);
13169                 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13170                     gainval_a0);
13171                 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13172         }
13173 }
13174
13175 static void
13176 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13177 {
13178         struct bwn_softc *sc = mac->mac_sc;
13179         struct ifnet *ifp = sc->sc_ifp;
13180         struct ieee80211com *ic = ifp->if_l2com;
13181         static struct bwn_txgain_entry txgain_r2[] = {
13182                 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13183                 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13184                 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13185                 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13186                 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13187                 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13188                 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13189                 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13190                 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13191                 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13192                 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13193                 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13194                 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13195                 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13196                 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13197                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13198                 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13199                 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13200                 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13201                 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13202                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13203                 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13204                 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13205                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13206                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13207                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13208                 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13209                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13210                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13211                 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13212                 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13213                 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13214                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13215                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13216                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13217                 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13218                 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13219                 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13220                 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13221                 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13222                 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13223                 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13224                 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13225                 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13226                 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13227                 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13228                 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13229                 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13230                 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13231                 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13232                 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13233                 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13234                 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13235                 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13236                 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13237                 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13238                 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13239                 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13240                 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13241                 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13242                 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13243                 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13244                 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13245                 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13246         };
13247         static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13248                 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13249                 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13250                 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13251                 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13252                 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13253                 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13254                 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13255                 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13256                 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13257                 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13258                 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13259                 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13260                 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13261                 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13262                 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13263                 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13264                 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13265                 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13266                 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13267                 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13268                 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13269                 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13270                 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13271                 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13272                 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13273                 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13274                 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13275                 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13276                 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13277                 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13278                 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13279                 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13280                 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13281                 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13282                 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13283                 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13284                 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13285                 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13286                 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13287                 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13288                 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13289                 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13290                 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13291                 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13292                 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13293                 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13294                 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13295                 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13296                 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13297                 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13298                 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13299                 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13300                 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13301                 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13302                 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13303                 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13304                 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13305                 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13306                 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13307                 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13308                 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13309                 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13310                 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13311                 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13312         };
13313         static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13314                 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13315                 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13316                 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13317                 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13318                 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13319                 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13320                 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13321                 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13322                 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13323                 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13324                 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13325                 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13326                 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13327                 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13328                 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13329                 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13330                 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13331                 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13332                 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13333                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13334                 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13335                 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13336                 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13337                 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13338                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13339                 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13340                 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13341                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13342                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13343                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13344                 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13345                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13346                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13347                 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13348                 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13349                 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13350                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13351                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13352                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13353                 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13354                 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13355                 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13356                 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13357                 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13358                 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13359                 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13360                 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13361                 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13362                 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13363                 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13364                 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13365                 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13366                 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13367                 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13368                 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13369                 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13370                 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13371                 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13372                 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13373                 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13374                 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13375                 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13376                 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13377                 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13378         };
13379         static struct bwn_txgain_entry txgain_r0[] = {
13380                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13381                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13382                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13383                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13384                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13385                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13386                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13387                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13388                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13389                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13390                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13391                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13392                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13393                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13394                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13395                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13396                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13397                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13398                 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13399                 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13400                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13401                 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13402                 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13403                 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13404                 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13405                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13406                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13407                 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13408                 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13409                 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13410                 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13411                 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13412                 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13413                 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13414                 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13415                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13416                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13417                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13418                 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13419                 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13420                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13421                 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13422                 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13423                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13424                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13425                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13426                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13427                 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13428                 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13429                 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13430                 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13431                 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13432                 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13433                 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13434                 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13435                 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13436                 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13437                 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13438                 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13439                 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13440                 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13441                 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13442                 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13443                 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13444         };
13445         static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13446                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13447                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13448                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13449                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13450                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13451                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13452                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13453                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13454                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13455                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13456                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13457                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13458                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13459                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13460                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13461                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13462                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13463                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13464                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13465                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13466                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13467                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13468                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13469                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13470                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13471                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13472                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13473                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13474                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13475                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13476                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13477                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13478                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13479                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13480                 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13481                 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13482                 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13483                 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13484                 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13485                 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13486                 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13487                 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13488                 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13489                 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13490                 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13491                 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13492                 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13493                 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13494                 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13495                 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13496                 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13497                 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13498                 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13499                 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13500                 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13501                 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13502                 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13503                 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13504                 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13505                 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13506                 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13507                 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13508                 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13509                 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13510         };
13511         static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13512                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13513                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13514                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13515                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13516                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13517                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13518                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13519                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13520                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13521                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13522                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13523                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13524                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13525                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13526                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13527                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13528                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13529                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13530                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13531                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13532                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13533                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13534                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13535                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13536                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13537                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13538                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13539                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13540                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13541                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13542                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13543                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13544                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13545                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13546                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13547                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13548                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13549                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13550                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13551                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13552                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13553                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13554                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13555                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13556                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13557                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13558                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13559                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13560                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13561                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13562                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13563                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13564                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13565                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13566                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13567                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13568                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13569                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13570                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13571                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13572                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13573                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13574                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13575                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13576         };
13577         static struct bwn_txgain_entry txgain_r1[] = {
13578                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13579                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13580                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13581                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13582                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13583                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13584                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13585                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13586                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13587                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13588                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13589                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13590                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13591                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13592                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13593                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13594                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13595                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13596                 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13597                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13598                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13599                 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13600                 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13601                 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13602                 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13603                 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13604                 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13605                 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13606                 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13607                 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13608                 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13609                 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13610                 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13611                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13612                 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13613                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13614                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13615                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13616                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13617                 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13618                 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13619                 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13620                 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13621                 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13622                 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13623                 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13624                 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13625                 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13626                 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13627                 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13628                 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13629                 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13630                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13631                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13632                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13633                 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13634                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13635                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13636                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13637                 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13638                 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13639                 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13640                 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13641                 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13642                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13643                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13644                 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13645                 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13646                 { 7, 11, 6, 0, 71 }
13647         };
13648         static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13649                 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13650                 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13651                 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13652                 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13653                 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13654                 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13655                 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13656                 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13657                 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13658                 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13659                 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13660                 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13661                 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13662                 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13663                 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13664                 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13665                 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13666                 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13667                 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13668                 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13669                 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13670                 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13671                 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13672                 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13673                 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13674                 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13675                 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13676                 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13677                 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13678                 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13679                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13680                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13681                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13682                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13683                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13684                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13685                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13686                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13687                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13688                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13689                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13690                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13691                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13692                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13693                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13694                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13695                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13696                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13697                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13698                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13699                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13700                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13701                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13702                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13703                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13704                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13705                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13706                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13707                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13708                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13709                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13710                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13711                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13712                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13713         };
13714         static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13715                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13716                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13717                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13718                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13719                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13720                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13721                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13722                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13723                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13724                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13725                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13726                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13727                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13728                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13729                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13730                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13731                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13732                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13733                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13734                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13735                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13736                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13737                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13738                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13739                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13740                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13741                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13742                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13743                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13744                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13745                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13746                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13747                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13748                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13749                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13750                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13751                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13752                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13753                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13754                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13755                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13756                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13757                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13758                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13759                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13760                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13761                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13762                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13763                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13764                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13765                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13766                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13767                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13768                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13769                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13770                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13771                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13772                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13773                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13774                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13775                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13776                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13777                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13778                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13779         };
13780
13781         if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13782                 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13783                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13784                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13785                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13786                             txgain_2ghz_r2);
13787                 else
13788                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13789                             txgain_5ghz_r2);
13790                 return;
13791         }
13792
13793         if (mac->mac_phy.rev == 0) {
13794                 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13795                     (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13796                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13797                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13798                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13799                             txgain_2ghz_r0);
13800                 else
13801                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13802                             txgain_5ghz_r0);
13803                 return;
13804         }
13805
13806         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13807             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13808                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13809         else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13810                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13811         else
13812                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13813 }
13814
13815 static void
13816 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13817 {
13818         uint32_t offset, type;
13819
13820         type = BWN_TAB_GETTYPE(typeoffset);
13821         offset = BWN_TAB_GETOFFSET(typeoffset);
13822         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13823
13824         switch (type) {
13825         case BWN_TAB_8BIT:
13826                 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13827                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13828                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13829                 break;
13830         case BWN_TAB_16BIT:
13831                 KASSERT(!(value & ~0xffff),
13832                     ("%s:%d: fail", __func__, __LINE__));
13833                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13834                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13835                 break;
13836         case BWN_TAB_32BIT:
13837                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13838                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13839                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13840                 break;
13841         default:
13842                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13843         }
13844 }
13845
13846 static int
13847 bwn_phy_lp_loopback(struct bwn_mac *mac)
13848 {
13849         struct bwn_phy_lp_iq_est ie;
13850         int i, index = -1;
13851         uint32_t tmp;
13852
13853         memset(&ie, 0, sizeof(ie));
13854
13855         bwn_phy_lp_set_trsw_over(mac, 1, 1);
13856         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13857         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13858         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13859         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13860         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13861         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13862         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13863         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13864         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13865         for (i = 0; i < 32; i++) {
13866                 bwn_phy_lp_set_rxgain_idx(mac, i);
13867                 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13868                 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13869                         continue;
13870                 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13871                 if ((tmp > 4000) && (tmp < 10000)) {
13872                         index = i;
13873                         break;
13874                 }
13875         }
13876         bwn_phy_lp_ddfs_turnoff(mac);
13877         return (index);
13878 }
13879
13880 static void
13881 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13882 {
13883
13884         bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
13885 }
13886
13887 static void
13888 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
13889     int incr1, int incr2, int scale_idx)
13890 {
13891
13892         bwn_phy_lp_ddfs_turnoff(mac);
13893         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
13894         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
13895         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
13896         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
13897         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
13898         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
13899         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
13900         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
13901         BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
13902         BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
13903 }
13904
13905 static uint8_t
13906 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
13907     struct bwn_phy_lp_iq_est *ie)
13908 {
13909         int i;
13910
13911         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
13912         BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
13913         BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
13914         BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
13915         BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
13916
13917         for (i = 0; i < 500; i++) {
13918                 if (!(BWN_PHY_READ(mac,
13919                     BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
13920                         break;
13921                 DELAY(1000);
13922         }
13923         if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
13924                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
13925                 return 0;
13926         }
13927
13928         ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
13929         ie->ie_iqprod <<= 16;
13930         ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
13931         ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
13932         ie->ie_ipwr <<= 16;
13933         ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
13934         ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
13935         ie->ie_qpwr <<= 16;
13936         ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
13937
13938         BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
13939         return 1;
13940 }
13941
13942 static uint32_t
13943 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
13944 {
13945         uint32_t offset, type, value;
13946
13947         type = BWN_TAB_GETTYPE(typeoffset);
13948         offset = BWN_TAB_GETOFFSET(typeoffset);
13949         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13950
13951         switch (type) {
13952         case BWN_TAB_8BIT:
13953                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13954                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
13955                 break;
13956         case BWN_TAB_16BIT:
13957                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13958                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
13959                 break;
13960         case BWN_TAB_32BIT:
13961                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13962                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
13963                 value <<= 16;
13964                 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
13965                 break;
13966         default:
13967                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13968                 value = 0;
13969         }
13970
13971         return (value);
13972 }
13973
13974 static void
13975 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
13976 {
13977
13978         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
13979         BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
13980 }
13981
13982 static void
13983 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
13984 {
13985         uint16_t ctl;
13986
13987         ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
13988         ctl |= dac << 7;
13989         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
13990 }
13991
13992 static void
13993 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
13994 {
13995
13996         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
13997         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
13998 }
13999
14000 static void
14001 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
14002 {
14003
14004         if (mac->mac_phy.rev < 2)
14005                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
14006         else {
14007                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
14008                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
14009         }
14010         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
14011 }
14012
14013 static uint16_t
14014 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
14015 {
14016
14017         return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
14018 }
14019
14020 static uint8_t
14021 bwn_nbits(int32_t val)
14022 {
14023         uint32_t tmp;
14024         uint8_t nbits = 0;
14025
14026         for (tmp = abs(val); tmp != 0; tmp >>= 1)
14027                 nbits++;
14028         return (nbits);
14029 }
14030
14031 static void
14032 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
14033     struct bwn_txgain_entry *table)
14034 {
14035         int i;
14036
14037         for (i = offset; i < count; i++)
14038                 bwn_phy_lp_gaintbl_write(mac, i, table[i]);
14039 }
14040
14041 static void
14042 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
14043     struct bwn_txgain_entry data)
14044 {
14045
14046         if (mac->mac_phy.rev >= 2)
14047                 bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14048         else
14049                 bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14050 }
14051
14052 static void
14053 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14054     struct bwn_txgain_entry te)
14055 {
14056         struct bwn_softc *sc = mac->mac_sc;
14057         struct ifnet *ifp = sc->sc_ifp;
14058         struct ieee80211com *ic = ifp->if_l2com;
14059         uint32_t tmp;
14060
14061         KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14062
14063         tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14064         if (mac->mac_phy.rev >= 3) {
14065                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14066                     (0x10 << 24) : (0x70 << 24));
14067         } else {
14068                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14069                     (0x14 << 24) : (0x7f << 24));
14070         }
14071         bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14072         bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14073             te.te_bbmult << 20 | te.te_dac << 28);
14074 }
14075
14076 static void
14077 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14078     struct bwn_txgain_entry te)
14079 {
14080
14081         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14082
14083         bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14084             (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm  << 4) |
14085             te.te_dac);
14086         bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14087 }
14088
14089 static void
14090 bwn_sysctl_node(struct bwn_softc *sc)
14091 {
14092         struct bwn_mac *mac;
14093         struct bwn_stats *stats;
14094         struct sysctl_ctx_list *ctx;
14095         struct sysctl_oid *tree;
14096
14097         /* XXX assume that count of MAC is only 1. */
14098
14099         if ((mac = sc->sc_curmac) == NULL)
14100                 return;
14101         stats = &mac->mac_stats;
14102
14103         ctx = device_get_sysctl_ctx(sc->sc_dev);
14104         tree = device_get_sysctl_tree(sc->sc_dev);
14105         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14106             "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14107         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14108             "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14109         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14110             "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14111
14112 #ifdef BWN_DEBUG
14113         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14114             "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14115 #endif
14116 }
14117
14118 static device_method_t bwn_methods[] = {
14119         /* Device interface */
14120         DEVMETHOD(device_probe,         bwn_probe),
14121         DEVMETHOD(device_attach,        bwn_attach),
14122         DEVMETHOD(device_detach,        bwn_detach),
14123         DEVMETHOD(device_suspend,       bwn_suspend),
14124         DEVMETHOD(device_resume,        bwn_resume),
14125         DEVMETHOD_END
14126 };
14127 static driver_t bwn_driver = {
14128         "bwn",
14129         bwn_methods,
14130         sizeof(struct bwn_softc)
14131 };
14132 static devclass_t bwn_devclass;
14133 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, NULL, NULL);
14134 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14135 MODULE_DEPEND(bwn, wlan, 1, 1, 1);              /* 802.11 media layer */
14136 MODULE_DEPEND(bwn, firmware, 1, 1, 1);          /* firmware support */
14137 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);