]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/bwn/if_bwn.c
MFH r289384-r293170
[FreeBSD/FreeBSD.git] / sys / dev / bwn / if_bwn.c
1 /*-
2  * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer,
10  *    without modification.
11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13  *    redistribution must be conditioned upon including a substantially
14  *    similar Disclaimer requirement for further binary redistribution.
15  *
16  * NO WARRANTY
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27  * THE POSSIBILITY OF SUCH DAMAGES.
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 /*
34  * The Broadcom Wireless LAN controller driver.
35  */
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/module.h>
40 #include <sys/kernel.h>
41 #include <sys/endian.h>
42 #include <sys/errno.h>
43 #include <sys/firmware.h>
44 #include <sys/lock.h>
45 #include <sys/mutex.h>
46 #include <machine/bus.h>
47 #include <machine/resource.h>
48 #include <sys/bus.h>
49 #include <sys/rman.h>
50 #include <sys/socket.h>
51 #include <sys/sockio.h>
52
53 #include <net/ethernet.h>
54 #include <net/if.h>
55 #include <net/if_var.h>
56 #include <net/if_arp.h>
57 #include <net/if_dl.h>
58 #include <net/if_llc.h>
59 #include <net/if_media.h>
60 #include <net/if_types.h>
61
62 #include <dev/pci/pcivar.h>
63 #include <dev/pci/pcireg.h>
64 #include <dev/siba/siba_ids.h>
65 #include <dev/siba/sibareg.h>
66 #include <dev/siba/sibavar.h>
67
68 #include <net80211/ieee80211_var.h>
69 #include <net80211/ieee80211_radiotap.h>
70 #include <net80211/ieee80211_regdomain.h>
71 #include <net80211/ieee80211_phy.h>
72 #include <net80211/ieee80211_ratectl.h>
73
74 #include <dev/bwn/if_bwnreg.h>
75 #include <dev/bwn/if_bwnvar.h>
76
77 static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0,
78     "Broadcom driver parameters");
79
80 /*
81  * Tunable & sysctl variables.
82  */
83
84 #ifdef BWN_DEBUG
85 static  int bwn_debug = 0;
86 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RWTUN, &bwn_debug, 0,
87     "Broadcom debugging printfs");
88 enum {
89         BWN_DEBUG_XMIT          = 0x00000001,   /* basic xmit operation */
90         BWN_DEBUG_RECV          = 0x00000002,   /* basic recv operation */
91         BWN_DEBUG_STATE         = 0x00000004,   /* 802.11 state transitions */
92         BWN_DEBUG_TXPOW         = 0x00000008,   /* tx power processing */
93         BWN_DEBUG_RESET         = 0x00000010,   /* reset processing */
94         BWN_DEBUG_OPS           = 0x00000020,   /* bwn_ops processing */
95         BWN_DEBUG_BEACON        = 0x00000040,   /* beacon handling */
96         BWN_DEBUG_WATCHDOG      = 0x00000080,   /* watchdog timeout */
97         BWN_DEBUG_INTR          = 0x00000100,   /* ISR */
98         BWN_DEBUG_CALIBRATE     = 0x00000200,   /* periodic calibration */
99         BWN_DEBUG_NODE          = 0x00000400,   /* node management */
100         BWN_DEBUG_LED           = 0x00000800,   /* led management */
101         BWN_DEBUG_CMD           = 0x00001000,   /* cmd submission */
102         BWN_DEBUG_LO            = 0x00002000,   /* LO */
103         BWN_DEBUG_FW            = 0x00004000,   /* firmware */
104         BWN_DEBUG_WME           = 0x00008000,   /* WME */
105         BWN_DEBUG_RF            = 0x00010000,   /* RF */
106         BWN_DEBUG_FATAL         = 0x80000000,   /* fatal errors */
107         BWN_DEBUG_ANY           = 0xffffffff
108 };
109 #define DPRINTF(sc, m, fmt, ...) do {                   \
110         if (sc->sc_debug & (m))                         \
111                 printf(fmt, __VA_ARGS__);               \
112 } while (0)
113 #else
114 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
115 #endif
116
117 static int      bwn_bfp = 0;            /* use "Bad Frames Preemption" */
118 SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0,
119     "uses Bad Frames Preemption");
120 static int      bwn_bluetooth = 1;
121 SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0,
122     "turns on Bluetooth Coexistence");
123 static int      bwn_hwpctl = 0;
124 SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0,
125     "uses H/W power control");
126 static int      bwn_msi_disable = 0;            /* MSI disabled  */
127 TUNABLE_INT("hw.bwn.msi_disable", &bwn_msi_disable);
128 static int      bwn_usedma = 1;
129 SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0,
130     "uses DMA");
131 TUNABLE_INT("hw.bwn.usedma", &bwn_usedma);
132 static int      bwn_wme = 1;
133 SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0,
134     "uses WME support");
135
136 static void     bwn_attach_pre(struct bwn_softc *);
137 static int      bwn_attach_post(struct bwn_softc *);
138 static void     bwn_sprom_bugfixes(device_t);
139 static int      bwn_init(struct bwn_softc *);
140 static void     bwn_parent(struct ieee80211com *);
141 static void     bwn_start(struct bwn_softc *);
142 static int      bwn_transmit(struct ieee80211com *, struct mbuf *);
143 static int      bwn_attach_core(struct bwn_mac *);
144 static void     bwn_reset_core(struct bwn_mac *, uint32_t);
145 static int      bwn_phy_getinfo(struct bwn_mac *, int);
146 static int      bwn_chiptest(struct bwn_mac *);
147 static int      bwn_setup_channels(struct bwn_mac *, int, int);
148 static int      bwn_phy_g_attach(struct bwn_mac *);
149 static void     bwn_phy_g_detach(struct bwn_mac *);
150 static void     bwn_phy_g_init_pre(struct bwn_mac *);
151 static int      bwn_phy_g_prepare_hw(struct bwn_mac *);
152 static int      bwn_phy_g_init(struct bwn_mac *);
153 static void     bwn_phy_g_exit(struct bwn_mac *);
154 static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t);
155 static void     bwn_phy_g_write(struct bwn_mac *, uint16_t,
156                     uint16_t);
157 static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t);
158 static void     bwn_phy_g_rf_write(struct bwn_mac *, uint16_t,
159                     uint16_t);
160 static int      bwn_phy_g_hwpctl(struct bwn_mac *);
161 static void     bwn_phy_g_rf_onoff(struct bwn_mac *, int);
162 static int      bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t);
163 static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *);
164 static void     bwn_phy_g_set_antenna(struct bwn_mac *, int);
165 static int      bwn_phy_g_im(struct bwn_mac *, int);
166 static int      bwn_phy_g_recalc_txpwr(struct bwn_mac *, int);
167 static void     bwn_phy_g_set_txpwr(struct bwn_mac *);
168 static void     bwn_phy_g_task_15s(struct bwn_mac *);
169 static void     bwn_phy_g_task_60s(struct bwn_mac *);
170 static uint16_t bwn_phy_g_txctl(struct bwn_mac *);
171 static void     bwn_phy_switch_analog(struct bwn_mac *, int);
172 static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t);
173 static void     bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t,
174                     uint16_t);
175 static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t);
176 static void     bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t,
177                     uint32_t);
178 static void     bwn_shm_ctlword(struct bwn_mac *, uint16_t,
179                     uint16_t);
180 static void     bwn_addchannels(struct ieee80211_channel [], int, int *,
181                     const struct bwn_channelinfo *, int);
182 static int      bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
183                     const struct ieee80211_bpf_params *);
184 static void     bwn_updateslot(struct ieee80211com *);
185 static void     bwn_update_promisc(struct ieee80211com *);
186 static void     bwn_wme_init(struct bwn_mac *);
187 static int      bwn_wme_update(struct ieee80211com *);
188 static void     bwn_wme_clear(struct bwn_softc *);
189 static void     bwn_wme_load(struct bwn_mac *);
190 static void     bwn_wme_loadparams(struct bwn_mac *,
191                     const struct wmeParams *, uint16_t);
192 static void     bwn_scan_start(struct ieee80211com *);
193 static void     bwn_scan_end(struct ieee80211com *);
194 static void     bwn_set_channel(struct ieee80211com *);
195 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *,
196                     const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
197                     const uint8_t [IEEE80211_ADDR_LEN],
198                     const uint8_t [IEEE80211_ADDR_LEN]);
199 static void     bwn_vap_delete(struct ieee80211vap *);
200 static void     bwn_stop(struct bwn_softc *);
201 static int      bwn_core_init(struct bwn_mac *);
202 static void     bwn_core_start(struct bwn_mac *);
203 static void     bwn_core_exit(struct bwn_mac *);
204 static void     bwn_bt_disable(struct bwn_mac *);
205 static int      bwn_chip_init(struct bwn_mac *);
206 static uint64_t bwn_hf_read(struct bwn_mac *);
207 static void     bwn_hf_write(struct bwn_mac *, uint64_t);
208 static void     bwn_set_txretry(struct bwn_mac *, int, int);
209 static void     bwn_rate_init(struct bwn_mac *);
210 static void     bwn_set_phytxctl(struct bwn_mac *);
211 static void     bwn_spu_setdelay(struct bwn_mac *, int);
212 static void     bwn_bt_enable(struct bwn_mac *);
213 static void     bwn_set_macaddr(struct bwn_mac *);
214 static void     bwn_crypt_init(struct bwn_mac *);
215 static void     bwn_chip_exit(struct bwn_mac *);
216 static int      bwn_fw_fillinfo(struct bwn_mac *);
217 static int      bwn_fw_loaducode(struct bwn_mac *);
218 static int      bwn_gpio_init(struct bwn_mac *);
219 static int      bwn_fw_loadinitvals(struct bwn_mac *);
220 static int      bwn_phy_init(struct bwn_mac *);
221 static void     bwn_set_txantenna(struct bwn_mac *, int);
222 static void     bwn_set_opmode(struct bwn_mac *);
223 static void     bwn_rate_write(struct bwn_mac *, uint16_t, int);
224 static uint8_t  bwn_plcp_getcck(const uint8_t);
225 static uint8_t  bwn_plcp_getofdm(const uint8_t);
226 static void     bwn_pio_init(struct bwn_mac *);
227 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int);
228 static void     bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *,
229                     int);
230 static void     bwn_pio_setupqueue_rx(struct bwn_mac *,
231                     struct bwn_pio_rxqueue *, int);
232 static void     bwn_destroy_queue_tx(struct bwn_pio_txqueue *);
233 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *,
234                     uint16_t);
235 static void     bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *);
236 static int      bwn_pio_rx(struct bwn_pio_rxqueue *);
237 static uint8_t  bwn_pio_rxeof(struct bwn_pio_rxqueue *);
238 static void     bwn_pio_handle_txeof(struct bwn_mac *,
239                     const struct bwn_txstatus *);
240 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t);
241 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t);
242 static void     bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t,
243                     uint16_t);
244 static void     bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t,
245                     uint32_t);
246 static int      bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *,
247                     struct mbuf *);
248 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t);
249 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *,
250                     struct bwn_pio_txqueue *, uint32_t, const void *, int);
251 static void     bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *,
252                     uint16_t, uint32_t);
253 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *,
254                     struct bwn_pio_txqueue *, uint16_t, const void *, int);
255 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *,
256                     struct bwn_pio_txqueue *, uint16_t, struct mbuf *);
257 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *,
258                     uint16_t, struct bwn_pio_txpkt **);
259 static void     bwn_dma_init(struct bwn_mac *);
260 static void     bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t);
261 static int      bwn_dma_mask2type(uint64_t);
262 static uint64_t bwn_dma_mask(struct bwn_mac *);
263 static uint16_t bwn_dma_base(int, int);
264 static void     bwn_dma_ringfree(struct bwn_dma_ring **);
265 static void     bwn_dma_32_getdesc(struct bwn_dma_ring *,
266                     int, struct bwn_dmadesc_generic **,
267                     struct bwn_dmadesc_meta **);
268 static void     bwn_dma_32_setdesc(struct bwn_dma_ring *,
269                     struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
270                     int, int);
271 static void     bwn_dma_32_start_transfer(struct bwn_dma_ring *, int);
272 static void     bwn_dma_32_suspend(struct bwn_dma_ring *);
273 static void     bwn_dma_32_resume(struct bwn_dma_ring *);
274 static int      bwn_dma_32_get_curslot(struct bwn_dma_ring *);
275 static void     bwn_dma_32_set_curslot(struct bwn_dma_ring *, int);
276 static void     bwn_dma_64_getdesc(struct bwn_dma_ring *,
277                     int, struct bwn_dmadesc_generic **,
278                     struct bwn_dmadesc_meta **);
279 static void     bwn_dma_64_setdesc(struct bwn_dma_ring *,
280                     struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
281                     int, int);
282 static void     bwn_dma_64_start_transfer(struct bwn_dma_ring *, int);
283 static void     bwn_dma_64_suspend(struct bwn_dma_ring *);
284 static void     bwn_dma_64_resume(struct bwn_dma_ring *);
285 static int      bwn_dma_64_get_curslot(struct bwn_dma_ring *);
286 static void     bwn_dma_64_set_curslot(struct bwn_dma_ring *, int);
287 static int      bwn_dma_allocringmemory(struct bwn_dma_ring *);
288 static void     bwn_dma_setup(struct bwn_dma_ring *);
289 static void     bwn_dma_free_ringmemory(struct bwn_dma_ring *);
290 static void     bwn_dma_cleanup(struct bwn_dma_ring *);
291 static void     bwn_dma_free_descbufs(struct bwn_dma_ring *);
292 static int      bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int);
293 static void     bwn_dma_rx(struct bwn_dma_ring *);
294 static int      bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int);
295 static void     bwn_dma_free_descbuf(struct bwn_dma_ring *,
296                     struct bwn_dmadesc_meta *);
297 static void     bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *);
298 static int      bwn_dma_gettype(struct bwn_mac *);
299 static void     bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int);
300 static int      bwn_dma_freeslot(struct bwn_dma_ring *);
301 static int      bwn_dma_nextslot(struct bwn_dma_ring *, int);
302 static void     bwn_dma_rxeof(struct bwn_dma_ring *, int *);
303 static int      bwn_dma_newbuf(struct bwn_dma_ring *,
304                     struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *,
305                     int);
306 static void     bwn_dma_buf_addr(void *, bus_dma_segment_t *, int,
307                     bus_size_t, int);
308 static uint8_t  bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *);
309 static void     bwn_dma_handle_txeof(struct bwn_mac *,
310                     const struct bwn_txstatus *);
311 static int      bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *,
312                     struct mbuf *);
313 static int      bwn_dma_getslot(struct bwn_dma_ring *);
314 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *,
315                     uint8_t);
316 static int      bwn_dma_attach(struct bwn_mac *);
317 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *,
318                     int, int, int);
319 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *,
320                     const struct bwn_txstatus *, uint16_t, int *);
321 static void     bwn_dma_free(struct bwn_mac *);
322 static void     bwn_phy_g_init_sub(struct bwn_mac *);
323 static uint8_t  bwn_has_hwpctl(struct bwn_mac *);
324 static void     bwn_phy_init_b5(struct bwn_mac *);
325 static void     bwn_phy_init_b6(struct bwn_mac *);
326 static void     bwn_phy_init_a(struct bwn_mac *);
327 static void     bwn_loopback_calcgain(struct bwn_mac *);
328 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *);
329 static void     bwn_lo_g_init(struct bwn_mac *);
330 static void     bwn_lo_g_adjust(struct bwn_mac *);
331 static void     bwn_lo_get_powervector(struct bwn_mac *);
332 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *,
333                     const struct bwn_bbatt *, const struct bwn_rfatt *);
334 static void     bwn_lo_write(struct bwn_mac *, struct bwn_loctl *);
335 static void     bwn_phy_hwpctl_init(struct bwn_mac *);
336 static void     bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t);
337 static void     bwn_phy_g_set_txpwr_sub(struct bwn_mac *,
338                     const struct bwn_bbatt *, const struct bwn_rfatt *,
339                     uint8_t);
340 static void     bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t);
341 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t);
342 static void     bwn_spu_workaround(struct bwn_mac *, uint8_t);
343 static void     bwn_wa_init(struct bwn_mac *);
344 static void     bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t,
345                     uint16_t);
346 static void     bwn_dummy_transmission(struct bwn_mac *, int, int);
347 static void     bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t,
348                     uint32_t);
349 static void     bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t,
350                     uint16_t);
351 static void     bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t);
352 static void     bwn_mac_suspend(struct bwn_mac *);
353 static void     bwn_mac_enable(struct bwn_mac *);
354 static void     bwn_psctl(struct bwn_mac *, uint32_t);
355 static int16_t  bwn_nrssi_read(struct bwn_mac *, uint16_t);
356 static void     bwn_nrssi_offset(struct bwn_mac *);
357 static void     bwn_nrssi_threshold(struct bwn_mac *);
358 static void     bwn_nrssi_slope_11g(struct bwn_mac *);
359 static void     bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t,
360                     int16_t);
361 static void     bwn_set_original_gains(struct bwn_mac *);
362 static void     bwn_hwpctl_early_init(struct bwn_mac *);
363 static void     bwn_hwpctl_init_gphy(struct bwn_mac *);
364 static uint16_t bwn_phy_g_chan2freq(uint8_t);
365 static int      bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype);
366 static int      bwn_fw_get(struct bwn_mac *, enum bwn_fwtype,
367                     const char *, struct bwn_fwfile *);
368 static void     bwn_release_firmware(struct bwn_mac *);
369 static void     bwn_do_release_fw(struct bwn_fwfile *);
370 static uint16_t bwn_fwcaps_read(struct bwn_mac *);
371 static int      bwn_fwinitvals_write(struct bwn_mac *,
372                     const struct bwn_fwinitvals *, size_t, size_t);
373 static int      bwn_switch_channel(struct bwn_mac *, int);
374 static uint16_t bwn_ant2phy(int);
375 static void     bwn_mac_write_bssid(struct bwn_mac *);
376 static void     bwn_mac_setfilter(struct bwn_mac *, uint16_t,
377                     const uint8_t *);
378 static void     bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t,
379                     const uint8_t *, size_t, const uint8_t *);
380 static void     bwn_key_macwrite(struct bwn_mac *, uint8_t,
381                     const uint8_t *);
382 static void     bwn_key_write(struct bwn_mac *, uint8_t, uint8_t,
383                     const uint8_t *);
384 static void     bwn_phy_exit(struct bwn_mac *);
385 static void     bwn_core_stop(struct bwn_mac *);
386 static int      bwn_switch_band(struct bwn_softc *,
387                     struct ieee80211_channel *);
388 static void     bwn_phy_reset(struct bwn_mac *);
389 static int      bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
390 static void     bwn_set_pretbtt(struct bwn_mac *);
391 static int      bwn_intr(void *);
392 static void     bwn_intrtask(void *, int);
393 static void     bwn_restart(struct bwn_mac *, const char *);
394 static void     bwn_intr_ucode_debug(struct bwn_mac *);
395 static void     bwn_intr_tbtt_indication(struct bwn_mac *);
396 static void     bwn_intr_atim_end(struct bwn_mac *);
397 static void     bwn_intr_beacon(struct bwn_mac *);
398 static void     bwn_intr_pmq(struct bwn_mac *);
399 static void     bwn_intr_noise(struct bwn_mac *);
400 static void     bwn_intr_txeof(struct bwn_mac *);
401 static void     bwn_hwreset(void *, int);
402 static void     bwn_handle_fwpanic(struct bwn_mac *);
403 static void     bwn_load_beacon0(struct bwn_mac *);
404 static void     bwn_load_beacon1(struct bwn_mac *);
405 static uint32_t bwn_jssi_read(struct bwn_mac *);
406 static void     bwn_noise_gensample(struct bwn_mac *);
407 static void     bwn_handle_txeof(struct bwn_mac *,
408                     const struct bwn_txstatus *);
409 static void     bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *);
410 static void     bwn_phy_txpower_check(struct bwn_mac *, uint32_t);
411 static int      bwn_tx_start(struct bwn_softc *, struct ieee80211_node *,
412                     struct mbuf *);
413 static int      bwn_tx_isfull(struct bwn_softc *, struct mbuf *);
414 static int      bwn_set_txhdr(struct bwn_mac *,
415                     struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *,
416                     uint16_t);
417 static void     bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t,
418                     const uint8_t);
419 static uint8_t  bwn_antenna_sanitize(struct bwn_mac *, uint8_t);
420 static uint8_t  bwn_get_fbrate(uint8_t);
421 static int      bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t);
422 static void     bwn_phy_g_setatt(struct bwn_mac *, int *, int *);
423 static void     bwn_phy_lock(struct bwn_mac *);
424 static void     bwn_phy_unlock(struct bwn_mac *);
425 static void     bwn_rf_lock(struct bwn_mac *);
426 static void     bwn_rf_unlock(struct bwn_mac *);
427 static void     bwn_txpwr(void *, int);
428 static void     bwn_tasks(void *);
429 static void     bwn_task_15s(struct bwn_mac *);
430 static void     bwn_task_30s(struct bwn_mac *);
431 static void     bwn_task_60s(struct bwn_mac *);
432 static int      bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *,
433                     uint8_t);
434 static int      bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *);
435 static void     bwn_rx_radiotap(struct bwn_mac *, struct mbuf *,
436                     const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int,
437                     int, int);
438 static void     bwn_tsf_read(struct bwn_mac *, uint64_t *);
439 static void     bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t);
440 static void     bwn_set_slot_time(struct bwn_mac *, uint16_t);
441 static void     bwn_watchdog(void *);
442 static void     bwn_dma_stop(struct bwn_mac *);
443 static void     bwn_pio_stop(struct bwn_mac *);
444 static void     bwn_dma_ringstop(struct bwn_dma_ring **);
445 static void     bwn_led_attach(struct bwn_mac *);
446 static void     bwn_led_newstate(struct bwn_mac *, enum ieee80211_state);
447 static void     bwn_led_event(struct bwn_mac *, int);
448 static void     bwn_led_blink_start(struct bwn_mac *, int, int);
449 static void     bwn_led_blink_next(void *);
450 static void     bwn_led_blink_end(void *);
451 static void     bwn_rfswitch(void *);
452 static void     bwn_rf_turnon(struct bwn_mac *);
453 static void     bwn_rf_turnoff(struct bwn_mac *);
454 static void     bwn_phy_lp_init_pre(struct bwn_mac *);
455 static int      bwn_phy_lp_init(struct bwn_mac *);
456 static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t);
457 static void     bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t);
458 static void     bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t,
459                     uint16_t);
460 static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t);
461 static void     bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t);
462 static void     bwn_phy_lp_rf_onoff(struct bwn_mac *, int);
463 static int      bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t);
464 static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *);
465 static void     bwn_phy_lp_set_antenna(struct bwn_mac *, int);
466 static void     bwn_phy_lp_task_60s(struct bwn_mac *);
467 static void     bwn_phy_lp_readsprom(struct bwn_mac *);
468 static void     bwn_phy_lp_bbinit(struct bwn_mac *);
469 static void     bwn_phy_lp_txpctl_init(struct bwn_mac *);
470 static void     bwn_phy_lp_calib(struct bwn_mac *);
471 static void     bwn_phy_lp_switch_analog(struct bwn_mac *, int);
472 static int      bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t);
473 static int      bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t);
474 static void     bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t);
475 static void     bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t);
476 static void     bwn_phy_lp_digflt_save(struct bwn_mac *);
477 static void     bwn_phy_lp_get_txpctlmode(struct bwn_mac *);
478 static void     bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t);
479 static void     bwn_phy_lp_bugfix(struct bwn_mac *);
480 static void     bwn_phy_lp_digflt_restore(struct bwn_mac *);
481 static void     bwn_phy_lp_tblinit(struct bwn_mac *);
482 static void     bwn_phy_lp_bbinit_r2(struct bwn_mac *);
483 static void     bwn_phy_lp_bbinit_r01(struct bwn_mac *);
484 static void     bwn_phy_lp_b2062_init(struct bwn_mac *);
485 static void     bwn_phy_lp_b2063_init(struct bwn_mac *);
486 static void     bwn_phy_lp_rxcal_r2(struct bwn_mac *);
487 static void     bwn_phy_lp_rccal_r12(struct bwn_mac *);
488 static void     bwn_phy_lp_set_rccap(struct bwn_mac *);
489 static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t);
490 static void     bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *);
491 static void     bwn_phy_lp_b2062_vco_calib(struct bwn_mac *);
492 static void     bwn_tab_write_multi(struct bwn_mac *, uint32_t, int,
493                     const void *);
494 static void     bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *);
495 static struct bwn_txgain
496                 bwn_phy_lp_get_txgain(struct bwn_mac *);
497 static uint8_t  bwn_phy_lp_get_bbmult(struct bwn_mac *);
498 static void     bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *);
499 static void     bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t);
500 static void     bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t);
501 static void     bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t);
502 static void     bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t);
503 static int      bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t);
504 static void     bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t);
505 static void     bwn_phy_lp_tblinit_r01(struct bwn_mac *);
506 static void     bwn_phy_lp_tblinit_r2(struct bwn_mac *);
507 static void     bwn_phy_lp_tblinit_txgain(struct bwn_mac *);
508 static void     bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t);
509 static void     bwn_phy_lp_b2062_tblinit(struct bwn_mac *);
510 static void     bwn_phy_lp_b2063_tblinit(struct bwn_mac *);
511 static int      bwn_phy_lp_loopback(struct bwn_mac *);
512 static void     bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t);
513 static void     bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int,
514                     int);
515 static uint8_t  bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t,
516                     struct bwn_phy_lp_iq_est *);
517 static void     bwn_phy_lp_ddfs_turnoff(struct bwn_mac *);
518 static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t);
519 static void     bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t);
520 static void     bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t);
521 static void     bwn_phy_lp_set_txgain_override(struct bwn_mac *);
522 static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *);
523 static uint8_t  bwn_nbits(int32_t);
524 static void     bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int,
525                     struct bwn_txgain_entry *);
526 static void     bwn_phy_lp_gaintbl_write(struct bwn_mac *, int,
527                     struct bwn_txgain_entry);
528 static void     bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int,
529                     struct bwn_txgain_entry);
530 static void     bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int,
531                     struct bwn_txgain_entry);
532 static void     bwn_sysctl_node(struct bwn_softc *);
533
534 static struct resource_spec bwn_res_spec_legacy[] = {
535         { SYS_RES_IRQ,          0,              RF_ACTIVE | RF_SHAREABLE },
536         { -1,                   0,              0 }
537 };
538
539 static struct resource_spec bwn_res_spec_msi[] = {
540         { SYS_RES_IRQ,          1,              RF_ACTIVE },
541         { -1,                   0,              0 }
542 };
543
544 static const struct bwn_channelinfo bwn_chantable_bg = {
545         .channels = {
546                 { 2412,  1, 30 }, { 2417,  2, 30 }, { 2422,  3, 30 },
547                 { 2427,  4, 30 }, { 2432,  5, 30 }, { 2437,  6, 30 },
548                 { 2442,  7, 30 }, { 2447,  8, 30 }, { 2452,  9, 30 },
549                 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 },
550                 { 2472, 13, 30 }, { 2484, 14, 30 } },
551         .nchannels = 14
552 };
553
554 static const struct bwn_channelinfo bwn_chantable_a = {
555         .channels = {
556                 { 5170,  34, 30 }, { 5180,  36, 30 }, { 5190,  38, 30 },
557                 { 5200,  40, 30 }, { 5210,  42, 30 }, { 5220,  44, 30 },
558                 { 5230,  46, 30 }, { 5240,  48, 30 }, { 5260,  52, 30 },
559                 { 5280,  56, 30 }, { 5300,  60, 30 }, { 5320,  64, 30 },
560                 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 },
561                 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 },
562                 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 },
563                 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 },
564                 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 },
565                 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 },
566                 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 },
567                 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 },
568                 { 6080, 216, 30 } },
569         .nchannels = 37
570 };
571
572 static const struct bwn_channelinfo bwn_chantable_n = {
573         .channels = {
574                 { 5160,  32, 30 }, { 5170,  34, 30 }, { 5180,  36, 30 },
575                 { 5190,  38, 30 }, { 5200,  40, 30 }, { 5210,  42, 30 },
576                 { 5220,  44, 30 }, { 5230,  46, 30 }, { 5240,  48, 30 },
577                 { 5250,  50, 30 }, { 5260,  52, 30 }, { 5270,  54, 30 },
578                 { 5280,  56, 30 }, { 5290,  58, 30 }, { 5300,  60, 30 },
579                 { 5310,  62, 30 }, { 5320,  64, 30 }, { 5330,  66, 30 },
580                 { 5340,  68, 30 }, { 5350,  70, 30 }, { 5360,  72, 30 },
581                 { 5370,  74, 30 }, { 5380,  76, 30 }, { 5390,  78, 30 },
582                 { 5400,  80, 30 }, { 5410,  82, 30 }, { 5420,  84, 30 },
583                 { 5430,  86, 30 }, { 5440,  88, 30 }, { 5450,  90, 30 },
584                 { 5460,  92, 30 }, { 5470,  94, 30 }, { 5480,  96, 30 },
585                 { 5490,  98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 },
586                 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 },
587                 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 },
588                 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 },
589                 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 },
590                 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 },
591                 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 },
592                 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 },
593                 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 },
594                 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 },
595                 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 },
596                 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 },
597                 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 },
598                 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 },
599                 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 },
600                 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 },
601                 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 },
602                 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 },
603                 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 },
604                 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 },
605                 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 },
606                 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
607                 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
608                 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
609                 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
610                 { 6130, 226, 30 }, { 6140, 228, 30 } },
611         .nchannels = 110
612 };
613
614 static const uint8_t bwn_b2063_chantable_data[33][12] = {
615         { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
616         { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
617         { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
618         { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
619         { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
620         { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 },
621         { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 },
622         { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 },
623         { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 },
624         { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 },
625         { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 },
626         { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 },
627         { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 },
628         { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 },
629         { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
630         { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
631         { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 },
632         { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 },
633         { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 },
634         { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
635         { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
636         { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
637         { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
638         { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
639         { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 },
640         { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
641         { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
642         { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
643         { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
644         { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
645         { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
646         { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
647         { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }
648 };
649
650 static const struct bwn_b206x_chan bwn_b2063_chantable[] = {
651         { 1, 2412, bwn_b2063_chantable_data[0] },
652         { 2, 2417, bwn_b2063_chantable_data[0] },
653         { 3, 2422, bwn_b2063_chantable_data[0] },
654         { 4, 2427, bwn_b2063_chantable_data[1] },
655         { 5, 2432, bwn_b2063_chantable_data[1] },
656         { 6, 2437, bwn_b2063_chantable_data[1] },
657         { 7, 2442, bwn_b2063_chantable_data[1] },
658         { 8, 2447, bwn_b2063_chantable_data[1] },
659         { 9, 2452, bwn_b2063_chantable_data[2] },
660         { 10, 2457, bwn_b2063_chantable_data[2] },
661         { 11, 2462, bwn_b2063_chantable_data[3] },
662         { 12, 2467, bwn_b2063_chantable_data[3] },
663         { 13, 2472, bwn_b2063_chantable_data[3] },
664         { 14, 2484, bwn_b2063_chantable_data[4] },
665         { 34, 5170, bwn_b2063_chantable_data[5] },
666         { 36, 5180, bwn_b2063_chantable_data[6] },
667         { 38, 5190, bwn_b2063_chantable_data[7] },
668         { 40, 5200, bwn_b2063_chantable_data[8] },
669         { 42, 5210, bwn_b2063_chantable_data[9] },
670         { 44, 5220, bwn_b2063_chantable_data[10] },
671         { 46, 5230, bwn_b2063_chantable_data[11] },
672         { 48, 5240, bwn_b2063_chantable_data[12] },
673         { 52, 5260, bwn_b2063_chantable_data[13] },
674         { 56, 5280, bwn_b2063_chantable_data[14] },
675         { 60, 5300, bwn_b2063_chantable_data[14] },
676         { 64, 5320, bwn_b2063_chantable_data[15] },
677         { 100, 5500, bwn_b2063_chantable_data[16] },
678         { 104, 5520, bwn_b2063_chantable_data[17] },
679         { 108, 5540, bwn_b2063_chantable_data[18] },
680         { 112, 5560, bwn_b2063_chantable_data[19] },
681         { 116, 5580, bwn_b2063_chantable_data[20] },
682         { 120, 5600, bwn_b2063_chantable_data[21] },
683         { 124, 5620, bwn_b2063_chantable_data[21] },
684         { 128, 5640, bwn_b2063_chantable_data[22] },
685         { 132, 5660, bwn_b2063_chantable_data[22] },
686         { 136, 5680, bwn_b2063_chantable_data[22] },
687         { 140, 5700, bwn_b2063_chantable_data[23] },
688         { 149, 5745, bwn_b2063_chantable_data[23] },
689         { 153, 5765, bwn_b2063_chantable_data[23] },
690         { 157, 5785, bwn_b2063_chantable_data[23] },
691         { 161, 5805, bwn_b2063_chantable_data[23] },
692         { 165, 5825, bwn_b2063_chantable_data[23] },
693         { 184, 4920, bwn_b2063_chantable_data[24] },
694         { 188, 4940, bwn_b2063_chantable_data[25] },
695         { 192, 4960, bwn_b2063_chantable_data[26] },
696         { 196, 4980, bwn_b2063_chantable_data[27] },
697         { 200, 5000, bwn_b2063_chantable_data[28] },
698         { 204, 5020, bwn_b2063_chantable_data[29] },
699         { 208, 5040, bwn_b2063_chantable_data[30] },
700         { 212, 5060, bwn_b2063_chantable_data[31] },
701         { 216, 5080, bwn_b2063_chantable_data[32] }
702 };
703
704 static const uint8_t bwn_b2062_chantable_data[22][12] = {
705         { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 },
706         { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
707         { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
708         { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
709         { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
710         { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
711         { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
712         { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
713         { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
714         { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
715         { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
716         { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
717         { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
718         { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
719         { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
720         { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
721         { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
722         { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
723         { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
724         { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
725         { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
726         { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }
727 };
728
729 static const struct bwn_b206x_chan bwn_b2062_chantable[] = {
730         { 1, 2412, bwn_b2062_chantable_data[0] },
731         { 2, 2417, bwn_b2062_chantable_data[0] },
732         { 3, 2422, bwn_b2062_chantable_data[0] },
733         { 4, 2427, bwn_b2062_chantable_data[0] },
734         { 5, 2432, bwn_b2062_chantable_data[0] },
735         { 6, 2437, bwn_b2062_chantable_data[0] },
736         { 7, 2442, bwn_b2062_chantable_data[0] },
737         { 8, 2447, bwn_b2062_chantable_data[0] },
738         { 9, 2452, bwn_b2062_chantable_data[0] },
739         { 10, 2457, bwn_b2062_chantable_data[0] },
740         { 11, 2462, bwn_b2062_chantable_data[0] },
741         { 12, 2467, bwn_b2062_chantable_data[0] },
742         { 13, 2472, bwn_b2062_chantable_data[0] },
743         { 14, 2484, bwn_b2062_chantable_data[0] },
744         { 34, 5170, bwn_b2062_chantable_data[1] },
745         { 38, 5190, bwn_b2062_chantable_data[2] },
746         { 42, 5210, bwn_b2062_chantable_data[2] },
747         { 46, 5230, bwn_b2062_chantable_data[3] },
748         { 36, 5180, bwn_b2062_chantable_data[4] },
749         { 40, 5200, bwn_b2062_chantable_data[5] },
750         { 44, 5220, bwn_b2062_chantable_data[6] },
751         { 48, 5240, bwn_b2062_chantable_data[3] },
752         { 52, 5260, bwn_b2062_chantable_data[3] },
753         { 56, 5280, bwn_b2062_chantable_data[3] },
754         { 60, 5300, bwn_b2062_chantable_data[7] },
755         { 64, 5320, bwn_b2062_chantable_data[8] },
756         { 100, 5500, bwn_b2062_chantable_data[9] },
757         { 104, 5520, bwn_b2062_chantable_data[10] },
758         { 108, 5540, bwn_b2062_chantable_data[10] },
759         { 112, 5560, bwn_b2062_chantable_data[10] },
760         { 116, 5580, bwn_b2062_chantable_data[11] },
761         { 120, 5600, bwn_b2062_chantable_data[12] },
762         { 124, 5620, bwn_b2062_chantable_data[12] },
763         { 128, 5640, bwn_b2062_chantable_data[12] },
764         { 132, 5660, bwn_b2062_chantable_data[12] },
765         { 136, 5680, bwn_b2062_chantable_data[12] },
766         { 140, 5700, bwn_b2062_chantable_data[12] },
767         { 149, 5745, bwn_b2062_chantable_data[12] },
768         { 153, 5765, bwn_b2062_chantable_data[12] },
769         { 157, 5785, bwn_b2062_chantable_data[12] },
770         { 161, 5805, bwn_b2062_chantable_data[12] },
771         { 165, 5825, bwn_b2062_chantable_data[12] },
772         { 184, 4920, bwn_b2062_chantable_data[13] },
773         { 188, 4940, bwn_b2062_chantable_data[14] },
774         { 192, 4960, bwn_b2062_chantable_data[15] },
775         { 196, 4980, bwn_b2062_chantable_data[16] },
776         { 200, 5000, bwn_b2062_chantable_data[17] },
777         { 204, 5020, bwn_b2062_chantable_data[18] },
778         { 208, 5040, bwn_b2062_chantable_data[19] },
779         { 212, 5060, bwn_b2062_chantable_data[20] },
780         { 216, 5080, bwn_b2062_chantable_data[21] }
781 };
782
783 /* for LP PHY */
784 static const struct bwn_rxcompco bwn_rxcompco_5354[] = {
785         {  1, -66, 15 }, {  2, -66, 15 }, {  3, -66, 15 }, {  4, -66, 15 },
786         {  5, -66, 15 }, {  6, -66, 15 }, {  7, -66, 14 }, {  8, -66, 14 },
787         {  9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 },
788         { 13, -66, 13 }, { 14, -66, 13 },
789 };
790
791 /* for LP PHY */
792 static const struct bwn_rxcompco bwn_rxcompco_r12[] = {
793         {   1, -64, 13 }, {   2, -64, 13 }, {   3, -64, 13 }, {   4, -64, 13 },
794         {   5, -64, 12 }, {   6, -64, 12 }, {   7, -64, 12 }, {   8, -64, 12 },
795         {   9, -64, 12 }, {  10, -64, 11 }, {  11, -64, 11 }, {  12, -64, 11 },
796         {  13, -64, 11 }, {  14, -64, 10 }, {  34, -62, 24 }, {  38, -62, 24 },
797         {  42, -62, 24 }, {  46, -62, 23 }, {  36, -62, 24 }, {  40, -62, 24 },
798         {  44, -62, 23 }, {  48, -62, 23 }, {  52, -62, 23 }, {  56, -62, 22 },
799         {  60, -62, 22 }, {  64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 },
800         { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 },
801         { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 },
802         { 140, -62, 10 }, { 149, -61,  9 }, { 153, -61,  9 }, { 157, -61,  9 },
803         { 161, -61,  8 }, { 165, -61,  8 }, { 184, -62, 25 }, { 188, -62, 25 },
804         { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 },
805         { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 },
806 };
807
808 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 };
809
810 static const uint8_t bwn_tab_sigsq_tbl[] = {
811         0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd,
812         0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
813         0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00,
814         0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
815         0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
816         0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
817 };
818
819 static const uint8_t bwn_tab_pllfrac_tbl[] = {
820         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80,
821         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
822 };
823
824 static const uint16_t bwn_tabl_iqlocal_tbl[] = {
825         0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002,
826         0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
827         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
828         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
829         0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006,
830         0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
831         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
832         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
833         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
834         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
835         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
836         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
837 };
838
839 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
840 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
841 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
842 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
843 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
844 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
845
846 #define VENDOR_LED_ACT(vendor)                          \
847 {                                                       \
848         .vid = PCI_VENDOR_##vendor,                     \
849         .led_act = { BWN_VENDOR_LED_ACT_##vendor }      \
850 }
851
852 static const struct {
853         uint16_t        vid;
854         uint8_t         led_act[BWN_LED_MAX];
855 } bwn_vendor_led_act[] = {
856         VENDOR_LED_ACT(COMPAQ),
857         VENDOR_LED_ACT(ASUSTEK)
858 };
859
860 static const uint8_t bwn_default_led_act[BWN_LED_MAX] =
861         { BWN_VENDOR_LED_ACT_DEFAULT };
862
863 #undef VENDOR_LED_ACT
864
865 static const struct {
866         int             on_dur;
867         int             off_dur;
868 } bwn_led_duration[109] = {
869         [0]     = { 400, 100 },
870         [2]     = { 150, 75 },
871         [4]     = { 90, 45 },
872         [11]    = { 66, 34 },
873         [12]    = { 53, 26 },
874         [18]    = { 42, 21 },
875         [22]    = { 35, 17 },
876         [24]    = { 32, 16 },
877         [36]    = { 21, 10 },
878         [48]    = { 16, 8 },
879         [72]    = { 11, 5 },
880         [96]    = { 9, 4 },
881         [108]   = { 7, 3 }
882 };
883
884 static const uint16_t bwn_wme_shm_offsets[] = {
885         [0] = BWN_WME_BESTEFFORT,
886         [1] = BWN_WME_BACKGROUND,
887         [2] = BWN_WME_VOICE,
888         [3] = BWN_WME_VIDEO,
889 };
890
891 static const struct siba_devid bwn_devs[] = {
892         SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"),
893         SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"),
894         SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"),
895         SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"),
896         SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"),
897         SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"),
898         SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"),
899         SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"),
900         SIBA_DEV(BROADCOM, 80211, 16, "Revision 16")
901 };
902
903 static int
904 bwn_probe(device_t dev)
905 {
906         int i;
907
908         for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) {
909                 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor &&
910                     siba_get_device(dev) == bwn_devs[i].sd_device &&
911                     siba_get_revid(dev) == bwn_devs[i].sd_rev)
912                         return (BUS_PROBE_DEFAULT);
913         }
914
915         return (ENXIO);
916 }
917
918 static int
919 bwn_attach(device_t dev)
920 {
921         struct bwn_mac *mac;
922         struct bwn_softc *sc = device_get_softc(dev);
923         int error, i, msic, reg;
924
925         sc->sc_dev = dev;
926 #ifdef BWN_DEBUG
927         sc->sc_debug = bwn_debug;
928 #endif
929
930         if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
931                 bwn_attach_pre(sc);
932                 bwn_sprom_bugfixes(dev);
933                 sc->sc_flags |= BWN_FLAG_ATTACHED;
934         }
935
936         if (!TAILQ_EMPTY(&sc->sc_maclist)) {
937                 if (siba_get_pci_device(dev) != 0x4313 &&
938                     siba_get_pci_device(dev) != 0x431a &&
939                     siba_get_pci_device(dev) != 0x4321) {
940                         device_printf(sc->sc_dev,
941                             "skip 802.11 cores\n");
942                         return (ENODEV);
943                 }
944         }
945
946         mac = malloc(sizeof(*mac), M_DEVBUF, M_WAITOK | M_ZERO);
947         mac->mac_sc = sc;
948         mac->mac_status = BWN_MAC_STATUS_UNINIT;
949         if (bwn_bfp != 0)
950                 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
951
952         TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac);
953         TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac);
954         TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac);
955
956         error = bwn_attach_core(mac);
957         if (error)
958                 goto fail0;
959         bwn_led_attach(mac);
960
961         device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) "
962             "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
963             siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev),
964             mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev,
965             mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver,
966             mac->mac_phy.rf_rev);
967         if (mac->mac_flags & BWN_MAC_FLAG_DMA)
968                 device_printf(sc->sc_dev, "DMA (%d bits)\n",
969                     mac->mac_method.dma.dmatype);
970         else
971                 device_printf(sc->sc_dev, "PIO\n");
972
973         /*
974          * setup PCI resources and interrupt.
975          */
976         if (pci_find_cap(dev, PCIY_EXPRESS, &reg) == 0) {
977                 msic = pci_msi_count(dev);
978                 if (bootverbose)
979                         device_printf(sc->sc_dev, "MSI count : %d\n", msic);
980         } else
981                 msic = 0;
982
983         mac->mac_intr_spec = bwn_res_spec_legacy;
984         if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) {
985                 if (pci_alloc_msi(dev, &msic) == 0) {
986                         device_printf(sc->sc_dev,
987                             "Using %d MSI messages\n", msic);
988                         mac->mac_intr_spec = bwn_res_spec_msi;
989                         mac->mac_msi = 1;
990                 }
991         }
992
993         error = bus_alloc_resources(dev, mac->mac_intr_spec,
994             mac->mac_res_irq);
995         if (error) {
996                 device_printf(sc->sc_dev,
997                     "couldn't allocate IRQ resources (%d)\n", error);
998                 goto fail1;
999         }
1000
1001         if (mac->mac_msi == 0)
1002                 error = bus_setup_intr(dev, mac->mac_res_irq[0],
1003                     INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1004                     &mac->mac_intrhand[0]);
1005         else {
1006                 for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1007                         error = bus_setup_intr(dev, mac->mac_res_irq[i],
1008                             INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1009                             &mac->mac_intrhand[i]);
1010                         if (error != 0) {
1011                                 device_printf(sc->sc_dev,
1012                                     "couldn't setup interrupt (%d)\n", error);
1013                                 break;
1014                         }
1015                 }
1016         }
1017
1018         TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list);
1019
1020         /*
1021          * calls attach-post routine
1022          */
1023         if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0)
1024                 bwn_attach_post(sc);
1025
1026         return (0);
1027 fail1:
1028         if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0)
1029                 pci_release_msi(dev);
1030 fail0:
1031         free(mac, M_DEVBUF);
1032         return (error);
1033 }
1034
1035 static int
1036 bwn_is_valid_ether_addr(uint8_t *addr)
1037 {
1038         char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
1039
1040         if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN)))
1041                 return (FALSE);
1042
1043         return (TRUE);
1044 }
1045
1046 static int
1047 bwn_attach_post(struct bwn_softc *sc)
1048 {
1049         struct ieee80211com *ic = &sc->sc_ic;
1050
1051         ic->ic_softc = sc;
1052         ic->ic_name = device_get_nameunit(sc->sc_dev);
1053         /* XXX not right but it's not used anywhere important */
1054         ic->ic_phytype = IEEE80211_T_OFDM;
1055         ic->ic_opmode = IEEE80211_M_STA;
1056         ic->ic_caps =
1057                   IEEE80211_C_STA               /* station mode supported */
1058                 | IEEE80211_C_MONITOR           /* monitor mode */
1059                 | IEEE80211_C_AHDEMO            /* adhoc demo mode */
1060                 | IEEE80211_C_SHPREAMBLE        /* short preamble supported */
1061                 | IEEE80211_C_SHSLOT            /* short slot time supported */
1062                 | IEEE80211_C_WME               /* WME/WMM supported */
1063                 | IEEE80211_C_WPA               /* capable of WPA1+WPA2 */
1064                 | IEEE80211_C_BGSCAN            /* capable of bg scanning */
1065                 | IEEE80211_C_TXPMGT            /* capable of txpow mgt */
1066                 ;
1067
1068         ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;     /* s/w bmiss */
1069
1070         IEEE80211_ADDR_COPY(ic->ic_macaddr,
1071             bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
1072             siba_sprom_get_mac_80211a(sc->sc_dev) :
1073             siba_sprom_get_mac_80211bg(sc->sc_dev));
1074
1075         /* call MI attach routine. */
1076         ieee80211_ifattach(ic);
1077
1078         ic->ic_headroom = sizeof(struct bwn_txhdr);
1079
1080         /* override default methods */
1081         ic->ic_raw_xmit = bwn_raw_xmit;
1082         ic->ic_updateslot = bwn_updateslot;
1083         ic->ic_update_promisc = bwn_update_promisc;
1084         ic->ic_wme.wme_update = bwn_wme_update;
1085         ic->ic_scan_start = bwn_scan_start;
1086         ic->ic_scan_end = bwn_scan_end;
1087         ic->ic_set_channel = bwn_set_channel;
1088         ic->ic_vap_create = bwn_vap_create;
1089         ic->ic_vap_delete = bwn_vap_delete;
1090         ic->ic_transmit = bwn_transmit;
1091         ic->ic_parent = bwn_parent;
1092
1093         ieee80211_radiotap_attach(ic,
1094             &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
1095             BWN_TX_RADIOTAP_PRESENT,
1096             &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
1097             BWN_RX_RADIOTAP_PRESENT);
1098
1099         bwn_sysctl_node(sc);
1100
1101         if (bootverbose)
1102                 ieee80211_announce(ic);
1103         return (0);
1104 }
1105
1106 static void
1107 bwn_phy_detach(struct bwn_mac *mac)
1108 {
1109
1110         if (mac->mac_phy.detach != NULL)
1111                 mac->mac_phy.detach(mac);
1112 }
1113
1114 static int
1115 bwn_detach(device_t dev)
1116 {
1117         struct bwn_softc *sc = device_get_softc(dev);
1118         struct bwn_mac *mac = sc->sc_curmac;
1119         struct ieee80211com *ic = &sc->sc_ic;
1120         int i;
1121
1122         sc->sc_flags |= BWN_FLAG_INVALID;
1123
1124         if (device_is_attached(sc->sc_dev)) {
1125                 BWN_LOCK(sc);
1126                 bwn_stop(sc);
1127                 BWN_UNLOCK(sc);
1128                 bwn_dma_free(mac);
1129                 callout_drain(&sc->sc_led_blink_ch);
1130                 callout_drain(&sc->sc_rfswitch_ch);
1131                 callout_drain(&sc->sc_task_ch);
1132                 callout_drain(&sc->sc_watchdog_ch);
1133                 bwn_phy_detach(mac);
1134                 ieee80211_draintask(ic, &mac->mac_hwreset);
1135                 ieee80211_draintask(ic, &mac->mac_txpower);
1136                 ieee80211_ifdetach(ic);
1137         }
1138         taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
1139         taskqueue_free(sc->sc_tq);
1140
1141         for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1142                 if (mac->mac_intrhand[i] != NULL) {
1143                         bus_teardown_intr(dev, mac->mac_res_irq[i],
1144                             mac->mac_intrhand[i]);
1145                         mac->mac_intrhand[i] = NULL;
1146                 }
1147         }
1148         bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq);
1149         if (mac->mac_msi != 0)
1150                 pci_release_msi(dev);
1151         mbufq_drain(&sc->sc_snd);
1152         BWN_LOCK_DESTROY(sc);
1153         return (0);
1154 }
1155
1156 static void
1157 bwn_attach_pre(struct bwn_softc *sc)
1158 {
1159
1160         BWN_LOCK_INIT(sc);
1161         TAILQ_INIT(&sc->sc_maclist);
1162         callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0);
1163         callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0);
1164         callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0);
1165         mbufq_init(&sc->sc_snd, ifqmaxlen);
1166         sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT,
1167                 taskqueue_thread_enqueue, &sc->sc_tq);
1168         taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
1169                 "%s taskq", device_get_nameunit(sc->sc_dev));
1170 }
1171
1172 static void
1173 bwn_sprom_bugfixes(device_t dev)
1174 {
1175 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice)             \
1176         ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) &&          \
1177          (siba_get_pci_device(dev) == _device) &&                       \
1178          (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) &&    \
1179          (siba_get_pci_subdevice(dev) == _subdevice))
1180
1181         if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
1182             siba_get_pci_subdevice(dev) == 0x4e &&
1183             siba_get_pci_revid(dev) > 0x40)
1184                 siba_sprom_set_bf_lo(dev,
1185                     siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
1186         if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
1187             siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
1188                 siba_sprom_set_bf_lo(dev,
1189                     siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
1190         if (siba_get_type(dev) == SIBA_TYPE_PCI) {
1191                 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1192                     BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1193                     BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1194                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1195                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1196                     BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1197                     BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1198                         siba_sprom_set_bf_lo(dev,
1199                             siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
1200         }
1201 #undef  BWN_ISDEV
1202 }
1203
1204 static void
1205 bwn_parent(struct ieee80211com *ic)
1206 {
1207         struct bwn_softc *sc = ic->ic_softc;
1208         int startall = 0;
1209
1210         BWN_LOCK(sc);
1211         if (ic->ic_nrunning > 0) {
1212                 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) {
1213                         bwn_init(sc);
1214                         startall = 1;
1215                 } else
1216                         bwn_update_promisc(ic);
1217         } else if (sc->sc_flags & BWN_FLAG_RUNNING)
1218                 bwn_stop(sc);
1219         BWN_UNLOCK(sc);
1220
1221         if (startall)
1222                 ieee80211_start_all(ic);
1223 }
1224
1225 static int
1226 bwn_transmit(struct ieee80211com *ic, struct mbuf *m)
1227 {
1228         struct bwn_softc *sc = ic->ic_softc;
1229         int error;
1230
1231         BWN_LOCK(sc);
1232         if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) {
1233                 BWN_UNLOCK(sc);
1234                 return (ENXIO);
1235         }
1236         error = mbufq_enqueue(&sc->sc_snd, m);
1237         if (error) {
1238                 BWN_UNLOCK(sc);
1239                 return (error);
1240         }
1241         bwn_start(sc);
1242         BWN_UNLOCK(sc);
1243         return (0);
1244 }
1245
1246 static void
1247 bwn_start(struct bwn_softc *sc)
1248 {
1249         struct bwn_mac *mac = sc->sc_curmac;
1250         struct ieee80211_frame *wh;
1251         struct ieee80211_node *ni;
1252         struct ieee80211_key *k;
1253         struct mbuf *m;
1254
1255         BWN_ASSERT_LOCKED(sc);
1256
1257         if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 || mac == NULL ||
1258             mac->mac_status < BWN_MAC_STATUS_STARTED)
1259                 return;
1260
1261         while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
1262                 if (bwn_tx_isfull(sc, m))
1263                         break;
1264                 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1265                 if (ni == NULL) {
1266                         device_printf(sc->sc_dev, "unexpected NULL ni\n");
1267                         m_freem(m);
1268                         counter_u64_add(sc->sc_ic.ic_oerrors, 1);
1269                         continue;
1270                 }
1271                 wh = mtod(m, struct ieee80211_frame *);
1272                 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1273                         k = ieee80211_crypto_encap(ni, m);
1274                         if (k == NULL) {
1275                                 if_inc_counter(ni->ni_vap->iv_ifp,
1276                                     IFCOUNTER_OERRORS, 1);
1277                                 ieee80211_free_node(ni);
1278                                 m_freem(m);
1279                                 continue;
1280                         }
1281                 }
1282                 wh = NULL;      /* Catch any invalid use */
1283                 if (bwn_tx_start(sc, ni, m) != 0) {
1284                         if (ni != NULL) {
1285                                 if_inc_counter(ni->ni_vap->iv_ifp,
1286                                     IFCOUNTER_OERRORS, 1);
1287                                 ieee80211_free_node(ni);
1288                         }
1289                         continue;
1290                 }
1291                 sc->sc_watchdog_timer = 5;
1292         }
1293 }
1294
1295 static int
1296 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1297 {
1298         struct bwn_dma_ring *dr;
1299         struct bwn_mac *mac = sc->sc_curmac;
1300         struct bwn_pio_txqueue *tq;
1301         int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1302
1303         BWN_ASSERT_LOCKED(sc);
1304
1305         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1306                 dr = bwn_dma_select(mac, M_WME_GETAC(m));
1307                 if (dr->dr_stop == 1 ||
1308                     bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1309                         dr->dr_stop = 1;
1310                         goto full;
1311                 }
1312         } else {
1313                 tq = bwn_pio_select(mac, M_WME_GETAC(m));
1314                 if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1315                     pktlen > (tq->tq_size - tq->tq_used))
1316                         goto full;
1317         }
1318         return (0);
1319 full:
1320         mbufq_prepend(&sc->sc_snd, m);
1321         return (1);
1322 }
1323
1324 static int
1325 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1326 {
1327         struct bwn_mac *mac = sc->sc_curmac;
1328         int error;
1329
1330         BWN_ASSERT_LOCKED(sc);
1331
1332         if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1333                 m_freem(m);
1334                 return (ENXIO);
1335         }
1336
1337         error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1338             bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1339         if (error) {
1340                 m_freem(m);
1341                 return (error);
1342         }
1343         return (0);
1344 }
1345
1346 static int
1347 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1348 {
1349         struct bwn_pio_txpkt *tp;
1350         struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1351         struct bwn_softc *sc = mac->mac_sc;
1352         struct bwn_txhdr txhdr;
1353         struct mbuf *m_new;
1354         uint32_t ctl32;
1355         int error;
1356         uint16_t ctl16;
1357
1358         BWN_ASSERT_LOCKED(sc);
1359
1360         /* XXX TODO send packets after DTIM */
1361
1362         KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1363         tp = TAILQ_FIRST(&tq->tq_pktlist);
1364         tp->tp_ni = ni;
1365         tp->tp_m = m;
1366
1367         error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1368         if (error) {
1369                 device_printf(sc->sc_dev, "tx fail\n");
1370                 return (error);
1371         }
1372
1373         TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1374         tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1375         tq->tq_free--;
1376
1377         if (siba_get_revid(sc->sc_dev) >= 8) {
1378                 /*
1379                  * XXX please removes m_defrag(9)
1380                  */
1381                 m_new = m_defrag(m, M_NOWAIT);
1382                 if (m_new == NULL) {
1383                         device_printf(sc->sc_dev,
1384                             "%s: can't defrag TX buffer\n",
1385                             __func__);
1386                         return (ENOBUFS);
1387                 }
1388                 if (m_new->m_next != NULL)
1389                         device_printf(sc->sc_dev,
1390                             "TODO: fragmented packets for PIO\n");
1391                 tp->tp_m = m_new;
1392
1393                 /* send HEADER */
1394                 ctl32 = bwn_pio_write_multi_4(mac, tq,
1395                     (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1396                         BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1397                     (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1398                 /* send BODY */
1399                 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1400                     mtod(m_new, const void *), m_new->m_pkthdr.len);
1401                 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1402                     ctl32 | BWN_PIO8_TXCTL_EOF);
1403         } else {
1404                 ctl16 = bwn_pio_write_multi_2(mac, tq,
1405                     (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1406                         BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1407                     (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1408                 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1409                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1410                     ctl16 | BWN_PIO_TXCTL_EOF);
1411         }
1412
1413         return (0);
1414 }
1415
1416 static struct bwn_pio_txqueue *
1417 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1418 {
1419
1420         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1421                 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1422
1423         switch (prio) {
1424         case 0:
1425                 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1426         case 1:
1427                 return (&mac->mac_method.pio.wme[WME_AC_BK]);
1428         case 2:
1429                 return (&mac->mac_method.pio.wme[WME_AC_VI]);
1430         case 3:
1431                 return (&mac->mac_method.pio.wme[WME_AC_VO]);
1432         }
1433         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1434         return (NULL);
1435 }
1436
1437 static int
1438 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1439 {
1440 #define BWN_GET_TXHDRCACHE(slot)                                        \
1441         &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)])
1442         struct bwn_dma *dma = &mac->mac_method.dma;
1443         struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1444         struct bwn_dmadesc_generic *desc;
1445         struct bwn_dmadesc_meta *mt;
1446         struct bwn_softc *sc = mac->mac_sc;
1447         uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1448         int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1449
1450         BWN_ASSERT_LOCKED(sc);
1451         KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1452
1453         /* XXX send after DTIM */
1454
1455         slot = bwn_dma_getslot(dr);
1456         dr->getdesc(dr, slot, &desc, &mt);
1457         KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1458             ("%s:%d: fail", __func__, __LINE__));
1459
1460         error = bwn_set_txhdr(dr->dr_mac, ni, m,
1461             (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1462             BWN_DMA_COOKIE(dr, slot));
1463         if (error)
1464                 goto fail;
1465         error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap,
1466             BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr,
1467             &mt->mt_paddr, BUS_DMA_NOWAIT);
1468         if (error) {
1469                 device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n",
1470                     __func__, error);
1471                 goto fail;
1472         }
1473         bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1474             BUS_DMASYNC_PREWRITE);
1475         dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1476         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1477             BUS_DMASYNC_PREWRITE);
1478
1479         slot = bwn_dma_getslot(dr);
1480         dr->getdesc(dr, slot, &desc, &mt);
1481         KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1482             mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1483         mt->mt_m = m;
1484         mt->mt_ni = ni;
1485
1486         error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1487             bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1488         if (error && error != EFBIG) {
1489                 device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n",
1490                     __func__, error);
1491                 goto fail;
1492         }
1493         if (error) {    /* error == EFBIG */
1494                 struct mbuf *m_new;
1495
1496                 m_new = m_defrag(m, M_NOWAIT);
1497                 if (m_new == NULL) {
1498                         device_printf(sc->sc_dev,
1499                             "%s: can't defrag TX buffer\n",
1500                             __func__);
1501                         error = ENOBUFS;
1502                         goto fail;
1503                 } else {
1504                         m = m_new;
1505                 }
1506
1507                 mt->mt_m = m;
1508                 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1509                     m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1510                 if (error) {
1511                         device_printf(sc->sc_dev,
1512                             "%s: can't load TX buffer (2) %d\n",
1513                             __func__, error);
1514                         goto fail;
1515                 }
1516         }
1517         bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1518         dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1519         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1520             BUS_DMASYNC_PREWRITE);
1521
1522         /* XXX send after DTIM */
1523
1524         dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1525         return (0);
1526 fail:
1527         dr->dr_curslot = backup[0];
1528         dr->dr_usedslot = backup[1];
1529         return (error);
1530 #undef BWN_GET_TXHDRCACHE
1531 }
1532
1533 static void
1534 bwn_watchdog(void *arg)
1535 {
1536         struct bwn_softc *sc = arg;
1537
1538         if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1539                 device_printf(sc->sc_dev, "device timeout\n");
1540                 counter_u64_add(sc->sc_ic.ic_oerrors, 1);
1541         }
1542         callout_schedule(&sc->sc_watchdog_ch, hz);
1543 }
1544
1545 static int
1546 bwn_attach_core(struct bwn_mac *mac)
1547 {
1548         struct bwn_softc *sc = mac->mac_sc;
1549         int error, have_bg = 0, have_a = 0;
1550         uint32_t high;
1551
1552         KASSERT(siba_get_revid(sc->sc_dev) >= 5,
1553             ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
1554
1555         siba_powerup(sc->sc_dev, 0);
1556
1557         high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
1558         bwn_reset_core(mac,
1559             (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1560         error = bwn_phy_getinfo(mac, high);
1561         if (error)
1562                 goto fail;
1563
1564         have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1565         have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1566         if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
1567             siba_get_pci_device(sc->sc_dev) != 0x4319 &&
1568             siba_get_pci_device(sc->sc_dev) != 0x4324) {
1569                 have_a = have_bg = 0;
1570                 if (mac->mac_phy.type == BWN_PHYTYPE_A)
1571                         have_a = 1;
1572                 else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1573                     mac->mac_phy.type == BWN_PHYTYPE_N ||
1574                     mac->mac_phy.type == BWN_PHYTYPE_LP)
1575                         have_bg = 1;
1576                 else
1577                         KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1578                             mac->mac_phy.type));
1579         }
1580         /* XXX turns off PHY A because it's not supported */
1581         if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1582             mac->mac_phy.type != BWN_PHYTYPE_N) {
1583                 have_a = 0;
1584                 have_bg = 1;
1585         }
1586
1587         if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1588                 mac->mac_phy.attach = bwn_phy_g_attach;
1589                 mac->mac_phy.detach = bwn_phy_g_detach;
1590                 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1591                 mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1592                 mac->mac_phy.init = bwn_phy_g_init;
1593                 mac->mac_phy.exit = bwn_phy_g_exit;
1594                 mac->mac_phy.phy_read = bwn_phy_g_read;
1595                 mac->mac_phy.phy_write = bwn_phy_g_write;
1596                 mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1597                 mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1598                 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1599                 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1600                 mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1601                 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1602                 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1603                 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1604                 mac->mac_phy.set_im = bwn_phy_g_im;
1605                 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1606                 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1607                 mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1608                 mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1609         } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1610                 mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1611                 mac->mac_phy.init = bwn_phy_lp_init;
1612                 mac->mac_phy.phy_read = bwn_phy_lp_read;
1613                 mac->mac_phy.phy_write = bwn_phy_lp_write;
1614                 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1615                 mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1616                 mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1617                 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1618                 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1619                 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1620                 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1621                 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1622                 mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1623         } else {
1624                 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1625                     mac->mac_phy.type);
1626                 error = ENXIO;
1627                 goto fail;
1628         }
1629
1630         mac->mac_phy.gmode = have_bg;
1631         if (mac->mac_phy.attach != NULL) {
1632                 error = mac->mac_phy.attach(mac);
1633                 if (error) {
1634                         device_printf(sc->sc_dev, "failed\n");
1635                         goto fail;
1636                 }
1637         }
1638
1639         bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1640
1641         error = bwn_chiptest(mac);
1642         if (error)
1643                 goto fail;
1644         error = bwn_setup_channels(mac, have_bg, have_a);
1645         if (error) {
1646                 device_printf(sc->sc_dev, "failed to setup channels\n");
1647                 goto fail;
1648         }
1649
1650         if (sc->sc_curmac == NULL)
1651                 sc->sc_curmac = mac;
1652
1653         error = bwn_dma_attach(mac);
1654         if (error != 0) {
1655                 device_printf(sc->sc_dev, "failed to initialize DMA\n");
1656                 goto fail;
1657         }
1658
1659         mac->mac_phy.switch_analog(mac, 0);
1660
1661         siba_dev_down(sc->sc_dev, 0);
1662 fail:
1663         siba_powerdown(sc->sc_dev);
1664         return (error);
1665 }
1666
1667 static void
1668 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1669 {
1670         struct bwn_softc *sc = mac->mac_sc;
1671         uint32_t low, ctl;
1672
1673         flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1674
1675         siba_dev_up(sc->sc_dev, flags);
1676         DELAY(2000);
1677
1678         low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1679             ~BWN_TGSLOW_PHYRESET;
1680         siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
1681         siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1682         DELAY(1000);
1683         siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1684         siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1685         DELAY(1000);
1686
1687         if (mac->mac_phy.switch_analog != NULL)
1688                 mac->mac_phy.switch_analog(mac, 1);
1689
1690         ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1691         if (flags & BWN_TGSLOW_SUPPORT_G)
1692                 ctl |= BWN_MACCTL_GMODE;
1693         BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1694 }
1695
1696 static int
1697 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1698 {
1699         struct bwn_phy *phy = &mac->mac_phy;
1700         struct bwn_softc *sc = mac->mac_sc;
1701         uint32_t tmp;
1702
1703         /* PHY */
1704         tmp = BWN_READ_2(mac, BWN_PHYVER);
1705         phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1706         phy->rf_on = 1;
1707         phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1708         phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1709         phy->rev = (tmp & BWN_PHYVER_VERSION);
1710         if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1711             (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1712                 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1713             (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1714             (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1715             (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1716                 goto unsupphy;
1717
1718         /* RADIO */
1719         if (siba_get_chipid(sc->sc_dev) == 0x4317) {
1720                 if (siba_get_chiprev(sc->sc_dev) == 0)
1721                         tmp = 0x3205017f;
1722                 else if (siba_get_chiprev(sc->sc_dev) == 1)
1723                         tmp = 0x4205017f;
1724                 else
1725                         tmp = 0x5205017f;
1726         } else {
1727                 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1728                 tmp = BWN_READ_2(mac, BWN_RFDATALO);
1729                 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1730                 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1731         }
1732         phy->rf_rev = (tmp & 0xf0000000) >> 28;
1733         phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1734         phy->rf_manuf = (tmp & 0x00000fff);
1735         if (phy->rf_manuf != 0x17f)     /* 0x17f is broadcom */
1736                 goto unsupradio;
1737         if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1738              phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1739             (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1740             (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1741             (phy->type == BWN_PHYTYPE_N &&
1742              phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1743             (phy->type == BWN_PHYTYPE_LP &&
1744              phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1745                 goto unsupradio;
1746
1747         return (0);
1748 unsupphy:
1749         device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1750             "analog %#x)\n",
1751             phy->type, phy->rev, phy->analog);
1752         return (ENXIO);
1753 unsupradio:
1754         device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1755             "rev %#x)\n",
1756             phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1757         return (ENXIO);
1758 }
1759
1760 static int
1761 bwn_chiptest(struct bwn_mac *mac)
1762 {
1763 #define TESTVAL0        0x55aaaa55
1764 #define TESTVAL1        0xaa5555aa
1765         struct bwn_softc *sc = mac->mac_sc;
1766         uint32_t v, backup;
1767
1768         BWN_LOCK(sc);
1769
1770         backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1771
1772         bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1773         if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1774                 goto error;
1775         bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1776         if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1777                 goto error;
1778
1779         bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1780
1781         if ((siba_get_revid(sc->sc_dev) >= 3) &&
1782             (siba_get_revid(sc->sc_dev) <= 10)) {
1783                 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1784                 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1785                 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1786                         goto error;
1787                 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1788                         goto error;
1789         }
1790         BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1791
1792         v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1793         if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1794                 goto error;
1795
1796         BWN_UNLOCK(sc);
1797         return (0);
1798 error:
1799         BWN_UNLOCK(sc);
1800         device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1801         return (ENODEV);
1802 }
1803
1804 #define IEEE80211_CHAN_HTG      (IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1805 #define IEEE80211_CHAN_HTA      (IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1806
1807 static int
1808 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1809 {
1810         struct bwn_softc *sc = mac->mac_sc;
1811         struct ieee80211com *ic = &sc->sc_ic;
1812
1813         memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1814         ic->ic_nchans = 0;
1815
1816         if (have_bg)
1817                 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1818                     &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1819         if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1820                 if (have_a)
1821                         bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1822                             &ic->ic_nchans, &bwn_chantable_n,
1823                             IEEE80211_CHAN_HTA);
1824         } else {
1825                 if (have_a)
1826                         bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1827                             &ic->ic_nchans, &bwn_chantable_a,
1828                             IEEE80211_CHAN_A);
1829         }
1830
1831         mac->mac_phy.supports_2ghz = have_bg;
1832         mac->mac_phy.supports_5ghz = have_a;
1833
1834         return (ic->ic_nchans == 0 ? ENXIO : 0);
1835 }
1836
1837 static uint32_t
1838 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1839 {
1840         uint32_t ret;
1841
1842         BWN_ASSERT_LOCKED(mac->mac_sc);
1843
1844         if (way == BWN_SHARED) {
1845                 KASSERT((offset & 0x0001) == 0,
1846                     ("%s:%d warn", __func__, __LINE__));
1847                 if (offset & 0x0003) {
1848                         bwn_shm_ctlword(mac, way, offset >> 2);
1849                         ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1850                         ret <<= 16;
1851                         bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1852                         ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1853                         goto out;
1854                 }
1855                 offset >>= 2;
1856         }
1857         bwn_shm_ctlword(mac, way, offset);
1858         ret = BWN_READ_4(mac, BWN_SHM_DATA);
1859 out:
1860         return (ret);
1861 }
1862
1863 static uint16_t
1864 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1865 {
1866         uint16_t ret;
1867
1868         BWN_ASSERT_LOCKED(mac->mac_sc);
1869
1870         if (way == BWN_SHARED) {
1871                 KASSERT((offset & 0x0001) == 0,
1872                     ("%s:%d warn", __func__, __LINE__));
1873                 if (offset & 0x0003) {
1874                         bwn_shm_ctlword(mac, way, offset >> 2);
1875                         ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1876                         goto out;
1877                 }
1878                 offset >>= 2;
1879         }
1880         bwn_shm_ctlword(mac, way, offset);
1881         ret = BWN_READ_2(mac, BWN_SHM_DATA);
1882 out:
1883
1884         return (ret);
1885 }
1886
1887 static void
1888 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1889     uint16_t offset)
1890 {
1891         uint32_t control;
1892
1893         control = way;
1894         control <<= 16;
1895         control |= offset;
1896         BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1897 }
1898
1899 static void
1900 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1901     uint32_t value)
1902 {
1903         BWN_ASSERT_LOCKED(mac->mac_sc);
1904
1905         if (way == BWN_SHARED) {
1906                 KASSERT((offset & 0x0001) == 0,
1907                     ("%s:%d warn", __func__, __LINE__));
1908                 if (offset & 0x0003) {
1909                         bwn_shm_ctlword(mac, way, offset >> 2);
1910                         BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1911                                     (value >> 16) & 0xffff);
1912                         bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1913                         BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1914                         return;
1915                 }
1916                 offset >>= 2;
1917         }
1918         bwn_shm_ctlword(mac, way, offset);
1919         BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1920 }
1921
1922 static void
1923 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1924     uint16_t value)
1925 {
1926         BWN_ASSERT_LOCKED(mac->mac_sc);
1927
1928         if (way == BWN_SHARED) {
1929                 KASSERT((offset & 0x0001) == 0,
1930                     ("%s:%d warn", __func__, __LINE__));
1931                 if (offset & 0x0003) {
1932                         bwn_shm_ctlword(mac, way, offset >> 2);
1933                         BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1934                         return;
1935                 }
1936                 offset >>= 2;
1937         }
1938         bwn_shm_ctlword(mac, way, offset);
1939         BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1940 }
1941
1942 static void
1943 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
1944     int txpow)
1945 {
1946
1947         c->ic_freq = freq;
1948         c->ic_flags = flags;
1949         c->ic_ieee = ieee;
1950         c->ic_minpower = 0;
1951         c->ic_maxpower = 2 * txpow;
1952         c->ic_maxregpower = txpow;
1953 }
1954
1955 static void
1956 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
1957     const struct bwn_channelinfo *ci, int flags)
1958 {
1959         struct ieee80211_channel *c;
1960         int i;
1961
1962         c = &chans[*nchans];
1963
1964         for (i = 0; i < ci->nchannels; i++) {
1965                 const struct bwn_channel *hc;
1966
1967                 hc = &ci->channels[i];
1968                 if (*nchans >= maxchans)
1969                         break;
1970                 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
1971                 c++, (*nchans)++;
1972                 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
1973                         /* g channel have a separate b-only entry */
1974                         if (*nchans >= maxchans)
1975                                 break;
1976                         c[0] = c[-1];
1977                         c[-1].ic_flags = IEEE80211_CHAN_B;
1978                         c++, (*nchans)++;
1979                 }
1980                 if (flags == IEEE80211_CHAN_HTG) {
1981                         /* HT g channel have a separate g-only entry */
1982                         if (*nchans >= maxchans)
1983                                 break;
1984                         c[-1].ic_flags = IEEE80211_CHAN_G;
1985                         c[0] = c[-1];
1986                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
1987                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
1988                         c++, (*nchans)++;
1989                 }
1990                 if (flags == IEEE80211_CHAN_HTA) {
1991                         /* HT a channel have a separate a-only entry */
1992                         if (*nchans >= maxchans)
1993                                 break;
1994                         c[-1].ic_flags = IEEE80211_CHAN_A;
1995                         c[0] = c[-1];
1996                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
1997                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
1998                         c++, (*nchans)++;
1999                 }
2000         }
2001 }
2002
2003 static int
2004 bwn_phy_g_attach(struct bwn_mac *mac)
2005 {
2006         struct bwn_softc *sc = mac->mac_sc;
2007         struct bwn_phy *phy = &mac->mac_phy;
2008         struct bwn_phy_g *pg = &phy->phy_g;
2009         unsigned int i;
2010         int16_t pab0, pab1, pab2;
2011         static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2012         int8_t bg;
2013
2014         bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
2015         pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
2016         pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
2017         pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
2018
2019         if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
2020                 device_printf(sc->sc_dev, "not supported anymore\n");
2021
2022         pg->pg_flags = 0;
2023         if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2024             pab2 == -1) {
2025                 pg->pg_idletssi = 52;
2026                 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2027                 return (0);
2028         }
2029
2030         pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2031         pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
2032         if (pg->pg_tssi2dbm == NULL) {
2033                 device_printf(sc->sc_dev, "failed to allocate buffer\n");
2034                 return (ENOMEM);
2035         }
2036         for (i = 0; i < 64; i++) {
2037                 int32_t m1, m2, f, q, delta;
2038                 int8_t j = 0;
2039
2040                 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2041                 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2042                 f = 256;
2043
2044                 do {
2045                         if (j > 15) {
2046                                 device_printf(sc->sc_dev,
2047                                     "failed to generate tssi2dBm\n");
2048                                 free(pg->pg_tssi2dbm, M_DEVBUF);
2049                                 return (ENOMEM);
2050                         }
2051                         q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2052                             f, 2048);
2053                         delta = abs(q - f);
2054                         f = q;
2055                         j++;
2056                 } while (delta >= 2);
2057
2058                 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2059                     128);
2060         }
2061
2062         pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2063         return (0);
2064 }
2065
2066 static void
2067 bwn_phy_g_detach(struct bwn_mac *mac)
2068 {
2069         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2070
2071         if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2072                 free(pg->pg_tssi2dbm, M_DEVBUF);
2073                 pg->pg_tssi2dbm = NULL;
2074         }
2075         pg->pg_flags = 0;
2076 }
2077
2078 static void
2079 bwn_phy_g_init_pre(struct bwn_mac *mac)
2080 {
2081         struct bwn_phy *phy = &mac->mac_phy;
2082         struct bwn_phy_g *pg = &phy->phy_g;
2083         void *tssi2dbm;
2084         int idletssi;
2085         unsigned int i;
2086
2087         tssi2dbm = pg->pg_tssi2dbm;
2088         idletssi = pg->pg_idletssi;
2089
2090         memset(pg, 0, sizeof(*pg));
2091
2092         pg->pg_tssi2dbm = tssi2dbm;
2093         pg->pg_idletssi = idletssi;
2094
2095         memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2096
2097         for (i = 0; i < N(pg->pg_nrssi); i++)
2098                 pg->pg_nrssi[i] = -1000;
2099         for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2100                 pg->pg_nrssi_lt[i] = i;
2101         pg->pg_lofcal = 0xffff;
2102         pg->pg_initval = 0xffff;
2103         pg->pg_immode = BWN_IMMODE_NONE;
2104         pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2105         pg->pg_avgtssi = 0xff;
2106
2107         pg->pg_loctl.tx_bias = 0xff;
2108         TAILQ_INIT(&pg->pg_loctl.calib_list);
2109 }
2110
2111 static int
2112 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2113 {
2114         struct bwn_phy *phy = &mac->mac_phy;
2115         struct bwn_phy_g *pg = &phy->phy_g;
2116         struct bwn_softc *sc = mac->mac_sc;
2117         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2118         static const struct bwn_rfatt rfatt0[] = {
2119                 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
2120                 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2121                 { 3, 1 }, { 4, 1 }
2122         };
2123         static const struct bwn_rfatt rfatt1[] = {
2124                 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2125                 { 14, 1 }
2126         };
2127         static const struct bwn_rfatt rfatt2[] = {
2128                 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2129                 { 9, 1 }
2130         };
2131         static const struct bwn_bbatt bbatt_0[] = {
2132                 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2133         };
2134
2135         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2136
2137         if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2138                 pg->pg_bbatt.att = 0;
2139         else
2140                 pg->pg_bbatt.att = 2;
2141
2142         /* prepare Radio Attenuation */
2143         pg->pg_rfatt.padmix = 0;
2144
2145         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
2146             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
2147                 if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
2148                         pg->pg_rfatt.att = 2;
2149                         goto done;
2150                 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
2151                         pg->pg_rfatt.att = 3;
2152                         goto done;
2153                 }
2154         }
2155
2156         if (phy->type == BWN_PHYTYPE_A) {
2157                 pg->pg_rfatt.att = 0x60;
2158                 goto done;
2159         }
2160
2161         switch (phy->rf_ver) {
2162         case 0x2050:
2163                 switch (phy->rf_rev) {
2164                 case 0:
2165                         pg->pg_rfatt.att = 5;
2166                         goto done;
2167                 case 1:
2168                         if (phy->type == BWN_PHYTYPE_G) {
2169                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2170                                     SIBA_BOARDVENDOR_BCM &&
2171                                     siba_get_pci_subdevice(sc->sc_dev) ==
2172                                     SIBA_BOARD_BCM4309G &&
2173                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2174                                         pg->pg_rfatt.att = 3;
2175                                 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2176                                     SIBA_BOARDVENDOR_BCM &&
2177                                     siba_get_pci_subdevice(sc->sc_dev) ==
2178                                     SIBA_BOARD_BU4306)
2179                                         pg->pg_rfatt.att = 3;
2180                                 else
2181                                         pg->pg_rfatt.att = 1;
2182                         } else {
2183                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2184                                     SIBA_BOARDVENDOR_BCM &&
2185                                     siba_get_pci_subdevice(sc->sc_dev) ==
2186                                     SIBA_BOARD_BCM4309G &&
2187                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2188                                         pg->pg_rfatt.att = 7;
2189                                 else
2190                                         pg->pg_rfatt.att = 6;
2191                         }
2192                         goto done;
2193                 case 2:
2194                         if (phy->type == BWN_PHYTYPE_G) {
2195                                 if (siba_get_pci_subvendor(sc->sc_dev) ==
2196                                     SIBA_BOARDVENDOR_BCM &&
2197                                     siba_get_pci_subdevice(sc->sc_dev) ==
2198                                     SIBA_BOARD_BCM4309G &&
2199                                     siba_get_pci_revid(sc->sc_dev) >= 30)
2200                                         pg->pg_rfatt.att = 3;
2201                                 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2202                                     SIBA_BOARDVENDOR_BCM &&
2203                                     siba_get_pci_subdevice(sc->sc_dev) ==
2204                                     SIBA_BOARD_BU4306)
2205                                         pg->pg_rfatt.att = 5;
2206                                 else if (siba_get_chipid(sc->sc_dev) == 0x4320)
2207                                         pg->pg_rfatt.att = 4;
2208                                 else
2209                                         pg->pg_rfatt.att = 3;
2210                         } else
2211                                 pg->pg_rfatt.att = 6;
2212                         goto done;
2213                 case 3:
2214                         pg->pg_rfatt.att = 5;
2215                         goto done;
2216                 case 4:
2217                 case 5:
2218                         pg->pg_rfatt.att = 1;
2219                         goto done;
2220                 case 6:
2221                 case 7:
2222                         pg->pg_rfatt.att = 5;
2223                         goto done;
2224                 case 8:
2225                         pg->pg_rfatt.att = 0xa;
2226                         pg->pg_rfatt.padmix = 1;
2227                         goto done;
2228                 case 9:
2229                 default:
2230                         pg->pg_rfatt.att = 5;
2231                         goto done;
2232                 }
2233                 break;
2234         case 0x2053:
2235                 switch (phy->rf_rev) {
2236                 case 1:
2237                         pg->pg_rfatt.att = 6;
2238                         goto done;
2239                 }
2240                 break;
2241         }
2242         pg->pg_rfatt.att = 5;
2243 done:
2244         pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2245
2246         if (!bwn_has_hwpctl(mac)) {
2247                 lo->rfatt.array = rfatt0;
2248                 lo->rfatt.len = N(rfatt0);
2249                 lo->rfatt.min = 0;
2250                 lo->rfatt.max = 9;
2251                 goto genbbatt;
2252         }
2253         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2254                 lo->rfatt.array = rfatt1;
2255                 lo->rfatt.len = N(rfatt1);
2256                 lo->rfatt.min = 0;
2257                 lo->rfatt.max = 14;
2258                 goto genbbatt;
2259         }
2260         lo->rfatt.array = rfatt2;
2261         lo->rfatt.len = N(rfatt2);
2262         lo->rfatt.min = 0;
2263         lo->rfatt.max = 9;
2264 genbbatt:
2265         lo->bbatt.array = bbatt_0;
2266         lo->bbatt.len = N(bbatt_0);
2267         lo->bbatt.min = 0;
2268         lo->bbatt.max = 8;
2269
2270         BWN_READ_4(mac, BWN_MACCTL);
2271         if (phy->rev == 1) {
2272                 phy->gmode = 0;
2273                 bwn_reset_core(mac, 0);
2274                 bwn_phy_g_init_sub(mac);
2275                 phy->gmode = 1;
2276                 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2277         }
2278         return (0);
2279 }
2280
2281 static uint16_t
2282 bwn_phy_g_txctl(struct bwn_mac *mac)
2283 {
2284         struct bwn_phy *phy = &mac->mac_phy;
2285
2286         if (phy->rf_ver != 0x2050)
2287                 return (0);
2288         if (phy->rf_rev == 1)
2289                 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2290         if (phy->rf_rev < 6)
2291                 return (BWN_TXCTL_PA2DB);
2292         if (phy->rf_rev == 8)
2293                 return (BWN_TXCTL_TXMIX);
2294         return (0);
2295 }
2296
2297 static int
2298 bwn_phy_g_init(struct bwn_mac *mac)
2299 {
2300
2301         bwn_phy_g_init_sub(mac);
2302         return (0);
2303 }
2304
2305 static void
2306 bwn_phy_g_exit(struct bwn_mac *mac)
2307 {
2308         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2309         struct bwn_lo_calib *cal, *tmp;
2310
2311         if (lo == NULL)
2312                 return;
2313         TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2314                 TAILQ_REMOVE(&lo->calib_list, cal, list);
2315                 free(cal, M_DEVBUF);
2316         }
2317 }
2318
2319 static uint16_t
2320 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2321 {
2322
2323         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2324         return (BWN_READ_2(mac, BWN_PHYDATA));
2325 }
2326
2327 static void
2328 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2329 {
2330
2331         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2332         BWN_WRITE_2(mac, BWN_PHYDATA, value);
2333 }
2334
2335 static uint16_t
2336 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2337 {
2338
2339         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2340         BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2341         return (BWN_READ_2(mac, BWN_RFDATALO));
2342 }
2343
2344 static void
2345 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2346 {
2347
2348         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2349         BWN_WRITE_2(mac, BWN_RFCTL, reg);
2350         BWN_WRITE_2(mac, BWN_RFDATALO, value);
2351 }
2352
2353 static int
2354 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2355 {
2356
2357         return (mac->mac_phy.rev >= 6);
2358 }
2359
2360 static void
2361 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2362 {
2363         struct bwn_phy *phy = &mac->mac_phy;
2364         struct bwn_phy_g *pg = &phy->phy_g;
2365         unsigned int channel;
2366         uint16_t rfover, rfoverval;
2367
2368         if (on) {
2369                 if (phy->rf_on)
2370                         return;
2371
2372                 BWN_PHY_WRITE(mac, 0x15, 0x8000);
2373                 BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2374                 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2375                 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2376                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2377                             pg->pg_radioctx_over);
2378                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2379                             pg->pg_radioctx_overval);
2380                         pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2381                 }
2382                 channel = phy->chan;
2383                 bwn_phy_g_switch_chan(mac, 6, 1);
2384                 bwn_phy_g_switch_chan(mac, channel, 0);
2385                 return;
2386         }
2387
2388         rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2389         rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2390         pg->pg_radioctx_over = rfover;
2391         pg->pg_radioctx_overval = rfoverval;
2392         pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2393         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2394         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2395 }
2396
2397 static int
2398 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2399 {
2400
2401         if ((newchan < 1) || (newchan > 14))
2402                 return (EINVAL);
2403         bwn_phy_g_switch_chan(mac, newchan, 0);
2404
2405         return (0);
2406 }
2407
2408 static uint32_t
2409 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2410 {
2411
2412         return (1);
2413 }
2414
2415 static void
2416 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2417 {
2418         struct bwn_phy *phy = &mac->mac_phy;
2419         uint64_t hf;
2420         int autodiv = 0;
2421         uint16_t tmp;
2422
2423         if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2424                 autodiv = 1;
2425
2426         hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2427         bwn_hf_write(mac, hf);
2428
2429         BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2430             (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2431             ((autodiv ? BWN_ANTAUTO1 : antenna)
2432                 << BWN_PHY_BBANDCFG_RXANT_SHIFT));
2433
2434         if (autodiv) {
2435                 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2436                 if (antenna == BWN_ANTAUTO1)
2437                         tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2438                 else
2439                         tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2440                 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2441         }
2442         tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2443         if (autodiv)
2444                 tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2445         else
2446                 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2447         BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2448         if (phy->rev >= 2) {
2449                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2450                     BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2451                 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2452                     (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2453                     0x15);
2454                 if (phy->rev == 2)
2455                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2456                 else
2457                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2458                             (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2459                             8);
2460         }
2461         if (phy->rev >= 6)
2462                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2463
2464         hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2465         bwn_hf_write(mac, hf);
2466 }
2467
2468 static int
2469 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2470 {
2471         struct bwn_phy *phy = &mac->mac_phy;
2472         struct bwn_phy_g *pg = &phy->phy_g;
2473
2474         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2475         KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2476
2477         if (phy->rev == 0 || !phy->gmode)
2478                 return (ENODEV);
2479
2480         pg->pg_aci_wlan_automatic = 0;
2481         return (0);
2482 }
2483
2484 static int
2485 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2486 {
2487         struct bwn_phy *phy = &mac->mac_phy;
2488         struct bwn_phy_g *pg = &phy->phy_g;
2489         struct bwn_softc *sc = mac->mac_sc;
2490         unsigned int tssi;
2491         int cck, ofdm;
2492         int power;
2493         int rfatt, bbatt;
2494         unsigned int max;
2495
2496         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2497
2498         cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2499         ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2500         if (cck < 0 && ofdm < 0) {
2501                 if (ignore_tssi == 0)
2502                         return (BWN_TXPWR_RES_DONE);
2503                 cck = 0;
2504                 ofdm = 0;
2505         }
2506         tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2507         if (pg->pg_avgtssi != 0xff)
2508                 tssi = (tssi + pg->pg_avgtssi) / 2;
2509         pg->pg_avgtssi = tssi;
2510         KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2511
2512         max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2513         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2514                 max -= 3;
2515         if (max >= 120) {
2516                 device_printf(sc->sc_dev, "invalid max TX-power value\n");
2517                 max = 80;
2518                 siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2519         }
2520
2521         power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2522             (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2523              tssi, 0x00), 0x3f)]);
2524         if (power == 0)
2525                 return (BWN_TXPWR_RES_DONE);
2526
2527         rfatt = -((power + 7) / 8);
2528         bbatt = (-(power / 2)) - (4 * rfatt);
2529         if ((rfatt == 0) && (bbatt == 0))
2530                 return (BWN_TXPWR_RES_DONE);
2531         pg->pg_bbatt_delta = bbatt;
2532         pg->pg_rfatt_delta = rfatt;
2533         return (BWN_TXPWR_RES_NEED_ADJUST);
2534 }
2535
2536 static void
2537 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2538 {
2539         struct bwn_phy *phy = &mac->mac_phy;
2540         struct bwn_phy_g *pg = &phy->phy_g;
2541         struct bwn_softc *sc = mac->mac_sc;
2542         int rfatt, bbatt;
2543         uint8_t txctl;
2544
2545         bwn_mac_suspend(mac);
2546
2547         BWN_ASSERT_LOCKED(sc);
2548
2549         bbatt = pg->pg_bbatt.att;
2550         bbatt += pg->pg_bbatt_delta;
2551         rfatt = pg->pg_rfatt.att;
2552         rfatt += pg->pg_rfatt_delta;
2553
2554         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2555         txctl = pg->pg_txctl;
2556         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2557                 if (rfatt <= 1) {
2558                         if (txctl == 0) {
2559                                 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2560                                 rfatt += 2;
2561                                 bbatt += 2;
2562                         } else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2563                             BWN_BFL_PACTRL) {
2564                                 bbatt += 4 * (rfatt - 2);
2565                                 rfatt = 2;
2566                         }
2567                 } else if (rfatt > 4 && txctl) {
2568                         txctl = 0;
2569                         if (bbatt < 3) {
2570                                 rfatt -= 3;
2571                                 bbatt += 2;
2572                         } else {
2573                                 rfatt -= 2;
2574                                 bbatt -= 2;
2575                         }
2576                 }
2577         }
2578         pg->pg_txctl = txctl;
2579         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2580         pg->pg_rfatt.att = rfatt;
2581         pg->pg_bbatt.att = bbatt;
2582
2583         DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2584
2585         bwn_phy_lock(mac);
2586         bwn_rf_lock(mac);
2587         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2588             pg->pg_txctl);
2589         bwn_rf_unlock(mac);
2590         bwn_phy_unlock(mac);
2591
2592         bwn_mac_enable(mac);
2593 }
2594
2595 static void
2596 bwn_phy_g_task_15s(struct bwn_mac *mac)
2597 {
2598         struct bwn_phy *phy = &mac->mac_phy;
2599         struct bwn_phy_g *pg = &phy->phy_g;
2600         struct bwn_softc *sc = mac->mac_sc;
2601         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2602         unsigned long expire, now;
2603         struct bwn_lo_calib *cal, *tmp;
2604         uint8_t expired = 0;
2605
2606         bwn_mac_suspend(mac);
2607
2608         if (lo == NULL)
2609                 goto fail;
2610
2611         BWN_GETTIME(now);
2612         if (bwn_has_hwpctl(mac)) {
2613                 expire = now - BWN_LO_PWRVEC_EXPIRE;
2614                 if (time_before(lo->pwr_vec_read_time, expire)) {
2615                         bwn_lo_get_powervector(mac);
2616                         bwn_phy_g_dc_lookup_init(mac, 0);
2617                 }
2618                 goto fail;
2619         }
2620
2621         expire = now - BWN_LO_CALIB_EXPIRE;
2622         TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2623                 if (!time_before(cal->calib_time, expire))
2624                         continue;
2625                 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2626                     BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2627                         KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2628                         expired = 1;
2629                 }
2630
2631                 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2632                     cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2633                     cal->ctl.i, cal->ctl.q);
2634
2635                 TAILQ_REMOVE(&lo->calib_list, cal, list);
2636                 free(cal, M_DEVBUF);
2637         }
2638         if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2639                 cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2640                     &pg->pg_rfatt);
2641                 if (cal == NULL) {
2642                         device_printf(sc->sc_dev,
2643                             "failed to recalibrate LO\n");
2644                         goto fail;
2645                 }
2646                 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2647                 bwn_lo_write(mac, &cal->ctl);
2648         }
2649
2650 fail:
2651         bwn_mac_enable(mac);
2652 }
2653
2654 static void
2655 bwn_phy_g_task_60s(struct bwn_mac *mac)
2656 {
2657         struct bwn_phy *phy = &mac->mac_phy;
2658         struct bwn_softc *sc = mac->mac_sc;
2659         uint8_t old = phy->chan;
2660
2661         if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2662                 return;
2663
2664         bwn_mac_suspend(mac);
2665         bwn_nrssi_slope_11g(mac);
2666         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2667                 bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2668                 bwn_switch_channel(mac, old);
2669         }
2670         bwn_mac_enable(mac);
2671 }
2672
2673 static void
2674 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2675 {
2676
2677         BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2678 }
2679
2680 static int
2681 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2682         const struct ieee80211_bpf_params *params)
2683 {
2684         struct ieee80211com *ic = ni->ni_ic;
2685         struct bwn_softc *sc = ic->ic_softc;
2686         struct bwn_mac *mac = sc->sc_curmac;
2687         int error;
2688
2689         if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 ||
2690             mac->mac_status < BWN_MAC_STATUS_STARTED) {
2691                 m_freem(m);
2692                 return (ENETDOWN);
2693         }
2694
2695         BWN_LOCK(sc);
2696         if (bwn_tx_isfull(sc, m)) {
2697                 m_freem(m);
2698                 BWN_UNLOCK(sc);
2699                 return (ENOBUFS);
2700         }
2701
2702         error = bwn_tx_start(sc, ni, m);
2703         if (error == 0)
2704                 sc->sc_watchdog_timer = 5;
2705         BWN_UNLOCK(sc);
2706         return (error);
2707 }
2708
2709 /*
2710  * Callback from the 802.11 layer to update the slot time
2711  * based on the current setting.  We use it to notify the
2712  * firmware of ERP changes and the f/w takes care of things
2713  * like slot time and preamble.
2714  */
2715 static void
2716 bwn_updateslot(struct ieee80211com *ic)
2717 {
2718         struct bwn_softc *sc = ic->ic_softc;
2719         struct bwn_mac *mac;
2720
2721         BWN_LOCK(sc);
2722         if (sc->sc_flags & BWN_FLAG_RUNNING) {
2723                 mac = (struct bwn_mac *)sc->sc_curmac;
2724                 bwn_set_slot_time(mac, IEEE80211_GET_SLOTTIME(ic));
2725         }
2726         BWN_UNLOCK(sc);
2727 }
2728
2729 /*
2730  * Callback from the 802.11 layer after a promiscuous mode change.
2731  * Note this interface does not check the operating mode as this
2732  * is an internal callback and we are expected to honor the current
2733  * state (e.g. this is used for setting the interface in promiscuous
2734  * mode when operating in hostap mode to do ACS).
2735  */
2736 static void
2737 bwn_update_promisc(struct ieee80211com *ic)
2738 {
2739         struct bwn_softc *sc = ic->ic_softc;
2740         struct bwn_mac *mac = sc->sc_curmac;
2741
2742         BWN_LOCK(sc);
2743         mac = sc->sc_curmac;
2744         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2745                 if (ic->ic_promisc > 0)
2746                         sc->sc_filters |= BWN_MACCTL_PROMISC;
2747                 else
2748                         sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2749                 bwn_set_opmode(mac);
2750         }
2751         BWN_UNLOCK(sc);
2752 }
2753
2754 /*
2755  * Callback from the 802.11 layer to update WME parameters.
2756  */
2757 static int
2758 bwn_wme_update(struct ieee80211com *ic)
2759 {
2760         struct bwn_softc *sc = ic->ic_softc;
2761         struct bwn_mac *mac = sc->sc_curmac;
2762         struct wmeParams *wmep;
2763         int i;
2764
2765         BWN_LOCK(sc);
2766         mac = sc->sc_curmac;
2767         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2768                 bwn_mac_suspend(mac);
2769                 for (i = 0; i < N(sc->sc_wmeParams); i++) {
2770                         wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2771                         bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2772                 }
2773                 bwn_mac_enable(mac);
2774         }
2775         BWN_UNLOCK(sc);
2776         return (0);
2777 }
2778
2779 static void
2780 bwn_scan_start(struct ieee80211com *ic)
2781 {
2782         struct bwn_softc *sc = ic->ic_softc;
2783         struct bwn_mac *mac;
2784
2785         BWN_LOCK(sc);
2786         mac = sc->sc_curmac;
2787         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2788                 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2789                 bwn_set_opmode(mac);
2790                 /* disable CFP update during scan */
2791                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2792         }
2793         BWN_UNLOCK(sc);
2794 }
2795
2796 static void
2797 bwn_scan_end(struct ieee80211com *ic)
2798 {
2799         struct bwn_softc *sc = ic->ic_softc;
2800         struct bwn_mac *mac;
2801
2802         BWN_LOCK(sc);
2803         mac = sc->sc_curmac;
2804         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2805                 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2806                 bwn_set_opmode(mac);
2807                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2808         }
2809         BWN_UNLOCK(sc);
2810 }
2811
2812 static void
2813 bwn_set_channel(struct ieee80211com *ic)
2814 {
2815         struct bwn_softc *sc = ic->ic_softc;
2816         struct bwn_mac *mac = sc->sc_curmac;
2817         struct bwn_phy *phy = &mac->mac_phy;
2818         int chan, error;
2819
2820         BWN_LOCK(sc);
2821
2822         error = bwn_switch_band(sc, ic->ic_curchan);
2823         if (error)
2824                 goto fail;
2825         bwn_mac_suspend(mac);
2826         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2827         chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2828         if (chan != phy->chan)
2829                 bwn_switch_channel(mac, chan);
2830
2831         /* TX power level */
2832         if (ic->ic_curchan->ic_maxpower != 0 &&
2833             ic->ic_curchan->ic_maxpower != phy->txpower) {
2834                 phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2835                 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2836                     BWN_TXPWR_IGNORE_TSSI);
2837         }
2838
2839         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2840         if (phy->set_antenna)
2841                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
2842
2843         if (sc->sc_rf_enabled != phy->rf_on) {
2844                 if (sc->sc_rf_enabled) {
2845                         bwn_rf_turnon(mac);
2846                         if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2847                                 device_printf(sc->sc_dev,
2848                                     "please turn on the RF switch\n");
2849                 } else
2850                         bwn_rf_turnoff(mac);
2851         }
2852
2853         bwn_mac_enable(mac);
2854
2855 fail:
2856         /*
2857          * Setup radio tap channel freq and flags
2858          */
2859         sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2860                 htole16(ic->ic_curchan->ic_freq);
2861         sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2862                 htole16(ic->ic_curchan->ic_flags & 0xffff);
2863
2864         BWN_UNLOCK(sc);
2865 }
2866
2867 static struct ieee80211vap *
2868 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
2869     enum ieee80211_opmode opmode, int flags,
2870     const uint8_t bssid[IEEE80211_ADDR_LEN],
2871     const uint8_t mac[IEEE80211_ADDR_LEN])
2872 {
2873         struct ieee80211vap *vap;
2874         struct bwn_vap *bvp;
2875
2876         switch (opmode) {
2877         case IEEE80211_M_HOSTAP:
2878         case IEEE80211_M_MBSS:
2879         case IEEE80211_M_STA:
2880         case IEEE80211_M_WDS:
2881         case IEEE80211_M_MONITOR:
2882         case IEEE80211_M_IBSS:
2883         case IEEE80211_M_AHDEMO:
2884                 break;
2885         default:
2886                 return (NULL);
2887         }
2888
2889         bvp = malloc(sizeof(struct bwn_vap), M_80211_VAP, M_WAITOK | M_ZERO);
2890         vap = &bvp->bv_vap;
2891         ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
2892         /* override with driver methods */
2893         bvp->bv_newstate = vap->iv_newstate;
2894         vap->iv_newstate = bwn_newstate;
2895
2896         /* override max aid so sta's cannot assoc when we're out of sta id's */
2897         vap->iv_max_aid = BWN_STAID_MAX;
2898
2899         ieee80211_ratectl_init(vap);
2900
2901         /* complete setup */
2902         ieee80211_vap_attach(vap, ieee80211_media_change,
2903             ieee80211_media_status, mac);
2904         return (vap);
2905 }
2906
2907 static void
2908 bwn_vap_delete(struct ieee80211vap *vap)
2909 {
2910         struct bwn_vap *bvp = BWN_VAP(vap);
2911
2912         ieee80211_ratectl_deinit(vap);
2913         ieee80211_vap_detach(vap);
2914         free(bvp, M_80211_VAP);
2915 }
2916
2917 static int
2918 bwn_init(struct bwn_softc *sc)
2919 {
2920         struct bwn_mac *mac;
2921         int error;
2922
2923         BWN_ASSERT_LOCKED(sc);
2924
2925         bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
2926         sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
2927         sc->sc_filters = 0;
2928         bwn_wme_clear(sc);
2929         sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
2930         sc->sc_rf_enabled = 1;
2931
2932         mac = sc->sc_curmac;
2933         if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
2934                 error = bwn_core_init(mac);
2935                 if (error != 0)
2936                         return (error);
2937         }
2938         if (mac->mac_status == BWN_MAC_STATUS_INITED)
2939                 bwn_core_start(mac);
2940
2941         bwn_set_opmode(mac);
2942         bwn_set_pretbtt(mac);
2943         bwn_spu_setdelay(mac, 0);
2944         bwn_set_macaddr(mac);
2945
2946         sc->sc_flags |= BWN_FLAG_RUNNING;
2947         callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
2948         callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
2949
2950         return (0);
2951 }
2952
2953 static void
2954 bwn_stop(struct bwn_softc *sc)
2955 {
2956         struct bwn_mac *mac = sc->sc_curmac;
2957
2958         BWN_ASSERT_LOCKED(sc);
2959
2960         if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
2961                 /* XXX FIXME opmode not based on VAP */
2962                 bwn_set_opmode(mac);
2963                 bwn_set_macaddr(mac);
2964         }
2965
2966         if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
2967                 bwn_core_stop(mac);
2968
2969         callout_stop(&sc->sc_led_blink_ch);
2970         sc->sc_led_blinking = 0;
2971
2972         bwn_core_exit(mac);
2973         sc->sc_rf_enabled = 0;
2974
2975         sc->sc_flags &= ~BWN_FLAG_RUNNING;
2976 }
2977
2978 static void
2979 bwn_wme_clear(struct bwn_softc *sc)
2980 {
2981 #define MS(_v, _f)      (((_v) & _f) >> _f##_S)
2982         struct wmeParams *p;
2983         unsigned int i;
2984
2985         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
2986             ("%s:%d: fail", __func__, __LINE__));
2987
2988         for (i = 0; i < N(sc->sc_wmeParams); i++) {
2989                 p = &(sc->sc_wmeParams[i]);
2990
2991                 switch (bwn_wme_shm_offsets[i]) {
2992                 case BWN_WME_VOICE:
2993                         p->wmep_txopLimit = 0;
2994                         p->wmep_aifsn = 2;
2995                         /* XXX FIXME: log2(cwmin) */
2996                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
2997                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
2998                         break;
2999                 case BWN_WME_VIDEO:
3000                         p->wmep_txopLimit = 0;
3001                         p->wmep_aifsn = 2;
3002                         /* XXX FIXME: log2(cwmin) */
3003                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3004                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3005                         break;
3006                 case BWN_WME_BESTEFFORT:
3007                         p->wmep_txopLimit = 0;
3008                         p->wmep_aifsn = 3;
3009                         /* XXX FIXME: log2(cwmin) */
3010                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3011                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3012                         break;
3013                 case BWN_WME_BACKGROUND:
3014                         p->wmep_txopLimit = 0;
3015                         p->wmep_aifsn = 7;
3016                         /* XXX FIXME: log2(cwmin) */
3017                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3018                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3019                         break;
3020                 default:
3021                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3022                 }
3023         }
3024 }
3025
3026 static int
3027 bwn_core_init(struct bwn_mac *mac)
3028 {
3029         struct bwn_softc *sc = mac->mac_sc;
3030         uint64_t hf;
3031         int error;
3032
3033         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3034             ("%s:%d: fail", __func__, __LINE__));
3035
3036         siba_powerup(sc->sc_dev, 0);
3037         if (!siba_dev_isup(sc->sc_dev))
3038                 bwn_reset_core(mac,
3039                     mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3040
3041         mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3042         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3043         mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3044         BWN_GETTIME(mac->mac_phy.nexttime);
3045         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3046         bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3047         mac->mac_stats.link_noise = -95;
3048         mac->mac_reason_intr = 0;
3049         bzero(mac->mac_reason, sizeof(mac->mac_reason));
3050         mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3051 #ifdef BWN_DEBUG
3052         if (sc->sc_debug & BWN_DEBUG_XMIT)
3053                 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3054 #endif
3055         mac->mac_suspended = 1;
3056         mac->mac_task_state = 0;
3057         memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3058
3059         mac->mac_phy.init_pre(mac);
3060
3061         siba_pcicore_intr(sc->sc_dev);
3062
3063         siba_fix_imcfglobug(sc->sc_dev);
3064         bwn_bt_disable(mac);
3065         if (mac->mac_phy.prepare_hw) {
3066                 error = mac->mac_phy.prepare_hw(mac);
3067                 if (error)
3068                         goto fail0;
3069         }
3070         error = bwn_chip_init(mac);
3071         if (error)
3072                 goto fail0;
3073         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3074             siba_get_revid(sc->sc_dev));
3075         hf = bwn_hf_read(mac);
3076         if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3077                 hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3078                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3079                         hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3080                 if (mac->mac_phy.rev == 1)
3081                         hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3082         }
3083         if (mac->mac_phy.rf_ver == 0x2050) {
3084                 if (mac->mac_phy.rf_rev < 6)
3085                         hf |= BWN_HF_FORCE_VCO_RECALC;
3086                 if (mac->mac_phy.rf_rev == 6)
3087                         hf |= BWN_HF_4318_TSSI;
3088         }
3089         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3090                 hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3091         if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3092             (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3093                 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3094         hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3095         bwn_hf_write(mac, hf);
3096
3097         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3098         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3099         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3100         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3101
3102         bwn_rate_init(mac);
3103         bwn_set_phytxctl(mac);
3104
3105         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3106             (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3107         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3108
3109         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3110                 bwn_pio_init(mac);
3111         else
3112                 bwn_dma_init(mac);
3113         bwn_wme_init(mac);
3114         bwn_spu_setdelay(mac, 1);
3115         bwn_bt_enable(mac);
3116
3117         siba_powerup(sc->sc_dev,
3118             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3119         bwn_set_macaddr(mac);
3120         bwn_crypt_init(mac);
3121
3122         /* XXX LED initializatin */
3123
3124         mac->mac_status = BWN_MAC_STATUS_INITED;
3125
3126         return (error);
3127
3128 fail0:
3129         siba_powerdown(sc->sc_dev);
3130         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3131             ("%s:%d: fail", __func__, __LINE__));
3132         return (error);
3133 }
3134
3135 static void
3136 bwn_core_start(struct bwn_mac *mac)
3137 {
3138         struct bwn_softc *sc = mac->mac_sc;
3139         uint32_t tmp;
3140
3141         KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3142             ("%s:%d: fail", __func__, __LINE__));
3143
3144         if (siba_get_revid(sc->sc_dev) < 5)
3145                 return;
3146
3147         while (1) {
3148                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3149                 if (!(tmp & 0x00000001))
3150                         break;
3151                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3152         }
3153
3154         bwn_mac_enable(mac);
3155         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3156         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3157
3158         mac->mac_status = BWN_MAC_STATUS_STARTED;
3159 }
3160
3161 static void
3162 bwn_core_exit(struct bwn_mac *mac)
3163 {
3164         struct bwn_softc *sc = mac->mac_sc;
3165         uint32_t macctl;
3166
3167         BWN_ASSERT_LOCKED(mac->mac_sc);
3168
3169         KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3170             ("%s:%d: fail", __func__, __LINE__));
3171
3172         if (mac->mac_status != BWN_MAC_STATUS_INITED)
3173                 return;
3174         mac->mac_status = BWN_MAC_STATUS_UNINIT;
3175
3176         macctl = BWN_READ_4(mac, BWN_MACCTL);
3177         macctl &= ~BWN_MACCTL_MCODE_RUN;
3178         macctl |= BWN_MACCTL_MCODE_JMP0;
3179         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3180
3181         bwn_dma_stop(mac);
3182         bwn_pio_stop(mac);
3183         bwn_chip_exit(mac);
3184         mac->mac_phy.switch_analog(mac, 0);
3185         siba_dev_down(sc->sc_dev, 0);
3186         siba_powerdown(sc->sc_dev);
3187 }
3188
3189 static void
3190 bwn_bt_disable(struct bwn_mac *mac)
3191 {
3192         struct bwn_softc *sc = mac->mac_sc;
3193
3194         (void)sc;
3195         /* XXX do nothing yet */
3196 }
3197
3198 static int
3199 bwn_chip_init(struct bwn_mac *mac)
3200 {
3201         struct bwn_softc *sc = mac->mac_sc;
3202         struct bwn_phy *phy = &mac->mac_phy;
3203         uint32_t macctl;
3204         int error;
3205
3206         macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3207         if (phy->gmode)
3208                 macctl |= BWN_MACCTL_GMODE;
3209         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3210
3211         error = bwn_fw_fillinfo(mac);
3212         if (error)
3213                 return (error);
3214         error = bwn_fw_loaducode(mac);
3215         if (error)
3216                 return (error);
3217
3218         error = bwn_gpio_init(mac);
3219         if (error)
3220                 return (error);
3221
3222         error = bwn_fw_loadinitvals(mac);
3223         if (error) {
3224                 siba_gpio_set(sc->sc_dev, 0);
3225                 return (error);
3226         }
3227         phy->switch_analog(mac, 1);
3228         error = bwn_phy_init(mac);
3229         if (error) {
3230                 siba_gpio_set(sc->sc_dev, 0);
3231                 return (error);
3232         }
3233         if (phy->set_im)
3234                 phy->set_im(mac, BWN_IMMODE_NONE);
3235         if (phy->set_antenna)
3236                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
3237         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3238
3239         if (phy->type == BWN_PHYTYPE_B)
3240                 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3241         BWN_WRITE_4(mac, 0x0100, 0x01000000);
3242         if (siba_get_revid(sc->sc_dev) < 5)
3243                 BWN_WRITE_4(mac, 0x010c, 0x01000000);
3244
3245         BWN_WRITE_4(mac, BWN_MACCTL,
3246             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3247         BWN_WRITE_4(mac, BWN_MACCTL,
3248             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3249         bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3250
3251         bwn_set_opmode(mac);
3252         if (siba_get_revid(sc->sc_dev) < 3) {
3253                 BWN_WRITE_2(mac, 0x060e, 0x0000);
3254                 BWN_WRITE_2(mac, 0x0610, 0x8000);
3255                 BWN_WRITE_2(mac, 0x0604, 0x0000);
3256                 BWN_WRITE_2(mac, 0x0606, 0x0200);
3257         } else {
3258                 BWN_WRITE_4(mac, 0x0188, 0x80000000);
3259                 BWN_WRITE_4(mac, 0x018c, 0x02000000);
3260         }
3261         BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3262         BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
3263         BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3264         BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3265         BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3266         BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3267         BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3268         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3269             siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3270         BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3271         return (error);
3272 }
3273
3274 /* read hostflags */
3275 static uint64_t
3276 bwn_hf_read(struct bwn_mac *mac)
3277 {
3278         uint64_t ret;
3279
3280         ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3281         ret <<= 16;
3282         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3283         ret <<= 16;
3284         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3285         return (ret);
3286 }
3287
3288 static void
3289 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3290 {
3291
3292         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3293             (value & 0x00000000ffffull));
3294         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3295             (value & 0x0000ffff0000ull) >> 16);
3296         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3297             (value & 0xffff00000000ULL) >> 32);
3298 }
3299
3300 static void
3301 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3302 {
3303
3304         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3305         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3306 }
3307
3308 static void
3309 bwn_rate_init(struct bwn_mac *mac)
3310 {
3311
3312         switch (mac->mac_phy.type) {
3313         case BWN_PHYTYPE_A:
3314         case BWN_PHYTYPE_G:
3315         case BWN_PHYTYPE_LP:
3316         case BWN_PHYTYPE_N:
3317                 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3318                 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3319                 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3320                 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3321                 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3322                 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3323                 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3324                 if (mac->mac_phy.type == BWN_PHYTYPE_A)
3325                         break;
3326                 /* FALLTHROUGH */
3327         case BWN_PHYTYPE_B:
3328                 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3329                 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3330                 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3331                 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3332                 break;
3333         default:
3334                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3335         }
3336 }
3337
3338 static void
3339 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3340 {
3341         uint16_t offset;
3342
3343         if (ofdm) {
3344                 offset = 0x480;
3345                 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3346         } else {
3347                 offset = 0x4c0;
3348                 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3349         }
3350         bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3351             bwn_shm_read_2(mac, BWN_SHARED, offset));
3352 }
3353
3354 static uint8_t
3355 bwn_plcp_getcck(const uint8_t bitrate)
3356 {
3357
3358         switch (bitrate) {
3359         case BWN_CCK_RATE_1MB:
3360                 return (0x0a);
3361         case BWN_CCK_RATE_2MB:
3362                 return (0x14);
3363         case BWN_CCK_RATE_5MB:
3364                 return (0x37);
3365         case BWN_CCK_RATE_11MB:
3366                 return (0x6e);
3367         }
3368         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3369         return (0);
3370 }
3371
3372 static uint8_t
3373 bwn_plcp_getofdm(const uint8_t bitrate)
3374 {
3375
3376         switch (bitrate) {
3377         case BWN_OFDM_RATE_6MB:
3378                 return (0xb);
3379         case BWN_OFDM_RATE_9MB:
3380                 return (0xf);
3381         case BWN_OFDM_RATE_12MB:
3382                 return (0xa);
3383         case BWN_OFDM_RATE_18MB:
3384                 return (0xe);
3385         case BWN_OFDM_RATE_24MB:
3386                 return (0x9);
3387         case BWN_OFDM_RATE_36MB:
3388                 return (0xd);
3389         case BWN_OFDM_RATE_48MB:
3390                 return (0x8);
3391         case BWN_OFDM_RATE_54MB:
3392                 return (0xc);
3393         }
3394         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3395         return (0);
3396 }
3397
3398 static void
3399 bwn_set_phytxctl(struct bwn_mac *mac)
3400 {
3401         uint16_t ctl;
3402
3403         ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3404             BWN_TX_PHY_TXPWR);
3405         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3406         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3407         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3408 }
3409
3410 static void
3411 bwn_pio_init(struct bwn_mac *mac)
3412 {
3413         struct bwn_pio *pio = &mac->mac_method.pio;
3414
3415         BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3416             & ~BWN_MACCTL_BIGENDIAN);
3417         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3418
3419         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3420         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3421         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3422         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3423         bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3424         bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3425 }
3426
3427 static void
3428 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3429     int index)
3430 {
3431         struct bwn_pio_txpkt *tp;
3432         struct bwn_softc *sc = mac->mac_sc;
3433         unsigned int i;
3434
3435         tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3436         tq->tq_index = index;
3437
3438         tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3439         if (siba_get_revid(sc->sc_dev) >= 8)
3440                 tq->tq_size = 1920;
3441         else {
3442                 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3443                 tq->tq_size -= 80;
3444         }
3445
3446         TAILQ_INIT(&tq->tq_pktlist);
3447         for (i = 0; i < N(tq->tq_pkts); i++) {
3448                 tp = &(tq->tq_pkts[i]);
3449                 tp->tp_index = i;
3450                 tp->tp_queue = tq;
3451                 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3452         }
3453 }
3454
3455 static uint16_t
3456 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3457 {
3458         struct bwn_softc *sc = mac->mac_sc;
3459         static const uint16_t bases[] = {
3460                 BWN_PIO_BASE0,
3461                 BWN_PIO_BASE1,
3462                 BWN_PIO_BASE2,
3463                 BWN_PIO_BASE3,
3464                 BWN_PIO_BASE4,
3465                 BWN_PIO_BASE5,
3466                 BWN_PIO_BASE6,
3467                 BWN_PIO_BASE7,
3468         };
3469         static const uint16_t bases_rev11[] = {
3470                 BWN_PIO11_BASE0,
3471                 BWN_PIO11_BASE1,
3472                 BWN_PIO11_BASE2,
3473                 BWN_PIO11_BASE3,
3474                 BWN_PIO11_BASE4,
3475                 BWN_PIO11_BASE5,
3476         };
3477
3478         if (siba_get_revid(sc->sc_dev) >= 11) {
3479                 if (index >= N(bases_rev11))
3480                         device_printf(sc->sc_dev, "%s: warning\n", __func__);
3481                 return (bases_rev11[index]);
3482         }
3483         if (index >= N(bases))
3484                 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3485         return (bases[index]);
3486 }
3487
3488 static void
3489 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3490     int index)
3491 {
3492         struct bwn_softc *sc = mac->mac_sc;
3493
3494         prq->prq_mac = mac;
3495         prq->prq_rev = siba_get_revid(sc->sc_dev);
3496         prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3497         bwn_dma_rxdirectfifo(mac, index, 1);
3498 }
3499
3500 static void
3501 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3502 {
3503         if (tq == NULL)
3504                 return;
3505         bwn_pio_cancel_tx_packets(tq);
3506 }
3507
3508 static void
3509 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3510 {
3511
3512         bwn_destroy_pioqueue_tx(pio);
3513 }
3514
3515 static uint16_t
3516 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3517     uint16_t offset)
3518 {
3519
3520         return (BWN_READ_2(mac, tq->tq_base + offset));
3521 }
3522
3523 static void
3524 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3525 {
3526         uint32_t ctl;
3527         int type;
3528         uint16_t base;
3529
3530         type = bwn_dma_mask2type(bwn_dma_mask(mac));
3531         base = bwn_dma_base(type, idx);
3532         if (type == BWN_DMA_64BIT) {
3533                 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3534                 ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3535                 if (enable)
3536                         ctl |= BWN_DMA64_RXDIRECTFIFO;
3537                 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3538         } else {
3539                 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3540                 ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3541                 if (enable)
3542                         ctl |= BWN_DMA32_RXDIRECTFIFO;
3543                 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3544         }
3545 }
3546
3547 static uint64_t
3548 bwn_dma_mask(struct bwn_mac *mac)
3549 {
3550         uint32_t tmp;
3551         uint16_t base;
3552
3553         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3554         if (tmp & SIBA_TGSHIGH_DMA64)
3555                 return (BWN_DMA_BIT_MASK(64));
3556         base = bwn_dma_base(0, 0);
3557         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3558         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3559         if (tmp & BWN_DMA32_TXADDREXT_MASK)
3560                 return (BWN_DMA_BIT_MASK(32));
3561
3562         return (BWN_DMA_BIT_MASK(30));
3563 }
3564
3565 static int
3566 bwn_dma_mask2type(uint64_t dmamask)
3567 {
3568
3569         if (dmamask == BWN_DMA_BIT_MASK(30))
3570                 return (BWN_DMA_30BIT);
3571         if (dmamask == BWN_DMA_BIT_MASK(32))
3572                 return (BWN_DMA_32BIT);
3573         if (dmamask == BWN_DMA_BIT_MASK(64))
3574                 return (BWN_DMA_64BIT);
3575         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3576         return (BWN_DMA_30BIT);
3577 }
3578
3579 static void
3580 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3581 {
3582         struct bwn_pio_txpkt *tp;
3583         unsigned int i;
3584
3585         for (i = 0; i < N(tq->tq_pkts); i++) {
3586                 tp = &(tq->tq_pkts[i]);
3587                 if (tp->tp_m) {
3588                         m_freem(tp->tp_m);
3589                         tp->tp_m = NULL;
3590                 }
3591         }
3592 }
3593
3594 static uint16_t
3595 bwn_dma_base(int type, int controller_idx)
3596 {
3597         static const uint16_t map64[] = {
3598                 BWN_DMA64_BASE0,
3599                 BWN_DMA64_BASE1,
3600                 BWN_DMA64_BASE2,
3601                 BWN_DMA64_BASE3,
3602                 BWN_DMA64_BASE4,
3603                 BWN_DMA64_BASE5,
3604         };
3605         static const uint16_t map32[] = {
3606                 BWN_DMA32_BASE0,
3607                 BWN_DMA32_BASE1,
3608                 BWN_DMA32_BASE2,
3609                 BWN_DMA32_BASE3,
3610                 BWN_DMA32_BASE4,
3611                 BWN_DMA32_BASE5,
3612         };
3613
3614         if (type == BWN_DMA_64BIT) {
3615                 KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3616                     ("%s:%d: fail", __func__, __LINE__));
3617                 return (map64[controller_idx]);
3618         }
3619         KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3620             ("%s:%d: fail", __func__, __LINE__));
3621         return (map32[controller_idx]);
3622 }
3623
3624 static void
3625 bwn_dma_init(struct bwn_mac *mac)
3626 {
3627         struct bwn_dma *dma = &mac->mac_method.dma;
3628
3629         /* setup TX DMA channels. */
3630         bwn_dma_setup(dma->wme[WME_AC_BK]);
3631         bwn_dma_setup(dma->wme[WME_AC_BE]);
3632         bwn_dma_setup(dma->wme[WME_AC_VI]);
3633         bwn_dma_setup(dma->wme[WME_AC_VO]);
3634         bwn_dma_setup(dma->mcast);
3635         /* setup RX DMA channel. */
3636         bwn_dma_setup(dma->rx);
3637 }
3638
3639 static struct bwn_dma_ring *
3640 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3641     int for_tx, int type)
3642 {
3643         struct bwn_dma *dma = &mac->mac_method.dma;
3644         struct bwn_dma_ring *dr;
3645         struct bwn_dmadesc_generic *desc;
3646         struct bwn_dmadesc_meta *mt;
3647         struct bwn_softc *sc = mac->mac_sc;
3648         int error, i;
3649
3650         dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO);
3651         if (dr == NULL)
3652                 goto out;
3653         dr->dr_numslots = BWN_RXRING_SLOTS;
3654         if (for_tx)
3655                 dr->dr_numslots = BWN_TXRING_SLOTS;
3656
3657         dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3658             M_DEVBUF, M_NOWAIT | M_ZERO);
3659         if (dr->dr_meta == NULL)
3660                 goto fail0;
3661
3662         dr->dr_type = type;
3663         dr->dr_mac = mac;
3664         dr->dr_base = bwn_dma_base(type, controller_index);
3665         dr->dr_index = controller_index;
3666         if (type == BWN_DMA_64BIT) {
3667                 dr->getdesc = bwn_dma_64_getdesc;
3668                 dr->setdesc = bwn_dma_64_setdesc;
3669                 dr->start_transfer = bwn_dma_64_start_transfer;
3670                 dr->suspend = bwn_dma_64_suspend;
3671                 dr->resume = bwn_dma_64_resume;
3672                 dr->get_curslot = bwn_dma_64_get_curslot;
3673                 dr->set_curslot = bwn_dma_64_set_curslot;
3674         } else {
3675                 dr->getdesc = bwn_dma_32_getdesc;
3676                 dr->setdesc = bwn_dma_32_setdesc;
3677                 dr->start_transfer = bwn_dma_32_start_transfer;
3678                 dr->suspend = bwn_dma_32_suspend;
3679                 dr->resume = bwn_dma_32_resume;
3680                 dr->get_curslot = bwn_dma_32_get_curslot;
3681                 dr->set_curslot = bwn_dma_32_set_curslot;
3682         }
3683         if (for_tx) {
3684                 dr->dr_tx = 1;
3685                 dr->dr_curslot = -1;
3686         } else {
3687                 if (dr->dr_index == 0) {
3688                         dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3689                         dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3690                 } else
3691                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3692         }
3693
3694         error = bwn_dma_allocringmemory(dr);
3695         if (error)
3696                 goto fail2;
3697
3698         if (for_tx) {
3699                 /*
3700                  * Assumption: BWN_TXRING_SLOTS can be divided by
3701                  * BWN_TX_SLOTS_PER_FRAME
3702                  */
3703                 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3704                     ("%s:%d: fail", __func__, __LINE__));
3705
3706                 dr->dr_txhdr_cache =
3707                     malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3708                         BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO);
3709                 KASSERT(dr->dr_txhdr_cache != NULL,
3710                     ("%s:%d: fail", __func__, __LINE__));
3711
3712                 /*
3713                  * Create TX ring DMA stuffs
3714                  */
3715                 error = bus_dma_tag_create(dma->parent_dtag,
3716                                     BWN_ALIGN, 0,
3717                                     BUS_SPACE_MAXADDR,
3718                                     BUS_SPACE_MAXADDR,
3719                                     NULL, NULL,
3720                                     BWN_HDRSIZE(mac),
3721                                     1,
3722                                     BUS_SPACE_MAXSIZE_32BIT,
3723                                     0,
3724                                     NULL, NULL,
3725                                     &dr->dr_txring_dtag);
3726                 if (error) {
3727                         device_printf(sc->sc_dev,
3728                             "can't create TX ring DMA tag: TODO frees\n");
3729                         goto fail1;
3730                 }
3731
3732                 for (i = 0; i < dr->dr_numslots; i += 2) {
3733                         dr->getdesc(dr, i, &desc, &mt);
3734
3735                         mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3736                         mt->mt_m = NULL;
3737                         mt->mt_ni = NULL;
3738                         mt->mt_islast = 0;
3739                         error = bus_dmamap_create(dr->dr_txring_dtag, 0,
3740                             &mt->mt_dmap);
3741                         if (error) {
3742                                 device_printf(sc->sc_dev,
3743                                      "can't create RX buf DMA map\n");
3744                                 goto fail1;
3745                         }
3746
3747                         dr->getdesc(dr, i + 1, &desc, &mt);
3748
3749                         mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3750                         mt->mt_m = NULL;
3751                         mt->mt_ni = NULL;
3752                         mt->mt_islast = 1;
3753                         error = bus_dmamap_create(dma->txbuf_dtag, 0,
3754                             &mt->mt_dmap);
3755                         if (error) {
3756                                 device_printf(sc->sc_dev,
3757                                      "can't create RX buf DMA map\n");
3758                                 goto fail1;
3759                         }
3760                 }
3761         } else {
3762                 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3763                     &dr->dr_spare_dmap);
3764                 if (error) {
3765                         device_printf(sc->sc_dev,
3766                             "can't create RX buf DMA map\n");
3767                         goto out;               /* XXX wrong! */
3768                 }
3769
3770                 for (i = 0; i < dr->dr_numslots; i++) {
3771                         dr->getdesc(dr, i, &desc, &mt);
3772
3773                         error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3774                             &mt->mt_dmap);
3775                         if (error) {
3776                                 device_printf(sc->sc_dev,
3777                                     "can't create RX buf DMA map\n");
3778                                 goto out;       /* XXX wrong! */
3779                         }
3780                         error = bwn_dma_newbuf(dr, desc, mt, 1);
3781                         if (error) {
3782                                 device_printf(sc->sc_dev,
3783                                     "failed to allocate RX buf\n");
3784                                 goto out;       /* XXX wrong! */
3785                         }
3786                 }
3787
3788                 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3789                     BUS_DMASYNC_PREWRITE);
3790
3791                 dr->dr_usedslot = dr->dr_numslots;
3792         }
3793
3794       out:
3795         return (dr);
3796
3797 fail2:
3798         free(dr->dr_txhdr_cache, M_DEVBUF);
3799 fail1:
3800         free(dr->dr_meta, M_DEVBUF);
3801 fail0:
3802         free(dr, M_DEVBUF);
3803         return (NULL);
3804 }
3805
3806 static void
3807 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3808 {
3809
3810         if (dr == NULL)
3811                 return;
3812
3813         bwn_dma_free_descbufs(*dr);
3814         bwn_dma_free_ringmemory(*dr);
3815
3816         free((*dr)->dr_txhdr_cache, M_DEVBUF);
3817         free((*dr)->dr_meta, M_DEVBUF);
3818         free(*dr, M_DEVBUF);
3819
3820         *dr = NULL;
3821 }
3822
3823 static void
3824 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3825     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3826 {
3827         struct bwn_dmadesc32 *desc;
3828
3829         *meta = &(dr->dr_meta[slot]);
3830         desc = dr->dr_ring_descbase;
3831         desc = &(desc[slot]);
3832
3833         *gdesc = (struct bwn_dmadesc_generic *)desc;
3834 }
3835
3836 static void
3837 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3838     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3839     int start, int end, int irq)
3840 {
3841         struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3842         struct bwn_softc *sc = dr->dr_mac->mac_sc;
3843         uint32_t addr, addrext, ctl;
3844         int slot;
3845
3846         slot = (int)(&(desc->dma.dma32) - descbase);
3847         KASSERT(slot >= 0 && slot < dr->dr_numslots,
3848             ("%s:%d: fail", __func__, __LINE__));
3849
3850         addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
3851         addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
3852         addr |= siba_dma_translation(sc->sc_dev);
3853         ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3854         if (slot == dr->dr_numslots - 1)
3855                 ctl |= BWN_DMA32_DCTL_DTABLEEND;
3856         if (start)
3857                 ctl |= BWN_DMA32_DCTL_FRAMESTART;
3858         if (end)
3859                 ctl |= BWN_DMA32_DCTL_FRAMEEND;
3860         if (irq)
3861                 ctl |= BWN_DMA32_DCTL_IRQ;
3862         ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3863             & BWN_DMA32_DCTL_ADDREXT_MASK;
3864
3865         desc->dma.dma32.control = htole32(ctl);
3866         desc->dma.dma32.address = htole32(addr);
3867 }
3868
3869 static void
3870 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3871 {
3872
3873         BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3874             (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3875 }
3876
3877 static void
3878 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3879 {
3880
3881         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3882             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3883 }
3884
3885 static void
3886 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3887 {
3888
3889         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3890             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
3891 }
3892
3893 static int
3894 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
3895 {
3896         uint32_t val;
3897
3898         val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
3899         val &= BWN_DMA32_RXDPTR;
3900
3901         return (val / sizeof(struct bwn_dmadesc32));
3902 }
3903
3904 static void
3905 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
3906 {
3907
3908         BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
3909             (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
3910 }
3911
3912 static void
3913 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
3914     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3915 {
3916         struct bwn_dmadesc64 *desc;
3917
3918         *meta = &(dr->dr_meta[slot]);
3919         desc = dr->dr_ring_descbase;
3920         desc = &(desc[slot]);
3921
3922         *gdesc = (struct bwn_dmadesc_generic *)desc;
3923 }
3924
3925 static void
3926 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
3927     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3928     int start, int end, int irq)
3929 {
3930         struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
3931         struct bwn_softc *sc = dr->dr_mac->mac_sc;
3932         int slot;
3933         uint32_t ctl0 = 0, ctl1 = 0;
3934         uint32_t addrlo, addrhi;
3935         uint32_t addrext;
3936
3937         slot = (int)(&(desc->dma.dma64) - descbase);
3938         KASSERT(slot >= 0 && slot < dr->dr_numslots,
3939             ("%s:%d: fail", __func__, __LINE__));
3940
3941         addrlo = (uint32_t) (dmaaddr & 0xffffffff);
3942         addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
3943         addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
3944             30;
3945         addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
3946         if (slot == dr->dr_numslots - 1)
3947                 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
3948         if (start)
3949                 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
3950         if (end)
3951                 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
3952         if (irq)
3953                 ctl0 |= BWN_DMA64_DCTL0_IRQ;
3954         ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
3955         ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
3956             & BWN_DMA64_DCTL1_ADDREXT_MASK;
3957
3958         desc->dma.dma64.control0 = htole32(ctl0);
3959         desc->dma.dma64.control1 = htole32(ctl1);
3960         desc->dma.dma64.address_low = htole32(addrlo);
3961         desc->dma.dma64.address_high = htole32(addrhi);
3962 }
3963
3964 static void
3965 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
3966 {
3967
3968         BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
3969             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
3970 }
3971
3972 static void
3973 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
3974 {
3975
3976         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
3977             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
3978 }
3979
3980 static void
3981 bwn_dma_64_resume(struct bwn_dma_ring *dr)
3982 {
3983
3984         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
3985             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
3986 }
3987
3988 static int
3989 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
3990 {
3991         uint32_t val;
3992
3993         val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
3994         val &= BWN_DMA64_RXSTATDPTR;
3995
3996         return (val / sizeof(struct bwn_dmadesc64));
3997 }
3998
3999 static void
4000 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4001 {
4002
4003         BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4004             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4005 }
4006
4007 static int
4008 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4009 {
4010         struct bwn_mac *mac = dr->dr_mac;
4011         struct bwn_dma *dma = &mac->mac_method.dma;
4012         struct bwn_softc *sc = mac->mac_sc;
4013         int error;
4014
4015         error = bus_dma_tag_create(dma->parent_dtag,
4016                             BWN_ALIGN, 0,
4017                             BUS_SPACE_MAXADDR,
4018                             BUS_SPACE_MAXADDR,
4019                             NULL, NULL,
4020                             BWN_DMA_RINGMEMSIZE,
4021                             1,
4022                             BUS_SPACE_MAXSIZE_32BIT,
4023                             0,
4024                             NULL, NULL,
4025                             &dr->dr_ring_dtag);
4026         if (error) {
4027                 device_printf(sc->sc_dev,
4028                     "can't create TX ring DMA tag: TODO frees\n");
4029                 return (-1);
4030         }
4031
4032         error = bus_dmamem_alloc(dr->dr_ring_dtag,
4033             &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4034             &dr->dr_ring_dmap);
4035         if (error) {
4036                 device_printf(sc->sc_dev,
4037                     "can't allocate DMA mem: TODO frees\n");
4038                 return (-1);
4039         }
4040         error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4041             dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4042             bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
4043         if (error) {
4044                 device_printf(sc->sc_dev,
4045                     "can't load DMA mem: TODO free\n");
4046                 return (-1);
4047         }
4048
4049         return (0);
4050 }
4051
4052 static void
4053 bwn_dma_setup(struct bwn_dma_ring *dr)
4054 {
4055         struct bwn_softc *sc = dr->dr_mac->mac_sc;
4056         uint64_t ring64;
4057         uint32_t addrext, ring32, value;
4058         uint32_t trans = siba_dma_translation(sc->sc_dev);
4059
4060         if (dr->dr_tx) {
4061                 dr->dr_curslot = -1;
4062
4063                 if (dr->dr_type == BWN_DMA_64BIT) {
4064                         ring64 = (uint64_t)(dr->dr_ring_dmabase);
4065                         addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4066                             >> 30;
4067                         value = BWN_DMA64_TXENABLE;
4068                         value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4069                             & BWN_DMA64_TXADDREXT_MASK;
4070                         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4071                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4072                             (ring64 & 0xffffffff));
4073                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4074                             ((ring64 >> 32) &
4075                             ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4076                 } else {
4077                         ring32 = (uint32_t)(dr->dr_ring_dmabase);
4078                         addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4079                         value = BWN_DMA32_TXENABLE;
4080                         value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4081                             & BWN_DMA32_TXADDREXT_MASK;
4082                         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4083                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4084                             (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4085                 }
4086                 return;
4087         }
4088
4089         /*
4090          * set for RX
4091          */
4092         dr->dr_usedslot = dr->dr_numslots;
4093
4094         if (dr->dr_type == BWN_DMA_64BIT) {
4095                 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4096                 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4097                 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4098                 value |= BWN_DMA64_RXENABLE;
4099                 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4100                     & BWN_DMA64_RXADDREXT_MASK;
4101                 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4102                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4103                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4104                     ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4105                     | (trans << 1));
4106                 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4107                     sizeof(struct bwn_dmadesc64));
4108         } else {
4109                 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4110                 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4111                 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4112                 value |= BWN_DMA32_RXENABLE;
4113                 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4114                     & BWN_DMA32_RXADDREXT_MASK;
4115                 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4116                 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4117                     (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4118                 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4119                     sizeof(struct bwn_dmadesc32));
4120         }
4121 }
4122
4123 static void
4124 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4125 {
4126
4127         bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4128         bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4129             dr->dr_ring_dmap);
4130 }
4131
4132 static void
4133 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4134 {
4135
4136         if (dr->dr_tx) {
4137                 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4138                 if (dr->dr_type == BWN_DMA_64BIT) {
4139                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4140                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4141                 } else
4142                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4143         } else {
4144                 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4145                 if (dr->dr_type == BWN_DMA_64BIT) {
4146                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4147                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4148                 } else
4149                         BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4150         }
4151 }
4152
4153 static void
4154 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4155 {
4156         struct bwn_dmadesc_generic *desc;
4157         struct bwn_dmadesc_meta *meta;
4158         struct bwn_mac *mac = dr->dr_mac;
4159         struct bwn_dma *dma = &mac->mac_method.dma;
4160         struct bwn_softc *sc = mac->mac_sc;
4161         int i;
4162
4163         if (!dr->dr_usedslot)
4164                 return;
4165         for (i = 0; i < dr->dr_numslots; i++) {
4166                 dr->getdesc(dr, i, &desc, &meta);
4167
4168                 if (meta->mt_m == NULL) {
4169                         if (!dr->dr_tx)
4170                                 device_printf(sc->sc_dev, "%s: not TX?\n",
4171                                     __func__);
4172                         continue;
4173                 }
4174                 if (dr->dr_tx) {
4175                         if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
4176                                 bus_dmamap_unload(dr->dr_txring_dtag,
4177                                     meta->mt_dmap);
4178                         else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
4179                                 bus_dmamap_unload(dma->txbuf_dtag,
4180                                     meta->mt_dmap);
4181                 } else
4182                         bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4183                 bwn_dma_free_descbuf(dr, meta);
4184         }
4185 }
4186
4187 static int
4188 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4189     int type)
4190 {
4191         struct bwn_softc *sc = mac->mac_sc;
4192         uint32_t value;
4193         int i;
4194         uint16_t offset;
4195
4196         for (i = 0; i < 10; i++) {
4197                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4198                     BWN_DMA32_TXSTATUS;
4199                 value = BWN_READ_4(mac, base + offset);
4200                 if (type == BWN_DMA_64BIT) {
4201                         value &= BWN_DMA64_TXSTAT;
4202                         if (value == BWN_DMA64_TXSTAT_DISABLED ||
4203                             value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4204                             value == BWN_DMA64_TXSTAT_STOPPED)
4205                                 break;
4206                 } else {
4207                         value &= BWN_DMA32_TXSTATE;
4208                         if (value == BWN_DMA32_TXSTAT_DISABLED ||
4209                             value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4210                             value == BWN_DMA32_TXSTAT_STOPPED)
4211                                 break;
4212                 }
4213                 DELAY(1000);
4214         }
4215         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4216         BWN_WRITE_4(mac, base + offset, 0);
4217         for (i = 0; i < 10; i++) {
4218                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4219                                                    BWN_DMA32_TXSTATUS;
4220                 value = BWN_READ_4(mac, base + offset);
4221                 if (type == BWN_DMA_64BIT) {
4222                         value &= BWN_DMA64_TXSTAT;
4223                         if (value == BWN_DMA64_TXSTAT_DISABLED) {
4224                                 i = -1;
4225                                 break;
4226                         }
4227                 } else {
4228                         value &= BWN_DMA32_TXSTATE;
4229                         if (value == BWN_DMA32_TXSTAT_DISABLED) {
4230                                 i = -1;
4231                                 break;
4232                         }
4233                 }
4234                 DELAY(1000);
4235         }
4236         if (i != -1) {
4237                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4238                 return (ENODEV);
4239         }
4240         DELAY(1000);
4241
4242         return (0);
4243 }
4244
4245 static int
4246 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4247     int type)
4248 {
4249         struct bwn_softc *sc = mac->mac_sc;
4250         uint32_t value;
4251         int i;
4252         uint16_t offset;
4253
4254         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4255         BWN_WRITE_4(mac, base + offset, 0);
4256         for (i = 0; i < 10; i++) {
4257                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4258                     BWN_DMA32_RXSTATUS;
4259                 value = BWN_READ_4(mac, base + offset);
4260                 if (type == BWN_DMA_64BIT) {
4261                         value &= BWN_DMA64_RXSTAT;
4262                         if (value == BWN_DMA64_RXSTAT_DISABLED) {
4263                                 i = -1;
4264                                 break;
4265                         }
4266                 } else {
4267                         value &= BWN_DMA32_RXSTATE;
4268                         if (value == BWN_DMA32_RXSTAT_DISABLED) {
4269                                 i = -1;
4270                                 break;
4271                         }
4272                 }
4273                 DELAY(1000);
4274         }
4275         if (i != -1) {
4276                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4277                 return (ENODEV);
4278         }
4279
4280         return (0);
4281 }
4282
4283 static void
4284 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4285     struct bwn_dmadesc_meta *meta)
4286 {
4287
4288         if (meta->mt_m != NULL) {
4289                 m_freem(meta->mt_m);
4290                 meta->mt_m = NULL;
4291         }
4292         if (meta->mt_ni != NULL) {
4293                 ieee80211_free_node(meta->mt_ni);
4294                 meta->mt_ni = NULL;
4295         }
4296 }
4297
4298 static void
4299 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4300 {
4301         struct bwn_rxhdr4 *rxhdr;
4302         unsigned char *frame;
4303
4304         rxhdr = mtod(m, struct bwn_rxhdr4 *);
4305         rxhdr->frame_len = 0;
4306
4307         KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4308             sizeof(struct bwn_plcp6) + 2,
4309             ("%s:%d: fail", __func__, __LINE__));
4310         frame = mtod(m, char *) + dr->dr_frameoffset;
4311         memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4312 }
4313
4314 static uint8_t
4315 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4316 {
4317         unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4318
4319         return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4320             == 0xff);
4321 }
4322
4323 static void
4324 bwn_wme_init(struct bwn_mac *mac)
4325 {
4326
4327         bwn_wme_load(mac);
4328
4329         /* enable WME support. */
4330         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4331         BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4332             BWN_IFSCTL_USE_EDCF);
4333 }
4334
4335 static void
4336 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4337 {
4338         struct bwn_softc *sc = mac->mac_sc;
4339         struct ieee80211com *ic = &sc->sc_ic;
4340         uint16_t delay; /* microsec */
4341
4342         delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4343         if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4344                 delay = 500;
4345         if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4346                 delay = max(delay, (uint16_t)2400);
4347
4348         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4349 }
4350
4351 static void
4352 bwn_bt_enable(struct bwn_mac *mac)
4353 {
4354         struct bwn_softc *sc = mac->mac_sc;
4355         uint64_t hf;
4356
4357         if (bwn_bluetooth == 0)
4358                 return;
4359         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4360                 return;
4361         if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4362                 return;
4363
4364         hf = bwn_hf_read(mac);
4365         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4366                 hf |= BWN_HF_BT_COEXISTALT;
4367         else
4368                 hf |= BWN_HF_BT_COEXIST;
4369         bwn_hf_write(mac, hf);
4370 }
4371
4372 static void
4373 bwn_set_macaddr(struct bwn_mac *mac)
4374 {
4375
4376         bwn_mac_write_bssid(mac);
4377         bwn_mac_setfilter(mac, BWN_MACFILTER_SELF,
4378             mac->mac_sc->sc_ic.ic_macaddr);
4379 }
4380
4381 static void
4382 bwn_clear_keys(struct bwn_mac *mac)
4383 {
4384         int i;
4385
4386         for (i = 0; i < mac->mac_max_nr_keys; i++) {
4387                 KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4388                     ("%s:%d: fail", __func__, __LINE__));
4389
4390                 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4391                     NULL, BWN_SEC_KEYSIZE, NULL);
4392                 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4393                         bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4394                             NULL, BWN_SEC_KEYSIZE, NULL);
4395                 }
4396                 mac->mac_key[i].keyconf = NULL;
4397         }
4398 }
4399
4400 static void
4401 bwn_crypt_init(struct bwn_mac *mac)
4402 {
4403         struct bwn_softc *sc = mac->mac_sc;
4404
4405         mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4406         KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4407             ("%s:%d: fail", __func__, __LINE__));
4408         mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4409         mac->mac_ktp *= 2;
4410         if (siba_get_revid(sc->sc_dev) >= 5)
4411                 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4412         bwn_clear_keys(mac);
4413 }
4414
4415 static void
4416 bwn_chip_exit(struct bwn_mac *mac)
4417 {
4418         struct bwn_softc *sc = mac->mac_sc;
4419
4420         bwn_phy_exit(mac);
4421         siba_gpio_set(sc->sc_dev, 0);
4422 }
4423
4424 static int
4425 bwn_fw_fillinfo(struct bwn_mac *mac)
4426 {
4427         int error;
4428
4429         error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4430         if (error == 0)
4431                 return (0);
4432         error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4433         if (error == 0)
4434                 return (0);
4435         return (error);
4436 }
4437
4438 static int
4439 bwn_gpio_init(struct bwn_mac *mac)
4440 {
4441         struct bwn_softc *sc = mac->mac_sc;
4442         uint32_t mask = 0x1f, set = 0xf, value;
4443
4444         BWN_WRITE_4(mac, BWN_MACCTL,
4445             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4446         BWN_WRITE_2(mac, BWN_GPIO_MASK,
4447             BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4448
4449         if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4450                 mask |= 0x0060;
4451                 set |= 0x0060;
4452         }
4453         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4454                 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4455                     BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4456                 mask |= 0x0200;
4457                 set |= 0x0200;
4458         }
4459         if (siba_get_revid(sc->sc_dev) >= 2)
4460                 mask |= 0x0010;
4461
4462         value = siba_gpio_get(sc->sc_dev);
4463         if (value == -1)
4464                 return (0);
4465         siba_gpio_set(sc->sc_dev, (value & mask) | set);
4466
4467         return (0);
4468 }
4469
4470 static int
4471 bwn_fw_loadinitvals(struct bwn_mac *mac)
4472 {
4473 #define GETFWOFFSET(fwp, offset)                                \
4474         ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4475         const size_t hdr_len = sizeof(struct bwn_fwhdr);
4476         const struct bwn_fwhdr *hdr;
4477         struct bwn_fw *fw = &mac->mac_fw;
4478         int error;
4479
4480         hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4481         error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4482             be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4483         if (error)
4484                 return (error);
4485         if (fw->initvals_band.fw) {
4486                 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4487                 error = bwn_fwinitvals_write(mac,
4488                     GETFWOFFSET(fw->initvals_band, hdr_len),
4489                     be32toh(hdr->size),
4490                     fw->initvals_band.fw->datasize - hdr_len);
4491         }
4492         return (error);
4493 #undef GETFWOFFSET
4494 }
4495
4496 static int
4497 bwn_phy_init(struct bwn_mac *mac)
4498 {
4499         struct bwn_softc *sc = mac->mac_sc;
4500         int error;
4501
4502         mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4503         mac->mac_phy.rf_onoff(mac, 1);
4504         error = mac->mac_phy.init(mac);
4505         if (error) {
4506                 device_printf(sc->sc_dev, "PHY init failed\n");
4507                 goto fail0;
4508         }
4509         error = bwn_switch_channel(mac,
4510             mac->mac_phy.get_default_chan(mac));
4511         if (error) {
4512                 device_printf(sc->sc_dev,
4513                     "failed to switch default channel\n");
4514                 goto fail1;
4515         }
4516         return (0);
4517 fail1:
4518         if (mac->mac_phy.exit)
4519                 mac->mac_phy.exit(mac);
4520 fail0:
4521         mac->mac_phy.rf_onoff(mac, 0);
4522
4523         return (error);
4524 }
4525
4526 static void
4527 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4528 {
4529         uint16_t ant;
4530         uint16_t tmp;
4531
4532         ant = bwn_ant2phy(antenna);
4533
4534         /* For ACK/CTS */
4535         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4536         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4537         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4538         /* For Probe Resposes */
4539         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4540         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4541         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4542 }
4543
4544 static void
4545 bwn_set_opmode(struct bwn_mac *mac)
4546 {
4547         struct bwn_softc *sc = mac->mac_sc;
4548         struct ieee80211com *ic = &sc->sc_ic;
4549         uint32_t ctl;
4550         uint16_t cfp_pretbtt;
4551
4552         ctl = BWN_READ_4(mac, BWN_MACCTL);
4553         ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4554             BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4555             BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4556         ctl |= BWN_MACCTL_STA;
4557
4558         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4559             ic->ic_opmode == IEEE80211_M_MBSS)
4560                 ctl |= BWN_MACCTL_HOSTAP;
4561         else if (ic->ic_opmode == IEEE80211_M_IBSS)
4562                 ctl &= ~BWN_MACCTL_STA;
4563         ctl |= sc->sc_filters;
4564
4565         if (siba_get_revid(sc->sc_dev) <= 4)
4566                 ctl |= BWN_MACCTL_PROMISC;
4567
4568         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4569
4570         cfp_pretbtt = 2;
4571         if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4572                 if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4573                     siba_get_chiprev(sc->sc_dev) == 3)
4574                         cfp_pretbtt = 100;
4575                 else
4576                         cfp_pretbtt = 50;
4577         }
4578         BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4579 }
4580
4581 static int
4582 bwn_dma_gettype(struct bwn_mac *mac)
4583 {
4584         uint32_t tmp;
4585         uint16_t base;
4586
4587         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4588         if (tmp & SIBA_TGSHIGH_DMA64)
4589                 return (BWN_DMA_64BIT);
4590         base = bwn_dma_base(0, 0);
4591         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4592         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4593         if (tmp & BWN_DMA32_TXADDREXT_MASK)
4594                 return (BWN_DMA_32BIT);
4595
4596         return (BWN_DMA_30BIT);
4597 }
4598
4599 static void
4600 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4601 {
4602         if (!error) {
4603                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4604                 *((bus_addr_t *)arg) = seg->ds_addr;
4605         }
4606 }
4607
4608 static void
4609 bwn_phy_g_init_sub(struct bwn_mac *mac)
4610 {
4611         struct bwn_phy *phy = &mac->mac_phy;
4612         struct bwn_phy_g *pg = &phy->phy_g;
4613         struct bwn_softc *sc = mac->mac_sc;
4614         uint16_t i, tmp;
4615
4616         if (phy->rev == 1)
4617                 bwn_phy_init_b5(mac);
4618         else
4619                 bwn_phy_init_b6(mac);
4620
4621         if (phy->rev >= 2 || phy->gmode)
4622                 bwn_phy_init_a(mac);
4623
4624         if (phy->rev >= 2) {
4625                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4626                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4627         }
4628         if (phy->rev == 2) {
4629                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4630                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4631         }
4632         if (phy->rev > 5) {
4633                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4634                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4635         }
4636         if (phy->gmode || phy->rev >= 2) {
4637                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4638                 tmp &= BWN_PHYVER_VERSION;
4639                 if (tmp == 3 || tmp == 5) {
4640                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4641                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4642                 }
4643                 if (tmp == 5) {
4644                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4645                             0x1f00);
4646                 }
4647         }
4648         if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4649                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4650         if (phy->rf_rev == 8) {
4651                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4652                 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4653         }
4654         if (BWN_HAS_LOOPBACK(phy))
4655                 bwn_loopback_calcgain(mac);
4656
4657         if (phy->rf_rev != 8) {
4658                 if (pg->pg_initval == 0xffff)
4659                         pg->pg_initval = bwn_rf_init_bcm2050(mac);
4660                 else
4661                         BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4662         }
4663         bwn_lo_g_init(mac);
4664         if (BWN_HAS_TXMAG(phy)) {
4665                 BWN_RF_WRITE(mac, 0x52,
4666                     (BWN_RF_READ(mac, 0x52) & 0xff00)
4667                     | pg->pg_loctl.tx_bias |
4668                     pg->pg_loctl.tx_magn);
4669         } else {
4670                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4671         }
4672         if (phy->rev >= 6) {
4673                 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4674                     (pg->pg_loctl.tx_bias << 12));
4675         }
4676         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4677                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4678         else
4679                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4680         if (phy->rev < 2)
4681                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4682         else
4683                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4684         if (phy->gmode || phy->rev >= 2) {
4685                 bwn_lo_g_adjust(mac);
4686                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4687         }
4688
4689         if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4690                 for (i = 0; i < 64; i++) {
4691                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4692                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4693                             (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4694                             -32), 31));
4695                 }
4696                 bwn_nrssi_threshold(mac);
4697         } else if (phy->gmode || phy->rev >= 2) {
4698                 if (pg->pg_nrssi[0] == -1000) {
4699                         KASSERT(pg->pg_nrssi[1] == -1000,
4700                             ("%s:%d: fail", __func__, __LINE__));
4701                         bwn_nrssi_slope_11g(mac);
4702                 } else
4703                         bwn_nrssi_threshold(mac);
4704         }
4705         if (phy->rf_rev == 8)
4706                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4707         bwn_phy_hwpctl_init(mac);
4708         if ((siba_get_chipid(sc->sc_dev) == 0x4306
4709              && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4710                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4711                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4712         }
4713 }
4714
4715 static uint8_t
4716 bwn_has_hwpctl(struct bwn_mac *mac)
4717 {
4718
4719         if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4720                 return (0);
4721         return (mac->mac_phy.use_hwpctl(mac));
4722 }
4723
4724 static void
4725 bwn_phy_init_b5(struct bwn_mac *mac)
4726 {
4727         struct bwn_phy *phy = &mac->mac_phy;
4728         struct bwn_phy_g *pg = &phy->phy_g;
4729         struct bwn_softc *sc = mac->mac_sc;
4730         uint16_t offset, value;
4731         uint8_t old_channel;
4732
4733         if (phy->analog == 1)
4734                 BWN_RF_SET(mac, 0x007a, 0x0050);
4735         if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4736             (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4737                 value = 0x2120;
4738                 for (offset = 0x00a8; offset < 0x00c7; offset++) {
4739                         BWN_PHY_WRITE(mac, offset, value);
4740                         value += 0x202;
4741                 }
4742         }
4743         BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4744         if (phy->rf_ver == 0x2050)
4745                 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4746
4747         if (phy->gmode || phy->rev >= 2) {
4748                 if (phy->rf_ver == 0x2050) {
4749                         BWN_RF_SET(mac, 0x007a, 0x0020);
4750                         BWN_RF_SET(mac, 0x0051, 0x0004);
4751                 }
4752                 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4753
4754                 BWN_PHY_SET(mac, 0x0802, 0x0100);
4755                 BWN_PHY_SET(mac, 0x042b, 0x2000);
4756
4757                 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4758
4759                 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4760                 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4761                 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4762         }
4763
4764         if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4765                 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4766
4767         if (phy->analog == 1) {
4768                 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4769                 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4770                 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4771                 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4772                 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4773         } else
4774                 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4775         BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4776         BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4777
4778         if (phy->analog == 1)
4779                 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4780         else
4781                 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4782
4783         if (phy->analog == 0)
4784                 BWN_WRITE_2(mac, 0x03e4, 0x3000);
4785
4786         old_channel = phy->chan;
4787         bwn_phy_g_switch_chan(mac, 7, 0);
4788
4789         if (phy->rf_ver != 0x2050) {
4790                 BWN_RF_WRITE(mac, 0x0075, 0x0080);
4791                 BWN_RF_WRITE(mac, 0x0079, 0x0081);
4792         }
4793
4794         BWN_RF_WRITE(mac, 0x0050, 0x0020);
4795         BWN_RF_WRITE(mac, 0x0050, 0x0023);
4796
4797         if (phy->rf_ver == 0x2050) {
4798                 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4799                 BWN_RF_WRITE(mac, 0x005a, 0x0070);
4800         }
4801
4802         BWN_RF_WRITE(mac, 0x005b, 0x007b);
4803         BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4804         BWN_RF_SET(mac, 0x007a, 0x0007);
4805
4806         bwn_phy_g_switch_chan(mac, old_channel, 0);
4807         BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4808         BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4809         BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4810
4811         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4812             pg->pg_txctl);
4813
4814         if (phy->rf_ver == 0x2050)
4815                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
4816
4817         BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4818 }
4819
4820 static void
4821 bwn_loopback_calcgain(struct bwn_mac *mac)
4822 {
4823         struct bwn_phy *phy = &mac->mac_phy;
4824         struct bwn_phy_g *pg = &phy->phy_g;
4825         struct bwn_softc *sc = mac->mac_sc;
4826         uint16_t backup_phy[16] = { 0 };
4827         uint16_t backup_radio[3];
4828         uint16_t backup_bband;
4829         uint16_t i, j, loop_i_max;
4830         uint16_t trsw_rx;
4831         uint16_t loop1_outer_done, loop1_inner_done;
4832
4833         backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4834         backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4835         backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4836         backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4837         if (phy->rev != 1) {
4838                 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4839                 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4840         }
4841         backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4842         backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4843         backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4844         backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4845         backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4846         backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4847         backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4848         backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4849         backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4850         backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4851         backup_bband = pg->pg_bbatt.att;
4852         backup_radio[0] = BWN_RF_READ(mac, 0x52);
4853         backup_radio[1] = BWN_RF_READ(mac, 0x43);
4854         backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4855
4856         BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4857         BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4858         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4859         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4860         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4861         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4862         if (phy->rev != 1) {
4863                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4864                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4865                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4866                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4867         }
4868         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4869         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4870         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4871         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4872
4873         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4874         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4875         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4876
4877         BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4878         if (phy->rev != 1) {
4879                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4880                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4881         }
4882         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4883
4884         if (phy->rf_rev == 8)
4885                 BWN_RF_WRITE(mac, 0x43, 0x000f);
4886         else {
4887                 BWN_RF_WRITE(mac, 0x52, 0);
4888                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4889         }
4890         bwn_phy_g_set_bbatt(mac, 11);
4891
4892         if (phy->rev >= 3)
4893                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
4894         else
4895                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
4896         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
4897
4898         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
4899         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
4900
4901         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
4902         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
4903
4904         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
4905                 if (phy->rev >= 7) {
4906                         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
4907                         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
4908                 }
4909         }
4910         BWN_RF_MASK(mac, 0x7a, 0x00f7);
4911
4912         j = 0;
4913         loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
4914         for (i = 0; i < loop_i_max; i++) {
4915                 for (j = 0; j < 16; j++) {
4916                         BWN_RF_WRITE(mac, 0x43, i);
4917                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
4918                             (j << 8));
4919                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4920                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4921                         DELAY(20);
4922                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4923                                 goto done0;
4924                 }
4925         }
4926 done0:
4927         loop1_outer_done = i;
4928         loop1_inner_done = j;
4929         if (j >= 8) {
4930                 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
4931                 trsw_rx = 0x1b;
4932                 for (j = j - 8; j < 16; j++) {
4933                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
4934                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4935                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4936                         DELAY(20);
4937                         trsw_rx -= 3;
4938                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4939                                 goto done1;
4940                 }
4941         } else
4942                 trsw_rx = 0x18;
4943 done1:
4944
4945         if (phy->rev != 1) {
4946                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
4947                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
4948         }
4949         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
4950         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
4951         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
4952         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
4953         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
4954         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
4955         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
4956         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
4957         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
4958
4959         bwn_phy_g_set_bbatt(mac, backup_bband);
4960
4961         BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
4962         BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
4963         BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
4964
4965         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
4966         DELAY(10);
4967         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
4968         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
4969         BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
4970         BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
4971
4972         pg->pg_max_lb_gain =
4973             ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
4974         pg->pg_trsw_rx_gain = trsw_rx * 2;
4975 }
4976
4977 static uint16_t
4978 bwn_rf_init_bcm2050(struct bwn_mac *mac)
4979 {
4980         struct bwn_phy *phy = &mac->mac_phy;
4981         uint32_t tmp1 = 0, tmp2 = 0;
4982         uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
4983             analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
4984             radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
4985         static const uint8_t rcc_table[] = {
4986                 0x02, 0x03, 0x01, 0x0f,
4987                 0x06, 0x07, 0x05, 0x0f,
4988                 0x0a, 0x0b, 0x09, 0x0f,
4989                 0x0e, 0x0f, 0x0d, 0x0f,
4990         };
4991
4992         loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
4993             rfoverval = rfover = cck3 = 0;
4994         radio0 = BWN_RF_READ(mac, 0x43);
4995         radio1 = BWN_RF_READ(mac, 0x51);
4996         radio2 = BWN_RF_READ(mac, 0x52);
4997         pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4998         cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4999         cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5000         cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5001
5002         if (phy->type == BWN_PHYTYPE_B) {
5003                 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5004                 reg0 = BWN_READ_2(mac, 0x3ec);
5005
5006                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5007                 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5008         } else if (phy->gmode || phy->rev >= 2) {
5009                 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5010                 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5011                 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5012                 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5013                 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5014                 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5015
5016                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5017                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5018                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5019                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5020                 if (BWN_HAS_LOOPBACK(phy)) {
5021                         lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5022                         loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5023                         if (phy->rev >= 3)
5024                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5025                         else
5026                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5027                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5028                 }
5029
5030                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5031                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5032                         BWN_LPD(0, 1, 1)));
5033                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5034                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5035         }
5036         BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5037
5038         syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5039         BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5040         reg1 = BWN_READ_2(mac, 0x3e6);
5041         reg2 = BWN_READ_2(mac, 0x3f4);
5042
5043         if (phy->analog == 0)
5044                 BWN_WRITE_2(mac, 0x03e6, 0x0122);
5045         else {
5046                 if (phy->analog >= 2)
5047                         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5048                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5049                     (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5050         }
5051
5052         reg = BWN_RF_READ(mac, 0x60);
5053         index = (reg & 0x001e) >> 1;
5054         rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5055
5056         if (phy->type == BWN_PHYTYPE_B)
5057                 BWN_RF_WRITE(mac, 0x78, 0x26);
5058         if (phy->gmode || phy->rev >= 2) {
5059                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5060                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5061                         BWN_LPD(0, 1, 1)));
5062         }
5063         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5064         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5065         if (phy->gmode || phy->rev >= 2) {
5066                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5067                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5068                         BWN_LPD(0, 0, 1)));
5069         }
5070         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5071         BWN_RF_SET(mac, 0x51, 0x0004);
5072         if (phy->rf_rev == 8)
5073                 BWN_RF_WRITE(mac, 0x43, 0x1f);
5074         else {
5075                 BWN_RF_WRITE(mac, 0x52, 0);
5076                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5077         }
5078         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5079
5080         for (i = 0; i < 16; i++) {
5081                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5082                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5083                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5084                 if (phy->gmode || phy->rev >= 2) {
5085                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5086                             bwn_rf_2050_rfoverval(mac,
5087                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5088                 }
5089                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5090                 DELAY(10);
5091                 if (phy->gmode || phy->rev >= 2) {
5092                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5093                             bwn_rf_2050_rfoverval(mac,
5094                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5095                 }
5096                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5097                 DELAY(10);
5098                 if (phy->gmode || phy->rev >= 2) {
5099                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5100                             bwn_rf_2050_rfoverval(mac,
5101                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5102                 }
5103                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5104                 DELAY(20);
5105                 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5106                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5107                 if (phy->gmode || phy->rev >= 2) {
5108                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5109                             bwn_rf_2050_rfoverval(mac,
5110                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5111                 }
5112                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5113         }
5114         DELAY(10);
5115
5116         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5117         tmp1++;
5118         tmp1 >>= 9;
5119
5120         for (i = 0; i < 16; i++) {
5121                 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5122                 BWN_RF_WRITE(mac, 0x78, radio78);
5123                 DELAY(10);
5124                 for (j = 0; j < 16; j++) {
5125                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5126                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5127                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5128                         if (phy->gmode || phy->rev >= 2) {
5129                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5130                                     bwn_rf_2050_rfoverval(mac,
5131                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5132                         }
5133                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5134                         DELAY(10);
5135                         if (phy->gmode || phy->rev >= 2) {
5136                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5137                                     bwn_rf_2050_rfoverval(mac,
5138                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5139                         }
5140                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5141                         DELAY(10);
5142                         if (phy->gmode || phy->rev >= 2) {
5143                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5144                                     bwn_rf_2050_rfoverval(mac,
5145                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5146                         }
5147                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5148                         DELAY(10);
5149                         tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5150                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5151                         if (phy->gmode || phy->rev >= 2) {
5152                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5153                                     bwn_rf_2050_rfoverval(mac,
5154                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5155                         }
5156                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5157                 }
5158                 tmp2++;
5159                 tmp2 >>= 8;
5160                 if (tmp1 < tmp2)
5161                         break;
5162         }
5163
5164         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5165         BWN_RF_WRITE(mac, 0x51, radio1);
5166         BWN_RF_WRITE(mac, 0x52, radio2);
5167         BWN_RF_WRITE(mac, 0x43, radio0);
5168         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5169         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5170         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5171         BWN_WRITE_2(mac, 0x3e6, reg1);
5172         if (phy->analog != 0)
5173                 BWN_WRITE_2(mac, 0x3f4, reg2);
5174         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5175         bwn_spu_workaround(mac, phy->chan);
5176         if (phy->type == BWN_PHYTYPE_B) {
5177                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5178                 BWN_WRITE_2(mac, 0x3ec, reg0);
5179         } else if (phy->gmode) {
5180                 BWN_WRITE_2(mac, BWN_PHY_RADIO,
5181                             BWN_READ_2(mac, BWN_PHY_RADIO)
5182                             & 0x7fff);
5183                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5184                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5185                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5186                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5187                               analogoverval);
5188                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5189                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5190                 if (BWN_HAS_LOOPBACK(phy)) {
5191                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5192                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5193                 }
5194         }
5195
5196         return ((i > 15) ? radio78 : rcc);
5197 }
5198
5199 static void
5200 bwn_phy_init_b6(struct bwn_mac *mac)
5201 {
5202         struct bwn_phy *phy = &mac->mac_phy;
5203         struct bwn_phy_g *pg = &phy->phy_g;
5204         struct bwn_softc *sc = mac->mac_sc;
5205         uint16_t offset, val;
5206         uint8_t old_channel;
5207
5208         KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5209             ("%s:%d: fail", __func__, __LINE__));
5210
5211         BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5212         BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5213         if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5214                 BWN_RF_WRITE(mac, 0x51, 0x37);
5215                 BWN_RF_WRITE(mac, 0x52, 0x70);
5216                 BWN_RF_WRITE(mac, 0x53, 0xb3);
5217                 BWN_RF_WRITE(mac, 0x54, 0x9b);
5218                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5219                 BWN_RF_WRITE(mac, 0x5b, 0x88);
5220                 BWN_RF_WRITE(mac, 0x5d, 0x88);
5221                 BWN_RF_WRITE(mac, 0x5e, 0x88);
5222                 BWN_RF_WRITE(mac, 0x7d, 0x88);
5223                 bwn_hf_write(mac,
5224                     bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5225         }
5226         if (phy->rf_rev == 8) {
5227                 BWN_RF_WRITE(mac, 0x51, 0);
5228                 BWN_RF_WRITE(mac, 0x52, 0x40);
5229                 BWN_RF_WRITE(mac, 0x53, 0xb7);
5230                 BWN_RF_WRITE(mac, 0x54, 0x98);
5231                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5232                 BWN_RF_WRITE(mac, 0x5b, 0x6b);
5233                 BWN_RF_WRITE(mac, 0x5c, 0x0f);
5234                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5235                         BWN_RF_WRITE(mac, 0x5d, 0xfa);
5236                         BWN_RF_WRITE(mac, 0x5e, 0xd8);
5237                 } else {
5238                         BWN_RF_WRITE(mac, 0x5d, 0xf5);
5239                         BWN_RF_WRITE(mac, 0x5e, 0xb8);
5240                 }
5241                 BWN_RF_WRITE(mac, 0x0073, 0x0003);
5242                 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5243                 BWN_RF_WRITE(mac, 0x007c, 0x0001);
5244                 BWN_RF_WRITE(mac, 0x007e, 0x0008);
5245         }
5246         for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5247                 BWN_PHY_WRITE(mac, offset, val);
5248                 val -= 0x0202;
5249         }
5250         for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5251                 BWN_PHY_WRITE(mac, offset, val);
5252                 val -= 0x0202;
5253         }
5254         for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5255                 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5256                 val += 0x0202;
5257         }
5258         if (phy->type == BWN_PHYTYPE_G) {
5259                 BWN_RF_SET(mac, 0x007a, 0x0020);
5260                 BWN_RF_SET(mac, 0x0051, 0x0004);
5261                 BWN_PHY_SET(mac, 0x0802, 0x0100);
5262                 BWN_PHY_SET(mac, 0x042b, 0x2000);
5263                 BWN_PHY_WRITE(mac, 0x5b, 0);
5264                 BWN_PHY_WRITE(mac, 0x5c, 0);
5265         }
5266
5267         old_channel = phy->chan;
5268         bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5269
5270         BWN_RF_WRITE(mac, 0x0050, 0x0020);
5271         BWN_RF_WRITE(mac, 0x0050, 0x0023);
5272         DELAY(40);
5273         if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5274                 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5275                 BWN_RF_WRITE(mac, 0x50, 0x20);
5276         }
5277         if (phy->rf_rev <= 2) {
5278                 BWN_RF_WRITE(mac, 0x7c, 0x20);
5279                 BWN_RF_WRITE(mac, 0x5a, 0x70);
5280                 BWN_RF_WRITE(mac, 0x5b, 0x7b);
5281                 BWN_RF_WRITE(mac, 0x5c, 0xb0);
5282         }
5283         BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5284
5285         bwn_phy_g_switch_chan(mac, old_channel, 0);
5286
5287         BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5288         if (phy->rf_rev >= 6)
5289                 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5290         else
5291                 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5292         BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5293         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5294             pg->pg_txctl);
5295         if (phy->rf_rev <= 5)
5296                 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5297         if (phy->rf_rev <= 2)
5298                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
5299
5300         if (phy->analog == 4) {
5301                 BWN_WRITE_2(mac, 0x3e4, 9);
5302                 BWN_PHY_MASK(mac, 0x61, 0x0fff);
5303         } else
5304                 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5305         if (phy->type == BWN_PHYTYPE_B)
5306                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5307         else if (phy->type == BWN_PHYTYPE_G)
5308                 BWN_WRITE_2(mac, 0x03e6, 0x0);
5309 }
5310
5311 static void
5312 bwn_phy_init_a(struct bwn_mac *mac)
5313 {
5314         struct bwn_phy *phy = &mac->mac_phy;
5315         struct bwn_softc *sc = mac->mac_sc;
5316
5317         KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5318             ("%s:%d: fail", __func__, __LINE__));
5319
5320         if (phy->rev >= 6) {
5321                 if (phy->type == BWN_PHYTYPE_A)
5322                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5323                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5324                         BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5325                 else
5326                         BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5327         }
5328
5329         bwn_wa_init(mac);
5330
5331         if (phy->type == BWN_PHYTYPE_G &&
5332             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5333                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5334 }
5335
5336 static void
5337 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5338 {
5339         int i;
5340
5341         for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5342                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5343 }
5344
5345 static void
5346 bwn_wa_agc(struct bwn_mac *mac)
5347 {
5348         struct bwn_phy *phy = &mac->mac_phy;
5349
5350         if (phy->rev == 1) {
5351                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5352                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5353                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5354                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5355                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5356                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5357                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5358                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5359                 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5360         } else {
5361                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5362                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5363                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5364                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5365         }
5366
5367         BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5368             0x5700);
5369         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5370         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5371         BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5372         BWN_RF_SET(mac, 0x7a, 0x0008);
5373         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5374         BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5375         BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5376         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5377         if (phy->rev == 1)
5378                 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5379         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5380         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5381         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5382         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5383         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5384         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5385         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5386         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5387         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5388         if (phy->rev == 1) {
5389                 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5390                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5391         } else {
5392                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5393                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5394                 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5395                 if (phy->rev >= 6) {
5396                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5397                         BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5398                             (uint16_t)~0xf000, 0x3000);
5399                 }
5400         }
5401         BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5402         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5403         if (phy->rev == 1) {
5404                 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5405                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5406                 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5407                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5408                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5409                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5410                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5411                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5412         } else {
5413                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5414                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5415                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5416                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5417         }
5418         if (phy->rev >= 6) {
5419                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5420                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5421         }
5422         BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5423 }
5424
5425 static void
5426 bwn_wa_grev1(struct bwn_mac *mac)
5427 {
5428         struct bwn_phy *phy = &mac->mac_phy;
5429         int i;
5430         static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5431         static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5432         static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5433
5434         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5435
5436         /* init CRSTHRES and ANTDWELL */
5437         if (phy->rev == 1) {
5438                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5439         } else if (phy->rev == 2) {
5440                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5441                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5442                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5443         } else {
5444                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5445                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5446                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5447                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5448         }
5449         BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5450         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5451         BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5452
5453         /* XXX support PHY-A??? */
5454         for (i = 0; i < N(bwn_tab_finefreqg); i++)
5455                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5456                     bwn_tab_finefreqg[i]);
5457
5458         /* XXX support PHY-A??? */
5459         if (phy->rev == 1)
5460                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5461                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5462                             bwn_tab_noise_g1[i]);
5463         else
5464                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5465                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5466                             bwn_tab_noise_g2[i]);
5467
5468
5469         for (i = 0; i < N(bwn_tab_rotor); i++)
5470                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5471                     bwn_tab_rotor[i]);
5472
5473         /* XXX support PHY-A??? */
5474         if (phy->rev >= 6) {
5475                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5476                     BWN_PHY_ENCORE_EN)
5477                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5478                 else
5479                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5480         } else
5481                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5482
5483         for (i = 0; i < N(bwn_tab_retard); i++)
5484                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5485                     bwn_tab_retard[i]);
5486
5487         if (phy->rev == 1) {
5488                 for (i = 0; i < 16; i++)
5489                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5490                             i, 0x0020);
5491         } else {
5492                 for (i = 0; i < 32; i++)
5493                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5494         }
5495
5496         bwn_wa_agc(mac);
5497 }
5498
5499 static void
5500 bwn_wa_grev26789(struct bwn_mac *mac)
5501 {
5502         struct bwn_phy *phy = &mac->mac_phy;
5503         int i;
5504         static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5505         uint16_t ofdmrev;
5506
5507         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5508
5509         bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5510
5511         /* init CRSTHRES and ANTDWELL */
5512         if (phy->rev == 1)
5513                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5514         else if (phy->rev == 2) {
5515                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5516                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5517                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5518         } else {
5519                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5520                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5521                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5522                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5523         }
5524
5525         for (i = 0; i < 64; i++)
5526                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5527
5528         /* XXX support PHY-A??? */
5529         if (phy->rev == 1)
5530                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5531                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5532                             bwn_tab_noise_g1[i]);
5533         else
5534                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5535                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5536                             bwn_tab_noise_g2[i]);
5537
5538         /* XXX support PHY-A??? */
5539         if (phy->rev >= 6) {
5540                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5541                     BWN_PHY_ENCORE_EN)
5542                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5543                 else
5544                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5545         } else
5546                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5547
5548         for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5549                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5550                     bwn_tab_sigmasqr2[i]);
5551
5552         if (phy->rev == 1) {
5553                 for (i = 0; i < 16; i++)
5554                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5555                             0x0020);
5556         } else {
5557                 for (i = 0; i < 32; i++)
5558                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5559         }
5560
5561         bwn_wa_agc(mac);
5562
5563         ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5564         if (ofdmrev > 2) {
5565                 if (phy->type == BWN_PHYTYPE_A)
5566                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5567                 else
5568                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5569         } else {
5570                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5571                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5572                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5573         }
5574
5575         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5576         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5577 }
5578
5579 static void
5580 bwn_wa_init(struct bwn_mac *mac)
5581 {
5582         struct bwn_phy *phy = &mac->mac_phy;
5583         struct bwn_softc *sc = mac->mac_sc;
5584
5585         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5586
5587         switch (phy->rev) {
5588         case 1:
5589                 bwn_wa_grev1(mac);
5590                 break;
5591         case 2:
5592         case 6:
5593         case 7:
5594         case 8:
5595         case 9:
5596                 bwn_wa_grev26789(mac);
5597                 break;
5598         default:
5599                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5600         }
5601
5602         if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5603             siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5604             siba_get_pci_revid(sc->sc_dev) != 0x17) {
5605                 if (phy->rev < 2) {
5606                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5607                             0x0002);
5608                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5609                             0x0001);
5610                 } else {
5611                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5612                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5613                         if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5614                              BWN_BFL_EXTLNA) &&
5615                             (phy->rev >= 7)) {
5616                                 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5617                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5618                                     0x0020, 0x0001);
5619                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5620                                     0x0021, 0x0001);
5621                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5622                                     0x0022, 0x0001);
5623                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5624                                     0x0023, 0x0000);
5625                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5626                                     0x0000, 0x0000);
5627                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5628                                     0x0003, 0x0002);
5629                         }
5630                 }
5631         }
5632         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5633                 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5634                 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5635         }
5636
5637         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5638         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5639 }
5640
5641 static void
5642 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5643     uint16_t value)
5644 {
5645         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5646         uint16_t addr;
5647
5648         addr = table + offset;
5649         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5650             (addr - 1 != pg->pg_ofdmtab_addr)) {
5651                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5652                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5653         }
5654         pg->pg_ofdmtab_addr = addr;
5655         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5656 }
5657
5658 static void
5659 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5660     uint32_t value)
5661 {
5662         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5663         uint16_t addr;
5664
5665         addr = table + offset;
5666         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5667             (addr - 1 != pg->pg_ofdmtab_addr)) {
5668                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5669                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5670         }
5671         pg->pg_ofdmtab_addr = addr;
5672
5673         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5674         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5675 }
5676
5677 static void
5678 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5679     uint16_t value)
5680 {
5681
5682         BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5683         BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5684 }
5685
5686 static void
5687 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5688 {
5689         struct bwn_phy *phy = &mac->mac_phy;
5690         struct bwn_softc *sc = mac->mac_sc;
5691         unsigned int i, max_loop;
5692         uint16_t value;
5693         uint32_t buffer[5] = {
5694                 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5695         };
5696
5697         if (ofdm) {
5698                 max_loop = 0x1e;
5699                 buffer[0] = 0x000201cc;
5700         } else {
5701                 max_loop = 0xfa;
5702                 buffer[0] = 0x000b846e;
5703         }
5704
5705         BWN_ASSERT_LOCKED(mac->mac_sc);
5706
5707         for (i = 0; i < 5; i++)
5708                 bwn_ram_write(mac, i * 4, buffer[i]);
5709
5710         BWN_WRITE_2(mac, 0x0568, 0x0000);
5711         BWN_WRITE_2(mac, 0x07c0,
5712             (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5713         value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5714         BWN_WRITE_2(mac, 0x050c, value);
5715         if (phy->type == BWN_PHYTYPE_LP)
5716                 BWN_WRITE_2(mac, 0x0514, 0x1a02);
5717         BWN_WRITE_2(mac, 0x0508, 0x0000);
5718         BWN_WRITE_2(mac, 0x050a, 0x0000);
5719         BWN_WRITE_2(mac, 0x054c, 0x0000);
5720         BWN_WRITE_2(mac, 0x056a, 0x0014);
5721         BWN_WRITE_2(mac, 0x0568, 0x0826);
5722         BWN_WRITE_2(mac, 0x0500, 0x0000);
5723         if (phy->type == BWN_PHYTYPE_LP)
5724                 BWN_WRITE_2(mac, 0x0502, 0x0050);
5725         else
5726                 BWN_WRITE_2(mac, 0x0502, 0x0030);
5727
5728         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5729                 BWN_RF_WRITE(mac, 0x0051, 0x0017);
5730         for (i = 0x00; i < max_loop; i++) {
5731                 value = BWN_READ_2(mac, 0x050e);
5732                 if (value & 0x0080)
5733                         break;
5734                 DELAY(10);
5735         }
5736         for (i = 0x00; i < 0x0a; i++) {
5737                 value = BWN_READ_2(mac, 0x050e);
5738                 if (value & 0x0400)
5739                         break;
5740                 DELAY(10);
5741         }
5742         for (i = 0x00; i < 0x19; i++) {
5743                 value = BWN_READ_2(mac, 0x0690);
5744                 if (!(value & 0x0100))
5745                         break;
5746                 DELAY(10);
5747         }
5748         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5749                 BWN_RF_WRITE(mac, 0x0051, 0x0037);
5750 }
5751
5752 static void
5753 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5754 {
5755         uint32_t macctl;
5756
5757         KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5758
5759         macctl = BWN_READ_4(mac, BWN_MACCTL);
5760         if (macctl & BWN_MACCTL_BIGENDIAN)
5761                 printf("TODO: need swap\n");
5762
5763         BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5764         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5765         BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5766 }
5767
5768 static void
5769 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5770 {
5771         uint16_t value;
5772
5773         KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5774             ("%s:%d: fail", __func__, __LINE__));
5775
5776         value = (uint8_t) (ctl->q);
5777         value |= ((uint8_t) (ctl->i)) << 8;
5778         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5779 }
5780
5781 static uint16_t
5782 bwn_lo_calcfeed(struct bwn_mac *mac,
5783     uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5784 {
5785         struct bwn_phy *phy = &mac->mac_phy;
5786         struct bwn_softc *sc = mac->mac_sc;
5787         uint16_t rfover;
5788         uint16_t feedthrough;
5789
5790         if (phy->gmode) {
5791                 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5792                 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5793
5794                 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5795                     ("%s:%d: fail", __func__, __LINE__));
5796                 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5797                     ("%s:%d: fail", __func__, __LINE__));
5798
5799                 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5800
5801                 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5802                 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5803                     phy->rev > 6)
5804                         rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5805
5806                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5807                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5808                 DELAY(10);
5809                 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5810                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5811                 DELAY(10);
5812                 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5813                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5814                 DELAY(10);
5815                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5816         } else {
5817                 pga |= BWN_PHY_PGACTL_UNKNOWN;
5818                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5819                 DELAY(10);
5820                 pga |= BWN_PHY_PGACTL_LOWBANDW;
5821                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5822                 DELAY(10);
5823                 pga |= BWN_PHY_PGACTL_LPF;
5824                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5825         }
5826         DELAY(21);
5827         feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5828
5829         return (feedthrough);
5830 }
5831
5832 static uint16_t
5833 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5834     uint16_t *value, uint16_t *pad_mix_gain)
5835 {
5836         struct bwn_phy *phy = &mac->mac_phy;
5837         uint16_t reg, v, padmix;
5838
5839         if (phy->type == BWN_PHYTYPE_B) {
5840                 v = 0x30;
5841                 if (phy->rf_rev <= 5) {
5842                         reg = 0x43;
5843                         padmix = 0;
5844                 } else {
5845                         reg = 0x52;
5846                         padmix = 5;
5847                 }
5848         } else {
5849                 if (phy->rev >= 2 && phy->rf_rev == 8) {
5850                         reg = 0x43;
5851                         v = 0x10;
5852                         padmix = 2;
5853                 } else {
5854                         reg = 0x52;
5855                         v = 0x30;
5856                         padmix = 5;
5857                 }
5858         }
5859         if (value)
5860                 *value = v;
5861         if (pad_mix_gain)
5862                 *pad_mix_gain = padmix;
5863
5864         return (reg);
5865 }
5866
5867 static void
5868 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5869 {
5870         struct bwn_phy *phy = &mac->mac_phy;
5871         struct bwn_phy_g *pg = &phy->phy_g;
5872         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5873         uint16_t reg, mask;
5874         uint16_t trsw_rx, pga;
5875         uint16_t rf_pctl_reg;
5876
5877         static const uint8_t tx_bias_values[] = {
5878                 0x09, 0x08, 0x0a, 0x01, 0x00,
5879                 0x02, 0x05, 0x04, 0x06,
5880         };
5881         static const uint8_t tx_magn_values[] = {
5882                 0x70, 0x40,
5883         };
5884
5885         if (!BWN_HAS_LOOPBACK(phy)) {
5886                 rf_pctl_reg = 6;
5887                 trsw_rx = 2;
5888                 pga = 0;
5889         } else {
5890                 int lb_gain;
5891
5892                 trsw_rx = 0;
5893                 lb_gain = pg->pg_max_lb_gain / 2;
5894                 if (lb_gain > 10) {
5895                         rf_pctl_reg = 0;
5896                         pga = abs(10 - lb_gain) / 6;
5897                         pga = MIN(MAX(pga, 0), 15);
5898                 } else {
5899                         int cmp_val;
5900                         int tmp;
5901
5902                         pga = 0;
5903                         cmp_val = 0x24;
5904                         if ((phy->rev >= 2) &&
5905                             (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
5906                                 cmp_val = 0x3c;
5907                         tmp = lb_gain;
5908                         if ((10 - lb_gain) < cmp_val)
5909                                 tmp = (10 - lb_gain);
5910                         if (tmp < 0)
5911                                 tmp += 6;
5912                         else
5913                                 tmp += 3;
5914                         cmp_val /= 4;
5915                         tmp /= 4;
5916                         if (tmp >= cmp_val)
5917                                 rf_pctl_reg = cmp_val;
5918                         else
5919                                 rf_pctl_reg = tmp;
5920                 }
5921         }
5922         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
5923         bwn_phy_g_set_bbatt(mac, 2);
5924
5925         reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
5926         mask = ~mask;
5927         BWN_RF_MASK(mac, reg, mask);
5928
5929         if (BWN_HAS_TXMAG(phy)) {
5930                 int i, j;
5931                 int feedthrough;
5932                 int min_feedth = 0xffff;
5933                 uint8_t tx_magn, tx_bias;
5934
5935                 for (i = 0; i < N(tx_magn_values); i++) {
5936                         tx_magn = tx_magn_values[i];
5937                         BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
5938                         for (j = 0; j < N(tx_bias_values); j++) {
5939                                 tx_bias = tx_bias_values[j];
5940                                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
5941                                 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
5942                                     trsw_rx);
5943                                 if (feedthrough < min_feedth) {
5944                                         lo->tx_bias = tx_bias;
5945                                         lo->tx_magn = tx_magn;
5946                                         min_feedth = feedthrough;
5947                                 }
5948                                 if (lo->tx_bias == 0)
5949                                         break;
5950                         }
5951                         BWN_RF_WRITE(mac, 0x52,
5952                                           (BWN_RF_READ(mac, 0x52)
5953                                            & 0xff00) | lo->tx_bias | lo->
5954                                           tx_magn);
5955                 }
5956         } else {
5957                 lo->tx_magn = 0;
5958                 lo->tx_bias = 0;
5959                 BWN_RF_MASK(mac, 0x52, 0xfff0);
5960         }
5961
5962         BWN_GETTIME(lo->txctl_measured_time);
5963 }
5964
5965 static void
5966 bwn_lo_get_powervector(struct bwn_mac *mac)
5967 {
5968         struct bwn_phy *phy = &mac->mac_phy;
5969         struct bwn_phy_g *pg = &phy->phy_g;
5970         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5971         int i;
5972         uint64_t tmp;
5973         uint64_t power_vector = 0;
5974
5975         for (i = 0; i < 8; i += 2) {
5976                 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
5977                 power_vector |= (tmp << (i * 8));
5978                 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
5979         }
5980         if (power_vector)
5981                 lo->power_vector = power_vector;
5982
5983         BWN_GETTIME(lo->pwr_vec_read_time);
5984 }
5985
5986 static void
5987 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
5988     int use_trsw_rx)
5989 {
5990         struct bwn_phy *phy = &mac->mac_phy;
5991         struct bwn_phy_g *pg = &phy->phy_g;
5992         uint16_t tmp;
5993
5994         if (max_rx_gain < 0)
5995                 max_rx_gain = 0;
5996
5997         if (BWN_HAS_LOOPBACK(phy)) {
5998                 int trsw_rx = 0;
5999                 int trsw_rx_gain;
6000
6001                 if (use_trsw_rx) {
6002                         trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6003                         if (max_rx_gain >= trsw_rx_gain) {
6004                                 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6005                                 trsw_rx = 0x20;
6006                         }
6007                 } else
6008                         trsw_rx_gain = max_rx_gain;
6009                 if (trsw_rx_gain < 9) {
6010                         pg->pg_lna_lod_gain = 0;
6011                 } else {
6012                         pg->pg_lna_lod_gain = 1;
6013                         trsw_rx_gain -= 8;
6014                 }
6015                 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6016                 pg->pg_pga_gain = trsw_rx_gain / 3;
6017                 if (pg->pg_pga_gain >= 5) {
6018                         pg->pg_pga_gain -= 5;
6019                         pg->pg_lna_gain = 2;
6020                 } else
6021                         pg->pg_lna_gain = 0;
6022         } else {
6023                 pg->pg_lna_gain = 0;
6024                 pg->pg_trsw_rx_gain = 0x20;
6025                 if (max_rx_gain >= 0x14) {
6026                         pg->pg_lna_lod_gain = 1;
6027                         pg->pg_pga_gain = 2;
6028                 } else if (max_rx_gain >= 0x12) {
6029                         pg->pg_lna_lod_gain = 1;
6030                         pg->pg_pga_gain = 1;
6031                 } else if (max_rx_gain >= 0xf) {
6032                         pg->pg_lna_lod_gain = 1;
6033                         pg->pg_pga_gain = 0;
6034                 } else {
6035                         pg->pg_lna_lod_gain = 0;
6036                         pg->pg_pga_gain = 0;
6037                 }
6038         }
6039
6040         tmp = BWN_RF_READ(mac, 0x7a);
6041         if (pg->pg_lna_lod_gain == 0)
6042                 tmp &= ~0x0008;
6043         else
6044                 tmp |= 0x0008;
6045         BWN_RF_WRITE(mac, 0x7a, tmp);
6046 }
6047
6048 static void
6049 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6050 {
6051         struct bwn_phy *phy = &mac->mac_phy;
6052         struct bwn_phy_g *pg = &phy->phy_g;
6053         struct bwn_softc *sc = mac->mac_sc;
6054         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6055         struct timespec ts;
6056         uint16_t tmp;
6057
6058         if (bwn_has_hwpctl(mac)) {
6059                 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6060                 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6061                 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6062                 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6063                 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6064
6065                 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6066                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6067                 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6068                 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6069         }
6070         if (phy->type == BWN_PHYTYPE_B &&
6071             phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6072                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6073                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6074         }
6075         if (phy->rev >= 2) {
6076                 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6077                 sav->phy_analogoverval =
6078                     BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6079                 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6080                 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6081                 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6082                 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6083                 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6084
6085                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6086                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6087                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6088                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6089                 if (phy->type == BWN_PHYTYPE_G) {
6090                         if ((phy->rev >= 7) &&
6091                             (siba_sprom_get_bf_lo(sc->sc_dev) &
6092                              BWN_BFL_EXTLNA)) {
6093                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6094                         } else {
6095                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6096                         }
6097                 } else {
6098                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6099                 }
6100                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6101         }
6102         sav->reg0 = BWN_READ_2(mac, 0x3f4);
6103         sav->reg1 = BWN_READ_2(mac, 0x3e2);
6104         sav->rf0 = BWN_RF_READ(mac, 0x43);
6105         sav->rf1 = BWN_RF_READ(mac, 0x7a);
6106         sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6107         sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6108         sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6109         sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6110
6111         if (!BWN_HAS_TXMAG(phy)) {
6112                 sav->rf2 = BWN_RF_READ(mac, 0x52);
6113                 sav->rf2 &= 0x00f0;
6114         }
6115         if (phy->type == BWN_PHYTYPE_B) {
6116                 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6117                 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6118                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6119                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6120         } else {
6121                 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6122                             | 0x8000);
6123         }
6124         BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6125                     & 0xf000);
6126
6127         tmp =
6128             (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6129         BWN_PHY_WRITE(mac, tmp, 0x007f);
6130
6131         tmp = sav->phy_syncctl;
6132         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6133         tmp = sav->rf1;
6134         BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6135
6136         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6137         if (phy->type == BWN_PHYTYPE_G ||
6138             (phy->type == BWN_PHYTYPE_B &&
6139              phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6140                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6141         } else
6142                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6143         if (phy->rev >= 2)
6144                 bwn_dummy_transmission(mac, 0, 1);
6145         bwn_phy_g_switch_chan(mac, 6, 0);
6146         BWN_RF_READ(mac, 0x51);
6147         if (phy->type == BWN_PHYTYPE_G)
6148                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6149
6150         nanouptime(&ts);
6151         if (time_before(lo->txctl_measured_time,
6152             (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6153                 bwn_lo_measure_txctl_values(mac);
6154
6155         if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6156                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6157         else {
6158                 if (phy->type == BWN_PHYTYPE_B)
6159                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6160                 else
6161                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6162         }
6163 }
6164
6165 static void
6166 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6167 {
6168         struct bwn_phy *phy = &mac->mac_phy;
6169         struct bwn_phy_g *pg = &phy->phy_g;
6170         uint16_t tmp;
6171
6172         if (phy->rev >= 2) {
6173                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6174                 tmp = (pg->pg_pga_gain << 8);
6175                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6176                 DELAY(5);
6177                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6178                 DELAY(2);
6179                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6180         } else {
6181                 tmp = (pg->pg_pga_gain | 0xefa0);
6182                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6183         }
6184         if (phy->type == BWN_PHYTYPE_G) {
6185                 if (phy->rev >= 3)
6186                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6187                 else
6188                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6189                 if (phy->rev >= 2)
6190                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6191                 else
6192                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6193         }
6194         BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6195         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6196         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6197         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6198         BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6199         BWN_RF_WRITE(mac, 0x43, sav->rf0);
6200         BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6201         if (!BWN_HAS_TXMAG(phy)) {
6202                 tmp = sav->rf2;
6203                 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6204         }
6205         BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6206         if (phy->type == BWN_PHYTYPE_B &&
6207             phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6208                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6209                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6210         }
6211         if (phy->rev >= 2) {
6212                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6213                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6214                               sav->phy_analogoverval);
6215                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6216                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6217                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6218                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6219                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6220         }
6221         if (bwn_has_hwpctl(mac)) {
6222                 tmp = (sav->phy_lomask & 0xbfff);
6223                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6224                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6225                 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6226                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6227                 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6228         }
6229         bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6230 }
6231
6232 static int
6233 bwn_lo_probe_loctl(struct bwn_mac *mac,
6234     struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6235 {
6236         struct bwn_phy *phy = &mac->mac_phy;
6237         struct bwn_phy_g *pg = &phy->phy_g;
6238         struct bwn_loctl orig, test;
6239         struct bwn_loctl prev = { -100, -100 };
6240         static const struct bwn_loctl modifiers[] = {
6241                 {  1,  1,}, {  1,  0,}, {  1, -1,}, {  0, -1,},
6242                 { -1, -1,}, { -1,  0,}, { -1,  1,}, {  0,  1,}
6243         };
6244         int begin, end, lower = 0, i;
6245         uint16_t feedth;
6246
6247         if (d->curstate == 0) {
6248                 begin = 1;
6249                 end = 8;
6250         } else if (d->curstate % 2 == 0) {
6251                 begin = d->curstate - 1;
6252                 end = d->curstate + 1;
6253         } else {
6254                 begin = d->curstate - 2;
6255                 end = d->curstate + 2;
6256         }
6257         if (begin < 1)
6258                 begin += 8;
6259         if (end > 8)
6260                 end -= 8;
6261
6262         memcpy(&orig, probe, sizeof(struct bwn_loctl));
6263         i = begin;
6264         d->curstate = i;
6265         while (1) {
6266                 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6267                 memcpy(&test, &orig, sizeof(struct bwn_loctl));
6268                 test.i += modifiers[i - 1].i * d->multipler;
6269                 test.q += modifiers[i - 1].q * d->multipler;
6270                 if ((test.i != prev.i || test.q != prev.q) &&
6271                     (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6272                         bwn_lo_write(mac, &test);
6273                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6274                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6275                         if (feedth < d->feedth) {
6276                                 memcpy(probe, &test,
6277                                     sizeof(struct bwn_loctl));
6278                                 lower = 1;
6279                                 d->feedth = feedth;
6280                                 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6281                                         break;
6282                         }
6283                 }
6284                 memcpy(&prev, &test, sizeof(prev));
6285                 if (i == end)
6286                         break;
6287                 if (i == 8)
6288                         i = 1;
6289                 else
6290                         i++;
6291                 d->curstate = i;
6292         }
6293
6294         return (lower);
6295 }
6296
6297 static void
6298 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6299 {
6300         struct bwn_phy *phy = &mac->mac_phy;
6301         struct bwn_phy_g *pg = &phy->phy_g;
6302         struct bwn_lo_g_sm d;
6303         struct bwn_loctl probe;
6304         int lower, repeat, cnt = 0;
6305         uint16_t feedth;
6306
6307         d.nmeasure = 0;
6308         d.multipler = 1;
6309         if (BWN_HAS_LOOPBACK(phy))
6310                 d.multipler = 3;
6311
6312         memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6313         repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6314
6315         do {
6316                 bwn_lo_write(mac, &d.loctl);
6317                 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6318                     pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6319                 if (feedth < 0x258) {
6320                         if (feedth >= 0x12c)
6321                                 *rxgain += 6;
6322                         else
6323                                 *rxgain += 3;
6324                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6325                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6326                 }
6327                 d.feedth = feedth;
6328                 d.curstate = 0;
6329                 do {
6330                         KASSERT(d.curstate >= 0 && d.curstate <= 8,
6331                             ("%s:%d: fail", __func__, __LINE__));
6332                         memcpy(&probe, &d.loctl,
6333                                sizeof(struct bwn_loctl));
6334                         lower = bwn_lo_probe_loctl(mac, &probe, &d);
6335                         if (!lower)
6336                                 break;
6337                         if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6338                                 break;
6339                         memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6340                         d.nmeasure++;
6341                 } while (d.nmeasure < 24);
6342                 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6343
6344                 if (BWN_HAS_LOOPBACK(phy)) {
6345                         if (d.feedth > 0x1194)
6346                                 *rxgain -= 6;
6347                         else if (d.feedth < 0x5dc)
6348                                 *rxgain += 3;
6349                         if (cnt == 0) {
6350                                 if (d.feedth <= 0x5dc) {
6351                                         d.multipler = 1;
6352                                         cnt++;
6353                                 } else
6354                                         d.multipler = 2;
6355                         } else if (cnt == 2)
6356                                 d.multipler = 1;
6357                 }
6358                 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6359         } while (++cnt < repeat);
6360 }
6361
6362 static struct bwn_lo_calib *
6363 bwn_lo_calibset(struct bwn_mac *mac,
6364     const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6365 {
6366         struct bwn_phy *phy = &mac->mac_phy;
6367         struct bwn_phy_g *pg = &phy->phy_g;
6368         struct bwn_loctl loctl = { 0, 0 };
6369         struct bwn_lo_calib *cal;
6370         struct bwn_lo_g_value sval = { 0 };
6371         int rxgain;
6372         uint16_t pad, reg, value;
6373
6374         sval.old_channel = phy->chan;
6375         bwn_mac_suspend(mac);
6376         bwn_lo_save(mac, &sval);
6377
6378         reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6379         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6380         BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6381
6382         rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6383         if (rfatt->padmix)
6384                 rxgain -= pad;
6385         if (BWN_HAS_LOOPBACK(phy))
6386                 rxgain += pg->pg_max_lb_gain;
6387         bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6388         bwn_phy_g_set_bbatt(mac, bbatt->att);
6389         bwn_lo_probe_sm(mac, &loctl, &rxgain);
6390
6391         bwn_lo_restore(mac, &sval);
6392         bwn_mac_enable(mac);
6393
6394         cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
6395         if (!cal) {
6396                 device_printf(mac->mac_sc->sc_dev, "out of memory\n");
6397                 return (NULL);
6398         }
6399         memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6400         memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6401         memcpy(&cal->ctl, &loctl, sizeof(loctl));
6402
6403         BWN_GETTIME(cal->calib_time);
6404
6405         return (cal);
6406 }
6407
6408 static struct bwn_lo_calib *
6409 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6410     const struct bwn_rfatt *rfatt)
6411 {
6412         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6413         struct bwn_lo_calib *c;
6414
6415         TAILQ_FOREACH(c, &lo->calib_list, list) {
6416                 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6417                         continue;
6418                 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6419                         continue;
6420                 return (c);
6421         }
6422
6423         c = bwn_lo_calibset(mac, bbatt, rfatt);
6424         if (!c)
6425                 return (NULL);
6426         TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6427
6428         return (c);
6429 }
6430
6431 static void
6432 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6433 {
6434         struct bwn_phy *phy = &mac->mac_phy;
6435         struct bwn_phy_g *pg = &phy->phy_g;
6436         struct bwn_softc *sc = mac->mac_sc;
6437         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6438         const struct bwn_rfatt *rfatt;
6439         const struct bwn_bbatt *bbatt;
6440         uint64_t pvector;
6441         int i;
6442         int rf_offset, bb_offset;
6443         uint8_t changed = 0;
6444
6445         KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6446         KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6447             ("%s:%d: fail", __func__, __LINE__));
6448
6449         pvector = lo->power_vector;
6450         if (!update && !pvector)
6451                 return;
6452
6453         bwn_mac_suspend(mac);
6454
6455         for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6456                 struct bwn_lo_calib *cal;
6457                 int idx;
6458                 uint16_t val;
6459
6460                 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6461                         continue;
6462                 bb_offset = i / lo->rfatt.len;
6463                 rf_offset = i % lo->rfatt.len;
6464                 bbatt = &(lo->bbatt.array[bb_offset]);
6465                 rfatt = &(lo->rfatt.array[rf_offset]);
6466
6467                 cal = bwn_lo_calibset(mac, bbatt, rfatt);
6468                 if (!cal) {
6469                         device_printf(sc->sc_dev, "LO: Could not "
6470                             "calibrate DC table entry\n");
6471                         continue;
6472                 }
6473                 val = (uint8_t)(cal->ctl.q);
6474                 val |= ((uint8_t)(cal->ctl.i)) << 4;
6475                 free(cal, M_DEVBUF);
6476
6477                 idx = i / 2;
6478                 if (i % 2)
6479                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6480                             | ((val & 0x00ff) << 8);
6481                 else
6482                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6483                             | (val & 0x00ff);
6484                 changed = 1;
6485         }
6486         if (changed) {
6487                 for (i = 0; i < BWN_DC_LT_SIZE; i++)
6488                         BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6489         }
6490         bwn_mac_enable(mac);
6491 }
6492
6493 static void
6494 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6495 {
6496
6497         if (!rf->padmix)
6498                 return;
6499         if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6500                 rf->att = 4;
6501 }
6502
6503 static void
6504 bwn_lo_g_adjust(struct bwn_mac *mac)
6505 {
6506         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6507         struct bwn_lo_calib *cal;
6508         struct bwn_rfatt rf;
6509
6510         memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6511         bwn_lo_fixup_rfatt(&rf);
6512
6513         cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6514         if (!cal)
6515                 return;
6516         bwn_lo_write(mac, &cal->ctl);
6517 }
6518
6519 static void
6520 bwn_lo_g_init(struct bwn_mac *mac)
6521 {
6522
6523         if (!bwn_has_hwpctl(mac))
6524                 return;
6525
6526         bwn_lo_get_powervector(mac);
6527         bwn_phy_g_dc_lookup_init(mac, 1);
6528 }
6529
6530 static void
6531 bwn_mac_suspend(struct bwn_mac *mac)
6532 {
6533         struct bwn_softc *sc = mac->mac_sc;
6534         int i;
6535         uint32_t tmp;
6536
6537         KASSERT(mac->mac_suspended >= 0,
6538             ("%s:%d: fail", __func__, __LINE__));
6539
6540         if (mac->mac_suspended == 0) {
6541                 bwn_psctl(mac, BWN_PS_AWAKE);
6542                 BWN_WRITE_4(mac, BWN_MACCTL,
6543                             BWN_READ_4(mac, BWN_MACCTL)
6544                             & ~BWN_MACCTL_ON);
6545                 BWN_READ_4(mac, BWN_MACCTL);
6546                 for (i = 35; i; i--) {
6547                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6548                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6549                                 goto out;
6550                         DELAY(10);
6551                 }
6552                 for (i = 40; i; i--) {
6553                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6554                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6555                                 goto out;
6556                         DELAY(1000);
6557                 }
6558                 device_printf(sc->sc_dev, "MAC suspend failed\n");
6559         }
6560 out:
6561         mac->mac_suspended++;
6562 }
6563
6564 static void
6565 bwn_mac_enable(struct bwn_mac *mac)
6566 {
6567         struct bwn_softc *sc = mac->mac_sc;
6568         uint16_t state;
6569
6570         state = bwn_shm_read_2(mac, BWN_SHARED,
6571             BWN_SHARED_UCODESTAT);
6572         if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6573             state != BWN_SHARED_UCODESTAT_SLEEP)
6574                 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6575
6576         mac->mac_suspended--;
6577         KASSERT(mac->mac_suspended >= 0,
6578             ("%s:%d: fail", __func__, __LINE__));
6579         if (mac->mac_suspended == 0) {
6580                 BWN_WRITE_4(mac, BWN_MACCTL,
6581                     BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6582                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6583                 BWN_READ_4(mac, BWN_MACCTL);
6584                 BWN_READ_4(mac, BWN_INTR_REASON);
6585                 bwn_psctl(mac, 0);
6586         }
6587 }
6588
6589 static void
6590 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6591 {
6592         struct bwn_softc *sc = mac->mac_sc;
6593         int i;
6594         uint16_t ucstat;
6595
6596         KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6597             ("%s:%d: fail", __func__, __LINE__));
6598         KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6599             ("%s:%d: fail", __func__, __LINE__));
6600
6601         /* XXX forcibly awake and hwps-off */
6602
6603         BWN_WRITE_4(mac, BWN_MACCTL,
6604             (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6605             ~BWN_MACCTL_HWPS);
6606         BWN_READ_4(mac, BWN_MACCTL);
6607         if (siba_get_revid(sc->sc_dev) >= 5) {
6608                 for (i = 0; i < 100; i++) {
6609                         ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6610                             BWN_SHARED_UCODESTAT);
6611                         if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6612                                 break;
6613                         DELAY(10);
6614                 }
6615         }
6616 }
6617
6618 static int16_t
6619 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6620 {
6621
6622         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6623         return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6624 }
6625
6626 static void
6627 bwn_nrssi_threshold(struct bwn_mac *mac)
6628 {
6629         struct bwn_phy *phy = &mac->mac_phy;
6630         struct bwn_phy_g *pg = &phy->phy_g;
6631         struct bwn_softc *sc = mac->mac_sc;
6632         int32_t a, b;
6633         int16_t tmp16;
6634         uint16_t tmpu16;
6635
6636         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6637
6638         if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6639                 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6640                         a = 0x13;
6641                         b = 0x12;
6642                 } else {
6643                         a = 0xe;
6644                         b = 0x11;
6645                 }
6646
6647                 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6648                 a += (pg->pg_nrssi[0] << 6);
6649                 a += (a < 32) ? 31 : 32;
6650                 a = a >> 6;
6651                 a = MIN(MAX(a, -31), 31);
6652
6653                 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6654                 b += (pg->pg_nrssi[0] << 6);
6655                 if (b < 32)
6656                         b += 31;
6657                 else
6658                         b += 32;
6659                 b = b >> 6;
6660                 b = MIN(MAX(b, -31), 31);
6661
6662                 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6663                 tmpu16 |= ((uint32_t)b & 0x0000003f);
6664                 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6665                 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6666                 return;
6667         }
6668
6669         tmp16 = bwn_nrssi_read(mac, 0x20);
6670         if (tmp16 >= 0x20)
6671                 tmp16 -= 0x40;
6672         BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6673 }
6674
6675 static void
6676 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6677 {
6678 #define SAVE_RF_MAX             3
6679 #define SAVE_PHY_COMM_MAX       4
6680 #define SAVE_PHY3_MAX           8
6681         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6682                 { 0x7a, 0x52, 0x43 };
6683         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6684                 { 0x15, 0x5a, 0x59, 0x58 };
6685         static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6686                 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6687                 0x0801, 0x0060, 0x0014, 0x0478
6688         };
6689         struct bwn_phy *phy = &mac->mac_phy;
6690         struct bwn_phy_g *pg = &phy->phy_g;
6691         int32_t i, tmp32, phy3_idx = 0;
6692         uint16_t delta, tmp;
6693         uint16_t save_rf[SAVE_RF_MAX];
6694         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6695         uint16_t save_phy3[SAVE_PHY3_MAX];
6696         uint16_t ant_div, phy0, chan_ex;
6697         int16_t nrssi0, nrssi1;
6698
6699         KASSERT(phy->type == BWN_PHYTYPE_G,
6700             ("%s:%d: fail", __func__, __LINE__));
6701
6702         if (phy->rf_rev >= 9)
6703                 return;
6704         if (phy->rf_rev == 8)
6705                 bwn_nrssi_offset(mac);
6706
6707         BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6708         BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6709
6710         /*
6711          * Save RF/PHY registers for later restoration
6712          */
6713         ant_div = BWN_READ_2(mac, 0x03e2);
6714         BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6715         for (i = 0; i < SAVE_RF_MAX; ++i)
6716                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6717         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6718                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6719
6720         phy0 = BWN_READ_2(mac, BWN_PHY0);
6721         chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6722         if (phy->rev >= 3) {
6723                 for (i = 0; i < SAVE_PHY3_MAX; ++i)
6724                         save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6725                 BWN_PHY_WRITE(mac, 0x002e, 0);
6726                 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6727                 switch (phy->rev) {
6728                 case 4:
6729                 case 6:
6730                 case 7:
6731                         BWN_PHY_SET(mac, 0x0478, 0x0100);
6732                         BWN_PHY_SET(mac, 0x0801, 0x0040);
6733                         break;
6734                 case 3:
6735                 case 5:
6736                         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6737                         break;
6738                 }
6739                 BWN_PHY_SET(mac, 0x0060, 0x0040);
6740                 BWN_PHY_SET(mac, 0x0014, 0x0200);
6741         }
6742         /*
6743          * Calculate nrssi0
6744          */
6745         BWN_RF_SET(mac, 0x007a, 0x0070);
6746         bwn_set_all_gains(mac, 0, 8, 0);
6747         BWN_RF_MASK(mac, 0x007a, 0x00f7);
6748         if (phy->rev >= 2) {
6749                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6750                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6751         }
6752         BWN_RF_SET(mac, 0x007a, 0x0080);
6753         DELAY(20);
6754
6755         nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6756         if (nrssi0 >= 0x0020)
6757                 nrssi0 -= 0x0040;
6758
6759         /*
6760          * Calculate nrssi1
6761          */
6762         BWN_RF_MASK(mac, 0x007a, 0x007f);
6763         if (phy->rev >= 2)
6764                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6765
6766         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6767             BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6768         BWN_RF_SET(mac, 0x007a, 0x000f);
6769         BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6770         if (phy->rev >= 2) {
6771                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6772                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6773         }
6774
6775         bwn_set_all_gains(mac, 3, 0, 1);
6776         if (phy->rf_rev == 8) {
6777                 BWN_RF_WRITE(mac, 0x0043, 0x001f);
6778         } else {
6779                 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6780                 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6781                 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6782                 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6783         }
6784         BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6785         BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6786         BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6787         DELAY(20);
6788         nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6789
6790         /*
6791          * Install calculated narrow RSSI values
6792          */
6793         if (nrssi1 >= 0x0020)
6794                 nrssi1 -= 0x0040;
6795         if (nrssi0 == nrssi1)
6796                 pg->pg_nrssi_slope = 0x00010000;
6797         else
6798                 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6799         if (nrssi0 >= -4) {
6800                 pg->pg_nrssi[0] = nrssi1;
6801                 pg->pg_nrssi[1] = nrssi0;
6802         }
6803
6804         /*
6805          * Restore saved RF/PHY registers
6806          */
6807         if (phy->rev >= 3) {
6808                 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6809                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6810                             save_phy3[phy3_idx]);
6811                 }
6812         }
6813         if (phy->rev >= 2) {
6814                 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6815                 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6816         }
6817
6818         for (i = 0; i < SAVE_RF_MAX; ++i)
6819                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6820
6821         BWN_WRITE_2(mac, 0x03e2, ant_div);
6822         BWN_WRITE_2(mac, 0x03e6, phy0);
6823         BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6824
6825         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6826                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6827
6828         bwn_spu_workaround(mac, phy->chan);
6829         BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6830         bwn_set_original_gains(mac);
6831         BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6832         if (phy->rev >= 3) {
6833                 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6834                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6835                             save_phy3[phy3_idx]);
6836                 }
6837         }
6838
6839         delta = 0x1f - pg->pg_nrssi[0];
6840         for (i = 0; i < 64; i++) {
6841                 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6842                 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6843                 pg->pg_nrssi_lt[i] = tmp32;
6844         }
6845
6846         bwn_nrssi_threshold(mac);
6847 #undef SAVE_RF_MAX
6848 #undef SAVE_PHY_COMM_MAX
6849 #undef SAVE_PHY3_MAX
6850 }
6851
6852 static void
6853 bwn_nrssi_offset(struct bwn_mac *mac)
6854 {
6855 #define SAVE_RF_MAX             2
6856 #define SAVE_PHY_COMM_MAX       10
6857 #define SAVE_PHY6_MAX           8
6858         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6859                 { 0x7a, 0x43 };
6860         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6861                 0x0001, 0x0811, 0x0812, 0x0814,
6862                 0x0815, 0x005a, 0x0059, 0x0058,
6863                 0x000a, 0x0003
6864         };
6865         static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6866                 0x002e, 0x002f, 0x080f, 0x0810,
6867                 0x0801, 0x0060, 0x0014, 0x0478
6868         };
6869         struct bwn_phy *phy = &mac->mac_phy;
6870         int i, phy6_idx = 0;
6871         uint16_t save_rf[SAVE_RF_MAX];
6872         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6873         uint16_t save_phy6[SAVE_PHY6_MAX];
6874         int16_t nrssi;
6875         uint16_t saved = 0xffff;
6876
6877         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6878                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6879         for (i = 0; i < SAVE_RF_MAX; ++i)
6880                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6881
6882         BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6883         BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6884         BWN_PHY_SET(mac, 0x0811, 0x000c);
6885         BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6886         BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6887         if (phy->rev >= 6) {
6888                 for (i = 0; i < SAVE_PHY6_MAX; ++i)
6889                         save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6890
6891                 BWN_PHY_WRITE(mac, 0x002e, 0);
6892                 BWN_PHY_WRITE(mac, 0x002f, 0);
6893                 BWN_PHY_WRITE(mac, 0x080f, 0);
6894                 BWN_PHY_WRITE(mac, 0x0810, 0);
6895                 BWN_PHY_SET(mac, 0x0478, 0x0100);
6896                 BWN_PHY_SET(mac, 0x0801, 0x0040);
6897                 BWN_PHY_SET(mac, 0x0060, 0x0040);
6898                 BWN_PHY_SET(mac, 0x0014, 0x0200);
6899         }
6900         BWN_RF_SET(mac, 0x007a, 0x0070);
6901         BWN_RF_SET(mac, 0x007a, 0x0080);
6902         DELAY(30);
6903
6904         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6905         if (nrssi >= 0x20)
6906                 nrssi -= 0x40;
6907         if (nrssi == 31) {
6908                 for (i = 7; i >= 4; i--) {
6909                         BWN_RF_WRITE(mac, 0x007b, i);
6910                         DELAY(20);
6911                         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
6912                             0x003f);
6913                         if (nrssi >= 0x20)
6914                                 nrssi -= 0x40;
6915                         if (nrssi < 31 && saved == 0xffff)
6916                                 saved = i;
6917                 }
6918                 if (saved == 0xffff)
6919                         saved = 4;
6920         } else {
6921                 BWN_RF_MASK(mac, 0x007a, 0x007f);
6922                 if (phy->rev != 1) {
6923                         BWN_PHY_SET(mac, 0x0814, 0x0001);
6924                         BWN_PHY_MASK(mac, 0x0815, 0xfffe);
6925                 }
6926                 BWN_PHY_SET(mac, 0x0811, 0x000c);
6927                 BWN_PHY_SET(mac, 0x0812, 0x000c);
6928                 BWN_PHY_SET(mac, 0x0811, 0x0030);
6929                 BWN_PHY_SET(mac, 0x0812, 0x0030);
6930                 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6931                 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6932                 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6933                 if (phy->rev == 0)
6934                         BWN_PHY_WRITE(mac, 0x0003, 0x0122);
6935                 else
6936                         BWN_PHY_SET(mac, 0x000a, 0x2000);
6937                 if (phy->rev != 1) {
6938                         BWN_PHY_SET(mac, 0x0814, 0x0004);
6939                         BWN_PHY_MASK(mac, 0x0815, 0xfffb);
6940                 }
6941                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6942                 BWN_RF_SET(mac, 0x007a, 0x000f);
6943                 bwn_set_all_gains(mac, 3, 0, 1);
6944                 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
6945                 DELAY(30);
6946                 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6947                 if (nrssi >= 0x20)
6948                         nrssi -= 0x40;
6949                 if (nrssi == -32) {
6950                         for (i = 0; i < 4; i++) {
6951                                 BWN_RF_WRITE(mac, 0x007b, i);
6952                                 DELAY(20);
6953                                 nrssi = (int16_t)((BWN_PHY_READ(mac,
6954                                     0x047f) >> 8) & 0x003f);
6955                                 if (nrssi >= 0x20)
6956                                         nrssi -= 0x40;
6957                                 if (nrssi > -31 && saved == 0xffff)
6958                                         saved = i;
6959                         }
6960                         if (saved == 0xffff)
6961                                 saved = 3;
6962                 } else
6963                         saved = 0;
6964         }
6965         BWN_RF_WRITE(mac, 0x007b, saved);
6966
6967         /*
6968          * Restore saved RF/PHY registers
6969          */
6970         if (phy->rev >= 6) {
6971                 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
6972                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
6973                             save_phy6[phy6_idx]);
6974                 }
6975         }
6976         if (phy->rev != 1) {
6977                 for (i = 3; i < 5; i++)
6978                         BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
6979                             save_phy_comm[i]);
6980         }
6981         for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
6982                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6983
6984         for (i = SAVE_RF_MAX - 1; i >= 0; --i)
6985                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6986
6987         BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
6988         BWN_PHY_SET(mac, 0x0429, 0x8000);
6989         bwn_set_original_gains(mac);
6990         if (phy->rev >= 6) {
6991                 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
6992                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
6993                             save_phy6[phy6_idx]);
6994                 }
6995         }
6996
6997         BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
6998         BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
6999         BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7000 }
7001
7002 static void
7003 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7004     int16_t third)
7005 {
7006         struct bwn_phy *phy = &mac->mac_phy;
7007         uint16_t i;
7008         uint16_t start = 0x08, end = 0x18;
7009         uint16_t tmp;
7010         uint16_t table;
7011
7012         if (phy->rev <= 1) {
7013                 start = 0x10;
7014                 end = 0x20;
7015         }
7016
7017         table = BWN_OFDMTAB_GAINX;
7018         if (phy->rev <= 1)
7019                 table = BWN_OFDMTAB_GAINX_R1;
7020         for (i = 0; i < 4; i++)
7021                 bwn_ofdmtab_write_2(mac, table, i, first);
7022
7023         for (i = start; i < end; i++)
7024                 bwn_ofdmtab_write_2(mac, table, i, second);
7025
7026         if (third != -1) {
7027                 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7028                 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7029                 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7030                 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7031         }
7032         bwn_dummy_transmission(mac, 0, 1);
7033 }
7034
7035 static void
7036 bwn_set_original_gains(struct bwn_mac *mac)
7037 {
7038         struct bwn_phy *phy = &mac->mac_phy;
7039         uint16_t i, tmp;
7040         uint16_t table;
7041         uint16_t start = 0x0008, end = 0x0018;
7042
7043         if (phy->rev <= 1) {
7044                 start = 0x0010;
7045                 end = 0x0020;
7046         }
7047
7048         table = BWN_OFDMTAB_GAINX;
7049         if (phy->rev <= 1)
7050                 table = BWN_OFDMTAB_GAINX_R1;
7051         for (i = 0; i < 4; i++) {
7052                 tmp = (i & 0xfffc);
7053                 tmp |= (i & 0x0001) << 1;
7054                 tmp |= (i & 0x0002) >> 1;
7055
7056                 bwn_ofdmtab_write_2(mac, table, i, tmp);
7057         }
7058
7059         for (i = start; i < end; i++)
7060                 bwn_ofdmtab_write_2(mac, table, i, i - start);
7061
7062         BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7063         BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7064         BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7065         bwn_dummy_transmission(mac, 0, 1);
7066 }
7067
7068 static void
7069 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7070 {
7071         struct bwn_phy *phy = &mac->mac_phy;
7072         struct bwn_phy_g *pg = &phy->phy_g;
7073         struct bwn_rfatt old_rfatt, rfatt;
7074         struct bwn_bbatt old_bbatt, bbatt;
7075         struct bwn_softc *sc = mac->mac_sc;
7076         uint8_t old_txctl = 0;
7077
7078         KASSERT(phy->type == BWN_PHYTYPE_G,
7079             ("%s:%d: fail", __func__, __LINE__));
7080
7081         if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7082             (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7083                 return;
7084
7085         BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7086
7087         BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7088
7089         if (!phy->gmode)
7090                 return;
7091         bwn_hwpctl_early_init(mac);
7092         if (pg->pg_curtssi == 0) {
7093                 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7094                         BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7095                 } else {
7096                         memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7097                         memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7098                         old_txctl = pg->pg_txctl;
7099
7100                         bbatt.att = 11;
7101                         if (phy->rf_rev == 8) {
7102                                 rfatt.att = 15;
7103                                 rfatt.padmix = 1;
7104                         } else {
7105                                 rfatt.att = 9;
7106                                 rfatt.padmix = 0;
7107                         }
7108                         bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7109                 }
7110                 bwn_dummy_transmission(mac, 0, 1);
7111                 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7112                 if (phy->rf_ver == 0x2050 && phy->analog == 0)
7113                         BWN_RF_MASK(mac, 0x0076, 0xff7b);
7114                 else
7115                         bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7116                             &old_rfatt, old_txctl);
7117         }
7118         bwn_hwpctl_init_gphy(mac);
7119
7120         /* clear TSSI */
7121         bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7122         bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7123         bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7124         bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7125 }
7126
7127 static void
7128 bwn_hwpctl_early_init(struct bwn_mac *mac)
7129 {
7130         struct bwn_phy *phy = &mac->mac_phy;
7131
7132         if (!bwn_has_hwpctl(mac)) {
7133                 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7134                 return;
7135         }
7136
7137         BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7138         BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7139         BWN_PHY_SET(mac, 0x047c, 0x0002);
7140         BWN_PHY_SET(mac, 0x047a, 0xf000);
7141         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7142                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7143                 BWN_PHY_SET(mac, 0x005d, 0x8000);
7144                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7145                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7146                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7147         } else {
7148                 BWN_PHY_SET(mac, 0x0036, 0x0200);
7149                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7150                 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7151                 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7152                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7153                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7154                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7155         }
7156 }
7157
7158 static void
7159 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7160 {
7161         struct bwn_phy *phy = &mac->mac_phy;
7162         struct bwn_phy_g *pg = &phy->phy_g;
7163         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7164         int i;
7165         uint16_t nr_written = 0, tmp, value;
7166         uint8_t rf, bb;
7167
7168         if (!bwn_has_hwpctl(mac)) {
7169                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7170                 return;
7171         }
7172
7173         BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7174             (pg->pg_idletssi - pg->pg_curtssi));
7175         BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7176             (pg->pg_idletssi - pg->pg_curtssi));
7177
7178         for (i = 0; i < 32; i++)
7179                 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7180         for (i = 32; i < 64; i++)
7181                 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7182         for (i = 0; i < 64; i += 2) {
7183                 value = (uint16_t) pg->pg_tssi2dbm[i];
7184                 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7185                 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7186         }
7187
7188         for (rf = 0; rf < lo->rfatt.len; rf++) {
7189                 for (bb = 0; bb < lo->bbatt.len; bb++) {
7190                         if (nr_written >= 0x40)
7191                                 return;
7192                         tmp = lo->bbatt.array[bb].att;
7193                         tmp <<= 8;
7194                         if (phy->rf_rev == 8)
7195                                 tmp |= 0x50;
7196                         else
7197                                 tmp |= 0x40;
7198                         tmp |= lo->rfatt.array[rf].att;
7199                         BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7200                         nr_written++;
7201                 }
7202         }
7203
7204         BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7205         BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7206
7207         KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7208         BWN_PHY_SET(mac, 0x0478, 0x0800);
7209         BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7210         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7211
7212         bwn_phy_g_dc_lookup_init(mac, 1);
7213         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7214 }
7215
7216 static void
7217 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7218 {
7219         struct bwn_softc *sc = mac->mac_sc;
7220
7221         if (spu != 0)
7222                 bwn_spu_workaround(mac, channel);
7223
7224         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7225
7226         if (channel == 14) {
7227                 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7228                         bwn_hf_write(mac,
7229                             bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7230                 else
7231                         bwn_hf_write(mac,
7232                             bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7233                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7234                     BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7235                 return;
7236         }
7237
7238         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7239             BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7240 }
7241
7242 static uint16_t
7243 bwn_phy_g_chan2freq(uint8_t channel)
7244 {
7245         static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7246
7247         KASSERT(channel >= 1 && channel <= 14,
7248             ("%s:%d: fail", __func__, __LINE__));
7249
7250         return (bwn_phy_g_rf_channels[channel - 1]);
7251 }
7252
7253 static void
7254 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7255     const struct bwn_rfatt *rfatt, uint8_t txctl)
7256 {
7257         struct bwn_phy *phy = &mac->mac_phy;
7258         struct bwn_phy_g *pg = &phy->phy_g;
7259         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7260         uint16_t bb, rf;
7261         uint16_t tx_bias, tx_magn;
7262
7263         bb = bbatt->att;
7264         rf = rfatt->att;
7265         tx_bias = lo->tx_bias;
7266         tx_magn = lo->tx_magn;
7267         if (tx_bias == 0xff)
7268                 tx_bias = 0;
7269
7270         pg->pg_txctl = txctl;
7271         memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7272         pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7273         memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7274         bwn_phy_g_set_bbatt(mac, bb);
7275         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7276         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7277                 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7278         else {
7279                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7280                 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7281         }
7282         if (BWN_HAS_TXMAG(phy))
7283                 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7284         else
7285                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7286         bwn_lo_g_adjust(mac);
7287 }
7288
7289 static void
7290 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7291     uint16_t bbatt)
7292 {
7293         struct bwn_phy *phy = &mac->mac_phy;
7294
7295         if (phy->analog == 0) {
7296                 BWN_WRITE_2(mac, BWN_PHY0,
7297                     (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7298                 return;
7299         }
7300         if (phy->analog > 1) {
7301                 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7302                 return;
7303         }
7304         BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7305 }
7306
7307 static uint16_t
7308 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7309 {
7310         struct bwn_phy *phy = &mac->mac_phy;
7311         struct bwn_phy_g *pg = &phy->phy_g;
7312         struct bwn_softc *sc = mac->mac_sc;
7313         int max_lb_gain;
7314         uint16_t extlna;
7315         uint16_t i;
7316
7317         if (phy->gmode == 0)
7318                 return (0);
7319
7320         if (BWN_HAS_LOOPBACK(phy)) {
7321                 max_lb_gain = pg->pg_max_lb_gain;
7322                 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7323                 if (max_lb_gain >= 0x46) {
7324                         extlna = 0x3000;
7325                         max_lb_gain -= 0x46;
7326                 } else if (max_lb_gain >= 0x3a) {
7327                         extlna = 0x1000;
7328                         max_lb_gain -= 0x3a;
7329                 } else if (max_lb_gain >= 0x2e) {
7330                         extlna = 0x2000;
7331                         max_lb_gain -= 0x2e;
7332                 } else {
7333                         extlna = 0;
7334                         max_lb_gain -= 0x10;
7335                 }
7336
7337                 for (i = 0; i < 16; i++) {
7338                         max_lb_gain -= (i * 6);
7339                         if (max_lb_gain < 6)
7340                                 break;
7341                 }
7342
7343                 if ((phy->rev < 7) ||
7344                     !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7345                         if (reg == BWN_PHY_RFOVER) {
7346                                 return (0x1b3);
7347                         } else if (reg == BWN_PHY_RFOVERVAL) {
7348                                 extlna |= (i << 8);
7349                                 switch (lpd) {
7350                                 case BWN_LPD(0, 1, 1):
7351                                         return (0x0f92);
7352                                 case BWN_LPD(0, 0, 1):
7353                                 case BWN_LPD(1, 0, 1):
7354                                         return (0x0092 | extlna);
7355                                 case BWN_LPD(1, 0, 0):
7356                                         return (0x0093 | extlna);
7357                                 }
7358                                 KASSERT(0 == 1,
7359                                     ("%s:%d: fail", __func__, __LINE__));
7360                         }
7361                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7362                 } else {
7363                         if (reg == BWN_PHY_RFOVER)
7364                                 return (0x9b3);
7365                         if (reg == BWN_PHY_RFOVERVAL) {
7366                                 if (extlna)
7367                                         extlna |= 0x8000;
7368                                 extlna |= (i << 8);
7369                                 switch (lpd) {
7370                                 case BWN_LPD(0, 1, 1):
7371                                         return (0x8f92);
7372                                 case BWN_LPD(0, 0, 1):
7373                                         return (0x8092 | extlna);
7374                                 case BWN_LPD(1, 0, 1):
7375                                         return (0x2092 | extlna);
7376                                 case BWN_LPD(1, 0, 0):
7377                                         return (0x2093 | extlna);
7378                                 }
7379                                 KASSERT(0 == 1,
7380                                     ("%s:%d: fail", __func__, __LINE__));
7381                         }
7382                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7383                 }
7384                 return (0);
7385         }
7386
7387         if ((phy->rev < 7) ||
7388             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7389                 if (reg == BWN_PHY_RFOVER) {
7390                         return (0x1b3);
7391                 } else if (reg == BWN_PHY_RFOVERVAL) {
7392                         switch (lpd) {
7393                         case BWN_LPD(0, 1, 1):
7394                                 return (0x0fb2);
7395                         case BWN_LPD(0, 0, 1):
7396                                 return (0x00b2);
7397                         case BWN_LPD(1, 0, 1):
7398                                 return (0x30b2);
7399                         case BWN_LPD(1, 0, 0):
7400                                 return (0x30b3);
7401                         }
7402                         KASSERT(0 == 1,
7403                             ("%s:%d: fail", __func__, __LINE__));
7404                 }
7405                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7406         } else {
7407                 if (reg == BWN_PHY_RFOVER) {
7408                         return (0x9b3);
7409                 } else if (reg == BWN_PHY_RFOVERVAL) {
7410                         switch (lpd) {
7411                         case BWN_LPD(0, 1, 1):
7412                                 return (0x8fb2);
7413                         case BWN_LPD(0, 0, 1):
7414                                 return (0x80b2);
7415                         case BWN_LPD(1, 0, 1):
7416                                 return (0x20b2);
7417                         case BWN_LPD(1, 0, 0):
7418                                 return (0x20b3);
7419                         }
7420                         KASSERT(0 == 1,
7421                             ("%s:%d: fail", __func__, __LINE__));
7422                 }
7423                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7424         }
7425         return (0);
7426 }
7427
7428 static void
7429 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7430 {
7431
7432         if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7433                 return;
7434         BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7435             bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7436         DELAY(1000);
7437         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7438 }
7439
7440 static int
7441 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7442 {
7443         struct bwn_softc *sc = mac->mac_sc;
7444         struct bwn_fw *fw = &mac->mac_fw;
7445         const uint8_t rev = siba_get_revid(sc->sc_dev);
7446         const char *filename;
7447         uint32_t high;
7448         int error;
7449
7450         /* microcode */
7451         if (rev >= 5 && rev <= 10)
7452                 filename = "ucode5";
7453         else if (rev >= 11 && rev <= 12)
7454                 filename = "ucode11";
7455         else if (rev == 13)
7456                 filename = "ucode13";
7457         else if (rev == 14)
7458                 filename = "ucode14";
7459         else if (rev >= 15)
7460                 filename = "ucode15";
7461         else {
7462                 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7463                 bwn_release_firmware(mac);
7464                 return (EOPNOTSUPP);
7465         }
7466         error = bwn_fw_get(mac, type, filename, &fw->ucode);
7467         if (error) {
7468                 bwn_release_firmware(mac);
7469                 return (error);
7470         }
7471
7472         /* PCM */
7473         KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7474         if (rev >= 5 && rev <= 10) {
7475                 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7476                 if (error == ENOENT)
7477                         fw->no_pcmfile = 1;
7478                 else if (error) {
7479                         bwn_release_firmware(mac);
7480                         return (error);
7481                 }
7482         } else if (rev < 11) {
7483                 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7484                 return (EOPNOTSUPP);
7485         }
7486
7487         /* initvals */
7488         high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7489         switch (mac->mac_phy.type) {
7490         case BWN_PHYTYPE_A:
7491                 if (rev < 5 || rev > 10)
7492                         goto fail1;
7493                 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7494                         filename = "a0g1initvals5";
7495                 else
7496                         filename = "a0g0initvals5";
7497                 break;
7498         case BWN_PHYTYPE_G:
7499                 if (rev >= 5 && rev <= 10)
7500                         filename = "b0g0initvals5";
7501                 else if (rev >= 13)
7502                         filename = "b0g0initvals13";
7503                 else
7504                         goto fail1;
7505                 break;
7506         case BWN_PHYTYPE_LP:
7507                 if (rev == 13)
7508                         filename = "lp0initvals13";
7509                 else if (rev == 14)
7510                         filename = "lp0initvals14";
7511                 else if (rev >= 15)
7512                         filename = "lp0initvals15";
7513                 else
7514                         goto fail1;
7515                 break;
7516         case BWN_PHYTYPE_N:
7517                 if (rev >= 11 && rev <= 12)
7518                         filename = "n0initvals11";
7519                 else
7520                         goto fail1;
7521                 break;
7522         default:
7523                 goto fail1;
7524         }
7525         error = bwn_fw_get(mac, type, filename, &fw->initvals);
7526         if (error) {
7527                 bwn_release_firmware(mac);
7528                 return (error);
7529         }
7530
7531         /* bandswitch initvals */
7532         switch (mac->mac_phy.type) {
7533         case BWN_PHYTYPE_A:
7534                 if (rev >= 5 && rev <= 10) {
7535                         if (high & BWN_TGSHIGH_HAVE_2GHZ)
7536                                 filename = "a0g1bsinitvals5";
7537                         else
7538                                 filename = "a0g0bsinitvals5";
7539                 } else if (rev >= 11)
7540                         filename = NULL;
7541                 else
7542                         goto fail1;
7543                 break;
7544         case BWN_PHYTYPE_G:
7545                 if (rev >= 5 && rev <= 10)
7546                         filename = "b0g0bsinitvals5";
7547                 else if (rev >= 11)
7548                         filename = NULL;
7549                 else
7550                         goto fail1;
7551                 break;
7552         case BWN_PHYTYPE_LP:
7553                 if (rev == 13)
7554                         filename = "lp0bsinitvals13";
7555                 else if (rev == 14)
7556                         filename = "lp0bsinitvals14";
7557                 else if (rev >= 15)
7558                         filename = "lp0bsinitvals15";
7559                 else
7560                         goto fail1;
7561                 break;
7562         case BWN_PHYTYPE_N:
7563                 if (rev >= 11 && rev <= 12)
7564                         filename = "n0bsinitvals11";
7565                 else
7566                         goto fail1;
7567                 break;
7568         default:
7569                 goto fail1;
7570         }
7571         error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7572         if (error) {
7573                 bwn_release_firmware(mac);
7574                 return (error);
7575         }
7576         return (0);
7577 fail1:
7578         device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7579         bwn_release_firmware(mac);
7580         return (EOPNOTSUPP);
7581 }
7582
7583 static int
7584 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7585     const char *name, struct bwn_fwfile *bfw)
7586 {
7587         const struct bwn_fwhdr *hdr;
7588         struct bwn_softc *sc = mac->mac_sc;
7589         const struct firmware *fw;
7590         char namebuf[64];
7591
7592         if (name == NULL) {
7593                 bwn_do_release_fw(bfw);
7594                 return (0);
7595         }
7596         if (bfw->filename != NULL) {
7597                 if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7598                         return (0);
7599                 bwn_do_release_fw(bfw);
7600         }
7601
7602         snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7603             (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7604             (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7605         /* XXX Sleeping on "fwload" with the non-sleepable locks held */
7606         fw = firmware_get(namebuf);
7607         if (fw == NULL) {
7608                 device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7609                     namebuf);
7610                 return (ENOENT);
7611         }
7612         if (fw->datasize < sizeof(struct bwn_fwhdr))
7613                 goto fail;
7614         hdr = (const struct bwn_fwhdr *)(fw->data);
7615         switch (hdr->type) {
7616         case BWN_FWTYPE_UCODE:
7617         case BWN_FWTYPE_PCM:
7618                 if (be32toh(hdr->size) !=
7619                     (fw->datasize - sizeof(struct bwn_fwhdr)))
7620                         goto fail;
7621                 /* FALLTHROUGH */
7622         case BWN_FWTYPE_IV:
7623                 if (hdr->ver != 1)
7624                         goto fail;
7625                 break;
7626         default:
7627                 goto fail;
7628         }
7629         bfw->filename = name;
7630         bfw->fw = fw;
7631         bfw->type = type;
7632         return (0);
7633 fail:
7634         device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7635         if (fw != NULL)
7636                 firmware_put(fw, FIRMWARE_UNLOAD);
7637         return (EPROTO);
7638 }
7639
7640 static void
7641 bwn_release_firmware(struct bwn_mac *mac)
7642 {
7643
7644         bwn_do_release_fw(&mac->mac_fw.ucode);
7645         bwn_do_release_fw(&mac->mac_fw.pcm);
7646         bwn_do_release_fw(&mac->mac_fw.initvals);
7647         bwn_do_release_fw(&mac->mac_fw.initvals_band);
7648 }
7649
7650 static void
7651 bwn_do_release_fw(struct bwn_fwfile *bfw)
7652 {
7653
7654         if (bfw->fw != NULL)
7655                 firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7656         bfw->fw = NULL;
7657         bfw->filename = NULL;
7658 }
7659
7660 static int
7661 bwn_fw_loaducode(struct bwn_mac *mac)
7662 {
7663 #define GETFWOFFSET(fwp, offset)        \
7664         ((const uint32_t *)((const char *)fwp.fw->data + offset))
7665 #define GETFWSIZE(fwp, offset)  \
7666         ((fwp.fw->datasize - offset) / sizeof(uint32_t))
7667         struct bwn_softc *sc = mac->mac_sc;
7668         const uint32_t *data;
7669         unsigned int i;
7670         uint32_t ctl;
7671         uint16_t date, fwcaps, time;
7672         int error = 0;
7673
7674         ctl = BWN_READ_4(mac, BWN_MACCTL);
7675         ctl |= BWN_MACCTL_MCODE_JMP0;
7676         KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7677             __LINE__));
7678         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7679         for (i = 0; i < 64; i++)
7680                 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7681         for (i = 0; i < 4096; i += 2)
7682                 bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7683
7684         data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7685         bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7686         for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7687              i++) {
7688                 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7689                 DELAY(10);
7690         }
7691
7692         if (mac->mac_fw.pcm.fw) {
7693                 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7694                 bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7695                 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7696                 bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7697                 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7698                     sizeof(struct bwn_fwhdr)); i++) {
7699                         BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7700                         DELAY(10);
7701                 }
7702         }
7703
7704         BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7705         BWN_WRITE_4(mac, BWN_MACCTL,
7706             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7707             BWN_MACCTL_MCODE_RUN);
7708
7709         for (i = 0; i < 21; i++) {
7710                 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7711                         break;
7712                 if (i >= 20) {
7713                         device_printf(sc->sc_dev, "ucode timeout\n");
7714                         error = ENXIO;
7715                         goto error;
7716                 }
7717                 DELAY(50000);
7718         }
7719         BWN_READ_4(mac, BWN_INTR_REASON);
7720
7721         mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7722         if (mac->mac_fw.rev <= 0x128) {
7723                 device_printf(sc->sc_dev, "the firmware is too old\n");
7724                 error = EOPNOTSUPP;
7725                 goto error;
7726         }
7727         mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7728             BWN_SHARED_UCODE_PATCH);
7729         date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7730         mac->mac_fw.opensource = (date == 0xffff);
7731         if (bwn_wme != 0)
7732                 mac->mac_flags |= BWN_MAC_FLAG_WME;
7733         mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7734
7735         time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7736         if (mac->mac_fw.opensource == 0) {
7737                 device_printf(sc->sc_dev,
7738                     "firmware version (rev %u patch %u date %#x time %#x)\n",
7739                     mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7740                 if (mac->mac_fw.no_pcmfile)
7741                         device_printf(sc->sc_dev,
7742                             "no HW crypto acceleration due to pcm5\n");
7743         } else {
7744                 mac->mac_fw.patch = time;
7745                 fwcaps = bwn_fwcaps_read(mac);
7746                 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7747                         device_printf(sc->sc_dev,
7748                             "disabling HW crypto acceleration\n");
7749                         mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7750                 }
7751                 if (!(fwcaps & BWN_FWCAPS_WME)) {
7752                         device_printf(sc->sc_dev, "disabling WME support\n");
7753                         mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7754                 }
7755         }
7756
7757         if (BWN_ISOLDFMT(mac))
7758                 device_printf(sc->sc_dev, "using old firmware image\n");
7759
7760         return (0);
7761
7762 error:
7763         BWN_WRITE_4(mac, BWN_MACCTL,
7764             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7765             BWN_MACCTL_MCODE_JMP0);
7766
7767         return (error);
7768 #undef GETFWSIZE
7769 #undef GETFWOFFSET
7770 }
7771
7772 /* OpenFirmware only */
7773 static uint16_t
7774 bwn_fwcaps_read(struct bwn_mac *mac)
7775 {
7776
7777         KASSERT(mac->mac_fw.opensource == 1,
7778             ("%s:%d: fail", __func__, __LINE__));
7779         return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7780 }
7781
7782 static int
7783 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7784     size_t count, size_t array_size)
7785 {
7786 #define GET_NEXTIV16(iv)                                                \
7787         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7788             sizeof(uint16_t) + sizeof(uint16_t)))
7789 #define GET_NEXTIV32(iv)                                                \
7790         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7791             sizeof(uint16_t) + sizeof(uint32_t)))
7792         struct bwn_softc *sc = mac->mac_sc;
7793         const struct bwn_fwinitvals *iv;
7794         uint16_t offset;
7795         size_t i;
7796         uint8_t bit32;
7797
7798         KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7799             ("%s:%d: fail", __func__, __LINE__));
7800         iv = ivals;
7801         for (i = 0; i < count; i++) {
7802                 if (array_size < sizeof(iv->offset_size))
7803                         goto fail;
7804                 array_size -= sizeof(iv->offset_size);
7805                 offset = be16toh(iv->offset_size);
7806                 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7807                 offset &= BWN_FWINITVALS_OFFSET_MASK;
7808                 if (offset >= 0x1000)
7809                         goto fail;
7810                 if (bit32) {
7811                         if (array_size < sizeof(iv->data.d32))
7812                                 goto fail;
7813                         array_size -= sizeof(iv->data.d32);
7814                         BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7815                         iv = GET_NEXTIV32(iv);
7816                 } else {
7817
7818                         if (array_size < sizeof(iv->data.d16))
7819                                 goto fail;
7820                         array_size -= sizeof(iv->data.d16);
7821                         BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7822
7823                         iv = GET_NEXTIV16(iv);
7824                 }
7825         }
7826         if (array_size != 0)
7827                 goto fail;
7828         return (0);
7829 fail:
7830         device_printf(sc->sc_dev, "initvals: invalid format\n");
7831         return (EPROTO);
7832 #undef GET_NEXTIV16
7833 #undef GET_NEXTIV32
7834 }
7835
7836 static int
7837 bwn_switch_channel(struct bwn_mac *mac, int chan)
7838 {
7839         struct bwn_phy *phy = &(mac->mac_phy);
7840         struct bwn_softc *sc = mac->mac_sc;
7841         struct ieee80211com *ic = &sc->sc_ic;
7842         uint16_t channelcookie, savedcookie;
7843         int error;
7844
7845         if (chan == 0xffff)
7846                 chan = phy->get_default_chan(mac);
7847
7848         channelcookie = chan;
7849         if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
7850                 channelcookie |= 0x100;
7851         savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
7852         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
7853         error = phy->switch_channel(mac, chan);
7854         if (error)
7855                 goto fail;
7856
7857         mac->mac_phy.chan = chan;
7858         DELAY(8000);
7859         return (0);
7860 fail:
7861         device_printf(sc->sc_dev, "failed to switch channel\n");
7862         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
7863         return (error);
7864 }
7865
7866 static uint16_t
7867 bwn_ant2phy(int antenna)
7868 {
7869
7870         switch (antenna) {
7871         case BWN_ANT0:
7872                 return (BWN_TX_PHY_ANT0);
7873         case BWN_ANT1:
7874                 return (BWN_TX_PHY_ANT1);
7875         case BWN_ANT2:
7876                 return (BWN_TX_PHY_ANT2);
7877         case BWN_ANT3:
7878                 return (BWN_TX_PHY_ANT3);
7879         case BWN_ANTAUTO:
7880                 return (BWN_TX_PHY_ANT01AUTO);
7881         }
7882         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7883         return (0);
7884 }
7885
7886 static void
7887 bwn_wme_load(struct bwn_mac *mac)
7888 {
7889         struct bwn_softc *sc = mac->mac_sc;
7890         int i;
7891
7892         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
7893             ("%s:%d: fail", __func__, __LINE__));
7894
7895         bwn_mac_suspend(mac);
7896         for (i = 0; i < N(sc->sc_wmeParams); i++)
7897                 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
7898                     bwn_wme_shm_offsets[i]);
7899         bwn_mac_enable(mac);
7900 }
7901
7902 static void
7903 bwn_wme_loadparams(struct bwn_mac *mac,
7904     const struct wmeParams *p, uint16_t shm_offset)
7905 {
7906 #define SM(_v, _f)      (((_v) << _f##_S) & _f)
7907         struct bwn_softc *sc = mac->mac_sc;
7908         uint16_t params[BWN_NR_WMEPARAMS];
7909         int slot, tmp;
7910         unsigned int i;
7911
7912         slot = BWN_READ_2(mac, BWN_RNG) &
7913             SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7914
7915         memset(&params, 0, sizeof(params));
7916
7917         DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
7918             "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
7919             p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
7920
7921         params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
7922         params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7923         params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
7924         params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7925         params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
7926         params[BWN_WMEPARAM_BSLOTS] = slot;
7927         params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
7928
7929         for (i = 0; i < N(params); i++) {
7930                 if (i == BWN_WMEPARAM_STATUS) {
7931                         tmp = bwn_shm_read_2(mac, BWN_SHARED,
7932                             shm_offset + (i * 2));
7933                         tmp |= 0x100;
7934                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
7935                             tmp);
7936                 } else {
7937                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
7938                             params[i]);
7939                 }
7940         }
7941 }
7942
7943 static void
7944 bwn_mac_write_bssid(struct bwn_mac *mac)
7945 {
7946         struct bwn_softc *sc = mac->mac_sc;
7947         uint32_t tmp;
7948         int i;
7949         uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
7950
7951         bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
7952         memcpy(mac_bssid, sc->sc_ic.ic_macaddr, IEEE80211_ADDR_LEN);
7953         memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
7954             IEEE80211_ADDR_LEN);
7955
7956         for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
7957                 tmp = (uint32_t) (mac_bssid[i + 0]);
7958                 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
7959                 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
7960                 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
7961                 bwn_ram_write(mac, 0x20 + i, tmp);
7962         }
7963 }
7964
7965 static void
7966 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
7967     const uint8_t *macaddr)
7968 {
7969         static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
7970         uint16_t data;
7971
7972         if (!mac)
7973                 macaddr = zero;
7974
7975         offset |= 0x0020;
7976         BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
7977
7978         data = macaddr[0];
7979         data |= macaddr[1] << 8;
7980         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7981         data = macaddr[2];
7982         data |= macaddr[3] << 8;
7983         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7984         data = macaddr[4];
7985         data |= macaddr[5] << 8;
7986         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7987 }
7988
7989 static void
7990 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
7991     const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
7992 {
7993         uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
7994         uint8_t per_sta_keys_start = 8;
7995
7996         if (BWN_SEC_NEWAPI(mac))
7997                 per_sta_keys_start = 4;
7998
7999         KASSERT(index < mac->mac_max_nr_keys,
8000             ("%s:%d: fail", __func__, __LINE__));
8001         KASSERT(key_len <= BWN_SEC_KEYSIZE,
8002             ("%s:%d: fail", __func__, __LINE__));
8003
8004         if (index >= per_sta_keys_start)
8005                 bwn_key_macwrite(mac, index, NULL);
8006         if (key)
8007                 memcpy(buf, key, key_len);
8008         bwn_key_write(mac, index, algorithm, buf);
8009         if (index >= per_sta_keys_start)
8010                 bwn_key_macwrite(mac, index, mac_addr);
8011
8012         mac->mac_key[index].algorithm = algorithm;
8013 }
8014
8015 static void
8016 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8017 {
8018         struct bwn_softc *sc = mac->mac_sc;
8019         uint32_t addrtmp[2] = { 0, 0 };
8020         uint8_t start = 8;
8021
8022         if (BWN_SEC_NEWAPI(mac))
8023                 start = 4;
8024
8025         KASSERT(index >= start,
8026             ("%s:%d: fail", __func__, __LINE__));
8027         index -= start;
8028
8029         if (addr) {
8030                 addrtmp[0] = addr[0];
8031                 addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8032                 addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8033                 addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8034                 addrtmp[1] = addr[4];
8035                 addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8036         }
8037
8038         if (siba_get_revid(sc->sc_dev) >= 5) {
8039                 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8040                 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8041         } else {
8042                 if (index >= 8) {
8043                         bwn_shm_write_4(mac, BWN_SHARED,
8044                             BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8045                         bwn_shm_write_2(mac, BWN_SHARED,
8046                             BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8047                 }
8048         }
8049 }
8050
8051 static void
8052 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8053     const uint8_t *key)
8054 {
8055         unsigned int i;
8056         uint32_t offset;
8057         uint16_t kidx, value;
8058
8059         kidx = BWN_SEC_KEY2FW(mac, index);
8060         bwn_shm_write_2(mac, BWN_SHARED,
8061             BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8062
8063         offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8064         for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8065                 value = key[i];
8066                 value |= (uint16_t)(key[i + 1]) << 8;
8067                 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8068         }
8069 }
8070
8071 static void
8072 bwn_phy_exit(struct bwn_mac *mac)
8073 {
8074
8075         mac->mac_phy.rf_onoff(mac, 0);
8076         if (mac->mac_phy.exit != NULL)
8077                 mac->mac_phy.exit(mac);
8078 }
8079
8080 static void
8081 bwn_dma_free(struct bwn_mac *mac)
8082 {
8083         struct bwn_dma *dma;
8084
8085         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8086                 return;
8087         dma = &mac->mac_method.dma;
8088
8089         bwn_dma_ringfree(&dma->rx);
8090         bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8091         bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8092         bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8093         bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8094         bwn_dma_ringfree(&dma->mcast);
8095 }
8096
8097 static void
8098 bwn_core_stop(struct bwn_mac *mac)
8099 {
8100         struct bwn_softc *sc = mac->mac_sc;
8101
8102         BWN_ASSERT_LOCKED(sc);
8103
8104         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8105                 return;
8106
8107         callout_stop(&sc->sc_rfswitch_ch);
8108         callout_stop(&sc->sc_task_ch);
8109         callout_stop(&sc->sc_watchdog_ch);
8110         sc->sc_watchdog_timer = 0;
8111         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8112         BWN_READ_4(mac, BWN_INTR_MASK);
8113         bwn_mac_suspend(mac);
8114
8115         mac->mac_status = BWN_MAC_STATUS_INITED;
8116 }
8117
8118 static int
8119 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8120 {
8121         struct bwn_mac *up_dev = NULL;
8122         struct bwn_mac *down_dev;
8123         struct bwn_mac *mac;
8124         int err, status;
8125         uint8_t gmode;
8126
8127         BWN_ASSERT_LOCKED(sc);
8128
8129         TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8130                 if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8131                     mac->mac_phy.supports_2ghz) {
8132                         up_dev = mac;
8133                         gmode = 1;
8134                 } else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8135                     mac->mac_phy.supports_5ghz) {
8136                         up_dev = mac;
8137                         gmode = 0;
8138                 } else {
8139                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8140                         return (EINVAL);
8141                 }
8142                 if (up_dev != NULL)
8143                         break;
8144         }
8145         if (up_dev == NULL) {
8146                 device_printf(sc->sc_dev, "Could not find a device\n");
8147                 return (ENODEV);
8148         }
8149         if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8150                 return (0);
8151
8152         device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8153             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8154
8155         down_dev = sc->sc_curmac;
8156         status = down_dev->mac_status;
8157         if (status >= BWN_MAC_STATUS_STARTED)
8158                 bwn_core_stop(down_dev);
8159         if (status >= BWN_MAC_STATUS_INITED)
8160                 bwn_core_exit(down_dev);
8161
8162         if (down_dev != up_dev)
8163                 bwn_phy_reset(down_dev);
8164
8165         up_dev->mac_phy.gmode = gmode;
8166         if (status >= BWN_MAC_STATUS_INITED) {
8167                 err = bwn_core_init(up_dev);
8168                 if (err) {
8169                         device_printf(sc->sc_dev,
8170                             "fatal: failed to initialize for %s-GHz\n",
8171                             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8172                         goto fail;
8173                 }
8174         }
8175         if (status >= BWN_MAC_STATUS_STARTED)
8176                 bwn_core_start(up_dev);
8177         KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8178         sc->sc_curmac = up_dev;
8179
8180         return (0);
8181 fail:
8182         sc->sc_curmac = NULL;
8183         return (err);
8184 }
8185
8186 static void
8187 bwn_rf_turnon(struct bwn_mac *mac)
8188 {
8189
8190         bwn_mac_suspend(mac);
8191         mac->mac_phy.rf_onoff(mac, 1);
8192         mac->mac_phy.rf_on = 1;
8193         bwn_mac_enable(mac);
8194 }
8195
8196 static void
8197 bwn_rf_turnoff(struct bwn_mac *mac)
8198 {
8199
8200         bwn_mac_suspend(mac);
8201         mac->mac_phy.rf_onoff(mac, 0);
8202         mac->mac_phy.rf_on = 0;
8203         bwn_mac_enable(mac);
8204 }
8205
8206 static void
8207 bwn_phy_reset(struct bwn_mac *mac)
8208 {
8209         struct bwn_softc *sc = mac->mac_sc;
8210
8211         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8212             ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8213              BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8214         DELAY(1000);
8215         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8216             (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8217             BWN_TGSLOW_PHYRESET);
8218         DELAY(1000);
8219 }
8220
8221 static int
8222 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8223 {
8224         struct bwn_vap *bvp = BWN_VAP(vap);
8225         struct ieee80211com *ic= vap->iv_ic;
8226         enum ieee80211_state ostate = vap->iv_state;
8227         struct bwn_softc *sc = ic->ic_softc;
8228         struct bwn_mac *mac = sc->sc_curmac;
8229         int error;
8230
8231         DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8232             ieee80211_state_name[vap->iv_state],
8233             ieee80211_state_name[nstate]);
8234
8235         error = bvp->bv_newstate(vap, nstate, arg);
8236         if (error != 0)
8237                 return (error);
8238
8239         BWN_LOCK(sc);
8240
8241         bwn_led_newstate(mac, nstate);
8242
8243         /*
8244          * Clear the BSSID when we stop a STA
8245          */
8246         if (vap->iv_opmode == IEEE80211_M_STA) {
8247                 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8248                         /*
8249                          * Clear out the BSSID.  If we reassociate to
8250                          * the same AP, this will reinialize things
8251                          * correctly...
8252                          */
8253                         if (ic->ic_opmode == IEEE80211_M_STA &&
8254                             (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8255                                 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8256                                 bwn_set_macaddr(mac);
8257                         }
8258                 }
8259         }
8260
8261         if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8262             vap->iv_opmode == IEEE80211_M_AHDEMO) {
8263                 /* XXX nothing to do? */
8264         } else if (nstate == IEEE80211_S_RUN) {
8265                 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8266                 bwn_set_opmode(mac);
8267                 bwn_set_pretbtt(mac);
8268                 bwn_spu_setdelay(mac, 0);
8269                 bwn_set_macaddr(mac);
8270         }
8271
8272         BWN_UNLOCK(sc);
8273
8274         return (error);
8275 }
8276
8277 static void
8278 bwn_set_pretbtt(struct bwn_mac *mac)
8279 {
8280         struct bwn_softc *sc = mac->mac_sc;
8281         struct ieee80211com *ic = &sc->sc_ic;
8282         uint16_t pretbtt;
8283
8284         if (ic->ic_opmode == IEEE80211_M_IBSS)
8285                 pretbtt = 2;
8286         else
8287                 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8288         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8289         BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8290 }
8291
8292 static int
8293 bwn_intr(void *arg)
8294 {
8295         struct bwn_mac *mac = arg;
8296         struct bwn_softc *sc = mac->mac_sc;
8297         uint32_t reason;
8298
8299         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8300             (sc->sc_flags & BWN_FLAG_INVALID))
8301                 return (FILTER_STRAY);
8302
8303         reason = BWN_READ_4(mac, BWN_INTR_REASON);
8304         if (reason == 0xffffffff)       /* shared IRQ */
8305                 return (FILTER_STRAY);
8306         reason &= mac->mac_intr_mask;
8307         if (reason == 0)
8308                 return (FILTER_HANDLED);
8309
8310         mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
8311         mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8312         mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8313         mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8314         mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8315         BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8316         BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8317         BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8318         BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8319         BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8320         BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8321
8322         /* Disable interrupts. */
8323         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8324
8325         mac->mac_reason_intr = reason;
8326
8327         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8328         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8329
8330         taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask);
8331         return (FILTER_HANDLED);
8332 }
8333
8334 static void
8335 bwn_intrtask(void *arg, int npending)
8336 {
8337         struct bwn_mac *mac = arg;
8338         struct bwn_softc *sc = mac->mac_sc;
8339         uint32_t merged = 0;
8340         int i, tx = 0, rx = 0;
8341
8342         BWN_LOCK(sc);
8343         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8344             (sc->sc_flags & BWN_FLAG_INVALID)) {
8345                 BWN_UNLOCK(sc);
8346                 return;
8347         }
8348
8349         for (i = 0; i < N(mac->mac_reason); i++)
8350                 merged |= mac->mac_reason[i];
8351
8352         if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8353                 device_printf(sc->sc_dev, "MAC trans error\n");
8354
8355         if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8356                 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8357                 mac->mac_phy.txerrors--;
8358                 if (mac->mac_phy.txerrors == 0) {
8359                         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8360                         bwn_restart(mac, "PHY TX errors");
8361                 }
8362         }
8363
8364         if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
8365                 if (merged & BWN_DMAINTR_FATALMASK) {
8366                         device_printf(sc->sc_dev,
8367                             "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8368                             mac->mac_reason[0], mac->mac_reason[1],
8369                             mac->mac_reason[2], mac->mac_reason[3],
8370                             mac->mac_reason[4], mac->mac_reason[5]);
8371                         bwn_restart(mac, "DMA error");
8372                         BWN_UNLOCK(sc);
8373                         return;
8374                 }
8375                 if (merged & BWN_DMAINTR_NONFATALMASK) {
8376                         device_printf(sc->sc_dev,
8377                             "DMA error: %#x %#x %#x %#x %#x %#x\n",
8378                             mac->mac_reason[0], mac->mac_reason[1],
8379                             mac->mac_reason[2], mac->mac_reason[3],
8380                             mac->mac_reason[4], mac->mac_reason[5]);
8381                 }
8382         }
8383
8384         if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8385                 bwn_intr_ucode_debug(mac);
8386         if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8387                 bwn_intr_tbtt_indication(mac);
8388         if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8389                 bwn_intr_atim_end(mac);
8390         if (mac->mac_reason_intr & BWN_INTR_BEACON)
8391                 bwn_intr_beacon(mac);
8392         if (mac->mac_reason_intr & BWN_INTR_PMQ)
8393                 bwn_intr_pmq(mac);
8394         if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8395                 bwn_intr_noise(mac);
8396
8397         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
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 (mbufq_first(&sc->sc_snd) != NULL)
8439                 bwn_start(sc);
8440
8441         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8442         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8443
8444         BWN_UNLOCK(sc);
8445 }
8446
8447 static void
8448 bwn_restart(struct bwn_mac *mac, const char *msg)
8449 {
8450         struct bwn_softc *sc = mac->mac_sc;
8451         struct ieee80211com *ic = &sc->sc_ic;
8452
8453         if (mac->mac_status < BWN_MAC_STATUS_INITED)
8454                 return;
8455
8456         device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8457         ieee80211_runtask(ic, &mac->mac_hwreset);
8458 }
8459
8460 static void
8461 bwn_intr_ucode_debug(struct bwn_mac *mac)
8462 {
8463         struct bwn_softc *sc = mac->mac_sc;
8464         uint16_t reason;
8465
8466         if (mac->mac_fw.opensource == 0)
8467                 return;
8468
8469         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8470         switch (reason) {
8471         case BWN_DEBUGINTR_PANIC:
8472                 bwn_handle_fwpanic(mac);
8473                 break;
8474         case BWN_DEBUGINTR_DUMP_SHM:
8475                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8476                 break;
8477         case BWN_DEBUGINTR_DUMP_REGS:
8478                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8479                 break;
8480         case BWN_DEBUGINTR_MARKER:
8481                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8482                 break;
8483         default:
8484                 device_printf(sc->sc_dev,
8485                     "ucode debug unknown reason: %#x\n", reason);
8486         }
8487
8488         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8489             BWN_DEBUGINTR_ACK);
8490 }
8491
8492 static void
8493 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8494 {
8495         struct bwn_softc *sc = mac->mac_sc;
8496         struct ieee80211com *ic = &sc->sc_ic;
8497
8498         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8499                 bwn_psctl(mac, 0);
8500         if (ic->ic_opmode == IEEE80211_M_IBSS)
8501                 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8502 }
8503
8504 static void
8505 bwn_intr_atim_end(struct bwn_mac *mac)
8506 {
8507
8508         if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8509                 BWN_WRITE_4(mac, BWN_MACCMD,
8510                     BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8511                 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8512         }
8513 }
8514
8515 static void
8516 bwn_intr_beacon(struct bwn_mac *mac)
8517 {
8518         struct bwn_softc *sc = mac->mac_sc;
8519         struct ieee80211com *ic = &sc->sc_ic;
8520         uint32_t cmd, beacon0, beacon1;
8521
8522         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8523             ic->ic_opmode == IEEE80211_M_MBSS)
8524                 return;
8525
8526         mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8527
8528         cmd = BWN_READ_4(mac, BWN_MACCMD);
8529         beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8530         beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8531
8532         if (beacon0 && beacon1) {
8533                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8534                 mac->mac_intr_mask |= BWN_INTR_BEACON;
8535                 return;
8536         }
8537
8538         if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8539                 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8540                 bwn_load_beacon0(mac);
8541                 bwn_load_beacon1(mac);
8542                 cmd = BWN_READ_4(mac, BWN_MACCMD);
8543                 cmd |= BWN_MACCMD_BEACON0_VALID;
8544                 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8545         } else {
8546                 if (!beacon0) {
8547                         bwn_load_beacon0(mac);
8548                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8549                         cmd |= BWN_MACCMD_BEACON0_VALID;
8550                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8551                 } else if (!beacon1) {
8552                         bwn_load_beacon1(mac);
8553                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8554                         cmd |= BWN_MACCMD_BEACON1_VALID;
8555                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8556                 }
8557         }
8558 }
8559
8560 static void
8561 bwn_intr_pmq(struct bwn_mac *mac)
8562 {
8563         uint32_t tmp;
8564
8565         while (1) {
8566                 tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8567                 if (!(tmp & 0x00000008))
8568                         break;
8569         }
8570         BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8571 }
8572
8573 static void
8574 bwn_intr_noise(struct bwn_mac *mac)
8575 {
8576         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8577         uint16_t tmp;
8578         uint8_t noise[4];
8579         uint8_t i, j;
8580         int32_t average;
8581
8582         if (mac->mac_phy.type != BWN_PHYTYPE_G)
8583                 return;
8584
8585         KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8586         *((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8587         if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8588             noise[3] == 0x7f)
8589                 goto new;
8590
8591         KASSERT(mac->mac_noise.noi_nsamples < 8,
8592             ("%s:%d: fail", __func__, __LINE__));
8593         i = mac->mac_noise.noi_nsamples;
8594         noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8595         noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8596         noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8597         noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8598         mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8599         mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8600         mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8601         mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8602         mac->mac_noise.noi_nsamples++;
8603         if (mac->mac_noise.noi_nsamples == 8) {
8604                 average = 0;
8605                 for (i = 0; i < 8; i++) {
8606                         for (j = 0; j < 4; j++)
8607                                 average += mac->mac_noise.noi_samples[i][j];
8608                 }
8609                 average = (((average / 32) * 125) + 64) / 128;
8610                 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8611                 if (tmp >= 8)
8612                         average += 2;
8613                 else
8614                         average -= 25;
8615                 average -= (tmp == 8) ? 72 : 48;
8616
8617                 mac->mac_stats.link_noise = average;
8618                 mac->mac_noise.noi_running = 0;
8619                 return;
8620         }
8621 new:
8622         bwn_noise_gensample(mac);
8623 }
8624
8625 static int
8626 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8627 {
8628         struct bwn_mac *mac = prq->prq_mac;
8629         struct bwn_softc *sc = mac->mac_sc;
8630         unsigned int i;
8631
8632         BWN_ASSERT_LOCKED(sc);
8633
8634         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8635                 return (0);
8636
8637         for (i = 0; i < 5000; i++) {
8638                 if (bwn_pio_rxeof(prq) == 0)
8639                         break;
8640         }
8641         if (i >= 5000)
8642                 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8643         return ((i > 0) ? 1 : 0);
8644 }
8645
8646 static void
8647 bwn_dma_rx(struct bwn_dma_ring *dr)
8648 {
8649         int slot, curslot;
8650
8651         KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8652         curslot = dr->get_curslot(dr);
8653         KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8654             ("%s:%d: fail", __func__, __LINE__));
8655
8656         slot = dr->dr_curslot;
8657         for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8658                 bwn_dma_rxeof(dr, &slot);
8659
8660         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8661             BUS_DMASYNC_PREWRITE);
8662
8663         dr->set_curslot(dr, slot);
8664         dr->dr_curslot = slot;
8665 }
8666
8667 static void
8668 bwn_intr_txeof(struct bwn_mac *mac)
8669 {
8670         struct bwn_txstatus stat;
8671         uint32_t stat0, stat1;
8672         uint16_t tmp;
8673
8674         BWN_ASSERT_LOCKED(mac->mac_sc);
8675
8676         while (1) {
8677                 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8678                 if (!(stat0 & 0x00000001))
8679                         break;
8680                 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8681
8682                 stat.cookie = (stat0 >> 16);
8683                 stat.seq = (stat1 & 0x0000ffff);
8684                 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8685                 tmp = (stat0 & 0x0000ffff);
8686                 stat.framecnt = ((tmp & 0xf000) >> 12);
8687                 stat.rtscnt = ((tmp & 0x0f00) >> 8);
8688                 stat.sreason = ((tmp & 0x001c) >> 2);
8689                 stat.pm = (tmp & 0x0080) ? 1 : 0;
8690                 stat.im = (tmp & 0x0040) ? 1 : 0;
8691                 stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8692                 stat.ack = (tmp & 0x0002) ? 1 : 0;
8693
8694                 bwn_handle_txeof(mac, &stat);
8695         }
8696 }
8697
8698 static void
8699 bwn_hwreset(void *arg, int npending)
8700 {
8701         struct bwn_mac *mac = arg;
8702         struct bwn_softc *sc = mac->mac_sc;
8703         int error = 0;
8704         int prev_status;
8705
8706         BWN_LOCK(sc);
8707
8708         prev_status = mac->mac_status;
8709         if (prev_status >= BWN_MAC_STATUS_STARTED)
8710                 bwn_core_stop(mac);
8711         if (prev_status >= BWN_MAC_STATUS_INITED)
8712                 bwn_core_exit(mac);
8713
8714         if (prev_status >= BWN_MAC_STATUS_INITED) {
8715                 error = bwn_core_init(mac);
8716                 if (error)
8717                         goto out;
8718         }
8719         if (prev_status >= BWN_MAC_STATUS_STARTED)
8720                 bwn_core_start(mac);
8721 out:
8722         if (error) {
8723                 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8724                 sc->sc_curmac = NULL;
8725         }
8726         BWN_UNLOCK(sc);
8727 }
8728
8729 static void
8730 bwn_handle_fwpanic(struct bwn_mac *mac)
8731 {
8732         struct bwn_softc *sc = mac->mac_sc;
8733         uint16_t reason;
8734
8735         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8736         device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8737
8738         if (reason == BWN_FWPANIC_RESTART)
8739                 bwn_restart(mac, "ucode panic");
8740 }
8741
8742 static void
8743 bwn_load_beacon0(struct bwn_mac *mac)
8744 {
8745
8746         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8747 }
8748
8749 static void
8750 bwn_load_beacon1(struct bwn_mac *mac)
8751 {
8752
8753         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8754 }
8755
8756 static uint32_t
8757 bwn_jssi_read(struct bwn_mac *mac)
8758 {
8759         uint32_t val = 0;
8760
8761         val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8762         val <<= 16;
8763         val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8764
8765         return (val);
8766 }
8767
8768 static void
8769 bwn_noise_gensample(struct bwn_mac *mac)
8770 {
8771         uint32_t jssi = 0x7f7f7f7f;
8772
8773         bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8774         bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8775         BWN_WRITE_4(mac, BWN_MACCMD,
8776             BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8777 }
8778
8779 static int
8780 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8781 {
8782         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8783
8784         return (dr->dr_numslots - dr->dr_usedslot);
8785 }
8786
8787 static int
8788 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8789 {
8790         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8791
8792         KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8793             ("%s:%d: fail", __func__, __LINE__));
8794         if (slot == dr->dr_numslots - 1)
8795                 return (0);
8796         return (slot + 1);
8797 }
8798
8799 static void
8800 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8801 {
8802         struct bwn_mac *mac = dr->dr_mac;
8803         struct bwn_softc *sc = mac->mac_sc;
8804         struct bwn_dma *dma = &mac->mac_method.dma;
8805         struct bwn_dmadesc_generic *desc;
8806         struct bwn_dmadesc_meta *meta;
8807         struct bwn_rxhdr4 *rxhdr;
8808         struct mbuf *m;
8809         uint32_t macstat;
8810         int32_t tmp;
8811         int cnt = 0;
8812         uint16_t len;
8813
8814         dr->getdesc(dr, *slot, &desc, &meta);
8815
8816         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8817         m = meta->mt_m;
8818
8819         if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8820                 counter_u64_add(sc->sc_ic.ic_ierrors, 1);
8821                 return;
8822         }
8823
8824         rxhdr = mtod(m, struct bwn_rxhdr4 *);
8825         len = le16toh(rxhdr->frame_len);
8826         if (len <= 0) {
8827                 counter_u64_add(sc->sc_ic.ic_ierrors, 1);
8828                 return;
8829         }
8830         if (bwn_dma_check_redzone(dr, m)) {
8831                 device_printf(sc->sc_dev, "redzone error.\n");
8832                 bwn_dma_set_redzone(dr, m);
8833                 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8834                     BUS_DMASYNC_PREWRITE);
8835                 return;
8836         }
8837         if (len > dr->dr_rx_bufsize) {
8838                 tmp = len;
8839                 while (1) {
8840                         dr->getdesc(dr, *slot, &desc, &meta);
8841                         bwn_dma_set_redzone(dr, meta->mt_m);
8842                         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8843                             BUS_DMASYNC_PREWRITE);
8844                         *slot = bwn_dma_nextslot(dr, *slot);
8845                         cnt++;
8846                         tmp -= dr->dr_rx_bufsize;
8847                         if (tmp <= 0)
8848                                 break;
8849                 }
8850                 device_printf(sc->sc_dev, "too small buffer "
8851                        "(len %u buffer %u dropped %d)\n",
8852                        len, dr->dr_rx_bufsize, cnt);
8853                 return;
8854         }
8855         macstat = le32toh(rxhdr->mac_status);
8856         if (macstat & BWN_RX_MAC_FCSERR) {
8857                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8858                         device_printf(sc->sc_dev, "RX drop\n");
8859                         return;
8860                 }
8861         }
8862
8863         m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8864         m_adj(m, dr->dr_frameoffset);
8865
8866         bwn_rxeof(dr->dr_mac, m, rxhdr);
8867 }
8868
8869 static void
8870 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8871 {
8872         struct bwn_dma_ring *dr;
8873         struct bwn_dmadesc_generic *desc;
8874         struct bwn_dmadesc_meta *meta;
8875         struct bwn_pio_txqueue *tq;
8876         struct bwn_pio_txpkt *tp = NULL;
8877         struct bwn_softc *sc = mac->mac_sc;
8878         struct bwn_stats *stats = &mac->mac_stats;
8879         struct ieee80211_node *ni;
8880         struct ieee80211vap *vap;
8881         int retrycnt = 0, slot;
8882
8883         BWN_ASSERT_LOCKED(mac->mac_sc);
8884
8885         if (status->im)
8886                 device_printf(sc->sc_dev, "TODO: STATUS IM\n");
8887         if (status->ampdu)
8888                 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
8889         if (status->rtscnt) {
8890                 if (status->rtscnt == 0xf)
8891                         stats->rtsfail++;
8892                 else
8893                         stats->rts++;
8894         }
8895
8896         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8897                 if (status->ack) {
8898                         dr = bwn_dma_parse_cookie(mac, status,
8899                             status->cookie, &slot);
8900                         if (dr == NULL) {
8901                                 device_printf(sc->sc_dev,
8902                                     "failed to parse cookie\n");
8903                                 return;
8904                         }
8905                         while (1) {
8906                                 dr->getdesc(dr, slot, &desc, &meta);
8907                                 if (meta->mt_islast) {
8908                                         ni = meta->mt_ni;
8909                                         vap = ni->ni_vap;
8910                                         ieee80211_ratectl_tx_complete(vap, ni,
8911                                             status->ack ?
8912                                               IEEE80211_RATECTL_TX_SUCCESS :
8913                                               IEEE80211_RATECTL_TX_FAILURE,
8914                                             &retrycnt, 0);
8915                                         break;
8916                                 }
8917                                 slot = bwn_dma_nextslot(dr, slot);
8918                         }
8919                 }
8920                 bwn_dma_handle_txeof(mac, status);
8921         } else {
8922                 if (status->ack) {
8923                         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
8924                         if (tq == NULL) {
8925                                 device_printf(sc->sc_dev,
8926                                     "failed to parse cookie\n");
8927                                 return;
8928                         }
8929                         ni = tp->tp_ni;
8930                         vap = ni->ni_vap;
8931                         ieee80211_ratectl_tx_complete(vap, ni,
8932                             status->ack ?
8933                               IEEE80211_RATECTL_TX_SUCCESS :
8934                               IEEE80211_RATECTL_TX_FAILURE,
8935                             &retrycnt, 0);
8936                 }
8937                 bwn_pio_handle_txeof(mac, status);
8938         }
8939
8940         bwn_phy_txpower_check(mac, 0);
8941 }
8942
8943 static uint8_t
8944 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
8945 {
8946         struct bwn_mac *mac = prq->prq_mac;
8947         struct bwn_softc *sc = mac->mac_sc;
8948         struct bwn_rxhdr4 rxhdr;
8949         struct mbuf *m;
8950         uint32_t ctl32, macstat, v32;
8951         unsigned int i, padding;
8952         uint16_t ctl16, len, totlen, v16;
8953         unsigned char *mp;
8954         char *data;
8955
8956         memset(&rxhdr, 0, sizeof(rxhdr));
8957
8958         if (prq->prq_rev >= 8) {
8959                 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
8960                 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
8961                         return (0);
8962                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
8963                     BWN_PIO8_RXCTL_FRAMEREADY);
8964                 for (i = 0; i < 10; i++) {
8965                         ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
8966                         if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
8967                                 goto ready;
8968                         DELAY(10);
8969                 }
8970         } else {
8971                 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
8972                 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
8973                         return (0);
8974                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
8975                     BWN_PIO_RXCTL_FRAMEREADY);
8976                 for (i = 0; i < 10; i++) {
8977                         ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
8978                         if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
8979                                 goto ready;
8980                         DELAY(10);
8981                 }
8982         }
8983         device_printf(sc->sc_dev, "%s: timed out\n", __func__);
8984         return (1);
8985 ready:
8986         if (prq->prq_rev >= 8)
8987                 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
8988                     prq->prq_base + BWN_PIO8_RXDATA);
8989         else
8990                 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
8991                     prq->prq_base + BWN_PIO_RXDATA);
8992         len = le16toh(rxhdr.frame_len);
8993         if (len > 0x700) {
8994                 device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
8995                 goto error;
8996         }
8997         if (len == 0) {
8998                 device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
8999                 goto error;
9000         }
9001
9002         macstat = le32toh(rxhdr.mac_status);
9003         if (macstat & BWN_RX_MAC_FCSERR) {
9004                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9005                         device_printf(sc->sc_dev, "%s: FCS error", __func__);
9006                         goto error;
9007                 }
9008         }
9009
9010         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9011         totlen = len + padding;
9012         KASSERT(totlen <= MCLBYTES, ("too big..\n"));
9013         m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9014         if (m == NULL) {
9015                 device_printf(sc->sc_dev, "%s: out of memory", __func__);
9016                 goto error;
9017         }
9018         mp = mtod(m, unsigned char *);
9019         if (prq->prq_rev >= 8) {
9020                 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3),
9021                     prq->prq_base + BWN_PIO8_RXDATA);
9022                 if (totlen & 3) {
9023                         v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9024                         data = &(mp[totlen - 1]);
9025                         switch (totlen & 3) {
9026                         case 3:
9027                                 *data = (v32 >> 16);
9028                                 data--;
9029                         case 2:
9030                                 *data = (v32 >> 8);
9031                                 data--;
9032                         case 1:
9033                                 *data = v32;
9034                         }
9035                 }
9036         } else {
9037                 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1),
9038                     prq->prq_base + BWN_PIO_RXDATA);
9039                 if (totlen & 1) {
9040                         v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9041                         mp[totlen - 1] = v16;
9042                 }
9043         }
9044
9045         m->m_len = m->m_pkthdr.len = totlen;
9046
9047         bwn_rxeof(prq->prq_mac, m, &rxhdr);
9048
9049         return (1);
9050 error:
9051         if (prq->prq_rev >= 8)
9052                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9053                     BWN_PIO8_RXCTL_DATAREADY);
9054         else
9055                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9056         return (1);
9057 }
9058
9059 static int
9060 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9061     struct bwn_dmadesc_meta *meta, int init)
9062 {
9063         struct bwn_mac *mac = dr->dr_mac;
9064         struct bwn_dma *dma = &mac->mac_method.dma;
9065         struct bwn_rxhdr4 *hdr;
9066         bus_dmamap_t map;
9067         bus_addr_t paddr;
9068         struct mbuf *m;
9069         int error;
9070
9071         m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9072         if (m == NULL) {
9073                 error = ENOBUFS;
9074
9075                 /*
9076                  * If the NIC is up and running, we need to:
9077                  * - Clear RX buffer's header.
9078                  * - Restore RX descriptor settings.
9079                  */
9080                 if (init)
9081                         return (error);
9082                 else
9083                         goto back;
9084         }
9085         m->m_len = m->m_pkthdr.len = MCLBYTES;
9086
9087         bwn_dma_set_redzone(dr, m);
9088
9089         /*
9090          * Try to load RX buf into temporary DMA map
9091          */
9092         error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9093             bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9094         if (error) {
9095                 m_freem(m);
9096
9097                 /*
9098                  * See the comment above
9099                  */
9100                 if (init)
9101                         return (error);
9102                 else
9103                         goto back;
9104         }
9105
9106         if (!init)
9107                 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9108         meta->mt_m = m;
9109         meta->mt_paddr = paddr;
9110
9111         /*
9112          * Swap RX buf's DMA map with the loaded temporary one
9113          */
9114         map = meta->mt_dmap;
9115         meta->mt_dmap = dr->dr_spare_dmap;
9116         dr->dr_spare_dmap = map;
9117
9118 back:
9119         /*
9120          * Clear RX buf header
9121          */
9122         hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9123         bzero(hdr, sizeof(*hdr));
9124         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9125             BUS_DMASYNC_PREWRITE);
9126
9127         /*
9128          * Setup RX buf descriptor
9129          */
9130         dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len -
9131             sizeof(*hdr), 0, 0, 0);
9132         return (error);
9133 }
9134
9135 static void
9136 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9137                  bus_size_t mapsz __unused, int error)
9138 {
9139
9140         if (!error) {
9141                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9142                 *((bus_addr_t *)arg) = seg->ds_addr;
9143         }
9144 }
9145
9146 static int
9147 bwn_hwrate2ieeerate(int rate)
9148 {
9149
9150         switch (rate) {
9151         case BWN_CCK_RATE_1MB:
9152                 return (2);
9153         case BWN_CCK_RATE_2MB:
9154                 return (4);
9155         case BWN_CCK_RATE_5MB:
9156                 return (11);
9157         case BWN_CCK_RATE_11MB:
9158                 return (22);
9159         case BWN_OFDM_RATE_6MB:
9160                 return (12);
9161         case BWN_OFDM_RATE_9MB:
9162                 return (18);
9163         case BWN_OFDM_RATE_12MB:
9164                 return (24);
9165         case BWN_OFDM_RATE_18MB:
9166                 return (36);
9167         case BWN_OFDM_RATE_24MB:
9168                 return (48);
9169         case BWN_OFDM_RATE_36MB:
9170                 return (72);
9171         case BWN_OFDM_RATE_48MB:
9172                 return (96);
9173         case BWN_OFDM_RATE_54MB:
9174                 return (108);
9175         default:
9176                 printf("Ooops\n");
9177                 return (0);
9178         }
9179 }
9180
9181 static void
9182 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9183 {
9184         const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9185         struct bwn_plcp6 *plcp;
9186         struct bwn_softc *sc = mac->mac_sc;
9187         struct ieee80211_frame_min *wh;
9188         struct ieee80211_node *ni;
9189         struct ieee80211com *ic = &sc->sc_ic;
9190         uint32_t macstat;
9191         int padding, rate, rssi = 0, noise = 0, type;
9192         uint16_t phytype, phystat0, phystat3, chanstat;
9193         unsigned char *mp = mtod(m, unsigned char *);
9194         static int rx_mac_dec_rpt = 0;
9195
9196         BWN_ASSERT_LOCKED(sc);
9197
9198         phystat0 = le16toh(rxhdr->phy_status0);
9199         phystat3 = le16toh(rxhdr->phy_status3);
9200         macstat = le32toh(rxhdr->mac_status);
9201         chanstat = le16toh(rxhdr->channel);
9202         phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9203
9204         if (macstat & BWN_RX_MAC_FCSERR)
9205                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9206         if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9207                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9208         if (macstat & BWN_RX_MAC_DECERR)
9209                 goto drop;
9210
9211         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9212         if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9213                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9214                     m->m_pkthdr.len);
9215                 goto drop;
9216         }
9217         plcp = (struct bwn_plcp6 *)(mp + padding);
9218         m_adj(m, sizeof(struct bwn_plcp6) + padding);
9219         if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9220                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9221                     m->m_pkthdr.len);
9222                 goto drop;
9223         }
9224         wh = mtod(m, struct ieee80211_frame_min *);
9225
9226         if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9227                 device_printf(sc->sc_dev,
9228                     "RX decryption attempted (old %d keyidx %#x)\n",
9229                     BWN_ISOLDFMT(mac),
9230                     (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9231
9232         /* XXX calculating RSSI & noise & antenna */
9233
9234         if (phystat0 & BWN_RX_PHYST0_OFDM)
9235                 rate = bwn_plcp_get_ofdmrate(mac, plcp,
9236                     phytype == BWN_PHYTYPE_A);
9237         else
9238                 rate = bwn_plcp_get_cckrate(mac, plcp);
9239         if (rate == -1) {
9240                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9241                         goto drop;
9242         }
9243         sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9244
9245         /* RX radio tap */
9246         if (ieee80211_radiotap_active(ic))
9247                 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9248         m_adj(m, -IEEE80211_CRC_LEN);
9249
9250         rssi = rxhdr->phy.abg.rssi;     /* XXX incorrect RSSI calculation? */
9251         noise = mac->mac_stats.link_noise;
9252
9253         BWN_UNLOCK(sc);
9254
9255         ni = ieee80211_find_rxnode(ic, wh);
9256         if (ni != NULL) {
9257                 type = ieee80211_input(ni, m, rssi, noise);
9258                 ieee80211_free_node(ni);
9259         } else
9260                 type = ieee80211_input_all(ic, m, rssi, noise);
9261
9262         BWN_LOCK(sc);
9263         return;
9264 drop:
9265         device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9266 }
9267
9268 static void
9269 bwn_dma_handle_txeof(struct bwn_mac *mac,
9270     const struct bwn_txstatus *status)
9271 {
9272         struct bwn_dma *dma = &mac->mac_method.dma;
9273         struct bwn_dma_ring *dr;
9274         struct bwn_dmadesc_generic *desc;
9275         struct bwn_dmadesc_meta *meta;
9276         struct bwn_softc *sc = mac->mac_sc;
9277         int slot;
9278
9279         BWN_ASSERT_LOCKED(sc);
9280
9281         dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9282         if (dr == NULL) {
9283                 device_printf(sc->sc_dev, "failed to parse cookie\n");
9284                 return;
9285         }
9286         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9287
9288         while (1) {
9289                 KASSERT(slot >= 0 && slot < dr->dr_numslots,
9290                     ("%s:%d: fail", __func__, __LINE__));
9291                 dr->getdesc(dr, slot, &desc, &meta);
9292
9293                 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
9294                         bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
9295                 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
9296                         bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9297
9298                 if (meta->mt_islast) {
9299                         KASSERT(meta->mt_m != NULL,
9300                             ("%s:%d: fail", __func__, __LINE__));
9301
9302                         ieee80211_tx_complete(meta->mt_ni, meta->mt_m, 0);
9303                         meta->mt_ni = NULL;
9304                         meta->mt_m = NULL;
9305                 } else
9306                         KASSERT(meta->mt_m == NULL,
9307                             ("%s:%d: fail", __func__, __LINE__));
9308
9309                 dr->dr_usedslot--;
9310                 if (meta->mt_islast)
9311                         break;
9312                 slot = bwn_dma_nextslot(dr, slot);
9313         }
9314         sc->sc_watchdog_timer = 0;
9315         if (dr->dr_stop) {
9316                 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9317                     ("%s:%d: fail", __func__, __LINE__));
9318                 dr->dr_stop = 0;
9319         }
9320 }
9321
9322 static void
9323 bwn_pio_handle_txeof(struct bwn_mac *mac,
9324     const struct bwn_txstatus *status)
9325 {
9326         struct bwn_pio_txqueue *tq;
9327         struct bwn_pio_txpkt *tp = NULL;
9328         struct bwn_softc *sc = mac->mac_sc;
9329
9330         BWN_ASSERT_LOCKED(sc);
9331
9332         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9333         if (tq == NULL)
9334                 return;
9335
9336         tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9337         tq->tq_free++;
9338
9339         if (tp->tp_ni != NULL) {
9340                 /*
9341                  * Do any tx complete callback.  Note this must
9342                  * be done before releasing the node reference.
9343                  */
9344                 if (tp->tp_m->m_flags & M_TXCB)
9345                         ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9346                 ieee80211_free_node(tp->tp_ni);
9347                 tp->tp_ni = NULL;
9348         }
9349         m_freem(tp->tp_m);
9350         tp->tp_m = NULL;
9351         TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9352
9353         sc->sc_watchdog_timer = 0;
9354 }
9355
9356 static void
9357 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9358 {
9359         struct bwn_softc *sc = mac->mac_sc;
9360         struct bwn_phy *phy = &mac->mac_phy;
9361         struct ieee80211com *ic = &sc->sc_ic;
9362         unsigned long now;
9363         int result;
9364
9365         BWN_GETTIME(now);
9366
9367         if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9368                 return;
9369         phy->nexttime = now + 2 * 1000;
9370
9371         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9372             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9373                 return;
9374
9375         if (phy->recalc_txpwr != NULL) {
9376                 result = phy->recalc_txpwr(mac,
9377                     (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9378                 if (result == BWN_TXPWR_RES_DONE)
9379                         return;
9380                 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9381                     ("%s: fail", __func__));
9382                 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9383
9384                 ieee80211_runtask(ic, &mac->mac_txpower);
9385         }
9386 }
9387
9388 static uint16_t
9389 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9390 {
9391
9392         return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9393 }
9394
9395 static uint32_t
9396 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9397 {
9398
9399         return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9400 }
9401
9402 static void
9403 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9404 {
9405
9406         BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9407 }
9408
9409 static void
9410 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9411 {
9412
9413         BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9414 }
9415
9416 static int
9417 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9418 {
9419
9420         switch (rate) {
9421         /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9422         case 12:
9423                 return (BWN_OFDM_RATE_6MB);
9424         case 18:
9425                 return (BWN_OFDM_RATE_9MB);
9426         case 24:
9427                 return (BWN_OFDM_RATE_12MB);
9428         case 36:
9429                 return (BWN_OFDM_RATE_18MB);
9430         case 48:
9431                 return (BWN_OFDM_RATE_24MB);
9432         case 72:
9433                 return (BWN_OFDM_RATE_36MB);
9434         case 96:
9435                 return (BWN_OFDM_RATE_48MB);
9436         case 108:
9437                 return (BWN_OFDM_RATE_54MB);
9438         /* CCK rates (NB: not IEEE std, device-specific) */
9439         case 2:
9440                 return (BWN_CCK_RATE_1MB);
9441         case 4:
9442                 return (BWN_CCK_RATE_2MB);
9443         case 11:
9444                 return (BWN_CCK_RATE_5MB);
9445         case 22:
9446                 return (BWN_CCK_RATE_11MB);
9447         }
9448
9449         device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9450         return (BWN_CCK_RATE_1MB);
9451 }
9452
9453 static int
9454 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9455     struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9456 {
9457         const struct bwn_phy *phy = &mac->mac_phy;
9458         struct bwn_softc *sc = mac->mac_sc;
9459         struct ieee80211_frame *wh;
9460         struct ieee80211_frame *protwh;
9461         struct ieee80211_frame_cts *cts;
9462         struct ieee80211_frame_rts *rts;
9463         const struct ieee80211_txparam *tp;
9464         struct ieee80211vap *vap = ni->ni_vap;
9465         struct ieee80211com *ic = &sc->sc_ic;
9466         struct mbuf *mprot;
9467         unsigned int len;
9468         uint32_t macctl = 0;
9469         int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9470         uint16_t phyctl = 0;
9471         uint8_t rate, rate_fb;
9472
9473         wh = mtod(m, struct ieee80211_frame *);
9474         memset(txhdr, 0, sizeof(*txhdr));
9475
9476         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9477         ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9478         isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9479
9480         /*
9481          * Find TX rate
9482          */
9483         tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9484         if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9485                 rate = rate_fb = tp->mgmtrate;
9486         else if (ismcast)
9487                 rate = rate_fb = tp->mcastrate;
9488         else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9489                 rate = rate_fb = tp->ucastrate;
9490         else {
9491                 rix = ieee80211_ratectl_rate(ni, NULL, 0);
9492                 rate = ni->ni_txrate;
9493
9494                 if (rix > 0)
9495                         rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9496                             IEEE80211_RATE_VAL;
9497                 else
9498                         rate_fb = rate;
9499         }
9500
9501         sc->sc_tx_rate = rate;
9502
9503         rate = bwn_ieeerate2hwrate(sc, rate);
9504         rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9505
9506         txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9507             bwn_plcp_getcck(rate);
9508         bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9509         bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9510
9511         if ((rate_fb == rate) ||
9512             (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9513             (*(u_int16_t *)wh->i_dur == htole16(0)))
9514                 txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9515         else
9516                 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9517                     m->m_pkthdr.len, rate, isshort);
9518
9519         /* XXX TX encryption */
9520         bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9521             (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9522             (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9523             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9524         bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9525             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9526
9527         txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9528             BWN_TX_EFT_FB_CCK;
9529         txhdr->chan = phy->chan;
9530         phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9531             BWN_TX_PHY_ENC_CCK;
9532         if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9533              rate == BWN_CCK_RATE_11MB))
9534                 phyctl |= BWN_TX_PHY_SHORTPRMBL;
9535
9536         /* XXX TX antenna selection */
9537
9538         switch (bwn_antenna_sanitize(mac, 0)) {
9539         case 0:
9540                 phyctl |= BWN_TX_PHY_ANT01AUTO;
9541                 break;
9542         case 1:
9543                 phyctl |= BWN_TX_PHY_ANT0;
9544                 break;
9545         case 2:
9546                 phyctl |= BWN_TX_PHY_ANT1;
9547                 break;
9548         case 3:
9549                 phyctl |= BWN_TX_PHY_ANT2;
9550                 break;
9551         case 4:
9552                 phyctl |= BWN_TX_PHY_ANT3;
9553                 break;
9554         default:
9555                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9556         }
9557
9558         if (!ismcast)
9559                 macctl |= BWN_TX_MAC_ACK;
9560
9561         macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9562         if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9563             m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9564                 macctl |= BWN_TX_MAC_LONGFRAME;
9565
9566         if (ic->ic_flags & IEEE80211_F_USEPROT) {
9567                 /* XXX RTS rate is always 1MB??? */
9568                 rts_rate = BWN_CCK_RATE_1MB;
9569                 rts_rate_fb = bwn_get_fbrate(rts_rate);
9570
9571                 protdur = ieee80211_compute_duration(ic->ic_rt,
9572                     m->m_pkthdr.len, rate, isshort) +
9573                     + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9574
9575                 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9576                         cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9577                             (txhdr->body.old.rts_frame) :
9578                             (txhdr->body.new.rts_frame));
9579                         mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9580                             protdur);
9581                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9582                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9583                             mprot->m_pkthdr.len);
9584                         m_freem(mprot);
9585                         macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9586                         len = sizeof(struct ieee80211_frame_cts);
9587                 } else {
9588                         rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9589                             (txhdr->body.old.rts_frame) :
9590                             (txhdr->body.new.rts_frame));
9591                         protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9592                             isshort);
9593                         mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9594                             wh->i_addr2, protdur);
9595                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9596                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9597                             mprot->m_pkthdr.len);
9598                         m_freem(mprot);
9599                         macctl |= BWN_TX_MAC_SEND_RTSCTS;
9600                         len = sizeof(struct ieee80211_frame_rts);
9601                 }
9602                 len += IEEE80211_CRC_LEN;
9603                 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9604                     &txhdr->body.old.rts_plcp :
9605                     &txhdr->body.new.rts_plcp), len, rts_rate);
9606                 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9607                     rts_rate_fb);
9608
9609                 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9610                     (&txhdr->body.old.rts_frame) :
9611                     (&txhdr->body.new.rts_frame));
9612                 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9613
9614                 if (BWN_ISOFDMRATE(rts_rate)) {
9615                         txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9616                         txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9617                 } else {
9618                         txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9619                         txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9620                 }
9621                 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9622                     BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9623         }
9624
9625         if (BWN_ISOLDFMT(mac))
9626                 txhdr->body.old.cookie = htole16(cookie);
9627         else
9628                 txhdr->body.new.cookie = htole16(cookie);
9629
9630         txhdr->macctl = htole32(macctl);
9631         txhdr->phyctl = htole16(phyctl);
9632
9633         /*
9634          * TX radio tap
9635          */
9636         if (ieee80211_radiotap_active_vap(vap)) {
9637                 sc->sc_tx_th.wt_flags = 0;
9638                 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
9639                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9640                 if (isshort &&
9641                     (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9642                      rate == BWN_CCK_RATE_11MB))
9643                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9644                 sc->sc_tx_th.wt_rate = rate;
9645
9646                 ieee80211_radiotap_tx(vap, m);
9647         }
9648
9649         return (0);
9650 }
9651
9652 static void
9653 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9654     const uint8_t rate)
9655 {
9656         uint32_t d, plen;
9657         uint8_t *raw = plcp->o.raw;
9658
9659         if (BWN_ISOFDMRATE(rate)) {
9660                 d = bwn_plcp_getofdm(rate);
9661                 KASSERT(!(octets & 0xf000),
9662                     ("%s:%d: fail", __func__, __LINE__));
9663                 d |= (octets << 5);
9664                 plcp->o.data = htole32(d);
9665         } else {
9666                 plen = octets * 16 / rate;
9667                 if ((octets * 16 % rate) > 0) {
9668                         plen++;
9669                         if ((rate == BWN_CCK_RATE_11MB)
9670                             && ((octets * 8 % 11) < 4)) {
9671                                 raw[1] = 0x84;
9672                         } else
9673                                 raw[1] = 0x04;
9674                 } else
9675                         raw[1] = 0x04;
9676                 plcp->o.data |= htole32(plen << 16);
9677                 raw[0] = bwn_plcp_getcck(rate);
9678         }
9679 }
9680
9681 static uint8_t
9682 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9683 {
9684         struct bwn_softc *sc = mac->mac_sc;
9685         uint8_t mask;
9686
9687         if (n == 0)
9688                 return (0);
9689         if (mac->mac_phy.gmode)
9690                 mask = siba_sprom_get_ant_bg(sc->sc_dev);
9691         else
9692                 mask = siba_sprom_get_ant_a(sc->sc_dev);
9693         if (!(mask & (1 << (n - 1))))
9694                 return (0);
9695         return (n);
9696 }
9697
9698 static uint8_t
9699 bwn_get_fbrate(uint8_t bitrate)
9700 {
9701         switch (bitrate) {
9702         case BWN_CCK_RATE_1MB:
9703                 return (BWN_CCK_RATE_1MB);
9704         case BWN_CCK_RATE_2MB:
9705                 return (BWN_CCK_RATE_1MB);
9706         case BWN_CCK_RATE_5MB:
9707                 return (BWN_CCK_RATE_2MB);
9708         case BWN_CCK_RATE_11MB:
9709                 return (BWN_CCK_RATE_5MB);
9710         case BWN_OFDM_RATE_6MB:
9711                 return (BWN_CCK_RATE_5MB);
9712         case BWN_OFDM_RATE_9MB:
9713                 return (BWN_OFDM_RATE_6MB);
9714         case BWN_OFDM_RATE_12MB:
9715                 return (BWN_OFDM_RATE_9MB);
9716         case BWN_OFDM_RATE_18MB:
9717                 return (BWN_OFDM_RATE_12MB);
9718         case BWN_OFDM_RATE_24MB:
9719                 return (BWN_OFDM_RATE_18MB);
9720         case BWN_OFDM_RATE_36MB:
9721                 return (BWN_OFDM_RATE_24MB);
9722         case BWN_OFDM_RATE_48MB:
9723                 return (BWN_OFDM_RATE_36MB);
9724         case BWN_OFDM_RATE_54MB:
9725                 return (BWN_OFDM_RATE_48MB);
9726         }
9727         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9728         return (0);
9729 }
9730
9731 static uint32_t
9732 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9733     uint32_t ctl, const void *_data, int len)
9734 {
9735         struct bwn_softc *sc = mac->mac_sc;
9736         uint32_t value = 0;
9737         const uint8_t *data = _data;
9738
9739         ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9740             BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9741         bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9742
9743         siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9744             tq->tq_base + BWN_PIO8_TXDATA);
9745         if (len & 3) {
9746                 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9747                     BWN_PIO8_TXCTL_24_31);
9748                 data = &(data[len - 1]);
9749                 switch (len & 3) {
9750                 case 3:
9751                         ctl |= BWN_PIO8_TXCTL_16_23;
9752                         value |= (uint32_t)(*data) << 16;
9753                         data--;
9754                 case 2:
9755                         ctl |= BWN_PIO8_TXCTL_8_15;
9756                         value |= (uint32_t)(*data) << 8;
9757                         data--;
9758                 case 1:
9759                         value |= (uint32_t)(*data);
9760                 }
9761                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9762                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9763         }
9764
9765         return (ctl);
9766 }
9767
9768 static void
9769 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9770     uint16_t offset, uint32_t value)
9771 {
9772
9773         BWN_WRITE_4(mac, tq->tq_base + offset, value);
9774 }
9775
9776 static uint16_t
9777 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9778     uint16_t ctl, const void *_data, int len)
9779 {
9780         struct bwn_softc *sc = mac->mac_sc;
9781         const uint8_t *data = _data;
9782
9783         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9784         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9785
9786         siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9787             tq->tq_base + BWN_PIO_TXDATA);
9788         if (len & 1) {
9789                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9790                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9791                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9792         }
9793
9794         return (ctl);
9795 }
9796
9797 static uint16_t
9798 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9799     uint16_t ctl, struct mbuf *m0)
9800 {
9801         int i, j = 0;
9802         uint16_t data = 0;
9803         const uint8_t *buf;
9804         struct mbuf *m = m0;
9805
9806         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9807         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9808
9809         for (; m != NULL; m = m->m_next) {
9810                 buf = mtod(m, const uint8_t *);
9811                 for (i = 0; i < m->m_len; i++) {
9812                         if (!((j++) % 2))
9813                                 data |= buf[i];
9814                         else {
9815                                 data |= (buf[i] << 8);
9816                                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9817                                 data = 0;
9818                         }
9819                 }
9820         }
9821         if (m0->m_pkthdr.len % 2) {
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);
9825         }
9826
9827         return (ctl);
9828 }
9829
9830 static void
9831 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9832 {
9833
9834         if (mac->mac_phy.type != BWN_PHYTYPE_G)
9835                 return;
9836         BWN_WRITE_2(mac, 0x684, 510 + time);
9837         bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9838 }
9839
9840 static struct bwn_dma_ring *
9841 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9842 {
9843
9844         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9845                 return (mac->mac_method.dma.wme[WME_AC_BE]);
9846
9847         switch (prio) {
9848         case 3:
9849                 return (mac->mac_method.dma.wme[WME_AC_VO]);
9850         case 2:
9851                 return (mac->mac_method.dma.wme[WME_AC_VI]);
9852         case 0:
9853                 return (mac->mac_method.dma.wme[WME_AC_BE]);
9854         case 1:
9855                 return (mac->mac_method.dma.wme[WME_AC_BK]);
9856         }
9857         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9858         return (NULL);
9859 }
9860
9861 static int
9862 bwn_dma_getslot(struct bwn_dma_ring *dr)
9863 {
9864         int slot;
9865
9866         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
9867
9868         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9869         KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
9870         KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
9871
9872         slot = bwn_dma_nextslot(dr, dr->dr_curslot);
9873         KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
9874         dr->dr_curslot = slot;
9875         dr->dr_usedslot++;
9876
9877         return (slot);
9878 }
9879
9880 static int
9881 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
9882 {
9883         const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
9884         unsigned int a, b, c, d;
9885         unsigned int avg;
9886         uint32_t tmp;
9887
9888         tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
9889         a = tmp & 0xff;
9890         b = (tmp >> 8) & 0xff;
9891         c = (tmp >> 16) & 0xff;
9892         d = (tmp >> 24) & 0xff;
9893         if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
9894             c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
9895                 return (ENOENT);
9896         bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
9897             BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
9898             (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
9899
9900         if (ofdm) {
9901                 a = (a + 32) & 0x3f;
9902                 b = (b + 32) & 0x3f;
9903                 c = (c + 32) & 0x3f;
9904                 d = (d + 32) & 0x3f;
9905         }
9906
9907         avg = (a + b + c + d + 2) / 4;
9908         if (ofdm) {
9909                 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
9910                     & BWN_HF_4DB_CCK_POWERBOOST)
9911                         avg = (avg >= 13) ? (avg - 13) : 0;
9912         }
9913         return (avg);
9914 }
9915
9916 static void
9917 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
9918 {
9919         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
9920         int rfatt = *rfattp;
9921         int bbatt = *bbattp;
9922
9923         while (1) {
9924                 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
9925                         break;
9926                 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
9927                         break;
9928                 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
9929                         break;
9930                 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
9931                         break;
9932                 if (bbatt > lo->bbatt.max) {
9933                         bbatt -= 4;
9934                         rfatt += 1;
9935                         continue;
9936                 }
9937                 if (bbatt < lo->bbatt.min) {
9938                         bbatt += 4;
9939                         rfatt -= 1;
9940                         continue;
9941                 }
9942                 if (rfatt > lo->rfatt.max) {
9943                         rfatt -= 1;
9944                         bbatt += 4;
9945                         continue;
9946                 }
9947                 if (rfatt < lo->rfatt.min) {
9948                         rfatt += 1;
9949                         bbatt -= 4;
9950                         continue;
9951                 }
9952                 break;
9953         }
9954
9955         *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
9956         *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
9957 }
9958
9959 static void
9960 bwn_phy_lock(struct bwn_mac *mac)
9961 {
9962         struct bwn_softc *sc = mac->mac_sc;
9963         struct ieee80211com *ic = &sc->sc_ic;
9964
9965         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
9966             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
9967
9968         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
9969                 bwn_psctl(mac, BWN_PS_AWAKE);
9970 }
9971
9972 static void
9973 bwn_phy_unlock(struct bwn_mac *mac)
9974 {
9975         struct bwn_softc *sc = mac->mac_sc;
9976         struct ieee80211com *ic = &sc->sc_ic;
9977
9978         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
9979             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
9980
9981         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
9982                 bwn_psctl(mac, 0);
9983 }
9984
9985 static void
9986 bwn_rf_lock(struct bwn_mac *mac)
9987 {
9988
9989         BWN_WRITE_4(mac, BWN_MACCTL,
9990             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
9991         BWN_READ_4(mac, BWN_MACCTL);
9992         DELAY(10);
9993 }
9994
9995 static void
9996 bwn_rf_unlock(struct bwn_mac *mac)
9997 {
9998
9999         BWN_READ_2(mac, BWN_PHYVER);
10000         BWN_WRITE_4(mac, BWN_MACCTL,
10001             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10002 }
10003
10004 static struct bwn_pio_txqueue *
10005 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10006     struct bwn_pio_txpkt **pack)
10007 {
10008         struct bwn_pio *pio = &mac->mac_method.pio;
10009         struct bwn_pio_txqueue *tq = NULL;
10010         unsigned int index;
10011
10012         switch (cookie & 0xf000) {
10013         case 0x1000:
10014                 tq = &pio->wme[WME_AC_BK];
10015                 break;
10016         case 0x2000:
10017                 tq = &pio->wme[WME_AC_BE];
10018                 break;
10019         case 0x3000:
10020                 tq = &pio->wme[WME_AC_VI];
10021                 break;
10022         case 0x4000:
10023                 tq = &pio->wme[WME_AC_VO];
10024                 break;
10025         case 0x5000:
10026                 tq = &pio->mcast;
10027                 break;
10028         }
10029         KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10030         if (tq == NULL)
10031                 return (NULL);
10032         index = (cookie & 0x0fff);
10033         KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10034         if (index >= N(tq->tq_pkts))
10035                 return (NULL);
10036         *pack = &tq->tq_pkts[index];
10037         KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10038         return (tq);
10039 }
10040
10041 static void
10042 bwn_txpwr(void *arg, int npending)
10043 {
10044         struct bwn_mac *mac = arg;
10045         struct bwn_softc *sc = mac->mac_sc;
10046
10047         BWN_LOCK(sc);
10048         if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10049             mac->mac_phy.set_txpwr != NULL)
10050                 mac->mac_phy.set_txpwr(mac);
10051         BWN_UNLOCK(sc);
10052 }
10053
10054 static void
10055 bwn_task_15s(struct bwn_mac *mac)
10056 {
10057         uint16_t reg;
10058
10059         if (mac->mac_fw.opensource) {
10060                 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10061                 if (reg) {
10062                         bwn_restart(mac, "fw watchdog");
10063                         return;
10064                 }
10065                 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10066         }
10067         if (mac->mac_phy.task_15s)
10068                 mac->mac_phy.task_15s(mac);
10069
10070         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10071 }
10072
10073 static void
10074 bwn_task_30s(struct bwn_mac *mac)
10075 {
10076
10077         if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10078                 return;
10079         mac->mac_noise.noi_running = 1;
10080         mac->mac_noise.noi_nsamples = 0;
10081
10082         bwn_noise_gensample(mac);
10083 }
10084
10085 static void
10086 bwn_task_60s(struct bwn_mac *mac)
10087 {
10088
10089         if (mac->mac_phy.task_60s)
10090                 mac->mac_phy.task_60s(mac);
10091         bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10092 }
10093
10094 static void
10095 bwn_tasks(void *arg)
10096 {
10097         struct bwn_mac *mac = arg;
10098         struct bwn_softc *sc = mac->mac_sc;
10099
10100         BWN_ASSERT_LOCKED(sc);
10101         if (mac->mac_status != BWN_MAC_STATUS_STARTED)
10102                 return;
10103
10104         if (mac->mac_task_state % 4 == 0)
10105                 bwn_task_60s(mac);
10106         if (mac->mac_task_state % 2 == 0)
10107                 bwn_task_30s(mac);
10108         bwn_task_15s(mac);
10109
10110         mac->mac_task_state++;
10111         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10112 }
10113
10114 static int
10115 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10116 {
10117         struct bwn_softc *sc = mac->mac_sc;
10118
10119         KASSERT(a == 0, ("not support APHY\n"));
10120
10121         switch (plcp->o.raw[0] & 0xf) {
10122         case 0xb:
10123                 return (BWN_OFDM_RATE_6MB);
10124         case 0xf:
10125                 return (BWN_OFDM_RATE_9MB);
10126         case 0xa:
10127                 return (BWN_OFDM_RATE_12MB);
10128         case 0xe:
10129                 return (BWN_OFDM_RATE_18MB);
10130         case 0x9:
10131                 return (BWN_OFDM_RATE_24MB);
10132         case 0xd:
10133                 return (BWN_OFDM_RATE_36MB);
10134         case 0x8:
10135                 return (BWN_OFDM_RATE_48MB);
10136         case 0xc:
10137                 return (BWN_OFDM_RATE_54MB);
10138         }
10139         device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10140             plcp->o.raw[0] & 0xf);
10141         return (-1);
10142 }
10143
10144 static int
10145 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10146 {
10147         struct bwn_softc *sc = mac->mac_sc;
10148
10149         switch (plcp->o.raw[0]) {
10150         case 0x0a:
10151                 return (BWN_CCK_RATE_1MB);
10152         case 0x14:
10153                 return (BWN_CCK_RATE_2MB);
10154         case 0x37:
10155                 return (BWN_CCK_RATE_5MB);
10156         case 0x6e:
10157                 return (BWN_CCK_RATE_11MB);
10158         }
10159         device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10160         return (-1);
10161 }
10162
10163 static void
10164 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10165     const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10166     int rssi, int noise)
10167 {
10168         struct bwn_softc *sc = mac->mac_sc;
10169         const struct ieee80211_frame_min *wh;
10170         uint64_t tsf;
10171         uint16_t low_mactime_now;
10172
10173         if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10174                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10175
10176         wh = mtod(m, const struct ieee80211_frame_min *);
10177         if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
10178                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10179
10180         bwn_tsf_read(mac, &tsf);
10181         low_mactime_now = tsf;
10182         tsf = tsf & ~0xffffULL;
10183         tsf += le16toh(rxhdr->mac_time);
10184         if (low_mactime_now < le16toh(rxhdr->mac_time))
10185                 tsf -= 0x10000;
10186
10187         sc->sc_rx_th.wr_tsf = tsf;
10188         sc->sc_rx_th.wr_rate = rate;
10189         sc->sc_rx_th.wr_antsignal = rssi;
10190         sc->sc_rx_th.wr_antnoise = noise;
10191 }
10192
10193 static void
10194 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10195 {
10196         uint32_t low, high;
10197
10198         KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10199             ("%s:%d: fail", __func__, __LINE__));
10200
10201         low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10202         high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10203         *tsf = high;
10204         *tsf <<= 32;
10205         *tsf |= low;
10206 }
10207
10208 static int
10209 bwn_dma_attach(struct bwn_mac *mac)
10210 {
10211         struct bwn_dma *dma = &mac->mac_method.dma;
10212         struct bwn_softc *sc = mac->mac_sc;
10213         bus_addr_t lowaddr = 0;
10214         int error;
10215
10216         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10217                 return (0);
10218
10219         KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10220
10221         mac->mac_flags |= BWN_MAC_FLAG_DMA;
10222
10223         dma->dmatype = bwn_dma_gettype(mac);
10224         if (dma->dmatype == BWN_DMA_30BIT)
10225                 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10226         else if (dma->dmatype == BWN_DMA_32BIT)
10227                 lowaddr = BUS_SPACE_MAXADDR_32BIT;
10228         else
10229                 lowaddr = BUS_SPACE_MAXADDR;
10230
10231         /*
10232          * Create top level DMA tag
10233          */
10234         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
10235                                BWN_ALIGN, 0,            /* alignment, bounds */
10236                                lowaddr,                 /* lowaddr */
10237                                BUS_SPACE_MAXADDR,       /* highaddr */
10238                                NULL, NULL,              /* filter, filterarg */
10239                                BUS_SPACE_MAXSIZE,       /* maxsize */
10240                                BUS_SPACE_UNRESTRICTED,  /* nsegments */
10241                                BUS_SPACE_MAXSIZE,       /* maxsegsize */
10242                                0,                       /* flags */
10243                                NULL, NULL,              /* lockfunc, lockarg */
10244                                &dma->parent_dtag);
10245         if (error) {
10246                 device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10247                 return (error);
10248         }
10249
10250         /*
10251          * Create TX/RX mbuf DMA tag
10252          */
10253         error = bus_dma_tag_create(dma->parent_dtag,
10254                                 1,
10255                                 0,
10256                                 BUS_SPACE_MAXADDR,
10257                                 BUS_SPACE_MAXADDR,
10258                                 NULL, NULL,
10259                                 MCLBYTES,
10260                                 1,
10261                                 BUS_SPACE_MAXSIZE_32BIT,
10262                                 0,
10263                                 NULL, NULL,
10264                                 &dma->rxbuf_dtag);
10265         if (error) {
10266                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10267                 goto fail0;
10268         }
10269         error = bus_dma_tag_create(dma->parent_dtag,
10270                                 1,
10271                                 0,
10272                                 BUS_SPACE_MAXADDR,
10273                                 BUS_SPACE_MAXADDR,
10274                                 NULL, NULL,
10275                                 MCLBYTES,
10276                                 1,
10277                                 BUS_SPACE_MAXSIZE_32BIT,
10278                                 0,
10279                                 NULL, NULL,
10280                                 &dma->txbuf_dtag);
10281         if (error) {
10282                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10283                 goto fail1;
10284         }
10285
10286         dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10287         if (!dma->wme[WME_AC_BK])
10288                 goto fail2;
10289
10290         dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10291         if (!dma->wme[WME_AC_BE])
10292                 goto fail3;
10293
10294         dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10295         if (!dma->wme[WME_AC_VI])
10296                 goto fail4;
10297
10298         dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10299         if (!dma->wme[WME_AC_VO])
10300                 goto fail5;
10301
10302         dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10303         if (!dma->mcast)
10304                 goto fail6;
10305         dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10306         if (!dma->rx)
10307                 goto fail7;
10308
10309         return (error);
10310
10311 fail7:  bwn_dma_ringfree(&dma->mcast);
10312 fail6:  bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10313 fail5:  bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10314 fail4:  bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10315 fail3:  bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10316 fail2:  bus_dma_tag_destroy(dma->txbuf_dtag);
10317 fail1:  bus_dma_tag_destroy(dma->rxbuf_dtag);
10318 fail0:  bus_dma_tag_destroy(dma->parent_dtag);
10319         return (error);
10320 }
10321
10322 static struct bwn_dma_ring *
10323 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10324     uint16_t cookie, int *slot)
10325 {
10326         struct bwn_dma *dma = &mac->mac_method.dma;
10327         struct bwn_dma_ring *dr;
10328         struct bwn_softc *sc = mac->mac_sc;
10329
10330         BWN_ASSERT_LOCKED(mac->mac_sc);
10331
10332         switch (cookie & 0xf000) {
10333         case 0x1000:
10334                 dr = dma->wme[WME_AC_BK];
10335                 break;
10336         case 0x2000:
10337                 dr = dma->wme[WME_AC_BE];
10338                 break;
10339         case 0x3000:
10340                 dr = dma->wme[WME_AC_VI];
10341                 break;
10342         case 0x4000:
10343                 dr = dma->wme[WME_AC_VO];
10344                 break;
10345         case 0x5000:
10346                 dr = dma->mcast;
10347                 break;
10348         default:
10349                 dr = NULL;
10350                 KASSERT(0 == 1,
10351                     ("invalid cookie value %d", cookie & 0xf000));
10352         }
10353         *slot = (cookie & 0x0fff);
10354         if (*slot < 0 || *slot >= dr->dr_numslots) {
10355                 /*
10356                  * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10357                  * that it occurs events which have same H/W sequence numbers.
10358                  * When it's occurred just prints a WARNING msgs and ignores.
10359                  */
10360                 KASSERT(status->seq == dma->lastseq,
10361                     ("%s:%d: fail", __func__, __LINE__));
10362                 device_printf(sc->sc_dev,
10363                     "out of slot ranges (0 < %d < %d)\n", *slot,
10364                     dr->dr_numslots);
10365                 return (NULL);
10366         }
10367         dma->lastseq = status->seq;
10368         return (dr);
10369 }
10370
10371 static void
10372 bwn_dma_stop(struct bwn_mac *mac)
10373 {
10374         struct bwn_dma *dma;
10375
10376         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10377                 return;
10378         dma = &mac->mac_method.dma;
10379
10380         bwn_dma_ringstop(&dma->rx);
10381         bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10382         bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10383         bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10384         bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10385         bwn_dma_ringstop(&dma->mcast);
10386 }
10387
10388 static void
10389 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10390 {
10391
10392         if (dr == NULL)
10393                 return;
10394
10395         bwn_dma_cleanup(*dr);
10396 }
10397
10398 static void
10399 bwn_pio_stop(struct bwn_mac *mac)
10400 {
10401         struct bwn_pio *pio;
10402
10403         if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10404                 return;
10405         pio = &mac->mac_method.pio;
10406
10407         bwn_destroy_queue_tx(&pio->mcast);
10408         bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10409         bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10410         bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10411         bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10412 }
10413
10414 static void
10415 bwn_led_attach(struct bwn_mac *mac)
10416 {
10417         struct bwn_softc *sc = mac->mac_sc;
10418         const uint8_t *led_act = NULL;
10419         uint16_t val[BWN_LED_MAX];
10420         int i;
10421
10422         sc->sc_led_idle = (2350 * hz) / 1000;
10423         sc->sc_led_blink = 1;
10424
10425         for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10426                 if (siba_get_pci_subvendor(sc->sc_dev) ==
10427                     bwn_vendor_led_act[i].vid) {
10428                         led_act = bwn_vendor_led_act[i].led_act;
10429                         break;
10430                 }
10431         }
10432         if (led_act == NULL)
10433                 led_act = bwn_default_led_act;
10434
10435         val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10436         val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10437         val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10438         val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10439
10440         for (i = 0; i < BWN_LED_MAX; ++i) {
10441                 struct bwn_led *led = &sc->sc_leds[i];
10442
10443                 if (val[i] == 0xff) {
10444                         led->led_act = led_act[i];
10445                 } else {
10446                         if (val[i] & BWN_LED_ACT_LOW)
10447                                 led->led_flags |= BWN_LED_F_ACTLOW;
10448                         led->led_act = val[i] & BWN_LED_ACT_MASK;
10449                 }
10450                 led->led_mask = (1 << i);
10451
10452                 if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10453                     led->led_act == BWN_LED_ACT_BLINK_POLL ||
10454                     led->led_act == BWN_LED_ACT_BLINK) {
10455                         led->led_flags |= BWN_LED_F_BLINK;
10456                         if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10457                                 led->led_flags |= BWN_LED_F_POLLABLE;
10458                         else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10459                                 led->led_flags |= BWN_LED_F_SLOW;
10460
10461                         if (sc->sc_blink_led == NULL) {
10462                                 sc->sc_blink_led = led;
10463                                 if (led->led_flags & BWN_LED_F_SLOW)
10464                                         BWN_LED_SLOWDOWN(sc->sc_led_idle);
10465                         }
10466                 }
10467
10468                 DPRINTF(sc, BWN_DEBUG_LED,
10469                     "%dth led, act %d, lowact %d\n", i,
10470                     led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10471         }
10472         callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
10473 }
10474
10475 static __inline uint16_t
10476 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10477 {
10478
10479         if (led->led_flags & BWN_LED_F_ACTLOW)
10480                 on = !on;
10481         if (on)
10482                 val |= led->led_mask;
10483         else
10484                 val &= ~led->led_mask;
10485         return val;
10486 }
10487
10488 static void
10489 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10490 {
10491         struct bwn_softc *sc = mac->mac_sc;
10492         struct ieee80211com *ic = &sc->sc_ic;
10493         uint16_t val;
10494         int i;
10495
10496         if (nstate == IEEE80211_S_INIT) {
10497                 callout_stop(&sc->sc_led_blink_ch);
10498                 sc->sc_led_blinking = 0;
10499         }
10500
10501         if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0)
10502                 return;
10503
10504         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10505         for (i = 0; i < BWN_LED_MAX; ++i) {
10506                 struct bwn_led *led = &sc->sc_leds[i];
10507                 int on;
10508
10509                 if (led->led_act == BWN_LED_ACT_UNKN ||
10510                     led->led_act == BWN_LED_ACT_NULL)
10511                         continue;
10512
10513                 if ((led->led_flags & BWN_LED_F_BLINK) &&
10514                     nstate != IEEE80211_S_INIT)
10515                         continue;
10516
10517                 switch (led->led_act) {
10518                 case BWN_LED_ACT_ON:    /* Always on */
10519                         on = 1;
10520                         break;
10521                 case BWN_LED_ACT_OFF:   /* Always off */
10522                 case BWN_LED_ACT_5GHZ:  /* TODO: 11A */
10523                         on = 0;
10524                         break;
10525                 default:
10526                         on = 1;
10527                         switch (nstate) {
10528                         case IEEE80211_S_INIT:
10529                                 on = 0;
10530                                 break;
10531                         case IEEE80211_S_RUN:
10532                                 if (led->led_act == BWN_LED_ACT_11G &&
10533                                     ic->ic_curmode != IEEE80211_MODE_11G)
10534                                         on = 0;
10535                                 break;
10536                         default:
10537                                 if (led->led_act == BWN_LED_ACT_ASSOC)
10538                                         on = 0;
10539                                 break;
10540                         }
10541                         break;
10542                 }
10543
10544                 val = bwn_led_onoff(led, val, on);
10545         }
10546         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10547 }
10548
10549 static void
10550 bwn_led_event(struct bwn_mac *mac, int event)
10551 {
10552         struct bwn_softc *sc = mac->mac_sc;
10553         struct bwn_led *led = sc->sc_blink_led;
10554         int rate;
10555
10556         if (event == BWN_LED_EVENT_POLL) {
10557                 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10558                         return;
10559                 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10560                         return;
10561         }
10562
10563         sc->sc_led_ticks = ticks;
10564         if (sc->sc_led_blinking)
10565                 return;
10566
10567         switch (event) {
10568         case BWN_LED_EVENT_RX:
10569                 rate = sc->sc_rx_rate;
10570                 break;
10571         case BWN_LED_EVENT_TX:
10572                 rate = sc->sc_tx_rate;
10573                 break;
10574         case BWN_LED_EVENT_POLL:
10575                 rate = 0;
10576                 break;
10577         default:
10578                 panic("unknown LED event %d\n", event);
10579                 break;
10580         }
10581         bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10582             bwn_led_duration[rate].off_dur);
10583 }
10584
10585 static void
10586 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10587 {
10588         struct bwn_softc *sc = mac->mac_sc;
10589         struct bwn_led *led = sc->sc_blink_led;
10590         uint16_t val;
10591
10592         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10593         val = bwn_led_onoff(led, val, 1);
10594         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10595
10596         if (led->led_flags & BWN_LED_F_SLOW) {
10597                 BWN_LED_SLOWDOWN(on_dur);
10598                 BWN_LED_SLOWDOWN(off_dur);
10599         }
10600
10601         sc->sc_led_blinking = 1;
10602         sc->sc_led_blink_offdur = off_dur;
10603
10604         callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10605 }
10606
10607 static void
10608 bwn_led_blink_next(void *arg)
10609 {
10610         struct bwn_mac *mac = arg;
10611         struct bwn_softc *sc = mac->mac_sc;
10612         uint16_t val;
10613
10614         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10615         val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10616         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10617
10618         callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10619             bwn_led_blink_end, mac);
10620 }
10621
10622 static void
10623 bwn_led_blink_end(void *arg)
10624 {
10625         struct bwn_mac *mac = arg;
10626         struct bwn_softc *sc = mac->mac_sc;
10627
10628         sc->sc_led_blinking = 0;
10629 }
10630
10631 static int
10632 bwn_suspend(device_t dev)
10633 {
10634         struct bwn_softc *sc = device_get_softc(dev);
10635
10636         BWN_LOCK(sc);
10637         bwn_stop(sc);
10638         BWN_UNLOCK(sc);
10639         return (0);
10640 }
10641
10642 static int
10643 bwn_resume(device_t dev)
10644 {
10645         struct bwn_softc *sc = device_get_softc(dev);
10646         int error = EDOOFUS;
10647
10648         BWN_LOCK(sc);
10649         if (sc->sc_ic.ic_nrunning > 0)
10650                 error = bwn_init(sc);
10651         BWN_UNLOCK(sc);
10652         if (error == 0)
10653                 ieee80211_start_all(&sc->sc_ic);
10654         return (0);
10655 }
10656
10657 static void
10658 bwn_rfswitch(void *arg)
10659 {
10660         struct bwn_softc *sc = arg;
10661         struct bwn_mac *mac = sc->sc_curmac;
10662         int cur = 0, prev = 0;
10663
10664         KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10665             ("%s: invalid MAC status %d", __func__, mac->mac_status));
10666
10667         if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10668                 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10669                         & BWN_RF_HWENABLED_HI_MASK))
10670                         cur = 1;
10671         } else {
10672                 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10673                     & BWN_RF_HWENABLED_LO_MASK)
10674                         cur = 1;
10675         }
10676
10677         if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10678                 prev = 1;
10679
10680         if (cur != prev) {
10681                 if (cur)
10682                         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10683                 else
10684                         mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10685
10686                 device_printf(sc->sc_dev,
10687                     "status of RF switch is changed to %s\n",
10688                     cur ? "ON" : "OFF");
10689                 if (cur != mac->mac_phy.rf_on) {
10690                         if (cur)
10691                                 bwn_rf_turnon(mac);
10692                         else
10693                                 bwn_rf_turnoff(mac);
10694                 }
10695         }
10696
10697         callout_schedule(&sc->sc_rfswitch_ch, hz);
10698 }
10699
10700 static void
10701 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10702 {
10703         struct bwn_phy *phy = &mac->mac_phy;
10704         struct bwn_phy_lp *plp = &phy->phy_lp;
10705
10706         plp->plp_antenna = BWN_ANT_DEFAULT;
10707 }
10708
10709 static int
10710 bwn_phy_lp_init(struct bwn_mac *mac)
10711 {
10712         static const struct bwn_stxtable tables[] = {
10713                 { 2,  6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10714                 { 1,  8, 0x50, 0, 0x7f }, { 0,  8, 0x44, 0, 0xff },
10715                 { 1,  0, 0x4a, 0, 0xff }, { 0,  4, 0x4d, 0, 0xff },
10716                 { 1,  4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10717                 { 1,  0, 0x4f, 4, 0x0f }, { 3,  0, 0x49, 0, 0x0f },
10718                 { 4,  3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10719                 { 4,  0, 0x46, 1, 0x07 }, { 3,  8, 0x48, 4, 0x07 },
10720                 { 3, 11, 0x48, 0, 0x0f }, { 3,  4, 0x49, 4, 0x0f },
10721                 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10722                 { 6,  0, 0x52, 7, 0x01 }, { 5,  3, 0x41, 5, 0x07 },
10723                 { 5,  6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10724                 { 4, 15, 0x42, 0, 0x01 }, { 5,  0, 0x42, 1, 0x07 },
10725                 { 4, 11, 0x43, 4, 0x0f }, { 4,  7, 0x43, 0, 0x0f },
10726                 { 4,  6, 0x45, 1, 0x01 }, { 2,  7, 0x40, 4, 0x0f },
10727                 { 2, 11, 0x40, 0, 0x0f }
10728         };
10729         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10730         struct bwn_softc *sc = mac->mac_sc;
10731         const struct bwn_stxtable *st;
10732         struct ieee80211com *ic = &sc->sc_ic;
10733         int i, error;
10734         uint16_t tmp;
10735
10736         bwn_phy_lp_readsprom(mac);      /* XXX bad place */
10737         bwn_phy_lp_bbinit(mac);
10738
10739         /* initialize RF */
10740         BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10741         DELAY(1);
10742         BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10743         DELAY(1);
10744
10745         if (mac->mac_phy.rf_ver == 0x2062)
10746                 bwn_phy_lp_b2062_init(mac);
10747         else {
10748                 bwn_phy_lp_b2063_init(mac);
10749
10750                 /* synchronize stx table. */
10751                 for (i = 0; i < N(tables); i++) {
10752                         st = &tables[i];
10753                         tmp = BWN_RF_READ(mac, st->st_rfaddr);
10754                         tmp >>= st->st_rfshift;
10755                         tmp <<= st->st_physhift;
10756                         BWN_PHY_SETMASK(mac,
10757                             BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10758                             ~(st->st_mask << st->st_physhift), tmp);
10759                 }
10760
10761                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10762                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10763         }
10764
10765         /* calibrate RC */
10766         if (mac->mac_phy.rev >= 2)
10767                 bwn_phy_lp_rxcal_r2(mac);
10768         else if (!plp->plp_rccap) {
10769                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10770                         bwn_phy_lp_rccal_r12(mac);
10771         } else
10772                 bwn_phy_lp_set_rccap(mac);
10773
10774         error = bwn_phy_lp_switch_channel(mac, 7);
10775         if (error)
10776                 device_printf(sc->sc_dev,
10777                     "failed to change channel 7 (%d)\n", error);
10778         bwn_phy_lp_txpctl_init(mac);
10779         bwn_phy_lp_calib(mac);
10780         return (0);
10781 }
10782
10783 static uint16_t
10784 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10785 {
10786
10787         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10788         return (BWN_READ_2(mac, BWN_PHYDATA));
10789 }
10790
10791 static void
10792 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10793 {
10794
10795         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10796         BWN_WRITE_2(mac, BWN_PHYDATA, value);
10797 }
10798
10799 static void
10800 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10801     uint16_t set)
10802 {
10803
10804         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10805         BWN_WRITE_2(mac, BWN_PHYDATA,
10806             (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10807 }
10808
10809 static uint16_t
10810 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10811 {
10812
10813         KASSERT(reg != 1, ("unaccessible register %d", reg));
10814         if (mac->mac_phy.rev < 2 && reg != 0x4001)
10815                 reg |= 0x100;
10816         if (mac->mac_phy.rev >= 2)
10817                 reg |= 0x200;
10818         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10819         return BWN_READ_2(mac, BWN_RFDATALO);
10820 }
10821
10822 static void
10823 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10824 {
10825
10826         KASSERT(reg != 1, ("unaccessible register %d", reg));
10827         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10828         BWN_WRITE_2(mac, BWN_RFDATALO, value);
10829 }
10830
10831 static void
10832 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10833 {
10834
10835         if (on) {
10836                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10837                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10838                     (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10839                 return;
10840         }
10841
10842         if (mac->mac_phy.rev >= 2) {
10843                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10844                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10845                 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10846                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10847                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
10848                 return;
10849         }
10850
10851         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
10852         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10853         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
10854         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
10855 }
10856
10857 static int
10858 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
10859 {
10860         struct bwn_phy *phy = &mac->mac_phy;
10861         struct bwn_phy_lp *plp = &phy->phy_lp;
10862         int error;
10863
10864         if (phy->rf_ver == 0x2063) {
10865                 error = bwn_phy_lp_b2063_switch_channel(mac, chan);
10866                 if (error)
10867                         return (error);
10868         } else {
10869                 error = bwn_phy_lp_b2062_switch_channel(mac, chan);
10870                 if (error)
10871                         return (error);
10872                 bwn_phy_lp_set_anafilter(mac, chan);
10873                 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
10874         }
10875
10876         plp->plp_chan = chan;
10877         BWN_WRITE_2(mac, BWN_CHANNEL, chan);
10878         return (0);
10879 }
10880
10881 static uint32_t
10882 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
10883 {
10884         struct bwn_softc *sc = mac->mac_sc;
10885         struct ieee80211com *ic = &sc->sc_ic;
10886
10887         return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
10888 }
10889
10890 static void
10891 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
10892 {
10893         struct bwn_phy *phy = &mac->mac_phy;
10894         struct bwn_phy_lp *plp = &phy->phy_lp;
10895
10896         if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
10897                 return;
10898
10899         bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
10900         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
10901         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
10902         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
10903         plp->plp_antenna = antenna;
10904 }
10905
10906 static void
10907 bwn_phy_lp_task_60s(struct bwn_mac *mac)
10908 {
10909
10910         bwn_phy_lp_calib(mac);
10911 }
10912
10913 static void
10914 bwn_phy_lp_readsprom(struct bwn_mac *mac)
10915 {
10916         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10917         struct bwn_softc *sc = mac->mac_sc;
10918         struct ieee80211com *ic = &sc->sc_ic;
10919
10920         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
10921                 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
10922                 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
10923                 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
10924                 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
10925                 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
10926                 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
10927                 return;
10928         }
10929
10930         plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
10931         plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
10932         plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
10933         plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
10934         plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
10935         plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
10936         plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
10937         plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
10938 }
10939
10940 static void
10941 bwn_phy_lp_bbinit(struct bwn_mac *mac)
10942 {
10943
10944         bwn_phy_lp_tblinit(mac);
10945         if (mac->mac_phy.rev >= 2)
10946                 bwn_phy_lp_bbinit_r2(mac);
10947         else
10948                 bwn_phy_lp_bbinit_r01(mac);
10949 }
10950
10951 static void
10952 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
10953 {
10954         struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
10955         struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
10956         struct bwn_softc *sc = mac->mac_sc;
10957         struct ieee80211com *ic = &sc->sc_ic;
10958
10959         bwn_phy_lp_set_txgain(mac,
10960             IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
10961         bwn_phy_lp_set_bbmult(mac, 150);
10962 }
10963
10964 static void
10965 bwn_phy_lp_calib(struct bwn_mac *mac)
10966 {
10967         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10968         struct bwn_softc *sc = mac->mac_sc;
10969         struct ieee80211com *ic = &sc->sc_ic;
10970         const struct bwn_rxcompco *rc = NULL;
10971         struct bwn_txgain ogain;
10972         int i, omode, oafeovr, orf, obbmult;
10973         uint8_t mode, fc = 0;
10974
10975         if (plp->plp_chanfullcal != plp->plp_chan) {
10976                 plp->plp_chanfullcal = plp->plp_chan;
10977                 fc = 1;
10978         }
10979
10980         bwn_mac_suspend(mac);
10981
10982         /* BlueTooth Coexistance Override */
10983         BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
10984         BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
10985
10986         if (mac->mac_phy.rev >= 2)
10987                 bwn_phy_lp_digflt_save(mac);
10988         bwn_phy_lp_get_txpctlmode(mac);
10989         mode = plp->plp_txpctlmode;
10990         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
10991         if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
10992                 bwn_phy_lp_bugfix(mac);
10993         if (mac->mac_phy.rev >= 2 && fc == 1) {
10994                 bwn_phy_lp_get_txpctlmode(mac);
10995                 omode = plp->plp_txpctlmode;
10996                 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
10997                 if (oafeovr)
10998                         ogain = bwn_phy_lp_get_txgain(mac);
10999                 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11000                 obbmult = bwn_phy_lp_get_bbmult(mac);
11001                 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11002                 if (oafeovr)
11003                         bwn_phy_lp_set_txgain(mac, &ogain);
11004                 bwn_phy_lp_set_bbmult(mac, obbmult);
11005                 bwn_phy_lp_set_txpctlmode(mac, omode);
11006                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11007         }
11008         bwn_phy_lp_set_txpctlmode(mac, mode);
11009         if (mac->mac_phy.rev >= 2)
11010                 bwn_phy_lp_digflt_restore(mac);
11011
11012         /* do RX IQ Calculation; assumes that noise is true. */
11013         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11014                 for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11015                         if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11016                                 rc = &bwn_rxcompco_5354[i];
11017                 }
11018         } else if (mac->mac_phy.rev >= 2)
11019                 rc = &bwn_rxcompco_r2;
11020         else {
11021                 for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11022                         if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11023                                 rc = &bwn_rxcompco_r12[i];
11024                 }
11025         }
11026         if (rc == NULL)
11027                 goto fail;
11028
11029         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11030         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11031
11032         bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11033
11034         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11035                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11036                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11037         } else {
11038                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11039                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11040         }
11041
11042         bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11043         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11044         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11045         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11046         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11047         bwn_phy_lp_set_deaf(mac, 0);
11048         /* XXX no checking return value? */
11049         (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11050         bwn_phy_lp_clear_deaf(mac, 0);
11051         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11052         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11053         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11054
11055         /* disable RX GAIN override. */
11056         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11057         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11058         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11059         if (mac->mac_phy.rev >= 2) {
11060                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11061                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11062                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11063                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11064                 }
11065         } else {
11066                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11067         }
11068
11069         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11070         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11071 fail:
11072         bwn_mac_enable(mac);
11073 }
11074
11075 static void
11076 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11077 {
11078
11079         if (on) {
11080                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11081                 return;
11082         }
11083
11084         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11085         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11086 }
11087
11088 static int
11089 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11090 {
11091         static const struct bwn_b206x_chan *bc = NULL;
11092         struct bwn_softc *sc = mac->mac_sc;
11093         uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11094             tmp[6];
11095         uint16_t old, scale, tmp16;
11096         int i, div;
11097
11098         for (i = 0; i < N(bwn_b2063_chantable); i++) {
11099                 if (bwn_b2063_chantable[i].bc_chan == chan) {
11100                         bc = &bwn_b2063_chantable[i];
11101                         break;
11102                 }
11103         }
11104         if (bc == NULL)
11105                 return (EINVAL);
11106
11107         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11108         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11109         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11110         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11111         BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11112         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11113         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11114         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11115         BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11116         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11117         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11118         BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11119
11120         old = BWN_RF_READ(mac, BWN_B2063_COM15);
11121         BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11122
11123         freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11124         freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11125         freqref = freqxtal * 3;
11126         div = (freqxtal <= 26000000 ? 1 : 2);
11127         timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11128         timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11129                 999999) / 1000000) + 1;
11130
11131         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11132         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11133             0xfff8, timeout >> 2);
11134         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11135             0xff9f,timeout << 5);
11136         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11137
11138         val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11139         val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11140         val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11141
11142         count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11143             (timeoutref + 1)) - 1;
11144         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11145             0xf0, count >> 8);
11146         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11147
11148         tmp[0] = ((val[2] * 62500) / freqref) << 4;
11149         tmp[1] = ((val[2] * 62500) % freqref) << 4;
11150         while (tmp[1] >= freqref) {
11151                 tmp[0]++;
11152                 tmp[1] -= freqref;
11153         }
11154         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11155         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11156         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11157         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11158         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11159
11160         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11161         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11162         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11163         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11164
11165         tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11166         tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11167
11168         if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11169                 scale = 1;
11170                 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11171         } else {
11172                 scale = 0;
11173                 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11174         }
11175         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11176         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11177
11178         tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11179             (scale + 1);
11180         if (tmp[5] > 150)
11181                 tmp[5] = 0;
11182
11183         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11184         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11185
11186         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11187         if (freqxtal > 26000000)
11188                 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11189         else
11190                 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11191
11192         if (val[0] == 45)
11193                 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11194         else
11195                 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11196
11197         BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11198         DELAY(1);
11199         BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11200
11201         /* VCO Calibration */
11202         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11203         tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11204         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11205         DELAY(1);
11206         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11207         DELAY(1);
11208         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11209         DELAY(1);
11210         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11211         DELAY(300);
11212         BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11213
11214         BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11215         return (0);
11216 }
11217
11218 static int
11219 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11220 {
11221         struct bwn_softc *sc = mac->mac_sc;
11222         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11223         const struct bwn_b206x_chan *bc = NULL;
11224         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11225         uint32_t tmp[9];
11226         int i;
11227
11228         for (i = 0; i < N(bwn_b2062_chantable); i++) {
11229                 if (bwn_b2062_chantable[i].bc_chan == chan) {
11230                         bc = &bwn_b2062_chantable[i];
11231                         break;
11232                 }
11233         }
11234
11235         if (bc == NULL)
11236                 return (EINVAL);
11237
11238         BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11239         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11240         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11241         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11242         BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11243         BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11244         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11245         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11246         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11247         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11248
11249         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11250         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11251         bwn_phy_lp_b2062_reset_pllbias(mac);
11252         tmp[0] = freqxtal / 1000;
11253         tmp[1] = plp->plp_div * 1000;
11254         tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11255         if (ieee80211_ieee2mhz(chan, 0) < 4000)
11256                 tmp[2] *= 2;
11257         tmp[3] = 48 * tmp[0];
11258         tmp[5] = tmp[2] / tmp[3];
11259         tmp[6] = tmp[2] % tmp[3];
11260         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11261         tmp[4] = tmp[6] * 0x100;
11262         tmp[5] = tmp[4] / tmp[3];
11263         tmp[6] = tmp[4] % tmp[3];
11264         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11265         tmp[4] = tmp[6] * 0x100;
11266         tmp[5] = tmp[4] / tmp[3];
11267         tmp[6] = tmp[4] % tmp[3];
11268         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11269         tmp[4] = tmp[6] * 0x100;
11270         tmp[5] = tmp[4] / tmp[3];
11271         tmp[6] = tmp[4] % tmp[3];
11272         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11273             tmp[5] + ((2 * tmp[6]) / tmp[3]));
11274         tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11275         tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11276         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11277         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11278
11279         bwn_phy_lp_b2062_vco_calib(mac);
11280         if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11281                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11282                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11283                 bwn_phy_lp_b2062_reset_pllbias(mac);
11284                 bwn_phy_lp_b2062_vco_calib(mac);
11285                 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11286                         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11287                         return (EIO);
11288                 }
11289         }
11290         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11291         return (0);
11292 }
11293
11294 static void
11295 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11296 {
11297         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11298         uint16_t tmp = (channel == 14);
11299
11300         if (mac->mac_phy.rev < 2) {
11301                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11302                 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11303                         bwn_phy_lp_set_rccap(mac);
11304                 return;
11305         }
11306
11307         BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11308 }
11309
11310 static void
11311 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11312 {
11313         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11314         struct bwn_softc *sc = mac->mac_sc;
11315         struct ieee80211com *ic = &sc->sc_ic;
11316         uint16_t iso, tmp[3];
11317
11318         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11319
11320         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11321                 iso = plp->plp_txisoband_m;
11322         else if (freq <= 5320)
11323                 iso = plp->plp_txisoband_l;
11324         else if (freq <= 5700)
11325                 iso = plp->plp_txisoband_m;
11326         else
11327                 iso = plp->plp_txisoband_h;
11328
11329         tmp[0] = ((iso - 26) / 12) << 12;
11330         tmp[1] = tmp[0] + 0x1000;
11331         tmp[2] = tmp[0] + 0x2000;
11332
11333         bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11334         bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11335 }
11336
11337 static void
11338 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11339 {
11340         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11341         int i;
11342         static const uint16_t addr[] = {
11343                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11344                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11345                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11346                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11347                 BWN_PHY_OFDM(0xcf),
11348         };
11349         static const uint16_t val[] = {
11350                 0xde5e, 0xe832, 0xe331, 0x4d26,
11351                 0x0026, 0x1420, 0x0020, 0xfe08,
11352                 0x0008,
11353         };
11354
11355         for (i = 0; i < N(addr); i++) {
11356                 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11357                 BWN_PHY_WRITE(mac, addr[i], val[i]);
11358         }
11359 }
11360
11361 static void
11362 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11363 {
11364         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11365         struct bwn_softc *sc = mac->mac_sc;
11366         uint16_t ctl;
11367
11368         ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11369         switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11370         case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11371                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11372                 break;
11373         case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11374                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11375                 break;
11376         case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11377                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11378                 break;
11379         default:
11380                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11381                 device_printf(sc->sc_dev, "unknown command mode\n");
11382                 break;
11383         }
11384 }
11385
11386 static void
11387 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11388 {
11389         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11390         uint16_t ctl;
11391         uint8_t old;
11392
11393         bwn_phy_lp_get_txpctlmode(mac);
11394         old = plp->plp_txpctlmode;
11395         if (old == mode)
11396                 return;
11397         plp->plp_txpctlmode = mode;
11398
11399         if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11400                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11401                     plp->plp_tssiidx);
11402                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11403                     0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11404
11405                 /* disable TX GAIN override */
11406                 if (mac->mac_phy.rev < 2)
11407                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11408                 else {
11409                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11410                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11411                 }
11412                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11413
11414                 plp->plp_txpwridx = -1;
11415         }
11416         if (mac->mac_phy.rev >= 2) {
11417                 if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11418                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11419                 else
11420                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11421         }
11422
11423         /* writes TX Power Control mode */
11424         switch (plp->plp_txpctlmode) {
11425         case BWN_PHYLP_TXPCTL_OFF:
11426                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11427                 break;
11428         case BWN_PHYLP_TXPCTL_ON_HW:
11429                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11430                 break;
11431         case BWN_PHYLP_TXPCTL_ON_SW:
11432                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11433                 break;
11434         default:
11435                 ctl = 0;
11436                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11437         }
11438         BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11439             (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11440 }
11441
11442 static void
11443 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11444 {
11445         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11446         struct bwn_softc *sc = mac->mac_sc;
11447         const unsigned int size = 256;
11448         struct bwn_txgain tg;
11449         uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11450         uint16_t tssinpt, tssiidx, value[2];
11451         uint8_t mode;
11452         int8_t txpwridx;
11453
11454         tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
11455             M_NOWAIT | M_ZERO);
11456         if (tabs == NULL) {
11457                 device_printf(sc->sc_dev, "failed to allocate buffer.\n");
11458                 return;
11459         }
11460
11461         bwn_phy_lp_get_txpctlmode(mac);
11462         mode = plp->plp_txpctlmode;
11463         txpwridx = plp->plp_txpwridx;
11464         tssinpt = plp->plp_tssinpt;
11465         tssiidx = plp->plp_tssiidx;
11466
11467         bwn_tab_read_multi(mac,
11468             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11469             BWN_TAB_4(7, 0x140), size, tabs);
11470
11471         bwn_phy_lp_tblinit(mac);
11472         bwn_phy_lp_bbinit(mac);
11473         bwn_phy_lp_txpctl_init(mac);
11474         bwn_phy_lp_rf_onoff(mac, 1);
11475         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11476
11477         bwn_tab_write_multi(mac,
11478             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11479             BWN_TAB_4(7, 0x140), size, tabs);
11480
11481         BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11482         plp->plp_tssinpt = tssinpt;
11483         plp->plp_tssiidx = tssiidx;
11484         bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11485         if (txpwridx != -1) {
11486                 /* set TX power by index */
11487                 plp->plp_txpwridx = txpwridx;
11488                 bwn_phy_lp_get_txpctlmode(mac);
11489                 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11490                         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11491                 if (mac->mac_phy.rev >= 2) {
11492                         rxcomp = bwn_tab_read(mac,
11493                             BWN_TAB_4(7, txpwridx + 320));
11494                         txgain = bwn_tab_read(mac,
11495                             BWN_TAB_4(7, txpwridx + 192));
11496                         tg.tg_pad = (txgain >> 16) & 0xff;
11497                         tg.tg_gm = txgain & 0xff;
11498                         tg.tg_pga = (txgain >> 8) & 0xff;
11499                         tg.tg_dac = (rxcomp >> 28) & 0xff;
11500                         bwn_phy_lp_set_txgain(mac, &tg);
11501                 } else {
11502                         rxcomp = bwn_tab_read(mac,
11503                             BWN_TAB_4(10, txpwridx + 320));
11504                         txgain = bwn_tab_read(mac,
11505                             BWN_TAB_4(10, txpwridx + 192));
11506                         BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11507                             0xf800, (txgain >> 4) & 0x7fff);
11508                         bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11509                         bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11510                 }
11511                 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11512
11513                 /* set TX IQCC */
11514                 value[0] = (rxcomp >> 10) & 0x3ff;
11515                 value[1] = rxcomp & 0x3ff;
11516                 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11517
11518                 coeff = bwn_tab_read(mac,
11519                     (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11520                     BWN_TAB_4(10, txpwridx + 448));
11521                 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11522                 if (mac->mac_phy.rev >= 2) {
11523                         rfpwr = bwn_tab_read(mac,
11524                             BWN_TAB_4(7, txpwridx + 576));
11525                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11526                             rfpwr & 0xffff);
11527                 }
11528                 bwn_phy_lp_set_txgain_override(mac);
11529         }
11530         if (plp->plp_rccap)
11531                 bwn_phy_lp_set_rccap(mac);
11532         bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11533         bwn_phy_lp_set_txpctlmode(mac, mode);
11534         free(tabs, M_DEVBUF);
11535 }
11536
11537 static void
11538 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11539 {
11540         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11541         int i;
11542         static const uint16_t addr[] = {
11543                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11544                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11545                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11546                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11547                 BWN_PHY_OFDM(0xcf),
11548         };
11549
11550         for (i = 0; i < N(addr); i++)
11551                 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11552 }
11553
11554 static void
11555 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11556 {
11557         uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11558
11559         if (mac->mac_phy.rev < 2) {
11560                 bwn_phy_lp_tblinit_r01(mac);
11561                 bwn_phy_lp_tblinit_txgain(mac);
11562                 bwn_phy_lp_set_gaintbl(mac, freq);
11563                 return;
11564         }
11565
11566         bwn_phy_lp_tblinit_r2(mac);
11567         bwn_phy_lp_tblinit_txgain(mac);
11568 }
11569
11570 struct bwn_wpair {
11571         uint16_t                reg;
11572         uint16_t                value;
11573 };
11574
11575 struct bwn_smpair {
11576         uint16_t                offset;
11577         uint16_t                mask;
11578         uint16_t                set;
11579 };
11580
11581 static void
11582 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11583 {
11584         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11585         struct bwn_softc *sc = mac->mac_sc;
11586         struct ieee80211com *ic = &sc->sc_ic;
11587         static const struct bwn_wpair v1[] = {
11588                 { BWN_PHY_AFE_DAC_CTL, 0x50 },
11589                 { BWN_PHY_AFE_CTL, 0x8800 },
11590                 { BWN_PHY_AFE_CTL_OVR, 0 },
11591                 { BWN_PHY_AFE_CTL_OVRVAL, 0 },
11592                 { BWN_PHY_RF_OVERRIDE_0, 0 },
11593                 { BWN_PHY_RF_OVERRIDE_2, 0 },
11594                 { BWN_PHY_OFDM(0xf9), 0 },
11595                 { BWN_PHY_TR_LOOKUP_1, 0 }
11596         };
11597         static const struct bwn_smpair v2[] = {
11598                 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11599                 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11600                 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11601                 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11602                 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11603         };
11604         static const struct bwn_smpair v3[] = {
11605                 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11606                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11607                 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11608                 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11609                 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11610                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11611                 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11612                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11613                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11614                 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11615
11616         };
11617         int i;
11618
11619         for (i = 0; i < N(v1); i++)
11620                 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11621         BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11622         for (i = 0; i < N(v2); i++)
11623                 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11624
11625         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11626         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11627         BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11628         if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11629                 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11630                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11631         } else {
11632                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11633         }
11634         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11635         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11636         BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11637         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11638         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11639         BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11640         BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11641         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11642         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11643         BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11644         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11645         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11646             (siba_get_chiprev(sc->sc_dev) == 0)) {
11647                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11648                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11649         } else {
11650                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11651                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11652         }
11653         for (i = 0; i < N(v3); i++)
11654                 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11655         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11656             (siba_get_chiprev(sc->sc_dev) == 0)) {
11657                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11658                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11659         }
11660
11661         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11662                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11663                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11664                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11665                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11666                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11667                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11668         } else
11669                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11670
11671         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11672         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11673         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11674         BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11675         BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11676         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11677         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11678             0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11679             ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11680
11681         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11682             (siba_get_chiprev(sc->sc_dev) == 0)) {
11683                 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11684                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11685                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11686         }
11687
11688         bwn_phy_lp_digflt_save(mac);
11689 }
11690
11691 static void
11692 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11693 {
11694         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11695         struct bwn_softc *sc = mac->mac_sc;
11696         struct ieee80211com *ic = &sc->sc_ic;
11697         static const struct bwn_smpair v1[] = {
11698                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11699                 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11700                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11701                 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11702                 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11703                 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11704                 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11705         };
11706         static const struct bwn_smpair v2[] = {
11707                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11708                 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11709                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11710                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11711                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11712                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11713                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11714                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11715                 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11716                 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11717                 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11718                 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11719                 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11720                 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11721                 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11722                 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11723         };
11724         static const struct bwn_smpair v3[] = {
11725                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11726                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11727                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11728                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11729                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11730                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11731                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11732                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11733         };
11734         static const struct bwn_smpair v4[] = {
11735                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11736                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11737                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11738                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11739                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11740                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11741                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11742                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11743         };
11744         static const struct bwn_smpair v5[] = {
11745                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11746                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11747                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11748                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11749                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11750                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11751                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11752                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11753         };
11754         int i;
11755         uint16_t tmp, tmp2;
11756
11757         BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11758         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11759         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11760         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11761         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11762         BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11763         BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11764         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11765         BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11766         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11767         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11768         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11769         BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11770         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11771         BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11772         for (i = 0; i < N(v1); i++)
11773                 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11774         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11775             0xff00, plp->plp_rxpwroffset);
11776         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11777             ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11778            (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11779                 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11780                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11781                 if (mac->mac_phy.rev == 0)
11782                         BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11783                             0xffcf, 0x0010);
11784                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11785         } else {
11786                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11787                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11788                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11789         }
11790         tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11791         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11792         if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11793                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11794         else
11795                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11796         bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11797         BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11798             0xfff9, (plp->plp_bxarch << 1));
11799         if (mac->mac_phy.rev == 1 &&
11800             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11801                 for (i = 0; i < N(v2); i++)
11802                         BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11803                             v2[i].set);
11804         } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11805             (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11806             ((mac->mac_phy.rev == 0) &&
11807              (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11808                 for (i = 0; i < N(v3); i++)
11809                         BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11810                             v3[i].set);
11811         } else if (mac->mac_phy.rev == 1 ||
11812                   (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11813                 for (i = 0; i < N(v4); i++)
11814                         BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11815                             v4[i].set);
11816         } else {
11817                 for (i = 0; i < N(v5); i++)
11818                         BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11819                             v5[i].set);
11820         }
11821         if (mac->mac_phy.rev == 1 &&
11822             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11823                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11824                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11825                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11826                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11827         }
11828         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11829             (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11830             (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11831                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11832                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11833                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11834                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11835         }
11836         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11837                 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11838                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11839                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11840                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11841                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11842                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
11843                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
11844                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11845         } else {
11846                 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
11847                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
11848         }
11849         if (mac->mac_phy.rev == 1) {
11850                 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
11851                 tmp2 = (tmp & 0x03e0) >> 5;
11852                 tmp2 |= tmp2 << 5;
11853                 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
11854                 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
11855                 tmp2 = (tmp & 0x1f00) >> 8;
11856                 tmp2 |= tmp2 << 5;
11857                 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
11858                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
11859                 tmp2 = tmp & 0x00ff;
11860                 tmp2 |= tmp << 8;
11861                 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
11862         }
11863 }
11864
11865 struct bwn_b2062_freq {
11866         uint16_t                freq;
11867         uint8_t                 value[6];
11868 };
11869
11870 static void
11871 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
11872 {
11873 #define CALC_CTL7(freq, div)                                            \
11874         (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
11875 #define CALC_CTL18(freq, div)                                           \
11876         ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
11877 #define CALC_CTL19(freq, div)                                           \
11878         ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
11879         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11880         struct bwn_softc *sc = mac->mac_sc;
11881         struct ieee80211com *ic = &sc->sc_ic;
11882         static const struct bwn_b2062_freq freqdata_tab[] = {
11883                 { 12000, { 6, 6, 6, 6, 10, 6 } },
11884                 { 13000, { 4, 4, 4, 4, 11, 7 } },
11885                 { 14400, { 3, 3, 3, 3, 12, 7 } },
11886                 { 16200, { 3, 3, 3, 3, 13, 8 } },
11887                 { 18000, { 2, 2, 2, 2, 14, 8 } },
11888                 { 19200, { 1, 1, 1, 1, 14, 9 } }
11889         };
11890         static const struct bwn_wpair v1[] = {
11891                 { BWN_B2062_N_TXCTL3, 0 },
11892                 { BWN_B2062_N_TXCTL4, 0 },
11893                 { BWN_B2062_N_TXCTL5, 0 },
11894                 { BWN_B2062_N_TXCTL6, 0 },
11895                 { BWN_B2062_N_PDNCTL0, 0x40 },
11896                 { BWN_B2062_N_PDNCTL0, 0 },
11897                 { BWN_B2062_N_CALIB_TS, 0x10 },
11898                 { BWN_B2062_N_CALIB_TS, 0 }
11899         };
11900         const struct bwn_b2062_freq *f = NULL;
11901         uint32_t xtalfreq, ref;
11902         unsigned int i;
11903
11904         bwn_phy_lp_b2062_tblinit(mac);
11905
11906         for (i = 0; i < N(v1); i++)
11907                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
11908         if (mac->mac_phy.rev > 0)
11909                 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
11910                     (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
11911         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11912                 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
11913         else
11914                 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
11915
11916         KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
11917             ("%s:%d: fail", __func__, __LINE__));
11918         xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11919         KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
11920
11921         if (xtalfreq <= 30000000) {
11922                 plp->plp_div = 1;
11923                 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
11924         } else {
11925                 plp->plp_div = 2;
11926                 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
11927         }
11928
11929         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
11930             CALC_CTL7(xtalfreq, plp->plp_div));
11931         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
11932             CALC_CTL18(xtalfreq, plp->plp_div));
11933         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
11934             CALC_CTL19(xtalfreq, plp->plp_div));
11935
11936         ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
11937         ref &= 0xffff;
11938         for (i = 0; i < N(freqdata_tab); i++) {
11939                 if (ref < freqdata_tab[i].freq) {
11940                         f = &freqdata_tab[i];
11941                         break;
11942                 }
11943         }
11944         if (f == NULL)
11945                 f = &freqdata_tab[N(freqdata_tab) - 1];
11946         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
11947             ((uint16_t)(f->value[1]) << 4) | f->value[0]);
11948         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
11949             ((uint16_t)(f->value[3]) << 4) | f->value[2]);
11950         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
11951         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
11952 #undef CALC_CTL7
11953 #undef CALC_CTL18
11954 #undef CALC_CTL19
11955 }
11956
11957 static void
11958 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
11959 {
11960
11961         bwn_phy_lp_b2063_tblinit(mac);
11962         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
11963         BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
11964         BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
11965         BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
11966         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
11967         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
11968         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
11969         if (mac->mac_phy.rev == 2) {
11970                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
11971                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
11972                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
11973         } else {
11974                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
11975                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
11976         }
11977 }
11978
11979 static void
11980 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
11981 {
11982         struct bwn_softc *sc = mac->mac_sc;
11983         static const struct bwn_wpair v1[] = {
11984                 { BWN_B2063_RX_BB_SP8, 0x0 },
11985                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
11986                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
11987                 { BWN_B2063_RC_CALIB_CTL2, 0x15 },
11988                 { BWN_B2063_RC_CALIB_CTL3, 0x70 },
11989                 { BWN_B2063_RC_CALIB_CTL4, 0x52 },
11990                 { BWN_B2063_RC_CALIB_CTL5, 0x1 },
11991                 { BWN_B2063_RC_CALIB_CTL1, 0x7d }
11992         };
11993         static const struct bwn_wpair v2[] = {
11994                 { BWN_B2063_TX_BB_SP3, 0x0 },
11995                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
11996                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
11997                 { BWN_B2063_RC_CALIB_CTL2, 0x55 },
11998                 { BWN_B2063_RC_CALIB_CTL3, 0x76 }
11999         };
12000         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12001         int i;
12002         uint8_t tmp;
12003
12004         tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12005
12006         for (i = 0; i < 2; i++)
12007                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12008         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12009         for (i = 2; i < N(v1); i++)
12010                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12011         for (i = 0; i < 10000; i++) {
12012                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12013                         break;
12014                 DELAY(1000);
12015         }
12016
12017         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12018                 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12019
12020         tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12021
12022         for (i = 0; i < N(v2); i++)
12023                 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12024         if (freqxtal == 24000000) {
12025                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12026                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12027         } else {
12028                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12029                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12030         }
12031         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12032         for (i = 0; i < 10000; i++) {
12033                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12034                         break;
12035                 DELAY(1000);
12036         }
12037         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12038                 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12039         BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12040 }
12041
12042 static void
12043 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12044 {
12045         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12046         struct bwn_softc *sc = mac->mac_sc;
12047         struct bwn_phy_lp_iq_est ie;
12048         struct bwn_txgain tx_gains;
12049         static const uint32_t pwrtbl[21] = {
12050                 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12051                 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12052                 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12053                 0x0004c, 0x0002c, 0x0001a,
12054         };
12055         uint32_t npwr, ipwr, sqpwr, tmp;
12056         int loopback, i, j, sum, error;
12057         uint16_t save[7];
12058         uint8_t txo, bbmult, txpctlmode;
12059
12060         error = bwn_phy_lp_switch_channel(mac, 7);
12061         if (error)
12062                 device_printf(sc->sc_dev,
12063                     "failed to change channel to 7 (%d)\n", error);
12064         txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12065         bbmult = bwn_phy_lp_get_bbmult(mac);
12066         if (txo)
12067                 tx_gains = bwn_phy_lp_get_txgain(mac);
12068
12069         save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12070         save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12071         save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12072         save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12073         save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12074         save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12075         save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12076
12077         bwn_phy_lp_get_txpctlmode(mac);
12078         txpctlmode = plp->plp_txpctlmode;
12079         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12080
12081         /* disable CRS */
12082         bwn_phy_lp_set_deaf(mac, 1);
12083         bwn_phy_lp_set_trsw_over(mac, 0, 1);
12084         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12085         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12086         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12087         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12088         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12089         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12090         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12091         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12092         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12093         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12094         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12095         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12096         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12097         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12098         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12099         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12100         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12101         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12102         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12103         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12104         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12105         BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12106         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12107
12108         loopback = bwn_phy_lp_loopback(mac);
12109         if (loopback == -1)
12110                 goto done;
12111         bwn_phy_lp_set_rxgain_idx(mac, loopback);
12112         BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12113         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12114         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12115         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12116
12117         tmp = 0;
12118         memset(&ie, 0, sizeof(ie));
12119         for (i = 128; i <= 159; i++) {
12120                 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12121                 sum = 0;
12122                 for (j = 5; j <= 25; j++) {
12123                         bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12124                         if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12125                                 goto done;
12126                         sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12127                         ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12128                         npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12129                             12);
12130                         sum += ((ipwr - npwr) * (ipwr - npwr));
12131                         if ((i == 128) || (sum < tmp)) {
12132                                 plp->plp_rccap = i;
12133                                 tmp = sum;
12134                         }
12135                 }
12136         }
12137         bwn_phy_lp_ddfs_turnoff(mac);
12138 done:
12139         /* restore CRS */
12140         bwn_phy_lp_clear_deaf(mac, 1);
12141         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12142         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12143
12144         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12145         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12146         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12147         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12148         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12149         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12150         BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12151
12152         bwn_phy_lp_set_bbmult(mac, bbmult);
12153         if (txo)
12154                 bwn_phy_lp_set_txgain(mac, &tx_gains);
12155         bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12156         if (plp->plp_rccap)
12157                 bwn_phy_lp_set_rccap(mac);
12158 }
12159
12160 static void
12161 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12162 {
12163         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12164         uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12165
12166         if (mac->mac_phy.rev == 1)
12167                 rc_cap = MIN(rc_cap + 5, 15);
12168
12169         BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12170             MAX(plp->plp_rccap - 4, 0x80));
12171         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12172         BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12173             ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12174 }
12175
12176 static uint32_t
12177 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12178 {
12179         uint32_t i, q, r;
12180
12181         if (div == 0)
12182                 return (0);
12183
12184         for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12185                 q <<= 1;
12186                 if (r << 1 >= div) {
12187                         q++;
12188                         r = (r << 1) - div;
12189                 }
12190         }
12191         if (r << 1 >= div)
12192                 q++;
12193         return (q);
12194 }
12195
12196 static void
12197 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12198 {
12199         struct bwn_softc *sc = mac->mac_sc;
12200
12201         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12202         DELAY(20);
12203         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12204                 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12205                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12206         } else {
12207                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12208         }
12209         DELAY(5);
12210 }
12211
12212 static void
12213 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12214 {
12215
12216         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12217         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12218         DELAY(200);
12219 }
12220
12221 static void
12222 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12223 {
12224 #define FLAG_A  0x01
12225 #define FLAG_G  0x02
12226         struct bwn_softc *sc = mac->mac_sc;
12227         struct ieee80211com *ic = &sc->sc_ic;
12228         static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12229                 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12230                 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12231                 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12232                 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12233                 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12234                 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12235                 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12236                 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12237                 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12238                 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12239                 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12240                 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12241                 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12242                 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12243                 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12244                 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12245                 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12246                 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12247                 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12248                 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12249                 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12250                 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12251                 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12252                 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12253                 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12254                 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12255                 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12256                 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12257                 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12258                 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12259                 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12260                 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12261                 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12262                 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12263                 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12264                 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12265                 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12266                 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12267                 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12268                 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12269                 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12270                 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12271                 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12272                 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12273                 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12274                 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12275                 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12276         };
12277         const struct bwn_b206x_rfinit_entry *br;
12278         unsigned int i;
12279
12280         for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12281                 br = &bwn_b2062_init_tab[i];
12282                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12283                         if (br->br_flags & FLAG_G)
12284                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12285                 } else {
12286                         if (br->br_flags & FLAG_A)
12287                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12288                 }
12289         }
12290 #undef FLAG_A
12291 #undef FLAG_B
12292 }
12293
12294 static void
12295 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12296 {
12297 #define FLAG_A  0x01
12298 #define FLAG_G  0x02
12299         struct bwn_softc *sc = mac->mac_sc;
12300         struct ieee80211com *ic = &sc->sc_ic;
12301         static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12302                 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12303                 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12304                 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12305                 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12306                 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12307                 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12308                 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12309                 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12310                 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12311                 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12312                 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12313                 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12314                 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12315                 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12316                 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12317                 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12318                 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12319                 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12320                 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12321                 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12322                 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12323                 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12324                 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12325                 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12326                 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12327                 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12328                 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12329                 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12330                 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12331                 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12332                 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12333                 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12334                 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12335                 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12336                 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12337                 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12338                 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12339                 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12340                 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12341                 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12342                 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12343                 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12344         };
12345         const struct bwn_b206x_rfinit_entry *br;
12346         unsigned int i;
12347
12348         for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12349                 br = &bwn_b2063_init_tab[i];
12350                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12351                         if (br->br_flags & FLAG_G)
12352                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12353                 } else {
12354                         if (br->br_flags & FLAG_A)
12355                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12356                 }
12357         }
12358 #undef FLAG_A
12359 #undef FLAG_B
12360 }
12361
12362 static void
12363 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12364     int count, void *_data)
12365 {
12366         unsigned int i;
12367         uint32_t offset, type;
12368         uint8_t *data = _data;
12369
12370         type = BWN_TAB_GETTYPE(typenoffset);
12371         offset = BWN_TAB_GETOFFSET(typenoffset);
12372         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12373
12374         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12375
12376         for (i = 0; i < count; i++) {
12377                 switch (type) {
12378                 case BWN_TAB_8BIT:
12379                         *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12380                         data++;
12381                         break;
12382                 case BWN_TAB_16BIT:
12383                         *((uint16_t *)data) = BWN_PHY_READ(mac,
12384                             BWN_PHY_TABLEDATALO);
12385                         data += 2;
12386                         break;
12387                 case BWN_TAB_32BIT:
12388                         *((uint32_t *)data) = BWN_PHY_READ(mac,
12389                             BWN_PHY_TABLEDATAHI);
12390                         *((uint32_t *)data) <<= 16;
12391                         *((uint32_t *)data) |= BWN_PHY_READ(mac,
12392                             BWN_PHY_TABLEDATALO);
12393                         data += 4;
12394                         break;
12395                 default:
12396                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12397                 }
12398         }
12399 }
12400
12401 static void
12402 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12403     int count, const void *_data)
12404 {
12405         uint32_t offset, type, value;
12406         const uint8_t *data = _data;
12407         unsigned int i;
12408
12409         type = BWN_TAB_GETTYPE(typenoffset);
12410         offset = BWN_TAB_GETOFFSET(typenoffset);
12411         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12412
12413         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12414
12415         for (i = 0; i < count; i++) {
12416                 switch (type) {
12417                 case BWN_TAB_8BIT:
12418                         value = *data;
12419                         data++;
12420                         KASSERT(!(value & ~0xff),
12421                             ("%s:%d: fail", __func__, __LINE__));
12422                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12423                         break;
12424                 case BWN_TAB_16BIT:
12425                         value = *((const uint16_t *)data);
12426                         data += 2;
12427                         KASSERT(!(value & ~0xffff),
12428                             ("%s:%d: fail", __func__, __LINE__));
12429                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12430                         break;
12431                 case BWN_TAB_32BIT:
12432                         value = *((const uint32_t *)data);
12433                         data += 4;
12434                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12435                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12436                         break;
12437                 default:
12438                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12439                 }
12440         }
12441 }
12442
12443 static struct bwn_txgain
12444 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12445 {
12446         struct bwn_txgain tg;
12447         uint16_t tmp;
12448
12449         tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12450         if (mac->mac_phy.rev < 2) {
12451                 tmp = BWN_PHY_READ(mac,
12452                     BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12453                 tg.tg_gm = tmp & 0x0007;
12454                 tg.tg_pga = (tmp & 0x0078) >> 3;
12455                 tg.tg_pad = (tmp & 0x780) >> 7;
12456                 return (tg);
12457         }
12458
12459         tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12460         tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12461         tg.tg_gm = tmp & 0xff;
12462         tg.tg_pga = (tmp >> 8) & 0xff;
12463         return (tg);
12464 }
12465
12466 static uint8_t
12467 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12468 {
12469
12470         return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12471 }
12472
12473 static void
12474 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12475 {
12476         uint16_t pa;
12477
12478         if (mac->mac_phy.rev < 2) {
12479                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12480                     (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12481                 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12482                 bwn_phy_lp_set_txgain_override(mac);
12483                 return;
12484         }
12485
12486         pa = bwn_phy_lp_get_pa_gain(mac);
12487         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12488             (tg->tg_pga << 8) | tg->tg_gm);
12489         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12490             tg->tg_pad | (pa << 6));
12491         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12492         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12493             tg->tg_pad | (pa << 8));
12494         bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12495         bwn_phy_lp_set_txgain_override(mac);
12496 }
12497
12498 static void
12499 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12500 {
12501
12502         bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12503 }
12504
12505 static void
12506 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12507 {
12508         uint16_t trsw = (tx << 1) | rx;
12509
12510         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12511         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12512 }
12513
12514 static void
12515 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12516 {
12517         struct bwn_softc *sc = mac->mac_sc;
12518         struct ieee80211com *ic = &sc->sc_ic;
12519         uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12520
12521         if (mac->mac_phy.rev < 2) {
12522                 trsw = gain & 0x1;
12523                 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12524                 ext_lna = (gain & 2) >> 1;
12525
12526                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12527                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12528                     0xfbff, ext_lna << 10);
12529                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12530                     0xf7ff, ext_lna << 11);
12531                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12532         } else {
12533                 low_gain = gain & 0xffff;
12534                 high_gain = (gain >> 16) & 0xf;
12535                 ext_lna = (gain >> 21) & 0x1;
12536                 trsw = ~(gain >> 20) & 0x1;
12537
12538                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12539                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12540                     0xfdff, ext_lna << 9);
12541                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12542                     0xfbff, ext_lna << 10);
12543                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12544                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12545                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12546                         tmp = (gain >> 2) & 0x3;
12547                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12548                             0xe7ff, tmp<<11);
12549                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12550                             tmp << 3);
12551                 }
12552         }
12553
12554         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12555         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12556         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12557         if (mac->mac_phy.rev >= 2) {
12558                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12559                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12560                         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12561                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12562                 }
12563                 return;
12564         }
12565         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12566 }
12567
12568 static void
12569 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12570 {
12571         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12572
12573         if (user)
12574                 plp->plp_crsusr_off = 1;
12575         else
12576                 plp->plp_crssys_off = 1;
12577
12578         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12579 }
12580
12581 static void
12582 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12583 {
12584         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12585         struct bwn_softc *sc = mac->mac_sc;
12586         struct ieee80211com *ic = &sc->sc_ic;
12587
12588         if (user)
12589                 plp->plp_crsusr_off = 0;
12590         else
12591                 plp->plp_crssys_off = 0;
12592
12593         if (plp->plp_crsusr_off || plp->plp_crssys_off)
12594                 return;
12595
12596         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12597                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12598         else
12599                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12600 }
12601
12602 static unsigned int
12603 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12604 {
12605         /* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12606         static uint8_t sqrt_table[256] = {
12607                 10, 14, 17, 20, 22, 24, 26, 28,
12608                 30, 31, 33, 34, 36, 37, 38, 40,
12609                 41, 42, 43, 44, 45, 46, 47, 48,
12610                 50, 50, 51, 52, 53, 54, 55, 56,
12611                 57, 58, 59, 60, 60, 61, 62, 63,
12612                 64, 64, 65, 66, 67, 67, 68, 69,
12613                 70, 70, 71, 72, 72, 73, 74, 74,
12614                 75, 76, 76, 77, 78, 78, 79, 80,
12615                 80, 81, 81, 82, 83, 83, 84, 84,
12616                 85, 86, 86, 87, 87, 88, 88, 89,
12617                 90, 90, 91, 91, 92, 92, 93, 93,
12618                 94, 94, 95, 95, 96, 96, 97, 97,
12619                 98, 98, 99, 100, 100, 100, 101, 101,
12620                 102, 102, 103, 103, 104, 104, 105, 105,
12621                 106, 106, 107, 107, 108, 108, 109, 109,
12622                 110, 110, 110, 111, 111, 112, 112, 113,
12623                 113, 114, 114, 114, 115, 115, 116, 116,
12624                 117, 117, 117, 118, 118, 119, 119, 120,
12625                 120, 120, 121, 121, 122, 122, 122, 123,
12626                 123, 124, 124, 124, 125, 125, 126, 126,
12627                 126, 127, 127, 128, 128, 128, 129, 129,
12628                 130, 130, 130, 131, 131, 131, 132, 132,
12629                 133, 133, 133, 134, 134, 134, 135, 135,
12630                 136, 136, 136, 137, 137, 137, 138, 138,
12631                 138, 139, 139, 140, 140, 140, 141, 141,
12632                 141, 142, 142, 142, 143, 143, 143, 144,
12633                 144, 144, 145, 145, 145, 146, 146, 146,
12634                 147, 147, 147, 148, 148, 148, 149, 149,
12635                 150, 150, 150, 150, 151, 151, 151, 152,
12636                 152, 152, 153, 153, 153, 154, 154, 154,
12637                 155, 155, 155, 156, 156, 156, 157, 157,
12638                 157, 158, 158, 158, 159, 159, 159, 160
12639         };
12640
12641         if (x == 0)
12642                 return (0);
12643         if (x >= 256) {
12644                 unsigned int tmp;
12645
12646                 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12647                         /* do nothing */ ;
12648                 return (tmp);
12649         }
12650         return (sqrt_table[x - 1] / 10);
12651 }
12652
12653 static int
12654 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12655 {
12656 #define CALC_COEFF(_v, _x, _y, _z)      do {                            \
12657         int _t;                                                         \
12658         _t = _x - 20;                                                   \
12659         if (_t >= 0) {                                                  \
12660                 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12661         } else {                                                        \
12662                 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12663         }                                                               \
12664 } while (0)
12665 #define CALC_COEFF2(_v, _x, _y, _z)     do {                            \
12666         int _t;                                                         \
12667         _t = _x - 11;                                                   \
12668         if (_t >= 0)                                                    \
12669                 _v = (_y << (31 - _x)) / (_z >> _t);                    \
12670         else                                                            \
12671                 _v = (_y << (31 - _x)) / (_z << -_t);                   \
12672 } while (0)
12673         struct bwn_phy_lp_iq_est ie;
12674         uint16_t v0, v1;
12675         int tmp[2], ret;
12676
12677         v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12678         v0 = v1 >> 8;
12679         v1 |= 0xff;
12680
12681         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12682         BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12683
12684         ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12685         if (ret == 0)
12686                 goto done;
12687
12688         if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12689                 ret = 0;
12690                 goto done;
12691         }
12692
12693         CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12694         CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12695
12696         tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12697         v0 = tmp[0] >> 3;
12698         v1 = tmp[1] >> 4;
12699 done:
12700         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12701         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12702         return ret;
12703 #undef CALC_COEFF
12704 #undef CALC_COEFF2
12705 }
12706
12707 static void
12708 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12709 {
12710         static const uint16_t noisescale[] = {
12711                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12712                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12713                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12714                 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12715                 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12716         };
12717         static const uint16_t crsgainnft[] = {
12718                 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12719                 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12720                 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12721                 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12722                 0x013d,
12723         };
12724         static const uint16_t filterctl[] = {
12725                 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12726                 0xff53, 0x0127,
12727         };
12728         static const uint32_t psctl[] = {
12729                 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12730                 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12731                 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12732                 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12733                 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12734                 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12735                 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12736                 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12737         };
12738         static const uint16_t ofdmcckgain_r0[] = {
12739                 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12740                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12741                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12742                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12743                 0x755d,
12744         };
12745         static const uint16_t ofdmcckgain_r1[] = {
12746                 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12747                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12748                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12749                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12750                 0x755d,
12751         };
12752         static const uint16_t gaindelta[] = {
12753                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12754                 0x0000,
12755         };
12756         static const uint32_t txpwrctl[] = {
12757                 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12758                 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12759                 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12760                 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12761                 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12762                 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12763                 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12764                 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12765                 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12766                 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12767                 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12768                 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12769                 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
12770                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12771                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12772                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12773                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12774                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12775                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12776                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12777                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12778                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12779                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12780                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12781                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12782                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12783                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12784                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12785                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12786                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12787                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12788                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12789                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12790                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12791                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12792                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12793                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12794                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12795                 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12796                 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12797                 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12798                 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12799                 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12800                 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12801                 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12802                 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12803                 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12804                 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12805                 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12806                 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12807                 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12808                 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12809                 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12810                 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12811                 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12812                 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12813                 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12814                 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12815                 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12816                 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12817                 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12818                 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12819                 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12820                 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12821                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12822                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12823                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12824                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12825                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12826                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12827                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12828                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12829                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12830                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12831                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12832                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12833                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12834                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12835                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12836                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12837                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12838                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12839                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12840                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12841                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12842                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12843                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12844                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12845                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12846                 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
12847                 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
12848                 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
12849                 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
12850                 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
12851                 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
12852                 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
12853                 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
12854                 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
12855                 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
12856                 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
12857                 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
12858                 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
12859                 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
12860                 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
12861                 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
12862                 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
12863                 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
12864                 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
12865                 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
12866                 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
12867                 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
12868                 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
12869                 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
12870                 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
12871                 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
12872                 0x00000702,
12873         };
12874
12875         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
12876
12877         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
12878             bwn_tab_sigsq_tbl);
12879         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
12880         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
12881         bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
12882         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
12883         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
12884             bwn_tab_pllfrac_tbl);
12885         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
12886             bwn_tabl_iqlocal_tbl);
12887         if (mac->mac_phy.rev == 0) {
12888                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
12889                     ofdmcckgain_r0);
12890                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
12891                     ofdmcckgain_r0);
12892         } else {
12893                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
12894                     ofdmcckgain_r1);
12895                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
12896                     ofdmcckgain_r1);
12897         }
12898         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
12899         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
12900 }
12901
12902 static void
12903 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
12904 {
12905         struct bwn_softc *sc = mac->mac_sc;
12906         int i;
12907         static const uint16_t noisescale[] = {
12908                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12909                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12910                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12911                 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12912                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12913                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12914                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
12915         };
12916         static const uint32_t filterctl[] = {
12917                 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
12918                 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
12919         };
12920         static const uint32_t psctl[] = {
12921                 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
12922                 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
12923                 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
12924                 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
12925         };
12926         static const uint32_t gainidx[] = {
12927                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12928                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12929                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12930                 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
12931                 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
12932                 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
12933                 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
12934                 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
12935                 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
12936                 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
12937                 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
12938                 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
12939                 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
12940                 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
12941                 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
12942                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12943                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12944                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12945                 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
12946                 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
12947                 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
12948                 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
12949                 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
12950                 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
12951                 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
12952                 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
12953                 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
12954                 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
12955                 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
12956                 0x0000001a, 0x64ca55ad, 0x0000001a
12957         };
12958         static const uint16_t auxgainidx[] = {
12959                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12960                 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
12961                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
12962                 0x0004, 0x0016
12963         };
12964         static const uint16_t swctl[] = {
12965                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
12966                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
12967                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
12968                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
12969                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
12970                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
12971                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
12972                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
12973         };
12974         static const uint8_t hf[] = {
12975                 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
12976                 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
12977         };
12978         static const uint32_t gainval[] = {
12979                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
12980                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
12981                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
12982                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
12983                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
12984                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
12985                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12986                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12987                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
12988                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
12989                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
12990                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
12991                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
12992                 0x000000f1, 0x00000000, 0x00000000
12993         };
12994         static const uint16_t gain[] = {
12995                 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
12996                 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
12997                 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
12998                 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
12999                 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13000                 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
13001                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13002                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13003                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13004                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13005                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13006                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13007         };
13008         static const uint32_t papdeps[] = {
13009                 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13010                 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13011                 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13012                 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13013                 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13014                 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13015                 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13016                 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13017                 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13018                 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13019                 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13020                 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13021                 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13022         };
13023         static const uint32_t papdmult[] = {
13024                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13025                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13026                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13027                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13028                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13029                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13030                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13031                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13032                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13033                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13034                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13035                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13036                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13037         };
13038         static const uint32_t gainidx_a0[] = {
13039                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13040                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13041                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13042                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13043                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13044                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13045                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13046                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13047                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13048                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13049                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13050                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13051                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13052         };
13053         static const uint16_t auxgainidx_a0[] = {
13054                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13055                 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13056                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13057                 0x0002, 0x0014
13058         };
13059         static const uint32_t gainval_a0[] = {
13060                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13061                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13062                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13063                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13064                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13065                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13066                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13067                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13068                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13069                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13070                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13071                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13072                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13073                 0x000000f7, 0x00000000, 0x00000000
13074         };
13075         static const uint16_t gain_a0[] = {
13076                 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13077                 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13078                 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13079                 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13080                 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13081                 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
13082                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13083                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13084                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13085                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13086                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13087                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13088         };
13089
13090         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13091
13092         for (i = 0; i < 704; i++)
13093                 bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13094
13095         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13096             bwn_tab_sigsq_tbl);
13097         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13098         bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13099         bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13100         bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13101         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13102         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13103         bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13104         bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13105         bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13106         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13107             bwn_tab_pllfrac_tbl);
13108         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13109             bwn_tabl_iqlocal_tbl);
13110         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13111         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13112
13113         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13114             (siba_get_chiprev(sc->sc_dev) == 0)) {
13115                 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13116                     gainidx_a0);
13117                 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13118                     auxgainidx_a0);
13119                 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13120                     gainval_a0);
13121                 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13122         }
13123 }
13124
13125 static void
13126 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13127 {
13128         struct bwn_softc *sc = mac->mac_sc;
13129         struct ieee80211com *ic = &sc->sc_ic;
13130         static struct bwn_txgain_entry txgain_r2[] = {
13131                 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13132                 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13133                 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13134                 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13135                 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13136                 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13137                 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13138                 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13139                 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13140                 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13141                 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13142                 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13143                 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13144                 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13145                 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13146                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13147                 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13148                 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13149                 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13150                 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13151                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13152                 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13153                 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13154                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13155                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13156                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13157                 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13158                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13159                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13160                 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13161                 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13162                 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13163                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13164                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13165                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13166                 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13167                 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13168                 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13169                 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13170                 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13171                 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13172                 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13173                 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13174                 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13175                 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13176                 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13177                 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13178                 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13179                 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13180                 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13181                 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13182                 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13183                 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13184                 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13185                 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13186                 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13187                 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13188                 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13189                 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13190                 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13191                 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13192                 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13193                 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13194                 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13195         };
13196         static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13197                 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13198                 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13199                 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13200                 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13201                 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13202                 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13203                 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13204                 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13205                 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13206                 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13207                 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13208                 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13209                 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13210                 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13211                 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13212                 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13213                 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13214                 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13215                 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13216                 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13217                 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13218                 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13219                 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13220                 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13221                 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13222                 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13223                 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13224                 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13225                 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13226                 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13227                 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13228                 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13229                 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13230                 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13231                 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13232                 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13233                 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13234                 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13235                 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13236                 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13237                 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13238                 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13239                 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13240                 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13241                 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13242                 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13243                 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13244                 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13245                 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13246                 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13247                 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13248                 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13249                 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13250                 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13251                 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13252                 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13253                 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13254                 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13255                 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13256                 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13257                 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13258                 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13259                 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13260                 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13261         };
13262         static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13263                 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13264                 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13265                 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13266                 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13267                 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13268                 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13269                 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13270                 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13271                 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13272                 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13273                 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13274                 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13275                 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13276                 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13277                 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13278                 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13279                 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13280                 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13281                 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13282                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13283                 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13284                 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13285                 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13286                 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13287                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13288                 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13289                 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13290                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13291                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13292                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13293                 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13294                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13295                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13296                 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13297                 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13298                 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13299                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13300                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13301                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13302                 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13303                 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13304                 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13305                 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13306                 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13307                 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13308                 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13309                 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13310                 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13311                 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13312                 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13313                 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13314                 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13315                 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13316                 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13317                 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13318                 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13319                 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13320                 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13321                 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13322                 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13323                 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13324                 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13325                 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13326                 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13327         };
13328         static struct bwn_txgain_entry txgain_r0[] = {
13329                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13330                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13331                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13332                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13333                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13334                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13335                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13336                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13337                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13338                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13339                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13340                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13341                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13342                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13343                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13344                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13345                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13346                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13347                 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13348                 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13349                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13350                 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13351                 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13352                 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13353                 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13354                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13355                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13356                 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13357                 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13358                 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13359                 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13360                 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13361                 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13362                 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13363                 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13364                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13365                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13366                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13367                 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13368                 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13369                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13370                 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13371                 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13372                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13373                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13374                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13375                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13376                 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13377                 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13378                 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13379                 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13380                 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13381                 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13382                 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13383                 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13384                 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13385                 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13386                 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13387                 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13388                 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13389                 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13390                 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13391                 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13392                 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13393         };
13394         static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13395                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13396                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13397                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13398                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13399                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13400                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13401                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13402                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13403                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13404                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13405                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13406                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13407                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13408                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13409                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13410                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13411                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13412                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13413                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13414                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13415                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13416                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13417                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13418                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13419                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13420                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13421                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13422                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13423                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13424                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13425                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13426                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13427                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13428                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13429                 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13430                 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13431                 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13432                 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13433                 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13434                 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13435                 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13436                 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13437                 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13438                 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13439                 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13440                 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13441                 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13442                 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13443                 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13444                 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13445                 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13446                 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13447                 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13448                 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13449                 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13450                 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13451                 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13452                 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13453                 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13454                 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13455                 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13456                 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13457                 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13458                 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13459         };
13460         static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13461                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13462                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13463                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13464                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13465                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13466                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13467                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13468                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13469                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13470                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13471                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13472                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13473                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13474                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13475                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13476                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13477                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13478                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13479                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13480                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13481                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13482                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13483                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13484                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13485                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13486                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13487                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13488                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13489                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13490                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13491                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13492                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13493                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13494                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13495                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13496                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13497                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13498                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13499                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13500                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13501                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13502                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13503                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13504                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13505                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13506                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13507                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13508                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13509                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13510                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13511                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13512                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13513                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13514                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13515                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13516                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13517                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13518                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13519                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13520                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13521                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13522                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13523                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13524                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13525         };
13526         static struct bwn_txgain_entry txgain_r1[] = {
13527                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13528                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13529                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13530                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13531                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13532                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13533                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13534                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13535                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13536                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13537                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13538                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13539                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13540                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13541                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13542                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13543                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13544                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13545                 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13546                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13547                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13548                 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13549                 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13550                 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13551                 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13552                 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13553                 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13554                 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13555                 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13556                 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13557                 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13558                 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13559                 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13560                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13561                 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13562                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13563                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13564                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13565                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13566                 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13567                 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13568                 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13569                 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13570                 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13571                 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13572                 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13573                 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13574                 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13575                 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13576                 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13577                 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13578                 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13579                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13580                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13581                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13582                 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13583                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13584                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13585                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13586                 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13587                 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13588                 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13589                 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13590                 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13591                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13592                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13593                 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13594                 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13595                 { 7, 11, 6, 0, 71 }
13596         };
13597         static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13598                 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13599                 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13600                 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13601                 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13602                 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13603                 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13604                 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13605                 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13606                 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13607                 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13608                 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13609                 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13610                 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13611                 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13612                 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13613                 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13614                 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13615                 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13616                 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13617                 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13618                 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13619                 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13620                 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13621                 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13622                 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13623                 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13624                 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13625                 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13626                 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13627                 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13628                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13629                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13630                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13631                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13632                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13633                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13634                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13635                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13636                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13637                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13638                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13639                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13640                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13641                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13642                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13643                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13644                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13645                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13646                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13647                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13648                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13649                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13650                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13651                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13652                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13653                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13654                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13655                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13656                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13657                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13658                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13659                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13660                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13661                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13662         };
13663         static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13664                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13665                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13666                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13667                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13668                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13669                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13670                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13671                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13672                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13673                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13674                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13675                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13676                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13677                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13678                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13679                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13680                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13681                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13682                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13683                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13684                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13685                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13686                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13687                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13688                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13689                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13690                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13691                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13692                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13693                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13694                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13695                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13696                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13697                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13698                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13699                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13700                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13701                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13702                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13703                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13704                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13705                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13706                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13707                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13708                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13709                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13710                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13711                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13712                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13713                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13714                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13715                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13716                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13717                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13718                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13719                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13720                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13721                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13722                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13723                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13724                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13725                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13726                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13727                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13728         };
13729
13730         if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13731                 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13732                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13733                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13734                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13735                             txgain_2ghz_r2);
13736                 else
13737                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13738                             txgain_5ghz_r2);
13739                 return;
13740         }
13741
13742         if (mac->mac_phy.rev == 0) {
13743                 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13744                     (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13745                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13746                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13747                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13748                             txgain_2ghz_r0);
13749                 else
13750                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13751                             txgain_5ghz_r0);
13752                 return;
13753         }
13754
13755         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13756             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13757                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13758         else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13759                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13760         else
13761                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13762 }
13763
13764 static void
13765 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13766 {
13767         uint32_t offset, type;
13768
13769         type = BWN_TAB_GETTYPE(typeoffset);
13770         offset = BWN_TAB_GETOFFSET(typeoffset);
13771         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13772
13773         switch (type) {
13774         case BWN_TAB_8BIT:
13775                 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13776                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13777                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13778                 break;
13779         case BWN_TAB_16BIT:
13780                 KASSERT(!(value & ~0xffff),
13781                     ("%s:%d: fail", __func__, __LINE__));
13782                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13783                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13784                 break;
13785         case BWN_TAB_32BIT:
13786                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13787                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13788                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13789                 break;
13790         default:
13791                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13792         }
13793 }
13794
13795 static int
13796 bwn_phy_lp_loopback(struct bwn_mac *mac)
13797 {
13798         struct bwn_phy_lp_iq_est ie;
13799         int i, index = -1;
13800         uint32_t tmp;
13801
13802         memset(&ie, 0, sizeof(ie));
13803
13804         bwn_phy_lp_set_trsw_over(mac, 1, 1);
13805         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13806         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13807         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13808         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13809         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13810         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13811         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13812         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13813         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13814         for (i = 0; i < 32; i++) {
13815                 bwn_phy_lp_set_rxgain_idx(mac, i);
13816                 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13817                 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13818                         continue;
13819                 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13820                 if ((tmp > 4000) && (tmp < 10000)) {
13821                         index = i;
13822                         break;
13823                 }
13824         }
13825         bwn_phy_lp_ddfs_turnoff(mac);
13826         return (index);
13827 }
13828
13829 static void
13830 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13831 {
13832
13833         bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
13834 }
13835
13836 static void
13837 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
13838     int incr1, int incr2, int scale_idx)
13839 {
13840
13841         bwn_phy_lp_ddfs_turnoff(mac);
13842         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
13843         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
13844         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
13845         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
13846         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
13847         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
13848         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
13849         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
13850         BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
13851         BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
13852 }
13853
13854 static uint8_t
13855 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
13856     struct bwn_phy_lp_iq_est *ie)
13857 {
13858         int i;
13859
13860         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
13861         BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
13862         BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
13863         BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
13864         BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
13865
13866         for (i = 0; i < 500; i++) {
13867                 if (!(BWN_PHY_READ(mac,
13868                     BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
13869                         break;
13870                 DELAY(1000);
13871         }
13872         if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
13873                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
13874                 return 0;
13875         }
13876
13877         ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
13878         ie->ie_iqprod <<= 16;
13879         ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
13880         ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
13881         ie->ie_ipwr <<= 16;
13882         ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
13883         ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
13884         ie->ie_qpwr <<= 16;
13885         ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
13886
13887         BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
13888         return 1;
13889 }
13890
13891 static uint32_t
13892 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
13893 {
13894         uint32_t offset, type, value;
13895
13896         type = BWN_TAB_GETTYPE(typeoffset);
13897         offset = BWN_TAB_GETOFFSET(typeoffset);
13898         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13899
13900         switch (type) {
13901         case BWN_TAB_8BIT:
13902                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13903                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
13904                 break;
13905         case BWN_TAB_16BIT:
13906                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13907                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
13908                 break;
13909         case BWN_TAB_32BIT:
13910                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13911                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
13912                 value <<= 16;
13913                 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
13914                 break;
13915         default:
13916                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13917                 value = 0;
13918         }
13919
13920         return (value);
13921 }
13922
13923 static void
13924 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
13925 {
13926
13927         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
13928         BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
13929 }
13930
13931 static void
13932 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
13933 {
13934         uint16_t ctl;
13935
13936         ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
13937         ctl |= dac << 7;
13938         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
13939 }
13940
13941 static void
13942 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
13943 {
13944
13945         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
13946         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
13947 }
13948
13949 static void
13950 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
13951 {
13952
13953         if (mac->mac_phy.rev < 2)
13954                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
13955         else {
13956                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
13957                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
13958         }
13959         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
13960 }
13961
13962 static uint16_t
13963 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
13964 {
13965
13966         return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
13967 }
13968
13969 static uint8_t
13970 bwn_nbits(int32_t val)
13971 {
13972         uint32_t tmp;
13973         uint8_t nbits = 0;
13974
13975         for (tmp = abs(val); tmp != 0; tmp >>= 1)
13976                 nbits++;
13977         return (nbits);
13978 }
13979
13980 static void
13981 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
13982     struct bwn_txgain_entry *table)
13983 {
13984         int i;
13985
13986         for (i = offset; i < count; i++)
13987                 bwn_phy_lp_gaintbl_write(mac, i, table[i]);
13988 }
13989
13990 static void
13991 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
13992     struct bwn_txgain_entry data)
13993 {
13994
13995         if (mac->mac_phy.rev >= 2)
13996                 bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
13997         else
13998                 bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
13999 }
14000
14001 static void
14002 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14003     struct bwn_txgain_entry te)
14004 {
14005         struct bwn_softc *sc = mac->mac_sc;
14006         struct ieee80211com *ic = &sc->sc_ic;
14007         uint32_t tmp;
14008
14009         KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14010
14011         tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14012         if (mac->mac_phy.rev >= 3) {
14013                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14014                     (0x10 << 24) : (0x70 << 24));
14015         } else {
14016                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14017                     (0x14 << 24) : (0x7f << 24));
14018         }
14019         bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14020         bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14021             te.te_bbmult << 20 | te.te_dac << 28);
14022 }
14023
14024 static void
14025 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14026     struct bwn_txgain_entry te)
14027 {
14028
14029         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14030
14031         bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14032             (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm  << 4) |
14033             te.te_dac);
14034         bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14035 }
14036
14037 static void
14038 bwn_sysctl_node(struct bwn_softc *sc)
14039 {
14040         device_t dev = sc->sc_dev;
14041         struct bwn_mac *mac;
14042         struct bwn_stats *stats;
14043
14044         /* XXX assume that count of MAC is only 1. */
14045
14046         if ((mac = sc->sc_curmac) == NULL)
14047                 return;
14048         stats = &mac->mac_stats;
14049
14050         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14051             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14052             "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14053         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14054             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14055             "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14056         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14057             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14058             "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14059
14060 #ifdef BWN_DEBUG
14061         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14062             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14063             "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14064 #endif
14065 }
14066
14067 static device_method_t bwn_methods[] = {
14068         /* Device interface */
14069         DEVMETHOD(device_probe,         bwn_probe),
14070         DEVMETHOD(device_attach,        bwn_attach),
14071         DEVMETHOD(device_detach,        bwn_detach),
14072         DEVMETHOD(device_suspend,       bwn_suspend),
14073         DEVMETHOD(device_resume,        bwn_resume),
14074         DEVMETHOD_END
14075 };
14076 static driver_t bwn_driver = {
14077         "bwn",
14078         bwn_methods,
14079         sizeof(struct bwn_softc)
14080 };
14081 static devclass_t bwn_devclass;
14082 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
14083 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14084 MODULE_DEPEND(bwn, wlan, 1, 1, 1);              /* 802.11 media layer */
14085 MODULE_DEPEND(bwn, firmware, 1, 1, 1);          /* firmware support */
14086 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);