]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/bwn/if_bwn.c
MFV r289003:
[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,
2725                     (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2726         }
2727         BWN_UNLOCK(sc);
2728 }
2729
2730 /*
2731  * Callback from the 802.11 layer after a promiscuous mode change.
2732  * Note this interface does not check the operating mode as this
2733  * is an internal callback and we are expected to honor the current
2734  * state (e.g. this is used for setting the interface in promiscuous
2735  * mode when operating in hostap mode to do ACS).
2736  */
2737 static void
2738 bwn_update_promisc(struct ieee80211com *ic)
2739 {
2740         struct bwn_softc *sc = ic->ic_softc;
2741         struct bwn_mac *mac = sc->sc_curmac;
2742
2743         BWN_LOCK(sc);
2744         mac = sc->sc_curmac;
2745         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2746                 if (ic->ic_promisc > 0)
2747                         sc->sc_filters |= BWN_MACCTL_PROMISC;
2748                 else
2749                         sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2750                 bwn_set_opmode(mac);
2751         }
2752         BWN_UNLOCK(sc);
2753 }
2754
2755 /*
2756  * Callback from the 802.11 layer to update WME parameters.
2757  */
2758 static int
2759 bwn_wme_update(struct ieee80211com *ic)
2760 {
2761         struct bwn_softc *sc = ic->ic_softc;
2762         struct bwn_mac *mac = sc->sc_curmac;
2763         struct wmeParams *wmep;
2764         int i;
2765
2766         BWN_LOCK(sc);
2767         mac = sc->sc_curmac;
2768         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2769                 bwn_mac_suspend(mac);
2770                 for (i = 0; i < N(sc->sc_wmeParams); i++) {
2771                         wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2772                         bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2773                 }
2774                 bwn_mac_enable(mac);
2775         }
2776         BWN_UNLOCK(sc);
2777         return (0);
2778 }
2779
2780 static void
2781 bwn_scan_start(struct ieee80211com *ic)
2782 {
2783         struct bwn_softc *sc = ic->ic_softc;
2784         struct bwn_mac *mac;
2785
2786         BWN_LOCK(sc);
2787         mac = sc->sc_curmac;
2788         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2789                 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2790                 bwn_set_opmode(mac);
2791                 /* disable CFP update during scan */
2792                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2793         }
2794         BWN_UNLOCK(sc);
2795 }
2796
2797 static void
2798 bwn_scan_end(struct ieee80211com *ic)
2799 {
2800         struct bwn_softc *sc = ic->ic_softc;
2801         struct bwn_mac *mac;
2802
2803         BWN_LOCK(sc);
2804         mac = sc->sc_curmac;
2805         if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2806                 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2807                 bwn_set_opmode(mac);
2808                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2809         }
2810         BWN_UNLOCK(sc);
2811 }
2812
2813 static void
2814 bwn_set_channel(struct ieee80211com *ic)
2815 {
2816         struct bwn_softc *sc = ic->ic_softc;
2817         struct bwn_mac *mac = sc->sc_curmac;
2818         struct bwn_phy *phy = &mac->mac_phy;
2819         int chan, error;
2820
2821         BWN_LOCK(sc);
2822
2823         error = bwn_switch_band(sc, ic->ic_curchan);
2824         if (error)
2825                 goto fail;
2826         bwn_mac_suspend(mac);
2827         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2828         chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2829         if (chan != phy->chan)
2830                 bwn_switch_channel(mac, chan);
2831
2832         /* TX power level */
2833         if (ic->ic_curchan->ic_maxpower != 0 &&
2834             ic->ic_curchan->ic_maxpower != phy->txpower) {
2835                 phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2836                 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2837                     BWN_TXPWR_IGNORE_TSSI);
2838         }
2839
2840         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2841         if (phy->set_antenna)
2842                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
2843
2844         if (sc->sc_rf_enabled != phy->rf_on) {
2845                 if (sc->sc_rf_enabled) {
2846                         bwn_rf_turnon(mac);
2847                         if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2848                                 device_printf(sc->sc_dev,
2849                                     "please turn on the RF switch\n");
2850                 } else
2851                         bwn_rf_turnoff(mac);
2852         }
2853
2854         bwn_mac_enable(mac);
2855
2856 fail:
2857         /*
2858          * Setup radio tap channel freq and flags
2859          */
2860         sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2861                 htole16(ic->ic_curchan->ic_freq);
2862         sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2863                 htole16(ic->ic_curchan->ic_flags & 0xffff);
2864
2865         BWN_UNLOCK(sc);
2866 }
2867
2868 static struct ieee80211vap *
2869 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
2870     enum ieee80211_opmode opmode, int flags,
2871     const uint8_t bssid[IEEE80211_ADDR_LEN],
2872     const uint8_t mac[IEEE80211_ADDR_LEN])
2873 {
2874         struct ieee80211vap *vap;
2875         struct bwn_vap *bvp;
2876
2877         switch (opmode) {
2878         case IEEE80211_M_HOSTAP:
2879         case IEEE80211_M_MBSS:
2880         case IEEE80211_M_STA:
2881         case IEEE80211_M_WDS:
2882         case IEEE80211_M_MONITOR:
2883         case IEEE80211_M_IBSS:
2884         case IEEE80211_M_AHDEMO:
2885                 break;
2886         default:
2887                 return (NULL);
2888         }
2889
2890         bvp = malloc(sizeof(struct bwn_vap), M_80211_VAP, M_WAITOK | M_ZERO);
2891         vap = &bvp->bv_vap;
2892         ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
2893         /* override with driver methods */
2894         bvp->bv_newstate = vap->iv_newstate;
2895         vap->iv_newstate = bwn_newstate;
2896
2897         /* override max aid so sta's cannot assoc when we're out of sta id's */
2898         vap->iv_max_aid = BWN_STAID_MAX;
2899
2900         ieee80211_ratectl_init(vap);
2901
2902         /* complete setup */
2903         ieee80211_vap_attach(vap, ieee80211_media_change,
2904             ieee80211_media_status, mac);
2905         return (vap);
2906 }
2907
2908 static void
2909 bwn_vap_delete(struct ieee80211vap *vap)
2910 {
2911         struct bwn_vap *bvp = BWN_VAP(vap);
2912
2913         ieee80211_ratectl_deinit(vap);
2914         ieee80211_vap_detach(vap);
2915         free(bvp, M_80211_VAP);
2916 }
2917
2918 static int
2919 bwn_init(struct bwn_softc *sc)
2920 {
2921         struct bwn_mac *mac;
2922         int error;
2923
2924         BWN_ASSERT_LOCKED(sc);
2925
2926         bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
2927         sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
2928         sc->sc_filters = 0;
2929         bwn_wme_clear(sc);
2930         sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
2931         sc->sc_rf_enabled = 1;
2932
2933         mac = sc->sc_curmac;
2934         if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
2935                 error = bwn_core_init(mac);
2936                 if (error != 0)
2937                         return (error);
2938         }
2939         if (mac->mac_status == BWN_MAC_STATUS_INITED)
2940                 bwn_core_start(mac);
2941
2942         bwn_set_opmode(mac);
2943         bwn_set_pretbtt(mac);
2944         bwn_spu_setdelay(mac, 0);
2945         bwn_set_macaddr(mac);
2946
2947         sc->sc_flags |= BWN_FLAG_RUNNING;
2948         callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
2949         callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
2950
2951         return (0);
2952 }
2953
2954 static void
2955 bwn_stop(struct bwn_softc *sc)
2956 {
2957         struct bwn_mac *mac = sc->sc_curmac;
2958
2959         BWN_ASSERT_LOCKED(sc);
2960
2961         if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
2962                 /* XXX FIXME opmode not based on VAP */
2963                 bwn_set_opmode(mac);
2964                 bwn_set_macaddr(mac);
2965         }
2966
2967         if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
2968                 bwn_core_stop(mac);
2969
2970         callout_stop(&sc->sc_led_blink_ch);
2971         sc->sc_led_blinking = 0;
2972
2973         bwn_core_exit(mac);
2974         sc->sc_rf_enabled = 0;
2975
2976         sc->sc_flags &= ~BWN_FLAG_RUNNING;
2977 }
2978
2979 static void
2980 bwn_wme_clear(struct bwn_softc *sc)
2981 {
2982 #define MS(_v, _f)      (((_v) & _f) >> _f##_S)
2983         struct wmeParams *p;
2984         unsigned int i;
2985
2986         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
2987             ("%s:%d: fail", __func__, __LINE__));
2988
2989         for (i = 0; i < N(sc->sc_wmeParams); i++) {
2990                 p = &(sc->sc_wmeParams[i]);
2991
2992                 switch (bwn_wme_shm_offsets[i]) {
2993                 case BWN_WME_VOICE:
2994                         p->wmep_txopLimit = 0;
2995                         p->wmep_aifsn = 2;
2996                         /* XXX FIXME: log2(cwmin) */
2997                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
2998                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
2999                         break;
3000                 case BWN_WME_VIDEO:
3001                         p->wmep_txopLimit = 0;
3002                         p->wmep_aifsn = 2;
3003                         /* XXX FIXME: log2(cwmin) */
3004                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3005                         p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3006                         break;
3007                 case BWN_WME_BESTEFFORT:
3008                         p->wmep_txopLimit = 0;
3009                         p->wmep_aifsn = 3;
3010                         /* XXX FIXME: log2(cwmin) */
3011                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3012                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3013                         break;
3014                 case BWN_WME_BACKGROUND:
3015                         p->wmep_txopLimit = 0;
3016                         p->wmep_aifsn = 7;
3017                         /* XXX FIXME: log2(cwmin) */
3018                         p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3019                         p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3020                         break;
3021                 default:
3022                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3023                 }
3024         }
3025 }
3026
3027 static int
3028 bwn_core_init(struct bwn_mac *mac)
3029 {
3030         struct bwn_softc *sc = mac->mac_sc;
3031         uint64_t hf;
3032         int error;
3033
3034         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3035             ("%s:%d: fail", __func__, __LINE__));
3036
3037         siba_powerup(sc->sc_dev, 0);
3038         if (!siba_dev_isup(sc->sc_dev))
3039                 bwn_reset_core(mac,
3040                     mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3041
3042         mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3043         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3044         mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3045         BWN_GETTIME(mac->mac_phy.nexttime);
3046         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3047         bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3048         mac->mac_stats.link_noise = -95;
3049         mac->mac_reason_intr = 0;
3050         bzero(mac->mac_reason, sizeof(mac->mac_reason));
3051         mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3052 #ifdef BWN_DEBUG
3053         if (sc->sc_debug & BWN_DEBUG_XMIT)
3054                 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3055 #endif
3056         mac->mac_suspended = 1;
3057         mac->mac_task_state = 0;
3058         memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3059
3060         mac->mac_phy.init_pre(mac);
3061
3062         siba_pcicore_intr(sc->sc_dev);
3063
3064         siba_fix_imcfglobug(sc->sc_dev);
3065         bwn_bt_disable(mac);
3066         if (mac->mac_phy.prepare_hw) {
3067                 error = mac->mac_phy.prepare_hw(mac);
3068                 if (error)
3069                         goto fail0;
3070         }
3071         error = bwn_chip_init(mac);
3072         if (error)
3073                 goto fail0;
3074         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3075             siba_get_revid(sc->sc_dev));
3076         hf = bwn_hf_read(mac);
3077         if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3078                 hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3079                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3080                         hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3081                 if (mac->mac_phy.rev == 1)
3082                         hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3083         }
3084         if (mac->mac_phy.rf_ver == 0x2050) {
3085                 if (mac->mac_phy.rf_rev < 6)
3086                         hf |= BWN_HF_FORCE_VCO_RECALC;
3087                 if (mac->mac_phy.rf_rev == 6)
3088                         hf |= BWN_HF_4318_TSSI;
3089         }
3090         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3091                 hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3092         if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3093             (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3094                 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3095         hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3096         bwn_hf_write(mac, hf);
3097
3098         bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3099         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3100         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3101         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3102
3103         bwn_rate_init(mac);
3104         bwn_set_phytxctl(mac);
3105
3106         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3107             (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3108         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3109
3110         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3111                 bwn_pio_init(mac);
3112         else
3113                 bwn_dma_init(mac);
3114         bwn_wme_init(mac);
3115         bwn_spu_setdelay(mac, 1);
3116         bwn_bt_enable(mac);
3117
3118         siba_powerup(sc->sc_dev,
3119             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3120         bwn_set_macaddr(mac);
3121         bwn_crypt_init(mac);
3122
3123         /* XXX LED initializatin */
3124
3125         mac->mac_status = BWN_MAC_STATUS_INITED;
3126
3127         return (error);
3128
3129 fail0:
3130         siba_powerdown(sc->sc_dev);
3131         KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3132             ("%s:%d: fail", __func__, __LINE__));
3133         return (error);
3134 }
3135
3136 static void
3137 bwn_core_start(struct bwn_mac *mac)
3138 {
3139         struct bwn_softc *sc = mac->mac_sc;
3140         uint32_t tmp;
3141
3142         KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3143             ("%s:%d: fail", __func__, __LINE__));
3144
3145         if (siba_get_revid(sc->sc_dev) < 5)
3146                 return;
3147
3148         while (1) {
3149                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3150                 if (!(tmp & 0x00000001))
3151                         break;
3152                 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3153         }
3154
3155         bwn_mac_enable(mac);
3156         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3157         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3158
3159         mac->mac_status = BWN_MAC_STATUS_STARTED;
3160 }
3161
3162 static void
3163 bwn_core_exit(struct bwn_mac *mac)
3164 {
3165         struct bwn_softc *sc = mac->mac_sc;
3166         uint32_t macctl;
3167
3168         BWN_ASSERT_LOCKED(mac->mac_sc);
3169
3170         KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3171             ("%s:%d: fail", __func__, __LINE__));
3172
3173         if (mac->mac_status != BWN_MAC_STATUS_INITED)
3174                 return;
3175         mac->mac_status = BWN_MAC_STATUS_UNINIT;
3176
3177         macctl = BWN_READ_4(mac, BWN_MACCTL);
3178         macctl &= ~BWN_MACCTL_MCODE_RUN;
3179         macctl |= BWN_MACCTL_MCODE_JMP0;
3180         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3181
3182         bwn_dma_stop(mac);
3183         bwn_pio_stop(mac);
3184         bwn_chip_exit(mac);
3185         mac->mac_phy.switch_analog(mac, 0);
3186         siba_dev_down(sc->sc_dev, 0);
3187         siba_powerdown(sc->sc_dev);
3188 }
3189
3190 static void
3191 bwn_bt_disable(struct bwn_mac *mac)
3192 {
3193         struct bwn_softc *sc = mac->mac_sc;
3194
3195         (void)sc;
3196         /* XXX do nothing yet */
3197 }
3198
3199 static int
3200 bwn_chip_init(struct bwn_mac *mac)
3201 {
3202         struct bwn_softc *sc = mac->mac_sc;
3203         struct bwn_phy *phy = &mac->mac_phy;
3204         uint32_t macctl;
3205         int error;
3206
3207         macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3208         if (phy->gmode)
3209                 macctl |= BWN_MACCTL_GMODE;
3210         BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3211
3212         error = bwn_fw_fillinfo(mac);
3213         if (error)
3214                 return (error);
3215         error = bwn_fw_loaducode(mac);
3216         if (error)
3217                 return (error);
3218
3219         error = bwn_gpio_init(mac);
3220         if (error)
3221                 return (error);
3222
3223         error = bwn_fw_loadinitvals(mac);
3224         if (error) {
3225                 siba_gpio_set(sc->sc_dev, 0);
3226                 return (error);
3227         }
3228         phy->switch_analog(mac, 1);
3229         error = bwn_phy_init(mac);
3230         if (error) {
3231                 siba_gpio_set(sc->sc_dev, 0);
3232                 return (error);
3233         }
3234         if (phy->set_im)
3235                 phy->set_im(mac, BWN_IMMODE_NONE);
3236         if (phy->set_antenna)
3237                 phy->set_antenna(mac, BWN_ANT_DEFAULT);
3238         bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3239
3240         if (phy->type == BWN_PHYTYPE_B)
3241                 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3242         BWN_WRITE_4(mac, 0x0100, 0x01000000);
3243         if (siba_get_revid(sc->sc_dev) < 5)
3244                 BWN_WRITE_4(mac, 0x010c, 0x01000000);
3245
3246         BWN_WRITE_4(mac, BWN_MACCTL,
3247             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3248         BWN_WRITE_4(mac, BWN_MACCTL,
3249             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3250         bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3251
3252         bwn_set_opmode(mac);
3253         if (siba_get_revid(sc->sc_dev) < 3) {
3254                 BWN_WRITE_2(mac, 0x060e, 0x0000);
3255                 BWN_WRITE_2(mac, 0x0610, 0x8000);
3256                 BWN_WRITE_2(mac, 0x0604, 0x0000);
3257                 BWN_WRITE_2(mac, 0x0606, 0x0200);
3258         } else {
3259                 BWN_WRITE_4(mac, 0x0188, 0x80000000);
3260                 BWN_WRITE_4(mac, 0x018c, 0x02000000);
3261         }
3262         BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3263         BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
3264         BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3265         BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3266         BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3267         BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3268         BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3269         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3270             siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3271         BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3272         return (error);
3273 }
3274
3275 /* read hostflags */
3276 static uint64_t
3277 bwn_hf_read(struct bwn_mac *mac)
3278 {
3279         uint64_t ret;
3280
3281         ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3282         ret <<= 16;
3283         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3284         ret <<= 16;
3285         ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3286         return (ret);
3287 }
3288
3289 static void
3290 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3291 {
3292
3293         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3294             (value & 0x00000000ffffull));
3295         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3296             (value & 0x0000ffff0000ull) >> 16);
3297         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3298             (value & 0xffff00000000ULL) >> 32);
3299 }
3300
3301 static void
3302 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3303 {
3304
3305         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3306         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3307 }
3308
3309 static void
3310 bwn_rate_init(struct bwn_mac *mac)
3311 {
3312
3313         switch (mac->mac_phy.type) {
3314         case BWN_PHYTYPE_A:
3315         case BWN_PHYTYPE_G:
3316         case BWN_PHYTYPE_LP:
3317         case BWN_PHYTYPE_N:
3318                 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3319                 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3320                 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3321                 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3322                 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3323                 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3324                 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3325                 if (mac->mac_phy.type == BWN_PHYTYPE_A)
3326                         break;
3327                 /* FALLTHROUGH */
3328         case BWN_PHYTYPE_B:
3329                 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3330                 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3331                 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3332                 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3333                 break;
3334         default:
3335                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3336         }
3337 }
3338
3339 static void
3340 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3341 {
3342         uint16_t offset;
3343
3344         if (ofdm) {
3345                 offset = 0x480;
3346                 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3347         } else {
3348                 offset = 0x4c0;
3349                 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3350         }
3351         bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3352             bwn_shm_read_2(mac, BWN_SHARED, offset));
3353 }
3354
3355 static uint8_t
3356 bwn_plcp_getcck(const uint8_t bitrate)
3357 {
3358
3359         switch (bitrate) {
3360         case BWN_CCK_RATE_1MB:
3361                 return (0x0a);
3362         case BWN_CCK_RATE_2MB:
3363                 return (0x14);
3364         case BWN_CCK_RATE_5MB:
3365                 return (0x37);
3366         case BWN_CCK_RATE_11MB:
3367                 return (0x6e);
3368         }
3369         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3370         return (0);
3371 }
3372
3373 static uint8_t
3374 bwn_plcp_getofdm(const uint8_t bitrate)
3375 {
3376
3377         switch (bitrate) {
3378         case BWN_OFDM_RATE_6MB:
3379                 return (0xb);
3380         case BWN_OFDM_RATE_9MB:
3381                 return (0xf);
3382         case BWN_OFDM_RATE_12MB:
3383                 return (0xa);
3384         case BWN_OFDM_RATE_18MB:
3385                 return (0xe);
3386         case BWN_OFDM_RATE_24MB:
3387                 return (0x9);
3388         case BWN_OFDM_RATE_36MB:
3389                 return (0xd);
3390         case BWN_OFDM_RATE_48MB:
3391                 return (0x8);
3392         case BWN_OFDM_RATE_54MB:
3393                 return (0xc);
3394         }
3395         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3396         return (0);
3397 }
3398
3399 static void
3400 bwn_set_phytxctl(struct bwn_mac *mac)
3401 {
3402         uint16_t ctl;
3403
3404         ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3405             BWN_TX_PHY_TXPWR);
3406         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3407         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3408         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3409 }
3410
3411 static void
3412 bwn_pio_init(struct bwn_mac *mac)
3413 {
3414         struct bwn_pio *pio = &mac->mac_method.pio;
3415
3416         BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3417             & ~BWN_MACCTL_BIGENDIAN);
3418         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3419
3420         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3421         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3422         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3423         bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3424         bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3425         bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3426 }
3427
3428 static void
3429 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3430     int index)
3431 {
3432         struct bwn_pio_txpkt *tp;
3433         struct bwn_softc *sc = mac->mac_sc;
3434         unsigned int i;
3435
3436         tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3437         tq->tq_index = index;
3438
3439         tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3440         if (siba_get_revid(sc->sc_dev) >= 8)
3441                 tq->tq_size = 1920;
3442         else {
3443                 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3444                 tq->tq_size -= 80;
3445         }
3446
3447         TAILQ_INIT(&tq->tq_pktlist);
3448         for (i = 0; i < N(tq->tq_pkts); i++) {
3449                 tp = &(tq->tq_pkts[i]);
3450                 tp->tp_index = i;
3451                 tp->tp_queue = tq;
3452                 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3453         }
3454 }
3455
3456 static uint16_t
3457 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3458 {
3459         struct bwn_softc *sc = mac->mac_sc;
3460         static const uint16_t bases[] = {
3461                 BWN_PIO_BASE0,
3462                 BWN_PIO_BASE1,
3463                 BWN_PIO_BASE2,
3464                 BWN_PIO_BASE3,
3465                 BWN_PIO_BASE4,
3466                 BWN_PIO_BASE5,
3467                 BWN_PIO_BASE6,
3468                 BWN_PIO_BASE7,
3469         };
3470         static const uint16_t bases_rev11[] = {
3471                 BWN_PIO11_BASE0,
3472                 BWN_PIO11_BASE1,
3473                 BWN_PIO11_BASE2,
3474                 BWN_PIO11_BASE3,
3475                 BWN_PIO11_BASE4,
3476                 BWN_PIO11_BASE5,
3477         };
3478
3479         if (siba_get_revid(sc->sc_dev) >= 11) {
3480                 if (index >= N(bases_rev11))
3481                         device_printf(sc->sc_dev, "%s: warning\n", __func__);
3482                 return (bases_rev11[index]);
3483         }
3484         if (index >= N(bases))
3485                 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3486         return (bases[index]);
3487 }
3488
3489 static void
3490 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3491     int index)
3492 {
3493         struct bwn_softc *sc = mac->mac_sc;
3494
3495         prq->prq_mac = mac;
3496         prq->prq_rev = siba_get_revid(sc->sc_dev);
3497         prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3498         bwn_dma_rxdirectfifo(mac, index, 1);
3499 }
3500
3501 static void
3502 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3503 {
3504         if (tq == NULL)
3505                 return;
3506         bwn_pio_cancel_tx_packets(tq);
3507 }
3508
3509 static void
3510 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3511 {
3512
3513         bwn_destroy_pioqueue_tx(pio);
3514 }
3515
3516 static uint16_t
3517 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3518     uint16_t offset)
3519 {
3520
3521         return (BWN_READ_2(mac, tq->tq_base + offset));
3522 }
3523
3524 static void
3525 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3526 {
3527         uint32_t ctl;
3528         int type;
3529         uint16_t base;
3530
3531         type = bwn_dma_mask2type(bwn_dma_mask(mac));
3532         base = bwn_dma_base(type, idx);
3533         if (type == BWN_DMA_64BIT) {
3534                 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3535                 ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3536                 if (enable)
3537                         ctl |= BWN_DMA64_RXDIRECTFIFO;
3538                 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3539         } else {
3540                 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3541                 ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3542                 if (enable)
3543                         ctl |= BWN_DMA32_RXDIRECTFIFO;
3544                 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3545         }
3546 }
3547
3548 static uint64_t
3549 bwn_dma_mask(struct bwn_mac *mac)
3550 {
3551         uint32_t tmp;
3552         uint16_t base;
3553
3554         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3555         if (tmp & SIBA_TGSHIGH_DMA64)
3556                 return (BWN_DMA_BIT_MASK(64));
3557         base = bwn_dma_base(0, 0);
3558         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3559         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3560         if (tmp & BWN_DMA32_TXADDREXT_MASK)
3561                 return (BWN_DMA_BIT_MASK(32));
3562
3563         return (BWN_DMA_BIT_MASK(30));
3564 }
3565
3566 static int
3567 bwn_dma_mask2type(uint64_t dmamask)
3568 {
3569
3570         if (dmamask == BWN_DMA_BIT_MASK(30))
3571                 return (BWN_DMA_30BIT);
3572         if (dmamask == BWN_DMA_BIT_MASK(32))
3573                 return (BWN_DMA_32BIT);
3574         if (dmamask == BWN_DMA_BIT_MASK(64))
3575                 return (BWN_DMA_64BIT);
3576         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3577         return (BWN_DMA_30BIT);
3578 }
3579
3580 static void
3581 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3582 {
3583         struct bwn_pio_txpkt *tp;
3584         unsigned int i;
3585
3586         for (i = 0; i < N(tq->tq_pkts); i++) {
3587                 tp = &(tq->tq_pkts[i]);
3588                 if (tp->tp_m) {
3589                         m_freem(tp->tp_m);
3590                         tp->tp_m = NULL;
3591                 }
3592         }
3593 }
3594
3595 static uint16_t
3596 bwn_dma_base(int type, int controller_idx)
3597 {
3598         static const uint16_t map64[] = {
3599                 BWN_DMA64_BASE0,
3600                 BWN_DMA64_BASE1,
3601                 BWN_DMA64_BASE2,
3602                 BWN_DMA64_BASE3,
3603                 BWN_DMA64_BASE4,
3604                 BWN_DMA64_BASE5,
3605         };
3606         static const uint16_t map32[] = {
3607                 BWN_DMA32_BASE0,
3608                 BWN_DMA32_BASE1,
3609                 BWN_DMA32_BASE2,
3610                 BWN_DMA32_BASE3,
3611                 BWN_DMA32_BASE4,
3612                 BWN_DMA32_BASE5,
3613         };
3614
3615         if (type == BWN_DMA_64BIT) {
3616                 KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3617                     ("%s:%d: fail", __func__, __LINE__));
3618                 return (map64[controller_idx]);
3619         }
3620         KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3621             ("%s:%d: fail", __func__, __LINE__));
3622         return (map32[controller_idx]);
3623 }
3624
3625 static void
3626 bwn_dma_init(struct bwn_mac *mac)
3627 {
3628         struct bwn_dma *dma = &mac->mac_method.dma;
3629
3630         /* setup TX DMA channels. */
3631         bwn_dma_setup(dma->wme[WME_AC_BK]);
3632         bwn_dma_setup(dma->wme[WME_AC_BE]);
3633         bwn_dma_setup(dma->wme[WME_AC_VI]);
3634         bwn_dma_setup(dma->wme[WME_AC_VO]);
3635         bwn_dma_setup(dma->mcast);
3636         /* setup RX DMA channel. */
3637         bwn_dma_setup(dma->rx);
3638 }
3639
3640 static struct bwn_dma_ring *
3641 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3642     int for_tx, int type)
3643 {
3644         struct bwn_dma *dma = &mac->mac_method.dma;
3645         struct bwn_dma_ring *dr;
3646         struct bwn_dmadesc_generic *desc;
3647         struct bwn_dmadesc_meta *mt;
3648         struct bwn_softc *sc = mac->mac_sc;
3649         int error, i;
3650
3651         dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO);
3652         if (dr == NULL)
3653                 goto out;
3654         dr->dr_numslots = BWN_RXRING_SLOTS;
3655         if (for_tx)
3656                 dr->dr_numslots = BWN_TXRING_SLOTS;
3657
3658         dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3659             M_DEVBUF, M_NOWAIT | M_ZERO);
3660         if (dr->dr_meta == NULL)
3661                 goto fail0;
3662
3663         dr->dr_type = type;
3664         dr->dr_mac = mac;
3665         dr->dr_base = bwn_dma_base(type, controller_index);
3666         dr->dr_index = controller_index;
3667         if (type == BWN_DMA_64BIT) {
3668                 dr->getdesc = bwn_dma_64_getdesc;
3669                 dr->setdesc = bwn_dma_64_setdesc;
3670                 dr->start_transfer = bwn_dma_64_start_transfer;
3671                 dr->suspend = bwn_dma_64_suspend;
3672                 dr->resume = bwn_dma_64_resume;
3673                 dr->get_curslot = bwn_dma_64_get_curslot;
3674                 dr->set_curslot = bwn_dma_64_set_curslot;
3675         } else {
3676                 dr->getdesc = bwn_dma_32_getdesc;
3677                 dr->setdesc = bwn_dma_32_setdesc;
3678                 dr->start_transfer = bwn_dma_32_start_transfer;
3679                 dr->suspend = bwn_dma_32_suspend;
3680                 dr->resume = bwn_dma_32_resume;
3681                 dr->get_curslot = bwn_dma_32_get_curslot;
3682                 dr->set_curslot = bwn_dma_32_set_curslot;
3683         }
3684         if (for_tx) {
3685                 dr->dr_tx = 1;
3686                 dr->dr_curslot = -1;
3687         } else {
3688                 if (dr->dr_index == 0) {
3689                         dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3690                         dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3691                 } else
3692                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3693         }
3694
3695         error = bwn_dma_allocringmemory(dr);
3696         if (error)
3697                 goto fail2;
3698
3699         if (for_tx) {
3700                 /*
3701                  * Assumption: BWN_TXRING_SLOTS can be divided by
3702                  * BWN_TX_SLOTS_PER_FRAME
3703                  */
3704                 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3705                     ("%s:%d: fail", __func__, __LINE__));
3706
3707                 dr->dr_txhdr_cache =
3708                     malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3709                         BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO);
3710                 KASSERT(dr->dr_txhdr_cache != NULL,
3711                     ("%s:%d: fail", __func__, __LINE__));
3712
3713                 /*
3714                  * Create TX ring DMA stuffs
3715                  */
3716                 error = bus_dma_tag_create(dma->parent_dtag,
3717                                     BWN_ALIGN, 0,
3718                                     BUS_SPACE_MAXADDR,
3719                                     BUS_SPACE_MAXADDR,
3720                                     NULL, NULL,
3721                                     BWN_HDRSIZE(mac),
3722                                     1,
3723                                     BUS_SPACE_MAXSIZE_32BIT,
3724                                     0,
3725                                     NULL, NULL,
3726                                     &dr->dr_txring_dtag);
3727                 if (error) {
3728                         device_printf(sc->sc_dev,
3729                             "can't create TX ring DMA tag: TODO frees\n");
3730                         goto fail1;
3731                 }
3732
3733                 for (i = 0; i < dr->dr_numslots; i += 2) {
3734                         dr->getdesc(dr, i, &desc, &mt);
3735
3736                         mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3737                         mt->mt_m = NULL;
3738                         mt->mt_ni = NULL;
3739                         mt->mt_islast = 0;
3740                         error = bus_dmamap_create(dr->dr_txring_dtag, 0,
3741                             &mt->mt_dmap);
3742                         if (error) {
3743                                 device_printf(sc->sc_dev,
3744                                      "can't create RX buf DMA map\n");
3745                                 goto fail1;
3746                         }
3747
3748                         dr->getdesc(dr, i + 1, &desc, &mt);
3749
3750                         mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3751                         mt->mt_m = NULL;
3752                         mt->mt_ni = NULL;
3753                         mt->mt_islast = 1;
3754                         error = bus_dmamap_create(dma->txbuf_dtag, 0,
3755                             &mt->mt_dmap);
3756                         if (error) {
3757                                 device_printf(sc->sc_dev,
3758                                      "can't create RX buf DMA map\n");
3759                                 goto fail1;
3760                         }
3761                 }
3762         } else {
3763                 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3764                     &dr->dr_spare_dmap);
3765                 if (error) {
3766                         device_printf(sc->sc_dev,
3767                             "can't create RX buf DMA map\n");
3768                         goto out;               /* XXX wrong! */
3769                 }
3770
3771                 for (i = 0; i < dr->dr_numslots; i++) {
3772                         dr->getdesc(dr, i, &desc, &mt);
3773
3774                         error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3775                             &mt->mt_dmap);
3776                         if (error) {
3777                                 device_printf(sc->sc_dev,
3778                                     "can't create RX buf DMA map\n");
3779                                 goto out;       /* XXX wrong! */
3780                         }
3781                         error = bwn_dma_newbuf(dr, desc, mt, 1);
3782                         if (error) {
3783                                 device_printf(sc->sc_dev,
3784                                     "failed to allocate RX buf\n");
3785                                 goto out;       /* XXX wrong! */
3786                         }
3787                 }
3788
3789                 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3790                     BUS_DMASYNC_PREWRITE);
3791
3792                 dr->dr_usedslot = dr->dr_numslots;
3793         }
3794
3795       out:
3796         return (dr);
3797
3798 fail2:
3799         free(dr->dr_txhdr_cache, M_DEVBUF);
3800 fail1:
3801         free(dr->dr_meta, M_DEVBUF);
3802 fail0:
3803         free(dr, M_DEVBUF);
3804         return (NULL);
3805 }
3806
3807 static void
3808 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3809 {
3810
3811         if (dr == NULL)
3812                 return;
3813
3814         bwn_dma_free_descbufs(*dr);
3815         bwn_dma_free_ringmemory(*dr);
3816
3817         free((*dr)->dr_txhdr_cache, M_DEVBUF);
3818         free((*dr)->dr_meta, M_DEVBUF);
3819         free(*dr, M_DEVBUF);
3820
3821         *dr = NULL;
3822 }
3823
3824 static void
3825 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3826     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3827 {
3828         struct bwn_dmadesc32 *desc;
3829
3830         *meta = &(dr->dr_meta[slot]);
3831         desc = dr->dr_ring_descbase;
3832         desc = &(desc[slot]);
3833
3834         *gdesc = (struct bwn_dmadesc_generic *)desc;
3835 }
3836
3837 static void
3838 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3839     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3840     int start, int end, int irq)
3841 {
3842         struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3843         struct bwn_softc *sc = dr->dr_mac->mac_sc;
3844         uint32_t addr, addrext, ctl;
3845         int slot;
3846
3847         slot = (int)(&(desc->dma.dma32) - descbase);
3848         KASSERT(slot >= 0 && slot < dr->dr_numslots,
3849             ("%s:%d: fail", __func__, __LINE__));
3850
3851         addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
3852         addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
3853         addr |= siba_dma_translation(sc->sc_dev);
3854         ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3855         if (slot == dr->dr_numslots - 1)
3856                 ctl |= BWN_DMA32_DCTL_DTABLEEND;
3857         if (start)
3858                 ctl |= BWN_DMA32_DCTL_FRAMESTART;
3859         if (end)
3860                 ctl |= BWN_DMA32_DCTL_FRAMEEND;
3861         if (irq)
3862                 ctl |= BWN_DMA32_DCTL_IRQ;
3863         ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3864             & BWN_DMA32_DCTL_ADDREXT_MASK;
3865
3866         desc->dma.dma32.control = htole32(ctl);
3867         desc->dma.dma32.address = htole32(addr);
3868 }
3869
3870 static void
3871 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3872 {
3873
3874         BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3875             (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3876 }
3877
3878 static void
3879 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3880 {
3881
3882         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3883             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3884 }
3885
3886 static void
3887 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3888 {
3889
3890         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3891             BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
3892 }
3893
3894 static int
3895 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
3896 {
3897         uint32_t val;
3898
3899         val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
3900         val &= BWN_DMA32_RXDPTR;
3901
3902         return (val / sizeof(struct bwn_dmadesc32));
3903 }
3904
3905 static void
3906 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
3907 {
3908
3909         BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
3910             (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
3911 }
3912
3913 static void
3914 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
3915     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3916 {
3917         struct bwn_dmadesc64 *desc;
3918
3919         *meta = &(dr->dr_meta[slot]);
3920         desc = dr->dr_ring_descbase;
3921         desc = &(desc[slot]);
3922
3923         *gdesc = (struct bwn_dmadesc_generic *)desc;
3924 }
3925
3926 static void
3927 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
3928     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3929     int start, int end, int irq)
3930 {
3931         struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
3932         struct bwn_softc *sc = dr->dr_mac->mac_sc;
3933         int slot;
3934         uint32_t ctl0 = 0, ctl1 = 0;
3935         uint32_t addrlo, addrhi;
3936         uint32_t addrext;
3937
3938         slot = (int)(&(desc->dma.dma64) - descbase);
3939         KASSERT(slot >= 0 && slot < dr->dr_numslots,
3940             ("%s:%d: fail", __func__, __LINE__));
3941
3942         addrlo = (uint32_t) (dmaaddr & 0xffffffff);
3943         addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
3944         addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
3945             30;
3946         addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
3947         if (slot == dr->dr_numslots - 1)
3948                 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
3949         if (start)
3950                 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
3951         if (end)
3952                 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
3953         if (irq)
3954                 ctl0 |= BWN_DMA64_DCTL0_IRQ;
3955         ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
3956         ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
3957             & BWN_DMA64_DCTL1_ADDREXT_MASK;
3958
3959         desc->dma.dma64.control0 = htole32(ctl0);
3960         desc->dma.dma64.control1 = htole32(ctl1);
3961         desc->dma.dma64.address_low = htole32(addrlo);
3962         desc->dma.dma64.address_high = htole32(addrhi);
3963 }
3964
3965 static void
3966 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
3967 {
3968
3969         BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
3970             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
3971 }
3972
3973 static void
3974 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
3975 {
3976
3977         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
3978             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
3979 }
3980
3981 static void
3982 bwn_dma_64_resume(struct bwn_dma_ring *dr)
3983 {
3984
3985         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
3986             BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
3987 }
3988
3989 static int
3990 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
3991 {
3992         uint32_t val;
3993
3994         val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
3995         val &= BWN_DMA64_RXSTATDPTR;
3996
3997         return (val / sizeof(struct bwn_dmadesc64));
3998 }
3999
4000 static void
4001 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4002 {
4003
4004         BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4005             (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4006 }
4007
4008 static int
4009 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4010 {
4011         struct bwn_mac *mac = dr->dr_mac;
4012         struct bwn_dma *dma = &mac->mac_method.dma;
4013         struct bwn_softc *sc = mac->mac_sc;
4014         int error;
4015
4016         error = bus_dma_tag_create(dma->parent_dtag,
4017                             BWN_ALIGN, 0,
4018                             BUS_SPACE_MAXADDR,
4019                             BUS_SPACE_MAXADDR,
4020                             NULL, NULL,
4021                             BWN_DMA_RINGMEMSIZE,
4022                             1,
4023                             BUS_SPACE_MAXSIZE_32BIT,
4024                             0,
4025                             NULL, NULL,
4026                             &dr->dr_ring_dtag);
4027         if (error) {
4028                 device_printf(sc->sc_dev,
4029                     "can't create TX ring DMA tag: TODO frees\n");
4030                 return (-1);
4031         }
4032
4033         error = bus_dmamem_alloc(dr->dr_ring_dtag,
4034             &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4035             &dr->dr_ring_dmap);
4036         if (error) {
4037                 device_printf(sc->sc_dev,
4038                     "can't allocate DMA mem: TODO frees\n");
4039                 return (-1);
4040         }
4041         error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4042             dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4043             bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
4044         if (error) {
4045                 device_printf(sc->sc_dev,
4046                     "can't load DMA mem: TODO free\n");
4047                 return (-1);
4048         }
4049
4050         return (0);
4051 }
4052
4053 static void
4054 bwn_dma_setup(struct bwn_dma_ring *dr)
4055 {
4056         struct bwn_softc *sc = dr->dr_mac->mac_sc;
4057         uint64_t ring64;
4058         uint32_t addrext, ring32, value;
4059         uint32_t trans = siba_dma_translation(sc->sc_dev);
4060
4061         if (dr->dr_tx) {
4062                 dr->dr_curslot = -1;
4063
4064                 if (dr->dr_type == BWN_DMA_64BIT) {
4065                         ring64 = (uint64_t)(dr->dr_ring_dmabase);
4066                         addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4067                             >> 30;
4068                         value = BWN_DMA64_TXENABLE;
4069                         value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4070                             & BWN_DMA64_TXADDREXT_MASK;
4071                         BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4072                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4073                             (ring64 & 0xffffffff));
4074                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4075                             ((ring64 >> 32) &
4076                             ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4077                 } else {
4078                         ring32 = (uint32_t)(dr->dr_ring_dmabase);
4079                         addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4080                         value = BWN_DMA32_TXENABLE;
4081                         value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4082                             & BWN_DMA32_TXADDREXT_MASK;
4083                         BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4084                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4085                             (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4086                 }
4087                 return;
4088         }
4089
4090         /*
4091          * set for RX
4092          */
4093         dr->dr_usedslot = dr->dr_numslots;
4094
4095         if (dr->dr_type == BWN_DMA_64BIT) {
4096                 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4097                 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4098                 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4099                 value |= BWN_DMA64_RXENABLE;
4100                 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4101                     & BWN_DMA64_RXADDREXT_MASK;
4102                 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4103                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4104                 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4105                     ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4106                     | (trans << 1));
4107                 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4108                     sizeof(struct bwn_dmadesc64));
4109         } else {
4110                 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4111                 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4112                 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4113                 value |= BWN_DMA32_RXENABLE;
4114                 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4115                     & BWN_DMA32_RXADDREXT_MASK;
4116                 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4117                 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4118                     (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4119                 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4120                     sizeof(struct bwn_dmadesc32));
4121         }
4122 }
4123
4124 static void
4125 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4126 {
4127
4128         bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4129         bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4130             dr->dr_ring_dmap);
4131 }
4132
4133 static void
4134 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4135 {
4136
4137         if (dr->dr_tx) {
4138                 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4139                 if (dr->dr_type == BWN_DMA_64BIT) {
4140                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4141                         BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4142                 } else
4143                         BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4144         } else {
4145                 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4146                 if (dr->dr_type == BWN_DMA_64BIT) {
4147                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4148                         BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4149                 } else
4150                         BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4151         }
4152 }
4153
4154 static void
4155 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4156 {
4157         struct bwn_dmadesc_generic *desc;
4158         struct bwn_dmadesc_meta *meta;
4159         struct bwn_mac *mac = dr->dr_mac;
4160         struct bwn_dma *dma = &mac->mac_method.dma;
4161         struct bwn_softc *sc = mac->mac_sc;
4162         int i;
4163
4164         if (!dr->dr_usedslot)
4165                 return;
4166         for (i = 0; i < dr->dr_numslots; i++) {
4167                 dr->getdesc(dr, i, &desc, &meta);
4168
4169                 if (meta->mt_m == NULL) {
4170                         if (!dr->dr_tx)
4171                                 device_printf(sc->sc_dev, "%s: not TX?\n",
4172                                     __func__);
4173                         continue;
4174                 }
4175                 if (dr->dr_tx) {
4176                         if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
4177                                 bus_dmamap_unload(dr->dr_txring_dtag,
4178                                     meta->mt_dmap);
4179                         else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
4180                                 bus_dmamap_unload(dma->txbuf_dtag,
4181                                     meta->mt_dmap);
4182                 } else
4183                         bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4184                 bwn_dma_free_descbuf(dr, meta);
4185         }
4186 }
4187
4188 static int
4189 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4190     int type)
4191 {
4192         struct bwn_softc *sc = mac->mac_sc;
4193         uint32_t value;
4194         int i;
4195         uint16_t offset;
4196
4197         for (i = 0; i < 10; i++) {
4198                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4199                     BWN_DMA32_TXSTATUS;
4200                 value = BWN_READ_4(mac, base + offset);
4201                 if (type == BWN_DMA_64BIT) {
4202                         value &= BWN_DMA64_TXSTAT;
4203                         if (value == BWN_DMA64_TXSTAT_DISABLED ||
4204                             value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4205                             value == BWN_DMA64_TXSTAT_STOPPED)
4206                                 break;
4207                 } else {
4208                         value &= BWN_DMA32_TXSTATE;
4209                         if (value == BWN_DMA32_TXSTAT_DISABLED ||
4210                             value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4211                             value == BWN_DMA32_TXSTAT_STOPPED)
4212                                 break;
4213                 }
4214                 DELAY(1000);
4215         }
4216         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4217         BWN_WRITE_4(mac, base + offset, 0);
4218         for (i = 0; i < 10; i++) {
4219                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4220                                                    BWN_DMA32_TXSTATUS;
4221                 value = BWN_READ_4(mac, base + offset);
4222                 if (type == BWN_DMA_64BIT) {
4223                         value &= BWN_DMA64_TXSTAT;
4224                         if (value == BWN_DMA64_TXSTAT_DISABLED) {
4225                                 i = -1;
4226                                 break;
4227                         }
4228                 } else {
4229                         value &= BWN_DMA32_TXSTATE;
4230                         if (value == BWN_DMA32_TXSTAT_DISABLED) {
4231                                 i = -1;
4232                                 break;
4233                         }
4234                 }
4235                 DELAY(1000);
4236         }
4237         if (i != -1) {
4238                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4239                 return (ENODEV);
4240         }
4241         DELAY(1000);
4242
4243         return (0);
4244 }
4245
4246 static int
4247 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4248     int type)
4249 {
4250         struct bwn_softc *sc = mac->mac_sc;
4251         uint32_t value;
4252         int i;
4253         uint16_t offset;
4254
4255         offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4256         BWN_WRITE_4(mac, base + offset, 0);
4257         for (i = 0; i < 10; i++) {
4258                 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4259                     BWN_DMA32_RXSTATUS;
4260                 value = BWN_READ_4(mac, base + offset);
4261                 if (type == BWN_DMA_64BIT) {
4262                         value &= BWN_DMA64_RXSTAT;
4263                         if (value == BWN_DMA64_RXSTAT_DISABLED) {
4264                                 i = -1;
4265                                 break;
4266                         }
4267                 } else {
4268                         value &= BWN_DMA32_RXSTATE;
4269                         if (value == BWN_DMA32_RXSTAT_DISABLED) {
4270                                 i = -1;
4271                                 break;
4272                         }
4273                 }
4274                 DELAY(1000);
4275         }
4276         if (i != -1) {
4277                 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4278                 return (ENODEV);
4279         }
4280
4281         return (0);
4282 }
4283
4284 static void
4285 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4286     struct bwn_dmadesc_meta *meta)
4287 {
4288
4289         if (meta->mt_m != NULL) {
4290                 m_freem(meta->mt_m);
4291                 meta->mt_m = NULL;
4292         }
4293         if (meta->mt_ni != NULL) {
4294                 ieee80211_free_node(meta->mt_ni);
4295                 meta->mt_ni = NULL;
4296         }
4297 }
4298
4299 static void
4300 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4301 {
4302         struct bwn_rxhdr4 *rxhdr;
4303         unsigned char *frame;
4304
4305         rxhdr = mtod(m, struct bwn_rxhdr4 *);
4306         rxhdr->frame_len = 0;
4307
4308         KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4309             sizeof(struct bwn_plcp6) + 2,
4310             ("%s:%d: fail", __func__, __LINE__));
4311         frame = mtod(m, char *) + dr->dr_frameoffset;
4312         memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4313 }
4314
4315 static uint8_t
4316 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4317 {
4318         unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4319
4320         return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4321             == 0xff);
4322 }
4323
4324 static void
4325 bwn_wme_init(struct bwn_mac *mac)
4326 {
4327
4328         bwn_wme_load(mac);
4329
4330         /* enable WME support. */
4331         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4332         BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4333             BWN_IFSCTL_USE_EDCF);
4334 }
4335
4336 static void
4337 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4338 {
4339         struct bwn_softc *sc = mac->mac_sc;
4340         struct ieee80211com *ic = &sc->sc_ic;
4341         uint16_t delay; /* microsec */
4342
4343         delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4344         if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4345                 delay = 500;
4346         if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4347                 delay = max(delay, (uint16_t)2400);
4348
4349         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4350 }
4351
4352 static void
4353 bwn_bt_enable(struct bwn_mac *mac)
4354 {
4355         struct bwn_softc *sc = mac->mac_sc;
4356         uint64_t hf;
4357
4358         if (bwn_bluetooth == 0)
4359                 return;
4360         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4361                 return;
4362         if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4363                 return;
4364
4365         hf = bwn_hf_read(mac);
4366         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4367                 hf |= BWN_HF_BT_COEXISTALT;
4368         else
4369                 hf |= BWN_HF_BT_COEXIST;
4370         bwn_hf_write(mac, hf);
4371 }
4372
4373 static void
4374 bwn_set_macaddr(struct bwn_mac *mac)
4375 {
4376
4377         bwn_mac_write_bssid(mac);
4378         bwn_mac_setfilter(mac, BWN_MACFILTER_SELF,
4379             mac->mac_sc->sc_ic.ic_macaddr);
4380 }
4381
4382 static void
4383 bwn_clear_keys(struct bwn_mac *mac)
4384 {
4385         int i;
4386
4387         for (i = 0; i < mac->mac_max_nr_keys; i++) {
4388                 KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4389                     ("%s:%d: fail", __func__, __LINE__));
4390
4391                 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4392                     NULL, BWN_SEC_KEYSIZE, NULL);
4393                 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4394                         bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4395                             NULL, BWN_SEC_KEYSIZE, NULL);
4396                 }
4397                 mac->mac_key[i].keyconf = NULL;
4398         }
4399 }
4400
4401 static void
4402 bwn_crypt_init(struct bwn_mac *mac)
4403 {
4404         struct bwn_softc *sc = mac->mac_sc;
4405
4406         mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4407         KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4408             ("%s:%d: fail", __func__, __LINE__));
4409         mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4410         mac->mac_ktp *= 2;
4411         if (siba_get_revid(sc->sc_dev) >= 5)
4412                 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4413         bwn_clear_keys(mac);
4414 }
4415
4416 static void
4417 bwn_chip_exit(struct bwn_mac *mac)
4418 {
4419         struct bwn_softc *sc = mac->mac_sc;
4420
4421         bwn_phy_exit(mac);
4422         siba_gpio_set(sc->sc_dev, 0);
4423 }
4424
4425 static int
4426 bwn_fw_fillinfo(struct bwn_mac *mac)
4427 {
4428         int error;
4429
4430         error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4431         if (error == 0)
4432                 return (0);
4433         error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4434         if (error == 0)
4435                 return (0);
4436         return (error);
4437 }
4438
4439 static int
4440 bwn_gpio_init(struct bwn_mac *mac)
4441 {
4442         struct bwn_softc *sc = mac->mac_sc;
4443         uint32_t mask = 0x1f, set = 0xf, value;
4444
4445         BWN_WRITE_4(mac, BWN_MACCTL,
4446             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4447         BWN_WRITE_2(mac, BWN_GPIO_MASK,
4448             BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4449
4450         if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4451                 mask |= 0x0060;
4452                 set |= 0x0060;
4453         }
4454         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4455                 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4456                     BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4457                 mask |= 0x0200;
4458                 set |= 0x0200;
4459         }
4460         if (siba_get_revid(sc->sc_dev) >= 2)
4461                 mask |= 0x0010;
4462
4463         value = siba_gpio_get(sc->sc_dev);
4464         if (value == -1)
4465                 return (0);
4466         siba_gpio_set(sc->sc_dev, (value & mask) | set);
4467
4468         return (0);
4469 }
4470
4471 static int
4472 bwn_fw_loadinitvals(struct bwn_mac *mac)
4473 {
4474 #define GETFWOFFSET(fwp, offset)                                \
4475         ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4476         const size_t hdr_len = sizeof(struct bwn_fwhdr);
4477         const struct bwn_fwhdr *hdr;
4478         struct bwn_fw *fw = &mac->mac_fw;
4479         int error;
4480
4481         hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4482         error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4483             be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4484         if (error)
4485                 return (error);
4486         if (fw->initvals_band.fw) {
4487                 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4488                 error = bwn_fwinitvals_write(mac,
4489                     GETFWOFFSET(fw->initvals_band, hdr_len),
4490                     be32toh(hdr->size),
4491                     fw->initvals_band.fw->datasize - hdr_len);
4492         }
4493         return (error);
4494 #undef GETFWOFFSET
4495 }
4496
4497 static int
4498 bwn_phy_init(struct bwn_mac *mac)
4499 {
4500         struct bwn_softc *sc = mac->mac_sc;
4501         int error;
4502
4503         mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4504         mac->mac_phy.rf_onoff(mac, 1);
4505         error = mac->mac_phy.init(mac);
4506         if (error) {
4507                 device_printf(sc->sc_dev, "PHY init failed\n");
4508                 goto fail0;
4509         }
4510         error = bwn_switch_channel(mac,
4511             mac->mac_phy.get_default_chan(mac));
4512         if (error) {
4513                 device_printf(sc->sc_dev,
4514                     "failed to switch default channel\n");
4515                 goto fail1;
4516         }
4517         return (0);
4518 fail1:
4519         if (mac->mac_phy.exit)
4520                 mac->mac_phy.exit(mac);
4521 fail0:
4522         mac->mac_phy.rf_onoff(mac, 0);
4523
4524         return (error);
4525 }
4526
4527 static void
4528 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4529 {
4530         uint16_t ant;
4531         uint16_t tmp;
4532
4533         ant = bwn_ant2phy(antenna);
4534
4535         /* For ACK/CTS */
4536         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4537         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4538         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4539         /* For Probe Resposes */
4540         tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4541         tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4542         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4543 }
4544
4545 static void
4546 bwn_set_opmode(struct bwn_mac *mac)
4547 {
4548         struct bwn_softc *sc = mac->mac_sc;
4549         struct ieee80211com *ic = &sc->sc_ic;
4550         uint32_t ctl;
4551         uint16_t cfp_pretbtt;
4552
4553         ctl = BWN_READ_4(mac, BWN_MACCTL);
4554         ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4555             BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4556             BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4557         ctl |= BWN_MACCTL_STA;
4558
4559         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4560             ic->ic_opmode == IEEE80211_M_MBSS)
4561                 ctl |= BWN_MACCTL_HOSTAP;
4562         else if (ic->ic_opmode == IEEE80211_M_IBSS)
4563                 ctl &= ~BWN_MACCTL_STA;
4564         ctl |= sc->sc_filters;
4565
4566         if (siba_get_revid(sc->sc_dev) <= 4)
4567                 ctl |= BWN_MACCTL_PROMISC;
4568
4569         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4570
4571         cfp_pretbtt = 2;
4572         if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4573                 if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4574                     siba_get_chiprev(sc->sc_dev) == 3)
4575                         cfp_pretbtt = 100;
4576                 else
4577                         cfp_pretbtt = 50;
4578         }
4579         BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4580 }
4581
4582 static int
4583 bwn_dma_gettype(struct bwn_mac *mac)
4584 {
4585         uint32_t tmp;
4586         uint16_t base;
4587
4588         tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4589         if (tmp & SIBA_TGSHIGH_DMA64)
4590                 return (BWN_DMA_64BIT);
4591         base = bwn_dma_base(0, 0);
4592         BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4593         tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4594         if (tmp & BWN_DMA32_TXADDREXT_MASK)
4595                 return (BWN_DMA_32BIT);
4596
4597         return (BWN_DMA_30BIT);
4598 }
4599
4600 static void
4601 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4602 {
4603         if (!error) {
4604                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4605                 *((bus_addr_t *)arg) = seg->ds_addr;
4606         }
4607 }
4608
4609 static void
4610 bwn_phy_g_init_sub(struct bwn_mac *mac)
4611 {
4612         struct bwn_phy *phy = &mac->mac_phy;
4613         struct bwn_phy_g *pg = &phy->phy_g;
4614         struct bwn_softc *sc = mac->mac_sc;
4615         uint16_t i, tmp;
4616
4617         if (phy->rev == 1)
4618                 bwn_phy_init_b5(mac);
4619         else
4620                 bwn_phy_init_b6(mac);
4621
4622         if (phy->rev >= 2 || phy->gmode)
4623                 bwn_phy_init_a(mac);
4624
4625         if (phy->rev >= 2) {
4626                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4627                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4628         }
4629         if (phy->rev == 2) {
4630                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4631                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4632         }
4633         if (phy->rev > 5) {
4634                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4635                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4636         }
4637         if (phy->gmode || phy->rev >= 2) {
4638                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4639                 tmp &= BWN_PHYVER_VERSION;
4640                 if (tmp == 3 || tmp == 5) {
4641                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4642                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4643                 }
4644                 if (tmp == 5) {
4645                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4646                             0x1f00);
4647                 }
4648         }
4649         if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4650                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4651         if (phy->rf_rev == 8) {
4652                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4653                 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4654         }
4655         if (BWN_HAS_LOOPBACK(phy))
4656                 bwn_loopback_calcgain(mac);
4657
4658         if (phy->rf_rev != 8) {
4659                 if (pg->pg_initval == 0xffff)
4660                         pg->pg_initval = bwn_rf_init_bcm2050(mac);
4661                 else
4662                         BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4663         }
4664         bwn_lo_g_init(mac);
4665         if (BWN_HAS_TXMAG(phy)) {
4666                 BWN_RF_WRITE(mac, 0x52,
4667                     (BWN_RF_READ(mac, 0x52) & 0xff00)
4668                     | pg->pg_loctl.tx_bias |
4669                     pg->pg_loctl.tx_magn);
4670         } else {
4671                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4672         }
4673         if (phy->rev >= 6) {
4674                 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4675                     (pg->pg_loctl.tx_bias << 12));
4676         }
4677         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4678                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4679         else
4680                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4681         if (phy->rev < 2)
4682                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4683         else
4684                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4685         if (phy->gmode || phy->rev >= 2) {
4686                 bwn_lo_g_adjust(mac);
4687                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4688         }
4689
4690         if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4691                 for (i = 0; i < 64; i++) {
4692                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4693                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4694                             (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4695                             -32), 31));
4696                 }
4697                 bwn_nrssi_threshold(mac);
4698         } else if (phy->gmode || phy->rev >= 2) {
4699                 if (pg->pg_nrssi[0] == -1000) {
4700                         KASSERT(pg->pg_nrssi[1] == -1000,
4701                             ("%s:%d: fail", __func__, __LINE__));
4702                         bwn_nrssi_slope_11g(mac);
4703                 } else
4704                         bwn_nrssi_threshold(mac);
4705         }
4706         if (phy->rf_rev == 8)
4707                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4708         bwn_phy_hwpctl_init(mac);
4709         if ((siba_get_chipid(sc->sc_dev) == 0x4306
4710              && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4711                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4712                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4713         }
4714 }
4715
4716 static uint8_t
4717 bwn_has_hwpctl(struct bwn_mac *mac)
4718 {
4719
4720         if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4721                 return (0);
4722         return (mac->mac_phy.use_hwpctl(mac));
4723 }
4724
4725 static void
4726 bwn_phy_init_b5(struct bwn_mac *mac)
4727 {
4728         struct bwn_phy *phy = &mac->mac_phy;
4729         struct bwn_phy_g *pg = &phy->phy_g;
4730         struct bwn_softc *sc = mac->mac_sc;
4731         uint16_t offset, value;
4732         uint8_t old_channel;
4733
4734         if (phy->analog == 1)
4735                 BWN_RF_SET(mac, 0x007a, 0x0050);
4736         if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4737             (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4738                 value = 0x2120;
4739                 for (offset = 0x00a8; offset < 0x00c7; offset++) {
4740                         BWN_PHY_WRITE(mac, offset, value);
4741                         value += 0x202;
4742                 }
4743         }
4744         BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4745         if (phy->rf_ver == 0x2050)
4746                 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4747
4748         if (phy->gmode || phy->rev >= 2) {
4749                 if (phy->rf_ver == 0x2050) {
4750                         BWN_RF_SET(mac, 0x007a, 0x0020);
4751                         BWN_RF_SET(mac, 0x0051, 0x0004);
4752                 }
4753                 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4754
4755                 BWN_PHY_SET(mac, 0x0802, 0x0100);
4756                 BWN_PHY_SET(mac, 0x042b, 0x2000);
4757
4758                 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4759
4760                 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4761                 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4762                 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4763         }
4764
4765         if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4766                 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4767
4768         if (phy->analog == 1) {
4769                 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4770                 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4771                 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4772                 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4773                 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4774         } else
4775                 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4776         BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4777         BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4778
4779         if (phy->analog == 1)
4780                 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4781         else
4782                 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4783
4784         if (phy->analog == 0)
4785                 BWN_WRITE_2(mac, 0x03e4, 0x3000);
4786
4787         old_channel = phy->chan;
4788         bwn_phy_g_switch_chan(mac, 7, 0);
4789
4790         if (phy->rf_ver != 0x2050) {
4791                 BWN_RF_WRITE(mac, 0x0075, 0x0080);
4792                 BWN_RF_WRITE(mac, 0x0079, 0x0081);
4793         }
4794
4795         BWN_RF_WRITE(mac, 0x0050, 0x0020);
4796         BWN_RF_WRITE(mac, 0x0050, 0x0023);
4797
4798         if (phy->rf_ver == 0x2050) {
4799                 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4800                 BWN_RF_WRITE(mac, 0x005a, 0x0070);
4801         }
4802
4803         BWN_RF_WRITE(mac, 0x005b, 0x007b);
4804         BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4805         BWN_RF_SET(mac, 0x007a, 0x0007);
4806
4807         bwn_phy_g_switch_chan(mac, old_channel, 0);
4808         BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4809         BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4810         BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4811
4812         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4813             pg->pg_txctl);
4814
4815         if (phy->rf_ver == 0x2050)
4816                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
4817
4818         BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4819 }
4820
4821 static void
4822 bwn_loopback_calcgain(struct bwn_mac *mac)
4823 {
4824         struct bwn_phy *phy = &mac->mac_phy;
4825         struct bwn_phy_g *pg = &phy->phy_g;
4826         struct bwn_softc *sc = mac->mac_sc;
4827         uint16_t backup_phy[16] = { 0 };
4828         uint16_t backup_radio[3];
4829         uint16_t backup_bband;
4830         uint16_t i, j, loop_i_max;
4831         uint16_t trsw_rx;
4832         uint16_t loop1_outer_done, loop1_inner_done;
4833
4834         backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4835         backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4836         backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4837         backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4838         if (phy->rev != 1) {
4839                 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4840                 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4841         }
4842         backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4843         backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4844         backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4845         backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4846         backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4847         backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4848         backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4849         backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4850         backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4851         backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4852         backup_bband = pg->pg_bbatt.att;
4853         backup_radio[0] = BWN_RF_READ(mac, 0x52);
4854         backup_radio[1] = BWN_RF_READ(mac, 0x43);
4855         backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4856
4857         BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4858         BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4859         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4860         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4861         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4862         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4863         if (phy->rev != 1) {
4864                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4865                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4866                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4867                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4868         }
4869         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4870         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4871         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4872         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4873
4874         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4875         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4876         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4877
4878         BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4879         if (phy->rev != 1) {
4880                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4881                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4882         }
4883         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4884
4885         if (phy->rf_rev == 8)
4886                 BWN_RF_WRITE(mac, 0x43, 0x000f);
4887         else {
4888                 BWN_RF_WRITE(mac, 0x52, 0);
4889                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4890         }
4891         bwn_phy_g_set_bbatt(mac, 11);
4892
4893         if (phy->rev >= 3)
4894                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
4895         else
4896                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
4897         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
4898
4899         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
4900         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
4901
4902         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
4903         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
4904
4905         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
4906                 if (phy->rev >= 7) {
4907                         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
4908                         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
4909                 }
4910         }
4911         BWN_RF_MASK(mac, 0x7a, 0x00f7);
4912
4913         j = 0;
4914         loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
4915         for (i = 0; i < loop_i_max; i++) {
4916                 for (j = 0; j < 16; j++) {
4917                         BWN_RF_WRITE(mac, 0x43, i);
4918                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
4919                             (j << 8));
4920                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4921                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4922                         DELAY(20);
4923                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4924                                 goto done0;
4925                 }
4926         }
4927 done0:
4928         loop1_outer_done = i;
4929         loop1_inner_done = j;
4930         if (j >= 8) {
4931                 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
4932                 trsw_rx = 0x1b;
4933                 for (j = j - 8; j < 16; j++) {
4934                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
4935                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4936                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4937                         DELAY(20);
4938                         trsw_rx -= 3;
4939                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4940                                 goto done1;
4941                 }
4942         } else
4943                 trsw_rx = 0x18;
4944 done1:
4945
4946         if (phy->rev != 1) {
4947                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
4948                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
4949         }
4950         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
4951         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
4952         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
4953         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
4954         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
4955         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
4956         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
4957         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
4958         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
4959
4960         bwn_phy_g_set_bbatt(mac, backup_bband);
4961
4962         BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
4963         BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
4964         BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
4965
4966         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
4967         DELAY(10);
4968         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
4969         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
4970         BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
4971         BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
4972
4973         pg->pg_max_lb_gain =
4974             ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
4975         pg->pg_trsw_rx_gain = trsw_rx * 2;
4976 }
4977
4978 static uint16_t
4979 bwn_rf_init_bcm2050(struct bwn_mac *mac)
4980 {
4981         struct bwn_phy *phy = &mac->mac_phy;
4982         uint32_t tmp1 = 0, tmp2 = 0;
4983         uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
4984             analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
4985             radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
4986         static const uint8_t rcc_table[] = {
4987                 0x02, 0x03, 0x01, 0x0f,
4988                 0x06, 0x07, 0x05, 0x0f,
4989                 0x0a, 0x0b, 0x09, 0x0f,
4990                 0x0e, 0x0f, 0x0d, 0x0f,
4991         };
4992
4993         loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
4994             rfoverval = rfover = cck3 = 0;
4995         radio0 = BWN_RF_READ(mac, 0x43);
4996         radio1 = BWN_RF_READ(mac, 0x51);
4997         radio2 = BWN_RF_READ(mac, 0x52);
4998         pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4999         cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5000         cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5001         cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5002
5003         if (phy->type == BWN_PHYTYPE_B) {
5004                 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5005                 reg0 = BWN_READ_2(mac, 0x3ec);
5006
5007                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5008                 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5009         } else if (phy->gmode || phy->rev >= 2) {
5010                 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5011                 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5012                 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5013                 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5014                 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5015                 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5016
5017                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5018                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5019                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5020                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5021                 if (BWN_HAS_LOOPBACK(phy)) {
5022                         lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5023                         loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5024                         if (phy->rev >= 3)
5025                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5026                         else
5027                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5028                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5029                 }
5030
5031                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5032                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5033                         BWN_LPD(0, 1, 1)));
5034                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5035                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5036         }
5037         BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5038
5039         syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5040         BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5041         reg1 = BWN_READ_2(mac, 0x3e6);
5042         reg2 = BWN_READ_2(mac, 0x3f4);
5043
5044         if (phy->analog == 0)
5045                 BWN_WRITE_2(mac, 0x03e6, 0x0122);
5046         else {
5047                 if (phy->analog >= 2)
5048                         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5049                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5050                     (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5051         }
5052
5053         reg = BWN_RF_READ(mac, 0x60);
5054         index = (reg & 0x001e) >> 1;
5055         rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5056
5057         if (phy->type == BWN_PHYTYPE_B)
5058                 BWN_RF_WRITE(mac, 0x78, 0x26);
5059         if (phy->gmode || phy->rev >= 2) {
5060                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5061                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5062                         BWN_LPD(0, 1, 1)));
5063         }
5064         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5065         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5066         if (phy->gmode || phy->rev >= 2) {
5067                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5068                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5069                         BWN_LPD(0, 0, 1)));
5070         }
5071         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5072         BWN_RF_SET(mac, 0x51, 0x0004);
5073         if (phy->rf_rev == 8)
5074                 BWN_RF_WRITE(mac, 0x43, 0x1f);
5075         else {
5076                 BWN_RF_WRITE(mac, 0x52, 0);
5077                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5078         }
5079         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5080
5081         for (i = 0; i < 16; i++) {
5082                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5083                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5084                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5085                 if (phy->gmode || phy->rev >= 2) {
5086                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5087                             bwn_rf_2050_rfoverval(mac,
5088                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5089                 }
5090                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5091                 DELAY(10);
5092                 if (phy->gmode || phy->rev >= 2) {
5093                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5094                             bwn_rf_2050_rfoverval(mac,
5095                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5096                 }
5097                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5098                 DELAY(10);
5099                 if (phy->gmode || phy->rev >= 2) {
5100                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5101                             bwn_rf_2050_rfoverval(mac,
5102                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5103                 }
5104                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5105                 DELAY(20);
5106                 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5107                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5108                 if (phy->gmode || phy->rev >= 2) {
5109                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5110                             bwn_rf_2050_rfoverval(mac,
5111                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5112                 }
5113                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5114         }
5115         DELAY(10);
5116
5117         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5118         tmp1++;
5119         tmp1 >>= 9;
5120
5121         for (i = 0; i < 16; i++) {
5122                 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5123                 BWN_RF_WRITE(mac, 0x78, radio78);
5124                 DELAY(10);
5125                 for (j = 0; j < 16; j++) {
5126                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5127                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5128                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5129                         if (phy->gmode || phy->rev >= 2) {
5130                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5131                                     bwn_rf_2050_rfoverval(mac,
5132                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5133                         }
5134                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5135                         DELAY(10);
5136                         if (phy->gmode || phy->rev >= 2) {
5137                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5138                                     bwn_rf_2050_rfoverval(mac,
5139                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5140                         }
5141                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5142                         DELAY(10);
5143                         if (phy->gmode || phy->rev >= 2) {
5144                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5145                                     bwn_rf_2050_rfoverval(mac,
5146                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5147                         }
5148                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5149                         DELAY(10);
5150                         tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5151                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5152                         if (phy->gmode || phy->rev >= 2) {
5153                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5154                                     bwn_rf_2050_rfoverval(mac,
5155                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5156                         }
5157                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5158                 }
5159                 tmp2++;
5160                 tmp2 >>= 8;
5161                 if (tmp1 < tmp2)
5162                         break;
5163         }
5164
5165         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5166         BWN_RF_WRITE(mac, 0x51, radio1);
5167         BWN_RF_WRITE(mac, 0x52, radio2);
5168         BWN_RF_WRITE(mac, 0x43, radio0);
5169         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5170         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5171         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5172         BWN_WRITE_2(mac, 0x3e6, reg1);
5173         if (phy->analog != 0)
5174                 BWN_WRITE_2(mac, 0x3f4, reg2);
5175         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5176         bwn_spu_workaround(mac, phy->chan);
5177         if (phy->type == BWN_PHYTYPE_B) {
5178                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5179                 BWN_WRITE_2(mac, 0x3ec, reg0);
5180         } else if (phy->gmode) {
5181                 BWN_WRITE_2(mac, BWN_PHY_RADIO,
5182                             BWN_READ_2(mac, BWN_PHY_RADIO)
5183                             & 0x7fff);
5184                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5185                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5186                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5187                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5188                               analogoverval);
5189                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5190                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5191                 if (BWN_HAS_LOOPBACK(phy)) {
5192                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5193                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5194                 }
5195         }
5196
5197         return ((i > 15) ? radio78 : rcc);
5198 }
5199
5200 static void
5201 bwn_phy_init_b6(struct bwn_mac *mac)
5202 {
5203         struct bwn_phy *phy = &mac->mac_phy;
5204         struct bwn_phy_g *pg = &phy->phy_g;
5205         struct bwn_softc *sc = mac->mac_sc;
5206         uint16_t offset, val;
5207         uint8_t old_channel;
5208
5209         KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5210             ("%s:%d: fail", __func__, __LINE__));
5211
5212         BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5213         BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5214         if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5215                 BWN_RF_WRITE(mac, 0x51, 0x37);
5216                 BWN_RF_WRITE(mac, 0x52, 0x70);
5217                 BWN_RF_WRITE(mac, 0x53, 0xb3);
5218                 BWN_RF_WRITE(mac, 0x54, 0x9b);
5219                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5220                 BWN_RF_WRITE(mac, 0x5b, 0x88);
5221                 BWN_RF_WRITE(mac, 0x5d, 0x88);
5222                 BWN_RF_WRITE(mac, 0x5e, 0x88);
5223                 BWN_RF_WRITE(mac, 0x7d, 0x88);
5224                 bwn_hf_write(mac,
5225                     bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5226         }
5227         if (phy->rf_rev == 8) {
5228                 BWN_RF_WRITE(mac, 0x51, 0);
5229                 BWN_RF_WRITE(mac, 0x52, 0x40);
5230                 BWN_RF_WRITE(mac, 0x53, 0xb7);
5231                 BWN_RF_WRITE(mac, 0x54, 0x98);
5232                 BWN_RF_WRITE(mac, 0x5a, 0x88);
5233                 BWN_RF_WRITE(mac, 0x5b, 0x6b);
5234                 BWN_RF_WRITE(mac, 0x5c, 0x0f);
5235                 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5236                         BWN_RF_WRITE(mac, 0x5d, 0xfa);
5237                         BWN_RF_WRITE(mac, 0x5e, 0xd8);
5238                 } else {
5239                         BWN_RF_WRITE(mac, 0x5d, 0xf5);
5240                         BWN_RF_WRITE(mac, 0x5e, 0xb8);
5241                 }
5242                 BWN_RF_WRITE(mac, 0x0073, 0x0003);
5243                 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5244                 BWN_RF_WRITE(mac, 0x007c, 0x0001);
5245                 BWN_RF_WRITE(mac, 0x007e, 0x0008);
5246         }
5247         for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5248                 BWN_PHY_WRITE(mac, offset, val);
5249                 val -= 0x0202;
5250         }
5251         for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5252                 BWN_PHY_WRITE(mac, offset, val);
5253                 val -= 0x0202;
5254         }
5255         for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5256                 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5257                 val += 0x0202;
5258         }
5259         if (phy->type == BWN_PHYTYPE_G) {
5260                 BWN_RF_SET(mac, 0x007a, 0x0020);
5261                 BWN_RF_SET(mac, 0x0051, 0x0004);
5262                 BWN_PHY_SET(mac, 0x0802, 0x0100);
5263                 BWN_PHY_SET(mac, 0x042b, 0x2000);
5264                 BWN_PHY_WRITE(mac, 0x5b, 0);
5265                 BWN_PHY_WRITE(mac, 0x5c, 0);
5266         }
5267
5268         old_channel = phy->chan;
5269         bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5270
5271         BWN_RF_WRITE(mac, 0x0050, 0x0020);
5272         BWN_RF_WRITE(mac, 0x0050, 0x0023);
5273         DELAY(40);
5274         if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5275                 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5276                 BWN_RF_WRITE(mac, 0x50, 0x20);
5277         }
5278         if (phy->rf_rev <= 2) {
5279                 BWN_RF_WRITE(mac, 0x7c, 0x20);
5280                 BWN_RF_WRITE(mac, 0x5a, 0x70);
5281                 BWN_RF_WRITE(mac, 0x5b, 0x7b);
5282                 BWN_RF_WRITE(mac, 0x5c, 0xb0);
5283         }
5284         BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5285
5286         bwn_phy_g_switch_chan(mac, old_channel, 0);
5287
5288         BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5289         if (phy->rf_rev >= 6)
5290                 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5291         else
5292                 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5293         BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5294         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5295             pg->pg_txctl);
5296         if (phy->rf_rev <= 5)
5297                 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5298         if (phy->rf_rev <= 2)
5299                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
5300
5301         if (phy->analog == 4) {
5302                 BWN_WRITE_2(mac, 0x3e4, 9);
5303                 BWN_PHY_MASK(mac, 0x61, 0x0fff);
5304         } else
5305                 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5306         if (phy->type == BWN_PHYTYPE_B)
5307                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5308         else if (phy->type == BWN_PHYTYPE_G)
5309                 BWN_WRITE_2(mac, 0x03e6, 0x0);
5310 }
5311
5312 static void
5313 bwn_phy_init_a(struct bwn_mac *mac)
5314 {
5315         struct bwn_phy *phy = &mac->mac_phy;
5316         struct bwn_softc *sc = mac->mac_sc;
5317
5318         KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5319             ("%s:%d: fail", __func__, __LINE__));
5320
5321         if (phy->rev >= 6) {
5322                 if (phy->type == BWN_PHYTYPE_A)
5323                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5324                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5325                         BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5326                 else
5327                         BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5328         }
5329
5330         bwn_wa_init(mac);
5331
5332         if (phy->type == BWN_PHYTYPE_G &&
5333             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5334                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5335 }
5336
5337 static void
5338 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5339 {
5340         int i;
5341
5342         for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5343                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5344 }
5345
5346 static void
5347 bwn_wa_agc(struct bwn_mac *mac)
5348 {
5349         struct bwn_phy *phy = &mac->mac_phy;
5350
5351         if (phy->rev == 1) {
5352                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5353                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5354                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5355                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5356                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5357                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5358                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5359                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5360                 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5361         } else {
5362                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5363                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5364                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5365                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5366         }
5367
5368         BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5369             0x5700);
5370         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5371         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5372         BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5373         BWN_RF_SET(mac, 0x7a, 0x0008);
5374         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5375         BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5376         BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5377         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5378         if (phy->rev == 1)
5379                 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5380         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5381         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5382         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5383         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5384         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5385         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5386         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5387         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5388         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5389         if (phy->rev == 1) {
5390                 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5391                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5392         } else {
5393                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5394                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5395                 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5396                 if (phy->rev >= 6) {
5397                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5398                         BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5399                             (uint16_t)~0xf000, 0x3000);
5400                 }
5401         }
5402         BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5403         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5404         if (phy->rev == 1) {
5405                 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5406                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5407                 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5408                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5409                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5410                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5411                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5412                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5413         } else {
5414                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5415                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5416                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5417                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5418         }
5419         if (phy->rev >= 6) {
5420                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5421                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5422         }
5423         BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5424 }
5425
5426 static void
5427 bwn_wa_grev1(struct bwn_mac *mac)
5428 {
5429         struct bwn_phy *phy = &mac->mac_phy;
5430         int i;
5431         static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5432         static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5433         static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5434
5435         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5436
5437         /* init CRSTHRES and ANTDWELL */
5438         if (phy->rev == 1) {
5439                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5440         } else if (phy->rev == 2) {
5441                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5442                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5443                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5444         } else {
5445                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5446                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5447                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5448                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5449         }
5450         BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5451         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5452         BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5453
5454         /* XXX support PHY-A??? */
5455         for (i = 0; i < N(bwn_tab_finefreqg); i++)
5456                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5457                     bwn_tab_finefreqg[i]);
5458
5459         /* XXX support PHY-A??? */
5460         if (phy->rev == 1)
5461                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5462                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5463                             bwn_tab_noise_g1[i]);
5464         else
5465                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5466                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5467                             bwn_tab_noise_g2[i]);
5468
5469
5470         for (i = 0; i < N(bwn_tab_rotor); i++)
5471                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5472                     bwn_tab_rotor[i]);
5473
5474         /* XXX support PHY-A??? */
5475         if (phy->rev >= 6) {
5476                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5477                     BWN_PHY_ENCORE_EN)
5478                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5479                 else
5480                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5481         } else
5482                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5483
5484         for (i = 0; i < N(bwn_tab_retard); i++)
5485                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5486                     bwn_tab_retard[i]);
5487
5488         if (phy->rev == 1) {
5489                 for (i = 0; i < 16; i++)
5490                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5491                             i, 0x0020);
5492         } else {
5493                 for (i = 0; i < 32; i++)
5494                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5495         }
5496
5497         bwn_wa_agc(mac);
5498 }
5499
5500 static void
5501 bwn_wa_grev26789(struct bwn_mac *mac)
5502 {
5503         struct bwn_phy *phy = &mac->mac_phy;
5504         int i;
5505         static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5506         uint16_t ofdmrev;
5507
5508         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5509
5510         bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5511
5512         /* init CRSTHRES and ANTDWELL */
5513         if (phy->rev == 1)
5514                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5515         else if (phy->rev == 2) {
5516                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5517                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5518                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5519         } else {
5520                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5521                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5522                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5523                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5524         }
5525
5526         for (i = 0; i < 64; i++)
5527                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5528
5529         /* XXX support PHY-A??? */
5530         if (phy->rev == 1)
5531                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5532                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5533                             bwn_tab_noise_g1[i]);
5534         else
5535                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5536                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5537                             bwn_tab_noise_g2[i]);
5538
5539         /* XXX support PHY-A??? */
5540         if (phy->rev >= 6) {
5541                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5542                     BWN_PHY_ENCORE_EN)
5543                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5544                 else
5545                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5546         } else
5547                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5548
5549         for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5550                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5551                     bwn_tab_sigmasqr2[i]);
5552
5553         if (phy->rev == 1) {
5554                 for (i = 0; i < 16; i++)
5555                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5556                             0x0020);
5557         } else {
5558                 for (i = 0; i < 32; i++)
5559                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5560         }
5561
5562         bwn_wa_agc(mac);
5563
5564         ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5565         if (ofdmrev > 2) {
5566                 if (phy->type == BWN_PHYTYPE_A)
5567                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5568                 else
5569                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5570         } else {
5571                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5572                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5573                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5574         }
5575
5576         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5577         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5578 }
5579
5580 static void
5581 bwn_wa_init(struct bwn_mac *mac)
5582 {
5583         struct bwn_phy *phy = &mac->mac_phy;
5584         struct bwn_softc *sc = mac->mac_sc;
5585
5586         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5587
5588         switch (phy->rev) {
5589         case 1:
5590                 bwn_wa_grev1(mac);
5591                 break;
5592         case 2:
5593         case 6:
5594         case 7:
5595         case 8:
5596         case 9:
5597                 bwn_wa_grev26789(mac);
5598                 break;
5599         default:
5600                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5601         }
5602
5603         if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5604             siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5605             siba_get_pci_revid(sc->sc_dev) != 0x17) {
5606                 if (phy->rev < 2) {
5607                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5608                             0x0002);
5609                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5610                             0x0001);
5611                 } else {
5612                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5613                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5614                         if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5615                              BWN_BFL_EXTLNA) &&
5616                             (phy->rev >= 7)) {
5617                                 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5618                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5619                                     0x0020, 0x0001);
5620                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5621                                     0x0021, 0x0001);
5622                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5623                                     0x0022, 0x0001);
5624                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5625                                     0x0023, 0x0000);
5626                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5627                                     0x0000, 0x0000);
5628                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5629                                     0x0003, 0x0002);
5630                         }
5631                 }
5632         }
5633         if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5634                 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5635                 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5636         }
5637
5638         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5639         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5640 }
5641
5642 static void
5643 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5644     uint16_t value)
5645 {
5646         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5647         uint16_t addr;
5648
5649         addr = table + offset;
5650         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5651             (addr - 1 != pg->pg_ofdmtab_addr)) {
5652                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5653                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5654         }
5655         pg->pg_ofdmtab_addr = addr;
5656         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5657 }
5658
5659 static void
5660 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5661     uint32_t value)
5662 {
5663         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5664         uint16_t addr;
5665
5666         addr = table + offset;
5667         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5668             (addr - 1 != pg->pg_ofdmtab_addr)) {
5669                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5670                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5671         }
5672         pg->pg_ofdmtab_addr = addr;
5673
5674         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5675         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5676 }
5677
5678 static void
5679 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5680     uint16_t value)
5681 {
5682
5683         BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5684         BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5685 }
5686
5687 static void
5688 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5689 {
5690         struct bwn_phy *phy = &mac->mac_phy;
5691         struct bwn_softc *sc = mac->mac_sc;
5692         unsigned int i, max_loop;
5693         uint16_t value;
5694         uint32_t buffer[5] = {
5695                 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5696         };
5697
5698         if (ofdm) {
5699                 max_loop = 0x1e;
5700                 buffer[0] = 0x000201cc;
5701         } else {
5702                 max_loop = 0xfa;
5703                 buffer[0] = 0x000b846e;
5704         }
5705
5706         BWN_ASSERT_LOCKED(mac->mac_sc);
5707
5708         for (i = 0; i < 5; i++)
5709                 bwn_ram_write(mac, i * 4, buffer[i]);
5710
5711         BWN_WRITE_2(mac, 0x0568, 0x0000);
5712         BWN_WRITE_2(mac, 0x07c0,
5713             (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5714         value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5715         BWN_WRITE_2(mac, 0x050c, value);
5716         if (phy->type == BWN_PHYTYPE_LP)
5717                 BWN_WRITE_2(mac, 0x0514, 0x1a02);
5718         BWN_WRITE_2(mac, 0x0508, 0x0000);
5719         BWN_WRITE_2(mac, 0x050a, 0x0000);
5720         BWN_WRITE_2(mac, 0x054c, 0x0000);
5721         BWN_WRITE_2(mac, 0x056a, 0x0014);
5722         BWN_WRITE_2(mac, 0x0568, 0x0826);
5723         BWN_WRITE_2(mac, 0x0500, 0x0000);
5724         if (phy->type == BWN_PHYTYPE_LP)
5725                 BWN_WRITE_2(mac, 0x0502, 0x0050);
5726         else
5727                 BWN_WRITE_2(mac, 0x0502, 0x0030);
5728
5729         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5730                 BWN_RF_WRITE(mac, 0x0051, 0x0017);
5731         for (i = 0x00; i < max_loop; i++) {
5732                 value = BWN_READ_2(mac, 0x050e);
5733                 if (value & 0x0080)
5734                         break;
5735                 DELAY(10);
5736         }
5737         for (i = 0x00; i < 0x0a; i++) {
5738                 value = BWN_READ_2(mac, 0x050e);
5739                 if (value & 0x0400)
5740                         break;
5741                 DELAY(10);
5742         }
5743         for (i = 0x00; i < 0x19; i++) {
5744                 value = BWN_READ_2(mac, 0x0690);
5745                 if (!(value & 0x0100))
5746                         break;
5747                 DELAY(10);
5748         }
5749         if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5750                 BWN_RF_WRITE(mac, 0x0051, 0x0037);
5751 }
5752
5753 static void
5754 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5755 {
5756         uint32_t macctl;
5757
5758         KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5759
5760         macctl = BWN_READ_4(mac, BWN_MACCTL);
5761         if (macctl & BWN_MACCTL_BIGENDIAN)
5762                 printf("TODO: need swap\n");
5763
5764         BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5765         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5766         BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5767 }
5768
5769 static void
5770 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5771 {
5772         uint16_t value;
5773
5774         KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5775             ("%s:%d: fail", __func__, __LINE__));
5776
5777         value = (uint8_t) (ctl->q);
5778         value |= ((uint8_t) (ctl->i)) << 8;
5779         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5780 }
5781
5782 static uint16_t
5783 bwn_lo_calcfeed(struct bwn_mac *mac,
5784     uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5785 {
5786         struct bwn_phy *phy = &mac->mac_phy;
5787         struct bwn_softc *sc = mac->mac_sc;
5788         uint16_t rfover;
5789         uint16_t feedthrough;
5790
5791         if (phy->gmode) {
5792                 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5793                 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5794
5795                 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5796                     ("%s:%d: fail", __func__, __LINE__));
5797                 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5798                     ("%s:%d: fail", __func__, __LINE__));
5799
5800                 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5801
5802                 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5803                 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5804                     phy->rev > 6)
5805                         rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5806
5807                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5808                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5809                 DELAY(10);
5810                 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5811                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5812                 DELAY(10);
5813                 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5814                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5815                 DELAY(10);
5816                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5817         } else {
5818                 pga |= BWN_PHY_PGACTL_UNKNOWN;
5819                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5820                 DELAY(10);
5821                 pga |= BWN_PHY_PGACTL_LOWBANDW;
5822                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5823                 DELAY(10);
5824                 pga |= BWN_PHY_PGACTL_LPF;
5825                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5826         }
5827         DELAY(21);
5828         feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5829
5830         return (feedthrough);
5831 }
5832
5833 static uint16_t
5834 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5835     uint16_t *value, uint16_t *pad_mix_gain)
5836 {
5837         struct bwn_phy *phy = &mac->mac_phy;
5838         uint16_t reg, v, padmix;
5839
5840         if (phy->type == BWN_PHYTYPE_B) {
5841                 v = 0x30;
5842                 if (phy->rf_rev <= 5) {
5843                         reg = 0x43;
5844                         padmix = 0;
5845                 } else {
5846                         reg = 0x52;
5847                         padmix = 5;
5848                 }
5849         } else {
5850                 if (phy->rev >= 2 && phy->rf_rev == 8) {
5851                         reg = 0x43;
5852                         v = 0x10;
5853                         padmix = 2;
5854                 } else {
5855                         reg = 0x52;
5856                         v = 0x30;
5857                         padmix = 5;
5858                 }
5859         }
5860         if (value)
5861                 *value = v;
5862         if (pad_mix_gain)
5863                 *pad_mix_gain = padmix;
5864
5865         return (reg);
5866 }
5867
5868 static void
5869 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5870 {
5871         struct bwn_phy *phy = &mac->mac_phy;
5872         struct bwn_phy_g *pg = &phy->phy_g;
5873         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5874         uint16_t reg, mask;
5875         uint16_t trsw_rx, pga;
5876         uint16_t rf_pctl_reg;
5877
5878         static const uint8_t tx_bias_values[] = {
5879                 0x09, 0x08, 0x0a, 0x01, 0x00,
5880                 0x02, 0x05, 0x04, 0x06,
5881         };
5882         static const uint8_t tx_magn_values[] = {
5883                 0x70, 0x40,
5884         };
5885
5886         if (!BWN_HAS_LOOPBACK(phy)) {
5887                 rf_pctl_reg = 6;
5888                 trsw_rx = 2;
5889                 pga = 0;
5890         } else {
5891                 int lb_gain;
5892
5893                 trsw_rx = 0;
5894                 lb_gain = pg->pg_max_lb_gain / 2;
5895                 if (lb_gain > 10) {
5896                         rf_pctl_reg = 0;
5897                         pga = abs(10 - lb_gain) / 6;
5898                         pga = MIN(MAX(pga, 0), 15);
5899                 } else {
5900                         int cmp_val;
5901                         int tmp;
5902
5903                         pga = 0;
5904                         cmp_val = 0x24;
5905                         if ((phy->rev >= 2) &&
5906                             (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
5907                                 cmp_val = 0x3c;
5908                         tmp = lb_gain;
5909                         if ((10 - lb_gain) < cmp_val)
5910                                 tmp = (10 - lb_gain);
5911                         if (tmp < 0)
5912                                 tmp += 6;
5913                         else
5914                                 tmp += 3;
5915                         cmp_val /= 4;
5916                         tmp /= 4;
5917                         if (tmp >= cmp_val)
5918                                 rf_pctl_reg = cmp_val;
5919                         else
5920                                 rf_pctl_reg = tmp;
5921                 }
5922         }
5923         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
5924         bwn_phy_g_set_bbatt(mac, 2);
5925
5926         reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
5927         mask = ~mask;
5928         BWN_RF_MASK(mac, reg, mask);
5929
5930         if (BWN_HAS_TXMAG(phy)) {
5931                 int i, j;
5932                 int feedthrough;
5933                 int min_feedth = 0xffff;
5934                 uint8_t tx_magn, tx_bias;
5935
5936                 for (i = 0; i < N(tx_magn_values); i++) {
5937                         tx_magn = tx_magn_values[i];
5938                         BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
5939                         for (j = 0; j < N(tx_bias_values); j++) {
5940                                 tx_bias = tx_bias_values[j];
5941                                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
5942                                 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
5943                                     trsw_rx);
5944                                 if (feedthrough < min_feedth) {
5945                                         lo->tx_bias = tx_bias;
5946                                         lo->tx_magn = tx_magn;
5947                                         min_feedth = feedthrough;
5948                                 }
5949                                 if (lo->tx_bias == 0)
5950                                         break;
5951                         }
5952                         BWN_RF_WRITE(mac, 0x52,
5953                                           (BWN_RF_READ(mac, 0x52)
5954                                            & 0xff00) | lo->tx_bias | lo->
5955                                           tx_magn);
5956                 }
5957         } else {
5958                 lo->tx_magn = 0;
5959                 lo->tx_bias = 0;
5960                 BWN_RF_MASK(mac, 0x52, 0xfff0);
5961         }
5962
5963         BWN_GETTIME(lo->txctl_measured_time);
5964 }
5965
5966 static void
5967 bwn_lo_get_powervector(struct bwn_mac *mac)
5968 {
5969         struct bwn_phy *phy = &mac->mac_phy;
5970         struct bwn_phy_g *pg = &phy->phy_g;
5971         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5972         int i;
5973         uint64_t tmp;
5974         uint64_t power_vector = 0;
5975
5976         for (i = 0; i < 8; i += 2) {
5977                 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
5978                 power_vector |= (tmp << (i * 8));
5979                 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
5980         }
5981         if (power_vector)
5982                 lo->power_vector = power_vector;
5983
5984         BWN_GETTIME(lo->pwr_vec_read_time);
5985 }
5986
5987 static void
5988 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
5989     int use_trsw_rx)
5990 {
5991         struct bwn_phy *phy = &mac->mac_phy;
5992         struct bwn_phy_g *pg = &phy->phy_g;
5993         uint16_t tmp;
5994
5995         if (max_rx_gain < 0)
5996                 max_rx_gain = 0;
5997
5998         if (BWN_HAS_LOOPBACK(phy)) {
5999                 int trsw_rx = 0;
6000                 int trsw_rx_gain;
6001
6002                 if (use_trsw_rx) {
6003                         trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6004                         if (max_rx_gain >= trsw_rx_gain) {
6005                                 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6006                                 trsw_rx = 0x20;
6007                         }
6008                 } else
6009                         trsw_rx_gain = max_rx_gain;
6010                 if (trsw_rx_gain < 9) {
6011                         pg->pg_lna_lod_gain = 0;
6012                 } else {
6013                         pg->pg_lna_lod_gain = 1;
6014                         trsw_rx_gain -= 8;
6015                 }
6016                 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6017                 pg->pg_pga_gain = trsw_rx_gain / 3;
6018                 if (pg->pg_pga_gain >= 5) {
6019                         pg->pg_pga_gain -= 5;
6020                         pg->pg_lna_gain = 2;
6021                 } else
6022                         pg->pg_lna_gain = 0;
6023         } else {
6024                 pg->pg_lna_gain = 0;
6025                 pg->pg_trsw_rx_gain = 0x20;
6026                 if (max_rx_gain >= 0x14) {
6027                         pg->pg_lna_lod_gain = 1;
6028                         pg->pg_pga_gain = 2;
6029                 } else if (max_rx_gain >= 0x12) {
6030                         pg->pg_lna_lod_gain = 1;
6031                         pg->pg_pga_gain = 1;
6032                 } else if (max_rx_gain >= 0xf) {
6033                         pg->pg_lna_lod_gain = 1;
6034                         pg->pg_pga_gain = 0;
6035                 } else {
6036                         pg->pg_lna_lod_gain = 0;
6037                         pg->pg_pga_gain = 0;
6038                 }
6039         }
6040
6041         tmp = BWN_RF_READ(mac, 0x7a);
6042         if (pg->pg_lna_lod_gain == 0)
6043                 tmp &= ~0x0008;
6044         else
6045                 tmp |= 0x0008;
6046         BWN_RF_WRITE(mac, 0x7a, tmp);
6047 }
6048
6049 static void
6050 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6051 {
6052         struct bwn_phy *phy = &mac->mac_phy;
6053         struct bwn_phy_g *pg = &phy->phy_g;
6054         struct bwn_softc *sc = mac->mac_sc;
6055         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6056         struct timespec ts;
6057         uint16_t tmp;
6058
6059         if (bwn_has_hwpctl(mac)) {
6060                 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6061                 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6062                 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6063                 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6064                 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6065
6066                 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6067                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6068                 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6069                 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6070         }
6071         if (phy->type == BWN_PHYTYPE_B &&
6072             phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6073                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6074                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6075         }
6076         if (phy->rev >= 2) {
6077                 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6078                 sav->phy_analogoverval =
6079                     BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6080                 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6081                 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6082                 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6083                 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6084                 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6085
6086                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6087                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6088                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6089                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6090                 if (phy->type == BWN_PHYTYPE_G) {
6091                         if ((phy->rev >= 7) &&
6092                             (siba_sprom_get_bf_lo(sc->sc_dev) &
6093                              BWN_BFL_EXTLNA)) {
6094                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6095                         } else {
6096                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6097                         }
6098                 } else {
6099                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6100                 }
6101                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6102         }
6103         sav->reg0 = BWN_READ_2(mac, 0x3f4);
6104         sav->reg1 = BWN_READ_2(mac, 0x3e2);
6105         sav->rf0 = BWN_RF_READ(mac, 0x43);
6106         sav->rf1 = BWN_RF_READ(mac, 0x7a);
6107         sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6108         sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6109         sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6110         sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6111
6112         if (!BWN_HAS_TXMAG(phy)) {
6113                 sav->rf2 = BWN_RF_READ(mac, 0x52);
6114                 sav->rf2 &= 0x00f0;
6115         }
6116         if (phy->type == BWN_PHYTYPE_B) {
6117                 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6118                 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6119                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6120                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6121         } else {
6122                 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6123                             | 0x8000);
6124         }
6125         BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6126                     & 0xf000);
6127
6128         tmp =
6129             (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6130         BWN_PHY_WRITE(mac, tmp, 0x007f);
6131
6132         tmp = sav->phy_syncctl;
6133         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6134         tmp = sav->rf1;
6135         BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6136
6137         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6138         if (phy->type == BWN_PHYTYPE_G ||
6139             (phy->type == BWN_PHYTYPE_B &&
6140              phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6141                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6142         } else
6143                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6144         if (phy->rev >= 2)
6145                 bwn_dummy_transmission(mac, 0, 1);
6146         bwn_phy_g_switch_chan(mac, 6, 0);
6147         BWN_RF_READ(mac, 0x51);
6148         if (phy->type == BWN_PHYTYPE_G)
6149                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6150
6151         nanouptime(&ts);
6152         if (time_before(lo->txctl_measured_time,
6153             (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6154                 bwn_lo_measure_txctl_values(mac);
6155
6156         if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6157                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6158         else {
6159                 if (phy->type == BWN_PHYTYPE_B)
6160                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6161                 else
6162                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6163         }
6164 }
6165
6166 static void
6167 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6168 {
6169         struct bwn_phy *phy = &mac->mac_phy;
6170         struct bwn_phy_g *pg = &phy->phy_g;
6171         uint16_t tmp;
6172
6173         if (phy->rev >= 2) {
6174                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6175                 tmp = (pg->pg_pga_gain << 8);
6176                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6177                 DELAY(5);
6178                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6179                 DELAY(2);
6180                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6181         } else {
6182                 tmp = (pg->pg_pga_gain | 0xefa0);
6183                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6184         }
6185         if (phy->type == BWN_PHYTYPE_G) {
6186                 if (phy->rev >= 3)
6187                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6188                 else
6189                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6190                 if (phy->rev >= 2)
6191                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6192                 else
6193                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6194         }
6195         BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6196         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6197         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6198         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6199         BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6200         BWN_RF_WRITE(mac, 0x43, sav->rf0);
6201         BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6202         if (!BWN_HAS_TXMAG(phy)) {
6203                 tmp = sav->rf2;
6204                 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6205         }
6206         BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6207         if (phy->type == BWN_PHYTYPE_B &&
6208             phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6209                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6210                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6211         }
6212         if (phy->rev >= 2) {
6213                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6214                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6215                               sav->phy_analogoverval);
6216                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6217                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6218                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6219                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6220                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6221         }
6222         if (bwn_has_hwpctl(mac)) {
6223                 tmp = (sav->phy_lomask & 0xbfff);
6224                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6225                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6226                 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6227                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6228                 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6229         }
6230         bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6231 }
6232
6233 static int
6234 bwn_lo_probe_loctl(struct bwn_mac *mac,
6235     struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6236 {
6237         struct bwn_phy *phy = &mac->mac_phy;
6238         struct bwn_phy_g *pg = &phy->phy_g;
6239         struct bwn_loctl orig, test;
6240         struct bwn_loctl prev = { -100, -100 };
6241         static const struct bwn_loctl modifiers[] = {
6242                 {  1,  1,}, {  1,  0,}, {  1, -1,}, {  0, -1,},
6243                 { -1, -1,}, { -1,  0,}, { -1,  1,}, {  0,  1,}
6244         };
6245         int begin, end, lower = 0, i;
6246         uint16_t feedth;
6247
6248         if (d->curstate == 0) {
6249                 begin = 1;
6250                 end = 8;
6251         } else if (d->curstate % 2 == 0) {
6252                 begin = d->curstate - 1;
6253                 end = d->curstate + 1;
6254         } else {
6255                 begin = d->curstate - 2;
6256                 end = d->curstate + 2;
6257         }
6258         if (begin < 1)
6259                 begin += 8;
6260         if (end > 8)
6261                 end -= 8;
6262
6263         memcpy(&orig, probe, sizeof(struct bwn_loctl));
6264         i = begin;
6265         d->curstate = i;
6266         while (1) {
6267                 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6268                 memcpy(&test, &orig, sizeof(struct bwn_loctl));
6269                 test.i += modifiers[i - 1].i * d->multipler;
6270                 test.q += modifiers[i - 1].q * d->multipler;
6271                 if ((test.i != prev.i || test.q != prev.q) &&
6272                     (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6273                         bwn_lo_write(mac, &test);
6274                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6275                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6276                         if (feedth < d->feedth) {
6277                                 memcpy(probe, &test,
6278                                     sizeof(struct bwn_loctl));
6279                                 lower = 1;
6280                                 d->feedth = feedth;
6281                                 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6282                                         break;
6283                         }
6284                 }
6285                 memcpy(&prev, &test, sizeof(prev));
6286                 if (i == end)
6287                         break;
6288                 if (i == 8)
6289                         i = 1;
6290                 else
6291                         i++;
6292                 d->curstate = i;
6293         }
6294
6295         return (lower);
6296 }
6297
6298 static void
6299 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6300 {
6301         struct bwn_phy *phy = &mac->mac_phy;
6302         struct bwn_phy_g *pg = &phy->phy_g;
6303         struct bwn_lo_g_sm d;
6304         struct bwn_loctl probe;
6305         int lower, repeat, cnt = 0;
6306         uint16_t feedth;
6307
6308         d.nmeasure = 0;
6309         d.multipler = 1;
6310         if (BWN_HAS_LOOPBACK(phy))
6311                 d.multipler = 3;
6312
6313         memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6314         repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6315
6316         do {
6317                 bwn_lo_write(mac, &d.loctl);
6318                 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6319                     pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6320                 if (feedth < 0x258) {
6321                         if (feedth >= 0x12c)
6322                                 *rxgain += 6;
6323                         else
6324                                 *rxgain += 3;
6325                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6326                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6327                 }
6328                 d.feedth = feedth;
6329                 d.curstate = 0;
6330                 do {
6331                         KASSERT(d.curstate >= 0 && d.curstate <= 8,
6332                             ("%s:%d: fail", __func__, __LINE__));
6333                         memcpy(&probe, &d.loctl,
6334                                sizeof(struct bwn_loctl));
6335                         lower = bwn_lo_probe_loctl(mac, &probe, &d);
6336                         if (!lower)
6337                                 break;
6338                         if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6339                                 break;
6340                         memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6341                         d.nmeasure++;
6342                 } while (d.nmeasure < 24);
6343                 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6344
6345                 if (BWN_HAS_LOOPBACK(phy)) {
6346                         if (d.feedth > 0x1194)
6347                                 *rxgain -= 6;
6348                         else if (d.feedth < 0x5dc)
6349                                 *rxgain += 3;
6350                         if (cnt == 0) {
6351                                 if (d.feedth <= 0x5dc) {
6352                                         d.multipler = 1;
6353                                         cnt++;
6354                                 } else
6355                                         d.multipler = 2;
6356                         } else if (cnt == 2)
6357                                 d.multipler = 1;
6358                 }
6359                 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6360         } while (++cnt < repeat);
6361 }
6362
6363 static struct bwn_lo_calib *
6364 bwn_lo_calibset(struct bwn_mac *mac,
6365     const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6366 {
6367         struct bwn_phy *phy = &mac->mac_phy;
6368         struct bwn_phy_g *pg = &phy->phy_g;
6369         struct bwn_loctl loctl = { 0, 0 };
6370         struct bwn_lo_calib *cal;
6371         struct bwn_lo_g_value sval = { 0 };
6372         int rxgain;
6373         uint16_t pad, reg, value;
6374
6375         sval.old_channel = phy->chan;
6376         bwn_mac_suspend(mac);
6377         bwn_lo_save(mac, &sval);
6378
6379         reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6380         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6381         BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6382
6383         rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6384         if (rfatt->padmix)
6385                 rxgain -= pad;
6386         if (BWN_HAS_LOOPBACK(phy))
6387                 rxgain += pg->pg_max_lb_gain;
6388         bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6389         bwn_phy_g_set_bbatt(mac, bbatt->att);
6390         bwn_lo_probe_sm(mac, &loctl, &rxgain);
6391
6392         bwn_lo_restore(mac, &sval);
6393         bwn_mac_enable(mac);
6394
6395         cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
6396         if (!cal) {
6397                 device_printf(mac->mac_sc->sc_dev, "out of memory\n");
6398                 return (NULL);
6399         }
6400         memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6401         memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6402         memcpy(&cal->ctl, &loctl, sizeof(loctl));
6403
6404         BWN_GETTIME(cal->calib_time);
6405
6406         return (cal);
6407 }
6408
6409 static struct bwn_lo_calib *
6410 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6411     const struct bwn_rfatt *rfatt)
6412 {
6413         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6414         struct bwn_lo_calib *c;
6415
6416         TAILQ_FOREACH(c, &lo->calib_list, list) {
6417                 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6418                         continue;
6419                 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6420                         continue;
6421                 return (c);
6422         }
6423
6424         c = bwn_lo_calibset(mac, bbatt, rfatt);
6425         if (!c)
6426                 return (NULL);
6427         TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6428
6429         return (c);
6430 }
6431
6432 static void
6433 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6434 {
6435         struct bwn_phy *phy = &mac->mac_phy;
6436         struct bwn_phy_g *pg = &phy->phy_g;
6437         struct bwn_softc *sc = mac->mac_sc;
6438         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6439         const struct bwn_rfatt *rfatt;
6440         const struct bwn_bbatt *bbatt;
6441         uint64_t pvector;
6442         int i;
6443         int rf_offset, bb_offset;
6444         uint8_t changed = 0;
6445
6446         KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6447         KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6448             ("%s:%d: fail", __func__, __LINE__));
6449
6450         pvector = lo->power_vector;
6451         if (!update && !pvector)
6452                 return;
6453
6454         bwn_mac_suspend(mac);
6455
6456         for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6457                 struct bwn_lo_calib *cal;
6458                 int idx;
6459                 uint16_t val;
6460
6461                 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6462                         continue;
6463                 bb_offset = i / lo->rfatt.len;
6464                 rf_offset = i % lo->rfatt.len;
6465                 bbatt = &(lo->bbatt.array[bb_offset]);
6466                 rfatt = &(lo->rfatt.array[rf_offset]);
6467
6468                 cal = bwn_lo_calibset(mac, bbatt, rfatt);
6469                 if (!cal) {
6470                         device_printf(sc->sc_dev, "LO: Could not "
6471                             "calibrate DC table entry\n");
6472                         continue;
6473                 }
6474                 val = (uint8_t)(cal->ctl.q);
6475                 val |= ((uint8_t)(cal->ctl.i)) << 4;
6476                 free(cal, M_DEVBUF);
6477
6478                 idx = i / 2;
6479                 if (i % 2)
6480                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6481                             | ((val & 0x00ff) << 8);
6482                 else
6483                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6484                             | (val & 0x00ff);
6485                 changed = 1;
6486         }
6487         if (changed) {
6488                 for (i = 0; i < BWN_DC_LT_SIZE; i++)
6489                         BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6490         }
6491         bwn_mac_enable(mac);
6492 }
6493
6494 static void
6495 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6496 {
6497
6498         if (!rf->padmix)
6499                 return;
6500         if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6501                 rf->att = 4;
6502 }
6503
6504 static void
6505 bwn_lo_g_adjust(struct bwn_mac *mac)
6506 {
6507         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6508         struct bwn_lo_calib *cal;
6509         struct bwn_rfatt rf;
6510
6511         memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6512         bwn_lo_fixup_rfatt(&rf);
6513
6514         cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6515         if (!cal)
6516                 return;
6517         bwn_lo_write(mac, &cal->ctl);
6518 }
6519
6520 static void
6521 bwn_lo_g_init(struct bwn_mac *mac)
6522 {
6523
6524         if (!bwn_has_hwpctl(mac))
6525                 return;
6526
6527         bwn_lo_get_powervector(mac);
6528         bwn_phy_g_dc_lookup_init(mac, 1);
6529 }
6530
6531 static void
6532 bwn_mac_suspend(struct bwn_mac *mac)
6533 {
6534         struct bwn_softc *sc = mac->mac_sc;
6535         int i;
6536         uint32_t tmp;
6537
6538         KASSERT(mac->mac_suspended >= 0,
6539             ("%s:%d: fail", __func__, __LINE__));
6540
6541         if (mac->mac_suspended == 0) {
6542                 bwn_psctl(mac, BWN_PS_AWAKE);
6543                 BWN_WRITE_4(mac, BWN_MACCTL,
6544                             BWN_READ_4(mac, BWN_MACCTL)
6545                             & ~BWN_MACCTL_ON);
6546                 BWN_READ_4(mac, BWN_MACCTL);
6547                 for (i = 35; i; i--) {
6548                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6549                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6550                                 goto out;
6551                         DELAY(10);
6552                 }
6553                 for (i = 40; i; i--) {
6554                         tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6555                         if (tmp & BWN_INTR_MAC_SUSPENDED)
6556                                 goto out;
6557                         DELAY(1000);
6558                 }
6559                 device_printf(sc->sc_dev, "MAC suspend failed\n");
6560         }
6561 out:
6562         mac->mac_suspended++;
6563 }
6564
6565 static void
6566 bwn_mac_enable(struct bwn_mac *mac)
6567 {
6568         struct bwn_softc *sc = mac->mac_sc;
6569         uint16_t state;
6570
6571         state = bwn_shm_read_2(mac, BWN_SHARED,
6572             BWN_SHARED_UCODESTAT);
6573         if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6574             state != BWN_SHARED_UCODESTAT_SLEEP)
6575                 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6576
6577         mac->mac_suspended--;
6578         KASSERT(mac->mac_suspended >= 0,
6579             ("%s:%d: fail", __func__, __LINE__));
6580         if (mac->mac_suspended == 0) {
6581                 BWN_WRITE_4(mac, BWN_MACCTL,
6582                     BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6583                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6584                 BWN_READ_4(mac, BWN_MACCTL);
6585                 BWN_READ_4(mac, BWN_INTR_REASON);
6586                 bwn_psctl(mac, 0);
6587         }
6588 }
6589
6590 static void
6591 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6592 {
6593         struct bwn_softc *sc = mac->mac_sc;
6594         int i;
6595         uint16_t ucstat;
6596
6597         KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6598             ("%s:%d: fail", __func__, __LINE__));
6599         KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6600             ("%s:%d: fail", __func__, __LINE__));
6601
6602         /* XXX forcibly awake and hwps-off */
6603
6604         BWN_WRITE_4(mac, BWN_MACCTL,
6605             (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6606             ~BWN_MACCTL_HWPS);
6607         BWN_READ_4(mac, BWN_MACCTL);
6608         if (siba_get_revid(sc->sc_dev) >= 5) {
6609                 for (i = 0; i < 100; i++) {
6610                         ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6611                             BWN_SHARED_UCODESTAT);
6612                         if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6613                                 break;
6614                         DELAY(10);
6615                 }
6616         }
6617 }
6618
6619 static int16_t
6620 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6621 {
6622
6623         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6624         return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6625 }
6626
6627 static void
6628 bwn_nrssi_threshold(struct bwn_mac *mac)
6629 {
6630         struct bwn_phy *phy = &mac->mac_phy;
6631         struct bwn_phy_g *pg = &phy->phy_g;
6632         struct bwn_softc *sc = mac->mac_sc;
6633         int32_t a, b;
6634         int16_t tmp16;
6635         uint16_t tmpu16;
6636
6637         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6638
6639         if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6640                 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6641                         a = 0x13;
6642                         b = 0x12;
6643                 } else {
6644                         a = 0xe;
6645                         b = 0x11;
6646                 }
6647
6648                 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6649                 a += (pg->pg_nrssi[0] << 6);
6650                 a += (a < 32) ? 31 : 32;
6651                 a = a >> 6;
6652                 a = MIN(MAX(a, -31), 31);
6653
6654                 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6655                 b += (pg->pg_nrssi[0] << 6);
6656                 if (b < 32)
6657                         b += 31;
6658                 else
6659                         b += 32;
6660                 b = b >> 6;
6661                 b = MIN(MAX(b, -31), 31);
6662
6663                 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6664                 tmpu16 |= ((uint32_t)b & 0x0000003f);
6665                 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6666                 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6667                 return;
6668         }
6669
6670         tmp16 = bwn_nrssi_read(mac, 0x20);
6671         if (tmp16 >= 0x20)
6672                 tmp16 -= 0x40;
6673         BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6674 }
6675
6676 static void
6677 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6678 {
6679 #define SAVE_RF_MAX             3
6680 #define SAVE_PHY_COMM_MAX       4
6681 #define SAVE_PHY3_MAX           8
6682         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6683                 { 0x7a, 0x52, 0x43 };
6684         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6685                 { 0x15, 0x5a, 0x59, 0x58 };
6686         static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6687                 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6688                 0x0801, 0x0060, 0x0014, 0x0478
6689         };
6690         struct bwn_phy *phy = &mac->mac_phy;
6691         struct bwn_phy_g *pg = &phy->phy_g;
6692         int32_t i, tmp32, phy3_idx = 0;
6693         uint16_t delta, tmp;
6694         uint16_t save_rf[SAVE_RF_MAX];
6695         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6696         uint16_t save_phy3[SAVE_PHY3_MAX];
6697         uint16_t ant_div, phy0, chan_ex;
6698         int16_t nrssi0, nrssi1;
6699
6700         KASSERT(phy->type == BWN_PHYTYPE_G,
6701             ("%s:%d: fail", __func__, __LINE__));
6702
6703         if (phy->rf_rev >= 9)
6704                 return;
6705         if (phy->rf_rev == 8)
6706                 bwn_nrssi_offset(mac);
6707
6708         BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6709         BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6710
6711         /*
6712          * Save RF/PHY registers for later restoration
6713          */
6714         ant_div = BWN_READ_2(mac, 0x03e2);
6715         BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6716         for (i = 0; i < SAVE_RF_MAX; ++i)
6717                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6718         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6719                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6720
6721         phy0 = BWN_READ_2(mac, BWN_PHY0);
6722         chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6723         if (phy->rev >= 3) {
6724                 for (i = 0; i < SAVE_PHY3_MAX; ++i)
6725                         save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6726                 BWN_PHY_WRITE(mac, 0x002e, 0);
6727                 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6728                 switch (phy->rev) {
6729                 case 4:
6730                 case 6:
6731                 case 7:
6732                         BWN_PHY_SET(mac, 0x0478, 0x0100);
6733                         BWN_PHY_SET(mac, 0x0801, 0x0040);
6734                         break;
6735                 case 3:
6736                 case 5:
6737                         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6738                         break;
6739                 }
6740                 BWN_PHY_SET(mac, 0x0060, 0x0040);
6741                 BWN_PHY_SET(mac, 0x0014, 0x0200);
6742         }
6743         /*
6744          * Calculate nrssi0
6745          */
6746         BWN_RF_SET(mac, 0x007a, 0x0070);
6747         bwn_set_all_gains(mac, 0, 8, 0);
6748         BWN_RF_MASK(mac, 0x007a, 0x00f7);
6749         if (phy->rev >= 2) {
6750                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6751                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6752         }
6753         BWN_RF_SET(mac, 0x007a, 0x0080);
6754         DELAY(20);
6755
6756         nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6757         if (nrssi0 >= 0x0020)
6758                 nrssi0 -= 0x0040;
6759
6760         /*
6761          * Calculate nrssi1
6762          */
6763         BWN_RF_MASK(mac, 0x007a, 0x007f);
6764         if (phy->rev >= 2)
6765                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6766
6767         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6768             BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6769         BWN_RF_SET(mac, 0x007a, 0x000f);
6770         BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6771         if (phy->rev >= 2) {
6772                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6773                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6774         }
6775
6776         bwn_set_all_gains(mac, 3, 0, 1);
6777         if (phy->rf_rev == 8) {
6778                 BWN_RF_WRITE(mac, 0x0043, 0x001f);
6779         } else {
6780                 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6781                 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6782                 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6783                 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6784         }
6785         BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6786         BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6787         BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6788         DELAY(20);
6789         nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6790
6791         /*
6792          * Install calculated narrow RSSI values
6793          */
6794         if (nrssi1 >= 0x0020)
6795                 nrssi1 -= 0x0040;
6796         if (nrssi0 == nrssi1)
6797                 pg->pg_nrssi_slope = 0x00010000;
6798         else
6799                 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6800         if (nrssi0 >= -4) {
6801                 pg->pg_nrssi[0] = nrssi1;
6802                 pg->pg_nrssi[1] = nrssi0;
6803         }
6804
6805         /*
6806          * Restore saved RF/PHY registers
6807          */
6808         if (phy->rev >= 3) {
6809                 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6810                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6811                             save_phy3[phy3_idx]);
6812                 }
6813         }
6814         if (phy->rev >= 2) {
6815                 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6816                 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6817         }
6818
6819         for (i = 0; i < SAVE_RF_MAX; ++i)
6820                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6821
6822         BWN_WRITE_2(mac, 0x03e2, ant_div);
6823         BWN_WRITE_2(mac, 0x03e6, phy0);
6824         BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6825
6826         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6827                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6828
6829         bwn_spu_workaround(mac, phy->chan);
6830         BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6831         bwn_set_original_gains(mac);
6832         BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6833         if (phy->rev >= 3) {
6834                 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6835                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6836                             save_phy3[phy3_idx]);
6837                 }
6838         }
6839
6840         delta = 0x1f - pg->pg_nrssi[0];
6841         for (i = 0; i < 64; i++) {
6842                 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6843                 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6844                 pg->pg_nrssi_lt[i] = tmp32;
6845         }
6846
6847         bwn_nrssi_threshold(mac);
6848 #undef SAVE_RF_MAX
6849 #undef SAVE_PHY_COMM_MAX
6850 #undef SAVE_PHY3_MAX
6851 }
6852
6853 static void
6854 bwn_nrssi_offset(struct bwn_mac *mac)
6855 {
6856 #define SAVE_RF_MAX             2
6857 #define SAVE_PHY_COMM_MAX       10
6858 #define SAVE_PHY6_MAX           8
6859         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6860                 { 0x7a, 0x43 };
6861         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6862                 0x0001, 0x0811, 0x0812, 0x0814,
6863                 0x0815, 0x005a, 0x0059, 0x0058,
6864                 0x000a, 0x0003
6865         };
6866         static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6867                 0x002e, 0x002f, 0x080f, 0x0810,
6868                 0x0801, 0x0060, 0x0014, 0x0478
6869         };
6870         struct bwn_phy *phy = &mac->mac_phy;
6871         int i, phy6_idx = 0;
6872         uint16_t save_rf[SAVE_RF_MAX];
6873         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6874         uint16_t save_phy6[SAVE_PHY6_MAX];
6875         int16_t nrssi;
6876         uint16_t saved = 0xffff;
6877
6878         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6879                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6880         for (i = 0; i < SAVE_RF_MAX; ++i)
6881                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6882
6883         BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6884         BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6885         BWN_PHY_SET(mac, 0x0811, 0x000c);
6886         BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6887         BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6888         if (phy->rev >= 6) {
6889                 for (i = 0; i < SAVE_PHY6_MAX; ++i)
6890                         save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6891
6892                 BWN_PHY_WRITE(mac, 0x002e, 0);
6893                 BWN_PHY_WRITE(mac, 0x002f, 0);
6894                 BWN_PHY_WRITE(mac, 0x080f, 0);
6895                 BWN_PHY_WRITE(mac, 0x0810, 0);
6896                 BWN_PHY_SET(mac, 0x0478, 0x0100);
6897                 BWN_PHY_SET(mac, 0x0801, 0x0040);
6898                 BWN_PHY_SET(mac, 0x0060, 0x0040);
6899                 BWN_PHY_SET(mac, 0x0014, 0x0200);
6900         }
6901         BWN_RF_SET(mac, 0x007a, 0x0070);
6902         BWN_RF_SET(mac, 0x007a, 0x0080);
6903         DELAY(30);
6904
6905         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6906         if (nrssi >= 0x20)
6907                 nrssi -= 0x40;
6908         if (nrssi == 31) {
6909                 for (i = 7; i >= 4; i--) {
6910                         BWN_RF_WRITE(mac, 0x007b, i);
6911                         DELAY(20);
6912                         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
6913                             0x003f);
6914                         if (nrssi >= 0x20)
6915                                 nrssi -= 0x40;
6916                         if (nrssi < 31 && saved == 0xffff)
6917                                 saved = i;
6918                 }
6919                 if (saved == 0xffff)
6920                         saved = 4;
6921         } else {
6922                 BWN_RF_MASK(mac, 0x007a, 0x007f);
6923                 if (phy->rev != 1) {
6924                         BWN_PHY_SET(mac, 0x0814, 0x0001);
6925                         BWN_PHY_MASK(mac, 0x0815, 0xfffe);
6926                 }
6927                 BWN_PHY_SET(mac, 0x0811, 0x000c);
6928                 BWN_PHY_SET(mac, 0x0812, 0x000c);
6929                 BWN_PHY_SET(mac, 0x0811, 0x0030);
6930                 BWN_PHY_SET(mac, 0x0812, 0x0030);
6931                 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6932                 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6933                 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6934                 if (phy->rev == 0)
6935                         BWN_PHY_WRITE(mac, 0x0003, 0x0122);
6936                 else
6937                         BWN_PHY_SET(mac, 0x000a, 0x2000);
6938                 if (phy->rev != 1) {
6939                         BWN_PHY_SET(mac, 0x0814, 0x0004);
6940                         BWN_PHY_MASK(mac, 0x0815, 0xfffb);
6941                 }
6942                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6943                 BWN_RF_SET(mac, 0x007a, 0x000f);
6944                 bwn_set_all_gains(mac, 3, 0, 1);
6945                 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
6946                 DELAY(30);
6947                 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6948                 if (nrssi >= 0x20)
6949                         nrssi -= 0x40;
6950                 if (nrssi == -32) {
6951                         for (i = 0; i < 4; i++) {
6952                                 BWN_RF_WRITE(mac, 0x007b, i);
6953                                 DELAY(20);
6954                                 nrssi = (int16_t)((BWN_PHY_READ(mac,
6955                                     0x047f) >> 8) & 0x003f);
6956                                 if (nrssi >= 0x20)
6957                                         nrssi -= 0x40;
6958                                 if (nrssi > -31 && saved == 0xffff)
6959                                         saved = i;
6960                         }
6961                         if (saved == 0xffff)
6962                                 saved = 3;
6963                 } else
6964                         saved = 0;
6965         }
6966         BWN_RF_WRITE(mac, 0x007b, saved);
6967
6968         /*
6969          * Restore saved RF/PHY registers
6970          */
6971         if (phy->rev >= 6) {
6972                 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
6973                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
6974                             save_phy6[phy6_idx]);
6975                 }
6976         }
6977         if (phy->rev != 1) {
6978                 for (i = 3; i < 5; i++)
6979                         BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
6980                             save_phy_comm[i]);
6981         }
6982         for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
6983                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6984
6985         for (i = SAVE_RF_MAX - 1; i >= 0; --i)
6986                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6987
6988         BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
6989         BWN_PHY_SET(mac, 0x0429, 0x8000);
6990         bwn_set_original_gains(mac);
6991         if (phy->rev >= 6) {
6992                 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
6993                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
6994                             save_phy6[phy6_idx]);
6995                 }
6996         }
6997
6998         BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
6999         BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7000         BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7001 }
7002
7003 static void
7004 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7005     int16_t third)
7006 {
7007         struct bwn_phy *phy = &mac->mac_phy;
7008         uint16_t i;
7009         uint16_t start = 0x08, end = 0x18;
7010         uint16_t tmp;
7011         uint16_t table;
7012
7013         if (phy->rev <= 1) {
7014                 start = 0x10;
7015                 end = 0x20;
7016         }
7017
7018         table = BWN_OFDMTAB_GAINX;
7019         if (phy->rev <= 1)
7020                 table = BWN_OFDMTAB_GAINX_R1;
7021         for (i = 0; i < 4; i++)
7022                 bwn_ofdmtab_write_2(mac, table, i, first);
7023
7024         for (i = start; i < end; i++)
7025                 bwn_ofdmtab_write_2(mac, table, i, second);
7026
7027         if (third != -1) {
7028                 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7029                 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7030                 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7031                 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7032         }
7033         bwn_dummy_transmission(mac, 0, 1);
7034 }
7035
7036 static void
7037 bwn_set_original_gains(struct bwn_mac *mac)
7038 {
7039         struct bwn_phy *phy = &mac->mac_phy;
7040         uint16_t i, tmp;
7041         uint16_t table;
7042         uint16_t start = 0x0008, end = 0x0018;
7043
7044         if (phy->rev <= 1) {
7045                 start = 0x0010;
7046                 end = 0x0020;
7047         }
7048
7049         table = BWN_OFDMTAB_GAINX;
7050         if (phy->rev <= 1)
7051                 table = BWN_OFDMTAB_GAINX_R1;
7052         for (i = 0; i < 4; i++) {
7053                 tmp = (i & 0xfffc);
7054                 tmp |= (i & 0x0001) << 1;
7055                 tmp |= (i & 0x0002) >> 1;
7056
7057                 bwn_ofdmtab_write_2(mac, table, i, tmp);
7058         }
7059
7060         for (i = start; i < end; i++)
7061                 bwn_ofdmtab_write_2(mac, table, i, i - start);
7062
7063         BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7064         BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7065         BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7066         bwn_dummy_transmission(mac, 0, 1);
7067 }
7068
7069 static void
7070 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7071 {
7072         struct bwn_phy *phy = &mac->mac_phy;
7073         struct bwn_phy_g *pg = &phy->phy_g;
7074         struct bwn_rfatt old_rfatt, rfatt;
7075         struct bwn_bbatt old_bbatt, bbatt;
7076         struct bwn_softc *sc = mac->mac_sc;
7077         uint8_t old_txctl = 0;
7078
7079         KASSERT(phy->type == BWN_PHYTYPE_G,
7080             ("%s:%d: fail", __func__, __LINE__));
7081
7082         if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7083             (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7084                 return;
7085
7086         BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7087
7088         BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7089
7090         if (!phy->gmode)
7091                 return;
7092         bwn_hwpctl_early_init(mac);
7093         if (pg->pg_curtssi == 0) {
7094                 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7095                         BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7096                 } else {
7097                         memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7098                         memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7099                         old_txctl = pg->pg_txctl;
7100
7101                         bbatt.att = 11;
7102                         if (phy->rf_rev == 8) {
7103                                 rfatt.att = 15;
7104                                 rfatt.padmix = 1;
7105                         } else {
7106                                 rfatt.att = 9;
7107                                 rfatt.padmix = 0;
7108                         }
7109                         bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7110                 }
7111                 bwn_dummy_transmission(mac, 0, 1);
7112                 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7113                 if (phy->rf_ver == 0x2050 && phy->analog == 0)
7114                         BWN_RF_MASK(mac, 0x0076, 0xff7b);
7115                 else
7116                         bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7117                             &old_rfatt, old_txctl);
7118         }
7119         bwn_hwpctl_init_gphy(mac);
7120
7121         /* clear TSSI */
7122         bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7123         bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7124         bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7125         bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7126 }
7127
7128 static void
7129 bwn_hwpctl_early_init(struct bwn_mac *mac)
7130 {
7131         struct bwn_phy *phy = &mac->mac_phy;
7132
7133         if (!bwn_has_hwpctl(mac)) {
7134                 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7135                 return;
7136         }
7137
7138         BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7139         BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7140         BWN_PHY_SET(mac, 0x047c, 0x0002);
7141         BWN_PHY_SET(mac, 0x047a, 0xf000);
7142         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7143                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7144                 BWN_PHY_SET(mac, 0x005d, 0x8000);
7145                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7146                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7147                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7148         } else {
7149                 BWN_PHY_SET(mac, 0x0036, 0x0200);
7150                 BWN_PHY_SET(mac, 0x0036, 0x0400);
7151                 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7152                 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7153                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7154                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7155                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7156         }
7157 }
7158
7159 static void
7160 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7161 {
7162         struct bwn_phy *phy = &mac->mac_phy;
7163         struct bwn_phy_g *pg = &phy->phy_g;
7164         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7165         int i;
7166         uint16_t nr_written = 0, tmp, value;
7167         uint8_t rf, bb;
7168
7169         if (!bwn_has_hwpctl(mac)) {
7170                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7171                 return;
7172         }
7173
7174         BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7175             (pg->pg_idletssi - pg->pg_curtssi));
7176         BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7177             (pg->pg_idletssi - pg->pg_curtssi));
7178
7179         for (i = 0; i < 32; i++)
7180                 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7181         for (i = 32; i < 64; i++)
7182                 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7183         for (i = 0; i < 64; i += 2) {
7184                 value = (uint16_t) pg->pg_tssi2dbm[i];
7185                 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7186                 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7187         }
7188
7189         for (rf = 0; rf < lo->rfatt.len; rf++) {
7190                 for (bb = 0; bb < lo->bbatt.len; bb++) {
7191                         if (nr_written >= 0x40)
7192                                 return;
7193                         tmp = lo->bbatt.array[bb].att;
7194                         tmp <<= 8;
7195                         if (phy->rf_rev == 8)
7196                                 tmp |= 0x50;
7197                         else
7198                                 tmp |= 0x40;
7199                         tmp |= lo->rfatt.array[rf].att;
7200                         BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7201                         nr_written++;
7202                 }
7203         }
7204
7205         BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7206         BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7207
7208         KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7209         BWN_PHY_SET(mac, 0x0478, 0x0800);
7210         BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7211         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7212
7213         bwn_phy_g_dc_lookup_init(mac, 1);
7214         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7215 }
7216
7217 static void
7218 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7219 {
7220         struct bwn_softc *sc = mac->mac_sc;
7221
7222         if (spu != 0)
7223                 bwn_spu_workaround(mac, channel);
7224
7225         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7226
7227         if (channel == 14) {
7228                 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7229                         bwn_hf_write(mac,
7230                             bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7231                 else
7232                         bwn_hf_write(mac,
7233                             bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7234                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7235                     BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7236                 return;
7237         }
7238
7239         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7240             BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7241 }
7242
7243 static uint16_t
7244 bwn_phy_g_chan2freq(uint8_t channel)
7245 {
7246         static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7247
7248         KASSERT(channel >= 1 && channel <= 14,
7249             ("%s:%d: fail", __func__, __LINE__));
7250
7251         return (bwn_phy_g_rf_channels[channel - 1]);
7252 }
7253
7254 static void
7255 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7256     const struct bwn_rfatt *rfatt, uint8_t txctl)
7257 {
7258         struct bwn_phy *phy = &mac->mac_phy;
7259         struct bwn_phy_g *pg = &phy->phy_g;
7260         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7261         uint16_t bb, rf;
7262         uint16_t tx_bias, tx_magn;
7263
7264         bb = bbatt->att;
7265         rf = rfatt->att;
7266         tx_bias = lo->tx_bias;
7267         tx_magn = lo->tx_magn;
7268         if (tx_bias == 0xff)
7269                 tx_bias = 0;
7270
7271         pg->pg_txctl = txctl;
7272         memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7273         pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7274         memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7275         bwn_phy_g_set_bbatt(mac, bb);
7276         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7277         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7278                 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7279         else {
7280                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7281                 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7282         }
7283         if (BWN_HAS_TXMAG(phy))
7284                 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7285         else
7286                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7287         bwn_lo_g_adjust(mac);
7288 }
7289
7290 static void
7291 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7292     uint16_t bbatt)
7293 {
7294         struct bwn_phy *phy = &mac->mac_phy;
7295
7296         if (phy->analog == 0) {
7297                 BWN_WRITE_2(mac, BWN_PHY0,
7298                     (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7299                 return;
7300         }
7301         if (phy->analog > 1) {
7302                 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7303                 return;
7304         }
7305         BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7306 }
7307
7308 static uint16_t
7309 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7310 {
7311         struct bwn_phy *phy = &mac->mac_phy;
7312         struct bwn_phy_g *pg = &phy->phy_g;
7313         struct bwn_softc *sc = mac->mac_sc;
7314         int max_lb_gain;
7315         uint16_t extlna;
7316         uint16_t i;
7317
7318         if (phy->gmode == 0)
7319                 return (0);
7320
7321         if (BWN_HAS_LOOPBACK(phy)) {
7322                 max_lb_gain = pg->pg_max_lb_gain;
7323                 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7324                 if (max_lb_gain >= 0x46) {
7325                         extlna = 0x3000;
7326                         max_lb_gain -= 0x46;
7327                 } else if (max_lb_gain >= 0x3a) {
7328                         extlna = 0x1000;
7329                         max_lb_gain -= 0x3a;
7330                 } else if (max_lb_gain >= 0x2e) {
7331                         extlna = 0x2000;
7332                         max_lb_gain -= 0x2e;
7333                 } else {
7334                         extlna = 0;
7335                         max_lb_gain -= 0x10;
7336                 }
7337
7338                 for (i = 0; i < 16; i++) {
7339                         max_lb_gain -= (i * 6);
7340                         if (max_lb_gain < 6)
7341                                 break;
7342                 }
7343
7344                 if ((phy->rev < 7) ||
7345                     !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7346                         if (reg == BWN_PHY_RFOVER) {
7347                                 return (0x1b3);
7348                         } else if (reg == BWN_PHY_RFOVERVAL) {
7349                                 extlna |= (i << 8);
7350                                 switch (lpd) {
7351                                 case BWN_LPD(0, 1, 1):
7352                                         return (0x0f92);
7353                                 case BWN_LPD(0, 0, 1):
7354                                 case BWN_LPD(1, 0, 1):
7355                                         return (0x0092 | extlna);
7356                                 case BWN_LPD(1, 0, 0):
7357                                         return (0x0093 | extlna);
7358                                 }
7359                                 KASSERT(0 == 1,
7360                                     ("%s:%d: fail", __func__, __LINE__));
7361                         }
7362                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7363                 } else {
7364                         if (reg == BWN_PHY_RFOVER)
7365                                 return (0x9b3);
7366                         if (reg == BWN_PHY_RFOVERVAL) {
7367                                 if (extlna)
7368                                         extlna |= 0x8000;
7369                                 extlna |= (i << 8);
7370                                 switch (lpd) {
7371                                 case BWN_LPD(0, 1, 1):
7372                                         return (0x8f92);
7373                                 case BWN_LPD(0, 0, 1):
7374                                         return (0x8092 | extlna);
7375                                 case BWN_LPD(1, 0, 1):
7376                                         return (0x2092 | extlna);
7377                                 case BWN_LPD(1, 0, 0):
7378                                         return (0x2093 | extlna);
7379                                 }
7380                                 KASSERT(0 == 1,
7381                                     ("%s:%d: fail", __func__, __LINE__));
7382                         }
7383                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7384                 }
7385                 return (0);
7386         }
7387
7388         if ((phy->rev < 7) ||
7389             !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7390                 if (reg == BWN_PHY_RFOVER) {
7391                         return (0x1b3);
7392                 } else if (reg == BWN_PHY_RFOVERVAL) {
7393                         switch (lpd) {
7394                         case BWN_LPD(0, 1, 1):
7395                                 return (0x0fb2);
7396                         case BWN_LPD(0, 0, 1):
7397                                 return (0x00b2);
7398                         case BWN_LPD(1, 0, 1):
7399                                 return (0x30b2);
7400                         case BWN_LPD(1, 0, 0):
7401                                 return (0x30b3);
7402                         }
7403                         KASSERT(0 == 1,
7404                             ("%s:%d: fail", __func__, __LINE__));
7405                 }
7406                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7407         } else {
7408                 if (reg == BWN_PHY_RFOVER) {
7409                         return (0x9b3);
7410                 } else if (reg == BWN_PHY_RFOVERVAL) {
7411                         switch (lpd) {
7412                         case BWN_LPD(0, 1, 1):
7413                                 return (0x8fb2);
7414                         case BWN_LPD(0, 0, 1):
7415                                 return (0x80b2);
7416                         case BWN_LPD(1, 0, 1):
7417                                 return (0x20b2);
7418                         case BWN_LPD(1, 0, 0):
7419                                 return (0x20b3);
7420                         }
7421                         KASSERT(0 == 1,
7422                             ("%s:%d: fail", __func__, __LINE__));
7423                 }
7424                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7425         }
7426         return (0);
7427 }
7428
7429 static void
7430 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7431 {
7432
7433         if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7434                 return;
7435         BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7436             bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7437         DELAY(1000);
7438         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7439 }
7440
7441 static int
7442 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7443 {
7444         struct bwn_softc *sc = mac->mac_sc;
7445         struct bwn_fw *fw = &mac->mac_fw;
7446         const uint8_t rev = siba_get_revid(sc->sc_dev);
7447         const char *filename;
7448         uint32_t high;
7449         int error;
7450
7451         /* microcode */
7452         if (rev >= 5 && rev <= 10)
7453                 filename = "ucode5";
7454         else if (rev >= 11 && rev <= 12)
7455                 filename = "ucode11";
7456         else if (rev == 13)
7457                 filename = "ucode13";
7458         else if (rev == 14)
7459                 filename = "ucode14";
7460         else if (rev >= 15)
7461                 filename = "ucode15";
7462         else {
7463                 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7464                 bwn_release_firmware(mac);
7465                 return (EOPNOTSUPP);
7466         }
7467         error = bwn_fw_get(mac, type, filename, &fw->ucode);
7468         if (error) {
7469                 bwn_release_firmware(mac);
7470                 return (error);
7471         }
7472
7473         /* PCM */
7474         KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7475         if (rev >= 5 && rev <= 10) {
7476                 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7477                 if (error == ENOENT)
7478                         fw->no_pcmfile = 1;
7479                 else if (error) {
7480                         bwn_release_firmware(mac);
7481                         return (error);
7482                 }
7483         } else if (rev < 11) {
7484                 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7485                 return (EOPNOTSUPP);
7486         }
7487
7488         /* initvals */
7489         high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7490         switch (mac->mac_phy.type) {
7491         case BWN_PHYTYPE_A:
7492                 if (rev < 5 || rev > 10)
7493                         goto fail1;
7494                 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7495                         filename = "a0g1initvals5";
7496                 else
7497                         filename = "a0g0initvals5";
7498                 break;
7499         case BWN_PHYTYPE_G:
7500                 if (rev >= 5 && rev <= 10)
7501                         filename = "b0g0initvals5";
7502                 else if (rev >= 13)
7503                         filename = "b0g0initvals13";
7504                 else
7505                         goto fail1;
7506                 break;
7507         case BWN_PHYTYPE_LP:
7508                 if (rev == 13)
7509                         filename = "lp0initvals13";
7510                 else if (rev == 14)
7511                         filename = "lp0initvals14";
7512                 else if (rev >= 15)
7513                         filename = "lp0initvals15";
7514                 else
7515                         goto fail1;
7516                 break;
7517         case BWN_PHYTYPE_N:
7518                 if (rev >= 11 && rev <= 12)
7519                         filename = "n0initvals11";
7520                 else
7521                         goto fail1;
7522                 break;
7523         default:
7524                 goto fail1;
7525         }
7526         error = bwn_fw_get(mac, type, filename, &fw->initvals);
7527         if (error) {
7528                 bwn_release_firmware(mac);
7529                 return (error);
7530         }
7531
7532         /* bandswitch initvals */
7533         switch (mac->mac_phy.type) {
7534         case BWN_PHYTYPE_A:
7535                 if (rev >= 5 && rev <= 10) {
7536                         if (high & BWN_TGSHIGH_HAVE_2GHZ)
7537                                 filename = "a0g1bsinitvals5";
7538                         else
7539                                 filename = "a0g0bsinitvals5";
7540                 } else if (rev >= 11)
7541                         filename = NULL;
7542                 else
7543                         goto fail1;
7544                 break;
7545         case BWN_PHYTYPE_G:
7546                 if (rev >= 5 && rev <= 10)
7547                         filename = "b0g0bsinitvals5";
7548                 else if (rev >= 11)
7549                         filename = NULL;
7550                 else
7551                         goto fail1;
7552                 break;
7553         case BWN_PHYTYPE_LP:
7554                 if (rev == 13)
7555                         filename = "lp0bsinitvals13";
7556                 else if (rev == 14)
7557                         filename = "lp0bsinitvals14";
7558                 else if (rev >= 15)
7559                         filename = "lp0bsinitvals15";
7560                 else
7561                         goto fail1;
7562                 break;
7563         case BWN_PHYTYPE_N:
7564                 if (rev >= 11 && rev <= 12)
7565                         filename = "n0bsinitvals11";
7566                 else
7567                         goto fail1;
7568                 break;
7569         default:
7570                 goto fail1;
7571         }
7572         error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7573         if (error) {
7574                 bwn_release_firmware(mac);
7575                 return (error);
7576         }
7577         return (0);
7578 fail1:
7579         device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7580         bwn_release_firmware(mac);
7581         return (EOPNOTSUPP);
7582 }
7583
7584 static int
7585 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7586     const char *name, struct bwn_fwfile *bfw)
7587 {
7588         const struct bwn_fwhdr *hdr;
7589         struct bwn_softc *sc = mac->mac_sc;
7590         const struct firmware *fw;
7591         char namebuf[64];
7592
7593         if (name == NULL) {
7594                 bwn_do_release_fw(bfw);
7595                 return (0);
7596         }
7597         if (bfw->filename != NULL) {
7598                 if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7599                         return (0);
7600                 bwn_do_release_fw(bfw);
7601         }
7602
7603         snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7604             (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7605             (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7606         /* XXX Sleeping on "fwload" with the non-sleepable locks held */
7607         fw = firmware_get(namebuf);
7608         if (fw == NULL) {
7609                 device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7610                     namebuf);
7611                 return (ENOENT);
7612         }
7613         if (fw->datasize < sizeof(struct bwn_fwhdr))
7614                 goto fail;
7615         hdr = (const struct bwn_fwhdr *)(fw->data);
7616         switch (hdr->type) {
7617         case BWN_FWTYPE_UCODE:
7618         case BWN_FWTYPE_PCM:
7619                 if (be32toh(hdr->size) !=
7620                     (fw->datasize - sizeof(struct bwn_fwhdr)))
7621                         goto fail;
7622                 /* FALLTHROUGH */
7623         case BWN_FWTYPE_IV:
7624                 if (hdr->ver != 1)
7625                         goto fail;
7626                 break;
7627         default:
7628                 goto fail;
7629         }
7630         bfw->filename = name;
7631         bfw->fw = fw;
7632         bfw->type = type;
7633         return (0);
7634 fail:
7635         device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7636         if (fw != NULL)
7637                 firmware_put(fw, FIRMWARE_UNLOAD);
7638         return (EPROTO);
7639 }
7640
7641 static void
7642 bwn_release_firmware(struct bwn_mac *mac)
7643 {
7644
7645         bwn_do_release_fw(&mac->mac_fw.ucode);
7646         bwn_do_release_fw(&mac->mac_fw.pcm);
7647         bwn_do_release_fw(&mac->mac_fw.initvals);
7648         bwn_do_release_fw(&mac->mac_fw.initvals_band);
7649 }
7650
7651 static void
7652 bwn_do_release_fw(struct bwn_fwfile *bfw)
7653 {
7654
7655         if (bfw->fw != NULL)
7656                 firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7657         bfw->fw = NULL;
7658         bfw->filename = NULL;
7659 }
7660
7661 static int
7662 bwn_fw_loaducode(struct bwn_mac *mac)
7663 {
7664 #define GETFWOFFSET(fwp, offset)        \
7665         ((const uint32_t *)((const char *)fwp.fw->data + offset))
7666 #define GETFWSIZE(fwp, offset)  \
7667         ((fwp.fw->datasize - offset) / sizeof(uint32_t))
7668         struct bwn_softc *sc = mac->mac_sc;
7669         const uint32_t *data;
7670         unsigned int i;
7671         uint32_t ctl;
7672         uint16_t date, fwcaps, time;
7673         int error = 0;
7674
7675         ctl = BWN_READ_4(mac, BWN_MACCTL);
7676         ctl |= BWN_MACCTL_MCODE_JMP0;
7677         KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7678             __LINE__));
7679         BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7680         for (i = 0; i < 64; i++)
7681                 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7682         for (i = 0; i < 4096; i += 2)
7683                 bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7684
7685         data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7686         bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7687         for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7688              i++) {
7689                 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7690                 DELAY(10);
7691         }
7692
7693         if (mac->mac_fw.pcm.fw) {
7694                 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7695                 bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7696                 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7697                 bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7698                 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7699                     sizeof(struct bwn_fwhdr)); i++) {
7700                         BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7701                         DELAY(10);
7702                 }
7703         }
7704
7705         BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7706         BWN_WRITE_4(mac, BWN_MACCTL,
7707             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7708             BWN_MACCTL_MCODE_RUN);
7709
7710         for (i = 0; i < 21; i++) {
7711                 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7712                         break;
7713                 if (i >= 20) {
7714                         device_printf(sc->sc_dev, "ucode timeout\n");
7715                         error = ENXIO;
7716                         goto error;
7717                 }
7718                 DELAY(50000);
7719         }
7720         BWN_READ_4(mac, BWN_INTR_REASON);
7721
7722         mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7723         if (mac->mac_fw.rev <= 0x128) {
7724                 device_printf(sc->sc_dev, "the firmware is too old\n");
7725                 error = EOPNOTSUPP;
7726                 goto error;
7727         }
7728         mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7729             BWN_SHARED_UCODE_PATCH);
7730         date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7731         mac->mac_fw.opensource = (date == 0xffff);
7732         if (bwn_wme != 0)
7733                 mac->mac_flags |= BWN_MAC_FLAG_WME;
7734         mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7735
7736         time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7737         if (mac->mac_fw.opensource == 0) {
7738                 device_printf(sc->sc_dev,
7739                     "firmware version (rev %u patch %u date %#x time %#x)\n",
7740                     mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7741                 if (mac->mac_fw.no_pcmfile)
7742                         device_printf(sc->sc_dev,
7743                             "no HW crypto acceleration due to pcm5\n");
7744         } else {
7745                 mac->mac_fw.patch = time;
7746                 fwcaps = bwn_fwcaps_read(mac);
7747                 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7748                         device_printf(sc->sc_dev,
7749                             "disabling HW crypto acceleration\n");
7750                         mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7751                 }
7752                 if (!(fwcaps & BWN_FWCAPS_WME)) {
7753                         device_printf(sc->sc_dev, "disabling WME support\n");
7754                         mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7755                 }
7756         }
7757
7758         if (BWN_ISOLDFMT(mac))
7759                 device_printf(sc->sc_dev, "using old firmware image\n");
7760
7761         return (0);
7762
7763 error:
7764         BWN_WRITE_4(mac, BWN_MACCTL,
7765             (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7766             BWN_MACCTL_MCODE_JMP0);
7767
7768         return (error);
7769 #undef GETFWSIZE
7770 #undef GETFWOFFSET
7771 }
7772
7773 /* OpenFirmware only */
7774 static uint16_t
7775 bwn_fwcaps_read(struct bwn_mac *mac)
7776 {
7777
7778         KASSERT(mac->mac_fw.opensource == 1,
7779             ("%s:%d: fail", __func__, __LINE__));
7780         return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7781 }
7782
7783 static int
7784 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7785     size_t count, size_t array_size)
7786 {
7787 #define GET_NEXTIV16(iv)                                                \
7788         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7789             sizeof(uint16_t) + sizeof(uint16_t)))
7790 #define GET_NEXTIV32(iv)                                                \
7791         ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +        \
7792             sizeof(uint16_t) + sizeof(uint32_t)))
7793         struct bwn_softc *sc = mac->mac_sc;
7794         const struct bwn_fwinitvals *iv;
7795         uint16_t offset;
7796         size_t i;
7797         uint8_t bit32;
7798
7799         KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7800             ("%s:%d: fail", __func__, __LINE__));
7801         iv = ivals;
7802         for (i = 0; i < count; i++) {
7803                 if (array_size < sizeof(iv->offset_size))
7804                         goto fail;
7805                 array_size -= sizeof(iv->offset_size);
7806                 offset = be16toh(iv->offset_size);
7807                 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7808                 offset &= BWN_FWINITVALS_OFFSET_MASK;
7809                 if (offset >= 0x1000)
7810                         goto fail;
7811                 if (bit32) {
7812                         if (array_size < sizeof(iv->data.d32))
7813                                 goto fail;
7814                         array_size -= sizeof(iv->data.d32);
7815                         BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7816                         iv = GET_NEXTIV32(iv);
7817                 } else {
7818
7819                         if (array_size < sizeof(iv->data.d16))
7820                                 goto fail;
7821                         array_size -= sizeof(iv->data.d16);
7822                         BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7823
7824                         iv = GET_NEXTIV16(iv);
7825                 }
7826         }
7827         if (array_size != 0)
7828                 goto fail;
7829         return (0);
7830 fail:
7831         device_printf(sc->sc_dev, "initvals: invalid format\n");
7832         return (EPROTO);
7833 #undef GET_NEXTIV16
7834 #undef GET_NEXTIV32
7835 }
7836
7837 static int
7838 bwn_switch_channel(struct bwn_mac *mac, int chan)
7839 {
7840         struct bwn_phy *phy = &(mac->mac_phy);
7841         struct bwn_softc *sc = mac->mac_sc;
7842         struct ieee80211com *ic = &sc->sc_ic;
7843         uint16_t channelcookie, savedcookie;
7844         int error;
7845
7846         if (chan == 0xffff)
7847                 chan = phy->get_default_chan(mac);
7848
7849         channelcookie = chan;
7850         if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
7851                 channelcookie |= 0x100;
7852         savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
7853         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
7854         error = phy->switch_channel(mac, chan);
7855         if (error)
7856                 goto fail;
7857
7858         mac->mac_phy.chan = chan;
7859         DELAY(8000);
7860         return (0);
7861 fail:
7862         device_printf(sc->sc_dev, "failed to switch channel\n");
7863         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
7864         return (error);
7865 }
7866
7867 static uint16_t
7868 bwn_ant2phy(int antenna)
7869 {
7870
7871         switch (antenna) {
7872         case BWN_ANT0:
7873                 return (BWN_TX_PHY_ANT0);
7874         case BWN_ANT1:
7875                 return (BWN_TX_PHY_ANT1);
7876         case BWN_ANT2:
7877                 return (BWN_TX_PHY_ANT2);
7878         case BWN_ANT3:
7879                 return (BWN_TX_PHY_ANT3);
7880         case BWN_ANTAUTO:
7881                 return (BWN_TX_PHY_ANT01AUTO);
7882         }
7883         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7884         return (0);
7885 }
7886
7887 static void
7888 bwn_wme_load(struct bwn_mac *mac)
7889 {
7890         struct bwn_softc *sc = mac->mac_sc;
7891         int i;
7892
7893         KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
7894             ("%s:%d: fail", __func__, __LINE__));
7895
7896         bwn_mac_suspend(mac);
7897         for (i = 0; i < N(sc->sc_wmeParams); i++)
7898                 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
7899                     bwn_wme_shm_offsets[i]);
7900         bwn_mac_enable(mac);
7901 }
7902
7903 static void
7904 bwn_wme_loadparams(struct bwn_mac *mac,
7905     const struct wmeParams *p, uint16_t shm_offset)
7906 {
7907 #define SM(_v, _f)      (((_v) << _f##_S) & _f)
7908         struct bwn_softc *sc = mac->mac_sc;
7909         uint16_t params[BWN_NR_WMEPARAMS];
7910         int slot, tmp;
7911         unsigned int i;
7912
7913         slot = BWN_READ_2(mac, BWN_RNG) &
7914             SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7915
7916         memset(&params, 0, sizeof(params));
7917
7918         DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
7919             "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
7920             p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
7921
7922         params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
7923         params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7924         params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
7925         params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7926         params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
7927         params[BWN_WMEPARAM_BSLOTS] = slot;
7928         params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
7929
7930         for (i = 0; i < N(params); i++) {
7931                 if (i == BWN_WMEPARAM_STATUS) {
7932                         tmp = bwn_shm_read_2(mac, BWN_SHARED,
7933                             shm_offset + (i * 2));
7934                         tmp |= 0x100;
7935                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
7936                             tmp);
7937                 } else {
7938                         bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
7939                             params[i]);
7940                 }
7941         }
7942 }
7943
7944 static void
7945 bwn_mac_write_bssid(struct bwn_mac *mac)
7946 {
7947         struct bwn_softc *sc = mac->mac_sc;
7948         uint32_t tmp;
7949         int i;
7950         uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
7951
7952         bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
7953         memcpy(mac_bssid, sc->sc_ic.ic_macaddr, IEEE80211_ADDR_LEN);
7954         memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
7955             IEEE80211_ADDR_LEN);
7956
7957         for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
7958                 tmp = (uint32_t) (mac_bssid[i + 0]);
7959                 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
7960                 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
7961                 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
7962                 bwn_ram_write(mac, 0x20 + i, tmp);
7963         }
7964 }
7965
7966 static void
7967 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
7968     const uint8_t *macaddr)
7969 {
7970         static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
7971         uint16_t data;
7972
7973         if (!mac)
7974                 macaddr = zero;
7975
7976         offset |= 0x0020;
7977         BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
7978
7979         data = macaddr[0];
7980         data |= macaddr[1] << 8;
7981         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7982         data = macaddr[2];
7983         data |= macaddr[3] << 8;
7984         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7985         data = macaddr[4];
7986         data |= macaddr[5] << 8;
7987         BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7988 }
7989
7990 static void
7991 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
7992     const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
7993 {
7994         uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
7995         uint8_t per_sta_keys_start = 8;
7996
7997         if (BWN_SEC_NEWAPI(mac))
7998                 per_sta_keys_start = 4;
7999
8000         KASSERT(index < mac->mac_max_nr_keys,
8001             ("%s:%d: fail", __func__, __LINE__));
8002         KASSERT(key_len <= BWN_SEC_KEYSIZE,
8003             ("%s:%d: fail", __func__, __LINE__));
8004
8005         if (index >= per_sta_keys_start)
8006                 bwn_key_macwrite(mac, index, NULL);
8007         if (key)
8008                 memcpy(buf, key, key_len);
8009         bwn_key_write(mac, index, algorithm, buf);
8010         if (index >= per_sta_keys_start)
8011                 bwn_key_macwrite(mac, index, mac_addr);
8012
8013         mac->mac_key[index].algorithm = algorithm;
8014 }
8015
8016 static void
8017 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8018 {
8019         struct bwn_softc *sc = mac->mac_sc;
8020         uint32_t addrtmp[2] = { 0, 0 };
8021         uint8_t start = 8;
8022
8023         if (BWN_SEC_NEWAPI(mac))
8024                 start = 4;
8025
8026         KASSERT(index >= start,
8027             ("%s:%d: fail", __func__, __LINE__));
8028         index -= start;
8029
8030         if (addr) {
8031                 addrtmp[0] = addr[0];
8032                 addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8033                 addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8034                 addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8035                 addrtmp[1] = addr[4];
8036                 addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8037         }
8038
8039         if (siba_get_revid(sc->sc_dev) >= 5) {
8040                 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8041                 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8042         } else {
8043                 if (index >= 8) {
8044                         bwn_shm_write_4(mac, BWN_SHARED,
8045                             BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8046                         bwn_shm_write_2(mac, BWN_SHARED,
8047                             BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8048                 }
8049         }
8050 }
8051
8052 static void
8053 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8054     const uint8_t *key)
8055 {
8056         unsigned int i;
8057         uint32_t offset;
8058         uint16_t kidx, value;
8059
8060         kidx = BWN_SEC_KEY2FW(mac, index);
8061         bwn_shm_write_2(mac, BWN_SHARED,
8062             BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8063
8064         offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8065         for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8066                 value = key[i];
8067                 value |= (uint16_t)(key[i + 1]) << 8;
8068                 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8069         }
8070 }
8071
8072 static void
8073 bwn_phy_exit(struct bwn_mac *mac)
8074 {
8075
8076         mac->mac_phy.rf_onoff(mac, 0);
8077         if (mac->mac_phy.exit != NULL)
8078                 mac->mac_phy.exit(mac);
8079 }
8080
8081 static void
8082 bwn_dma_free(struct bwn_mac *mac)
8083 {
8084         struct bwn_dma *dma;
8085
8086         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8087                 return;
8088         dma = &mac->mac_method.dma;
8089
8090         bwn_dma_ringfree(&dma->rx);
8091         bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8092         bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8093         bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8094         bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8095         bwn_dma_ringfree(&dma->mcast);
8096 }
8097
8098 static void
8099 bwn_core_stop(struct bwn_mac *mac)
8100 {
8101         struct bwn_softc *sc = mac->mac_sc;
8102
8103         BWN_ASSERT_LOCKED(sc);
8104
8105         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8106                 return;
8107
8108         callout_stop(&sc->sc_rfswitch_ch);
8109         callout_stop(&sc->sc_task_ch);
8110         callout_stop(&sc->sc_watchdog_ch);
8111         sc->sc_watchdog_timer = 0;
8112         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8113         BWN_READ_4(mac, BWN_INTR_MASK);
8114         bwn_mac_suspend(mac);
8115
8116         mac->mac_status = BWN_MAC_STATUS_INITED;
8117 }
8118
8119 static int
8120 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8121 {
8122         struct bwn_mac *up_dev = NULL;
8123         struct bwn_mac *down_dev;
8124         struct bwn_mac *mac;
8125         int err, status;
8126         uint8_t gmode;
8127
8128         BWN_ASSERT_LOCKED(sc);
8129
8130         TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8131                 if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8132                     mac->mac_phy.supports_2ghz) {
8133                         up_dev = mac;
8134                         gmode = 1;
8135                 } else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8136                     mac->mac_phy.supports_5ghz) {
8137                         up_dev = mac;
8138                         gmode = 0;
8139                 } else {
8140                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8141                         return (EINVAL);
8142                 }
8143                 if (up_dev != NULL)
8144                         break;
8145         }
8146         if (up_dev == NULL) {
8147                 device_printf(sc->sc_dev, "Could not find a device\n");
8148                 return (ENODEV);
8149         }
8150         if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8151                 return (0);
8152
8153         device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8154             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8155
8156         down_dev = sc->sc_curmac;
8157         status = down_dev->mac_status;
8158         if (status >= BWN_MAC_STATUS_STARTED)
8159                 bwn_core_stop(down_dev);
8160         if (status >= BWN_MAC_STATUS_INITED)
8161                 bwn_core_exit(down_dev);
8162
8163         if (down_dev != up_dev)
8164                 bwn_phy_reset(down_dev);
8165
8166         up_dev->mac_phy.gmode = gmode;
8167         if (status >= BWN_MAC_STATUS_INITED) {
8168                 err = bwn_core_init(up_dev);
8169                 if (err) {
8170                         device_printf(sc->sc_dev,
8171                             "fatal: failed to initialize for %s-GHz\n",
8172                             IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8173                         goto fail;
8174                 }
8175         }
8176         if (status >= BWN_MAC_STATUS_STARTED)
8177                 bwn_core_start(up_dev);
8178         KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8179         sc->sc_curmac = up_dev;
8180
8181         return (0);
8182 fail:
8183         sc->sc_curmac = NULL;
8184         return (err);
8185 }
8186
8187 static void
8188 bwn_rf_turnon(struct bwn_mac *mac)
8189 {
8190
8191         bwn_mac_suspend(mac);
8192         mac->mac_phy.rf_onoff(mac, 1);
8193         mac->mac_phy.rf_on = 1;
8194         bwn_mac_enable(mac);
8195 }
8196
8197 static void
8198 bwn_rf_turnoff(struct bwn_mac *mac)
8199 {
8200
8201         bwn_mac_suspend(mac);
8202         mac->mac_phy.rf_onoff(mac, 0);
8203         mac->mac_phy.rf_on = 0;
8204         bwn_mac_enable(mac);
8205 }
8206
8207 static void
8208 bwn_phy_reset(struct bwn_mac *mac)
8209 {
8210         struct bwn_softc *sc = mac->mac_sc;
8211
8212         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8213             ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8214              BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8215         DELAY(1000);
8216         siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8217             (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8218             BWN_TGSLOW_PHYRESET);
8219         DELAY(1000);
8220 }
8221
8222 static int
8223 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8224 {
8225         struct bwn_vap *bvp = BWN_VAP(vap);
8226         struct ieee80211com *ic= vap->iv_ic;
8227         enum ieee80211_state ostate = vap->iv_state;
8228         struct bwn_softc *sc = ic->ic_softc;
8229         struct bwn_mac *mac = sc->sc_curmac;
8230         int error;
8231
8232         DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8233             ieee80211_state_name[vap->iv_state],
8234             ieee80211_state_name[nstate]);
8235
8236         error = bvp->bv_newstate(vap, nstate, arg);
8237         if (error != 0)
8238                 return (error);
8239
8240         BWN_LOCK(sc);
8241
8242         bwn_led_newstate(mac, nstate);
8243
8244         /*
8245          * Clear the BSSID when we stop a STA
8246          */
8247         if (vap->iv_opmode == IEEE80211_M_STA) {
8248                 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8249                         /*
8250                          * Clear out the BSSID.  If we reassociate to
8251                          * the same AP, this will reinialize things
8252                          * correctly...
8253                          */
8254                         if (ic->ic_opmode == IEEE80211_M_STA &&
8255                             (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8256                                 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8257                                 bwn_set_macaddr(mac);
8258                         }
8259                 }
8260         }
8261
8262         if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8263             vap->iv_opmode == IEEE80211_M_AHDEMO) {
8264                 /* XXX nothing to do? */
8265         } else if (nstate == IEEE80211_S_RUN) {
8266                 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8267                 bwn_set_opmode(mac);
8268                 bwn_set_pretbtt(mac);
8269                 bwn_spu_setdelay(mac, 0);
8270                 bwn_set_macaddr(mac);
8271         }
8272
8273         BWN_UNLOCK(sc);
8274
8275         return (error);
8276 }
8277
8278 static void
8279 bwn_set_pretbtt(struct bwn_mac *mac)
8280 {
8281         struct bwn_softc *sc = mac->mac_sc;
8282         struct ieee80211com *ic = &sc->sc_ic;
8283         uint16_t pretbtt;
8284
8285         if (ic->ic_opmode == IEEE80211_M_IBSS)
8286                 pretbtt = 2;
8287         else
8288                 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8289         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8290         BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8291 }
8292
8293 static int
8294 bwn_intr(void *arg)
8295 {
8296         struct bwn_mac *mac = arg;
8297         struct bwn_softc *sc = mac->mac_sc;
8298         uint32_t reason;
8299
8300         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8301             (sc->sc_flags & BWN_FLAG_INVALID))
8302                 return (FILTER_STRAY);
8303
8304         reason = BWN_READ_4(mac, BWN_INTR_REASON);
8305         if (reason == 0xffffffff)       /* shared IRQ */
8306                 return (FILTER_STRAY);
8307         reason &= mac->mac_intr_mask;
8308         if (reason == 0)
8309                 return (FILTER_HANDLED);
8310
8311         mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
8312         mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8313         mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8314         mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8315         mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8316         BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8317         BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8318         BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8319         BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8320         BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8321         BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8322
8323         /* Disable interrupts. */
8324         BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8325
8326         mac->mac_reason_intr = reason;
8327
8328         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8329         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8330
8331         taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask);
8332         return (FILTER_HANDLED);
8333 }
8334
8335 static void
8336 bwn_intrtask(void *arg, int npending)
8337 {
8338         struct bwn_mac *mac = arg;
8339         struct bwn_softc *sc = mac->mac_sc;
8340         uint32_t merged = 0;
8341         int i, tx = 0, rx = 0;
8342
8343         BWN_LOCK(sc);
8344         if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8345             (sc->sc_flags & BWN_FLAG_INVALID)) {
8346                 BWN_UNLOCK(sc);
8347                 return;
8348         }
8349
8350         for (i = 0; i < N(mac->mac_reason); i++)
8351                 merged |= mac->mac_reason[i];
8352
8353         if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8354                 device_printf(sc->sc_dev, "MAC trans error\n");
8355
8356         if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8357                 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8358                 mac->mac_phy.txerrors--;
8359                 if (mac->mac_phy.txerrors == 0) {
8360                         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8361                         bwn_restart(mac, "PHY TX errors");
8362                 }
8363         }
8364
8365         if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
8366                 if (merged & BWN_DMAINTR_FATALMASK) {
8367                         device_printf(sc->sc_dev,
8368                             "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8369                             mac->mac_reason[0], mac->mac_reason[1],
8370                             mac->mac_reason[2], mac->mac_reason[3],
8371                             mac->mac_reason[4], mac->mac_reason[5]);
8372                         bwn_restart(mac, "DMA error");
8373                         BWN_UNLOCK(sc);
8374                         return;
8375                 }
8376                 if (merged & BWN_DMAINTR_NONFATALMASK) {
8377                         device_printf(sc->sc_dev,
8378                             "DMA error: %#x %#x %#x %#x %#x %#x\n",
8379                             mac->mac_reason[0], mac->mac_reason[1],
8380                             mac->mac_reason[2], mac->mac_reason[3],
8381                             mac->mac_reason[4], mac->mac_reason[5]);
8382                 }
8383         }
8384
8385         if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8386                 bwn_intr_ucode_debug(mac);
8387         if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8388                 bwn_intr_tbtt_indication(mac);
8389         if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8390                 bwn_intr_atim_end(mac);
8391         if (mac->mac_reason_intr & BWN_INTR_BEACON)
8392                 bwn_intr_beacon(mac);
8393         if (mac->mac_reason_intr & BWN_INTR_PMQ)
8394                 bwn_intr_pmq(mac);
8395         if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8396                 bwn_intr_noise(mac);
8397
8398         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8399                 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8400                         bwn_dma_rx(mac->mac_method.dma.rx);
8401                         rx = 1;
8402                 }
8403         } else
8404                 rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8405
8406         KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8407         KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8408         KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8409         KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8410         KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8411
8412         if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8413                 bwn_intr_txeof(mac);
8414                 tx = 1;
8415         }
8416
8417         BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8418
8419         if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8420                 int evt = BWN_LED_EVENT_NONE;
8421
8422                 if (tx && rx) {
8423                         if (sc->sc_rx_rate > sc->sc_tx_rate)
8424                                 evt = BWN_LED_EVENT_RX;
8425                         else
8426                                 evt = BWN_LED_EVENT_TX;
8427                 } else if (tx) {
8428                         evt = BWN_LED_EVENT_TX;
8429                 } else if (rx) {
8430                         evt = BWN_LED_EVENT_RX;
8431                 } else if (rx == 0) {
8432                         evt = BWN_LED_EVENT_POLL;
8433                 }
8434
8435                 if (evt != BWN_LED_EVENT_NONE)
8436                         bwn_led_event(mac, evt);
8437        }
8438
8439         if (mbufq_first(&sc->sc_snd) != NULL)
8440                 bwn_start(sc);
8441
8442         BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8443         BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8444
8445         BWN_UNLOCK(sc);
8446 }
8447
8448 static void
8449 bwn_restart(struct bwn_mac *mac, const char *msg)
8450 {
8451         struct bwn_softc *sc = mac->mac_sc;
8452         struct ieee80211com *ic = &sc->sc_ic;
8453
8454         if (mac->mac_status < BWN_MAC_STATUS_INITED)
8455                 return;
8456
8457         device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8458         ieee80211_runtask(ic, &mac->mac_hwreset);
8459 }
8460
8461 static void
8462 bwn_intr_ucode_debug(struct bwn_mac *mac)
8463 {
8464         struct bwn_softc *sc = mac->mac_sc;
8465         uint16_t reason;
8466
8467         if (mac->mac_fw.opensource == 0)
8468                 return;
8469
8470         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8471         switch (reason) {
8472         case BWN_DEBUGINTR_PANIC:
8473                 bwn_handle_fwpanic(mac);
8474                 break;
8475         case BWN_DEBUGINTR_DUMP_SHM:
8476                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8477                 break;
8478         case BWN_DEBUGINTR_DUMP_REGS:
8479                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8480                 break;
8481         case BWN_DEBUGINTR_MARKER:
8482                 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8483                 break;
8484         default:
8485                 device_printf(sc->sc_dev,
8486                     "ucode debug unknown reason: %#x\n", reason);
8487         }
8488
8489         bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8490             BWN_DEBUGINTR_ACK);
8491 }
8492
8493 static void
8494 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8495 {
8496         struct bwn_softc *sc = mac->mac_sc;
8497         struct ieee80211com *ic = &sc->sc_ic;
8498
8499         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8500                 bwn_psctl(mac, 0);
8501         if (ic->ic_opmode == IEEE80211_M_IBSS)
8502                 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8503 }
8504
8505 static void
8506 bwn_intr_atim_end(struct bwn_mac *mac)
8507 {
8508
8509         if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8510                 BWN_WRITE_4(mac, BWN_MACCMD,
8511                     BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8512                 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8513         }
8514 }
8515
8516 static void
8517 bwn_intr_beacon(struct bwn_mac *mac)
8518 {
8519         struct bwn_softc *sc = mac->mac_sc;
8520         struct ieee80211com *ic = &sc->sc_ic;
8521         uint32_t cmd, beacon0, beacon1;
8522
8523         if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8524             ic->ic_opmode == IEEE80211_M_MBSS)
8525                 return;
8526
8527         mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8528
8529         cmd = BWN_READ_4(mac, BWN_MACCMD);
8530         beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8531         beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8532
8533         if (beacon0 && beacon1) {
8534                 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8535                 mac->mac_intr_mask |= BWN_INTR_BEACON;
8536                 return;
8537         }
8538
8539         if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8540                 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8541                 bwn_load_beacon0(mac);
8542                 bwn_load_beacon1(mac);
8543                 cmd = BWN_READ_4(mac, BWN_MACCMD);
8544                 cmd |= BWN_MACCMD_BEACON0_VALID;
8545                 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8546         } else {
8547                 if (!beacon0) {
8548                         bwn_load_beacon0(mac);
8549                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8550                         cmd |= BWN_MACCMD_BEACON0_VALID;
8551                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8552                 } else if (!beacon1) {
8553                         bwn_load_beacon1(mac);
8554                         cmd = BWN_READ_4(mac, BWN_MACCMD);
8555                         cmd |= BWN_MACCMD_BEACON1_VALID;
8556                         BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8557                 }
8558         }
8559 }
8560
8561 static void
8562 bwn_intr_pmq(struct bwn_mac *mac)
8563 {
8564         uint32_t tmp;
8565
8566         while (1) {
8567                 tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8568                 if (!(tmp & 0x00000008))
8569                         break;
8570         }
8571         BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8572 }
8573
8574 static void
8575 bwn_intr_noise(struct bwn_mac *mac)
8576 {
8577         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8578         uint16_t tmp;
8579         uint8_t noise[4];
8580         uint8_t i, j;
8581         int32_t average;
8582
8583         if (mac->mac_phy.type != BWN_PHYTYPE_G)
8584                 return;
8585
8586         KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8587         *((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8588         if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8589             noise[3] == 0x7f)
8590                 goto new;
8591
8592         KASSERT(mac->mac_noise.noi_nsamples < 8,
8593             ("%s:%d: fail", __func__, __LINE__));
8594         i = mac->mac_noise.noi_nsamples;
8595         noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8596         noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8597         noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8598         noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8599         mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8600         mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8601         mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8602         mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8603         mac->mac_noise.noi_nsamples++;
8604         if (mac->mac_noise.noi_nsamples == 8) {
8605                 average = 0;
8606                 for (i = 0; i < 8; i++) {
8607                         for (j = 0; j < 4; j++)
8608                                 average += mac->mac_noise.noi_samples[i][j];
8609                 }
8610                 average = (((average / 32) * 125) + 64) / 128;
8611                 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8612                 if (tmp >= 8)
8613                         average += 2;
8614                 else
8615                         average -= 25;
8616                 average -= (tmp == 8) ? 72 : 48;
8617
8618                 mac->mac_stats.link_noise = average;
8619                 mac->mac_noise.noi_running = 0;
8620                 return;
8621         }
8622 new:
8623         bwn_noise_gensample(mac);
8624 }
8625
8626 static int
8627 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8628 {
8629         struct bwn_mac *mac = prq->prq_mac;
8630         struct bwn_softc *sc = mac->mac_sc;
8631         unsigned int i;
8632
8633         BWN_ASSERT_LOCKED(sc);
8634
8635         if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8636                 return (0);
8637
8638         for (i = 0; i < 5000; i++) {
8639                 if (bwn_pio_rxeof(prq) == 0)
8640                         break;
8641         }
8642         if (i >= 5000)
8643                 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8644         return ((i > 0) ? 1 : 0);
8645 }
8646
8647 static void
8648 bwn_dma_rx(struct bwn_dma_ring *dr)
8649 {
8650         int slot, curslot;
8651
8652         KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8653         curslot = dr->get_curslot(dr);
8654         KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8655             ("%s:%d: fail", __func__, __LINE__));
8656
8657         slot = dr->dr_curslot;
8658         for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8659                 bwn_dma_rxeof(dr, &slot);
8660
8661         bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8662             BUS_DMASYNC_PREWRITE);
8663
8664         dr->set_curslot(dr, slot);
8665         dr->dr_curslot = slot;
8666 }
8667
8668 static void
8669 bwn_intr_txeof(struct bwn_mac *mac)
8670 {
8671         struct bwn_txstatus stat;
8672         uint32_t stat0, stat1;
8673         uint16_t tmp;
8674
8675         BWN_ASSERT_LOCKED(mac->mac_sc);
8676
8677         while (1) {
8678                 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8679                 if (!(stat0 & 0x00000001))
8680                         break;
8681                 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8682
8683                 stat.cookie = (stat0 >> 16);
8684                 stat.seq = (stat1 & 0x0000ffff);
8685                 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8686                 tmp = (stat0 & 0x0000ffff);
8687                 stat.framecnt = ((tmp & 0xf000) >> 12);
8688                 stat.rtscnt = ((tmp & 0x0f00) >> 8);
8689                 stat.sreason = ((tmp & 0x001c) >> 2);
8690                 stat.pm = (tmp & 0x0080) ? 1 : 0;
8691                 stat.im = (tmp & 0x0040) ? 1 : 0;
8692                 stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8693                 stat.ack = (tmp & 0x0002) ? 1 : 0;
8694
8695                 bwn_handle_txeof(mac, &stat);
8696         }
8697 }
8698
8699 static void
8700 bwn_hwreset(void *arg, int npending)
8701 {
8702         struct bwn_mac *mac = arg;
8703         struct bwn_softc *sc = mac->mac_sc;
8704         int error = 0;
8705         int prev_status;
8706
8707         BWN_LOCK(sc);
8708
8709         prev_status = mac->mac_status;
8710         if (prev_status >= BWN_MAC_STATUS_STARTED)
8711                 bwn_core_stop(mac);
8712         if (prev_status >= BWN_MAC_STATUS_INITED)
8713                 bwn_core_exit(mac);
8714
8715         if (prev_status >= BWN_MAC_STATUS_INITED) {
8716                 error = bwn_core_init(mac);
8717                 if (error)
8718                         goto out;
8719         }
8720         if (prev_status >= BWN_MAC_STATUS_STARTED)
8721                 bwn_core_start(mac);
8722 out:
8723         if (error) {
8724                 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8725                 sc->sc_curmac = NULL;
8726         }
8727         BWN_UNLOCK(sc);
8728 }
8729
8730 static void
8731 bwn_handle_fwpanic(struct bwn_mac *mac)
8732 {
8733         struct bwn_softc *sc = mac->mac_sc;
8734         uint16_t reason;
8735
8736         reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8737         device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8738
8739         if (reason == BWN_FWPANIC_RESTART)
8740                 bwn_restart(mac, "ucode panic");
8741 }
8742
8743 static void
8744 bwn_load_beacon0(struct bwn_mac *mac)
8745 {
8746
8747         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8748 }
8749
8750 static void
8751 bwn_load_beacon1(struct bwn_mac *mac)
8752 {
8753
8754         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8755 }
8756
8757 static uint32_t
8758 bwn_jssi_read(struct bwn_mac *mac)
8759 {
8760         uint32_t val = 0;
8761
8762         val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8763         val <<= 16;
8764         val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8765
8766         return (val);
8767 }
8768
8769 static void
8770 bwn_noise_gensample(struct bwn_mac *mac)
8771 {
8772         uint32_t jssi = 0x7f7f7f7f;
8773
8774         bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8775         bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8776         BWN_WRITE_4(mac, BWN_MACCMD,
8777             BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8778 }
8779
8780 static int
8781 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8782 {
8783         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8784
8785         return (dr->dr_numslots - dr->dr_usedslot);
8786 }
8787
8788 static int
8789 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8790 {
8791         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8792
8793         KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8794             ("%s:%d: fail", __func__, __LINE__));
8795         if (slot == dr->dr_numslots - 1)
8796                 return (0);
8797         return (slot + 1);
8798 }
8799
8800 static void
8801 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8802 {
8803         struct bwn_mac *mac = dr->dr_mac;
8804         struct bwn_softc *sc = mac->mac_sc;
8805         struct bwn_dma *dma = &mac->mac_method.dma;
8806         struct bwn_dmadesc_generic *desc;
8807         struct bwn_dmadesc_meta *meta;
8808         struct bwn_rxhdr4 *rxhdr;
8809         struct mbuf *m;
8810         uint32_t macstat;
8811         int32_t tmp;
8812         int cnt = 0;
8813         uint16_t len;
8814
8815         dr->getdesc(dr, *slot, &desc, &meta);
8816
8817         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8818         m = meta->mt_m;
8819
8820         if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8821                 counter_u64_add(sc->sc_ic.ic_ierrors, 1);
8822                 return;
8823         }
8824
8825         rxhdr = mtod(m, struct bwn_rxhdr4 *);
8826         len = le16toh(rxhdr->frame_len);
8827         if (len <= 0) {
8828                 counter_u64_add(sc->sc_ic.ic_ierrors, 1);
8829                 return;
8830         }
8831         if (bwn_dma_check_redzone(dr, m)) {
8832                 device_printf(sc->sc_dev, "redzone error.\n");
8833                 bwn_dma_set_redzone(dr, m);
8834                 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8835                     BUS_DMASYNC_PREWRITE);
8836                 return;
8837         }
8838         if (len > dr->dr_rx_bufsize) {
8839                 tmp = len;
8840                 while (1) {
8841                         dr->getdesc(dr, *slot, &desc, &meta);
8842                         bwn_dma_set_redzone(dr, meta->mt_m);
8843                         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8844                             BUS_DMASYNC_PREWRITE);
8845                         *slot = bwn_dma_nextslot(dr, *slot);
8846                         cnt++;
8847                         tmp -= dr->dr_rx_bufsize;
8848                         if (tmp <= 0)
8849                                 break;
8850                 }
8851                 device_printf(sc->sc_dev, "too small buffer "
8852                        "(len %u buffer %u dropped %d)\n",
8853                        len, dr->dr_rx_bufsize, cnt);
8854                 return;
8855         }
8856         macstat = le32toh(rxhdr->mac_status);
8857         if (macstat & BWN_RX_MAC_FCSERR) {
8858                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8859                         device_printf(sc->sc_dev, "RX drop\n");
8860                         return;
8861                 }
8862         }
8863
8864         m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8865         m_adj(m, dr->dr_frameoffset);
8866
8867         bwn_rxeof(dr->dr_mac, m, rxhdr);
8868 }
8869
8870 static void
8871 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8872 {
8873         struct bwn_dma_ring *dr;
8874         struct bwn_dmadesc_generic *desc;
8875         struct bwn_dmadesc_meta *meta;
8876         struct bwn_pio_txqueue *tq;
8877         struct bwn_pio_txpkt *tp = NULL;
8878         struct bwn_softc *sc = mac->mac_sc;
8879         struct bwn_stats *stats = &mac->mac_stats;
8880         struct ieee80211_node *ni;
8881         struct ieee80211vap *vap;
8882         int retrycnt = 0, slot;
8883
8884         BWN_ASSERT_LOCKED(mac->mac_sc);
8885
8886         if (status->im)
8887                 device_printf(sc->sc_dev, "TODO: STATUS IM\n");
8888         if (status->ampdu)
8889                 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
8890         if (status->rtscnt) {
8891                 if (status->rtscnt == 0xf)
8892                         stats->rtsfail++;
8893                 else
8894                         stats->rts++;
8895         }
8896
8897         if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8898                 if (status->ack) {
8899                         dr = bwn_dma_parse_cookie(mac, status,
8900                             status->cookie, &slot);
8901                         if (dr == NULL) {
8902                                 device_printf(sc->sc_dev,
8903                                     "failed to parse cookie\n");
8904                                 return;
8905                         }
8906                         while (1) {
8907                                 dr->getdesc(dr, slot, &desc, &meta);
8908                                 if (meta->mt_islast) {
8909                                         ni = meta->mt_ni;
8910                                         vap = ni->ni_vap;
8911                                         ieee80211_ratectl_tx_complete(vap, ni,
8912                                             status->ack ?
8913                                               IEEE80211_RATECTL_TX_SUCCESS :
8914                                               IEEE80211_RATECTL_TX_FAILURE,
8915                                             &retrycnt, 0);
8916                                         break;
8917                                 }
8918                                 slot = bwn_dma_nextslot(dr, slot);
8919                         }
8920                 }
8921                 bwn_dma_handle_txeof(mac, status);
8922         } else {
8923                 if (status->ack) {
8924                         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
8925                         if (tq == NULL) {
8926                                 device_printf(sc->sc_dev,
8927                                     "failed to parse cookie\n");
8928                                 return;
8929                         }
8930                         ni = tp->tp_ni;
8931                         vap = ni->ni_vap;
8932                         ieee80211_ratectl_tx_complete(vap, ni,
8933                             status->ack ?
8934                               IEEE80211_RATECTL_TX_SUCCESS :
8935                               IEEE80211_RATECTL_TX_FAILURE,
8936                             &retrycnt, 0);
8937                 }
8938                 bwn_pio_handle_txeof(mac, status);
8939         }
8940
8941         bwn_phy_txpower_check(mac, 0);
8942 }
8943
8944 static uint8_t
8945 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
8946 {
8947         struct bwn_mac *mac = prq->prq_mac;
8948         struct bwn_softc *sc = mac->mac_sc;
8949         struct bwn_rxhdr4 rxhdr;
8950         struct mbuf *m;
8951         uint32_t ctl32, macstat, v32;
8952         unsigned int i, padding;
8953         uint16_t ctl16, len, totlen, v16;
8954         unsigned char *mp;
8955         char *data;
8956
8957         memset(&rxhdr, 0, sizeof(rxhdr));
8958
8959         if (prq->prq_rev >= 8) {
8960                 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
8961                 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
8962                         return (0);
8963                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
8964                     BWN_PIO8_RXCTL_FRAMEREADY);
8965                 for (i = 0; i < 10; i++) {
8966                         ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
8967                         if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
8968                                 goto ready;
8969                         DELAY(10);
8970                 }
8971         } else {
8972                 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
8973                 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
8974                         return (0);
8975                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
8976                     BWN_PIO_RXCTL_FRAMEREADY);
8977                 for (i = 0; i < 10; i++) {
8978                         ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
8979                         if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
8980                                 goto ready;
8981                         DELAY(10);
8982                 }
8983         }
8984         device_printf(sc->sc_dev, "%s: timed out\n", __func__);
8985         return (1);
8986 ready:
8987         if (prq->prq_rev >= 8)
8988                 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
8989                     prq->prq_base + BWN_PIO8_RXDATA);
8990         else
8991                 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
8992                     prq->prq_base + BWN_PIO_RXDATA);
8993         len = le16toh(rxhdr.frame_len);
8994         if (len > 0x700) {
8995                 device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
8996                 goto error;
8997         }
8998         if (len == 0) {
8999                 device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9000                 goto error;
9001         }
9002
9003         macstat = le32toh(rxhdr.mac_status);
9004         if (macstat & BWN_RX_MAC_FCSERR) {
9005                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9006                         device_printf(sc->sc_dev, "%s: FCS error", __func__);
9007                         goto error;
9008                 }
9009         }
9010
9011         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9012         totlen = len + padding;
9013         KASSERT(totlen <= MCLBYTES, ("too big..\n"));
9014         m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9015         if (m == NULL) {
9016                 device_printf(sc->sc_dev, "%s: out of memory", __func__);
9017                 goto error;
9018         }
9019         mp = mtod(m, unsigned char *);
9020         if (prq->prq_rev >= 8) {
9021                 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3),
9022                     prq->prq_base + BWN_PIO8_RXDATA);
9023                 if (totlen & 3) {
9024                         v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9025                         data = &(mp[totlen - 1]);
9026                         switch (totlen & 3) {
9027                         case 3:
9028                                 *data = (v32 >> 16);
9029                                 data--;
9030                         case 2:
9031                                 *data = (v32 >> 8);
9032                                 data--;
9033                         case 1:
9034                                 *data = v32;
9035                         }
9036                 }
9037         } else {
9038                 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1),
9039                     prq->prq_base + BWN_PIO_RXDATA);
9040                 if (totlen & 1) {
9041                         v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9042                         mp[totlen - 1] = v16;
9043                 }
9044         }
9045
9046         m->m_len = m->m_pkthdr.len = totlen;
9047
9048         bwn_rxeof(prq->prq_mac, m, &rxhdr);
9049
9050         return (1);
9051 error:
9052         if (prq->prq_rev >= 8)
9053                 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9054                     BWN_PIO8_RXCTL_DATAREADY);
9055         else
9056                 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9057         return (1);
9058 }
9059
9060 static int
9061 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9062     struct bwn_dmadesc_meta *meta, int init)
9063 {
9064         struct bwn_mac *mac = dr->dr_mac;
9065         struct bwn_dma *dma = &mac->mac_method.dma;
9066         struct bwn_rxhdr4 *hdr;
9067         bus_dmamap_t map;
9068         bus_addr_t paddr;
9069         struct mbuf *m;
9070         int error;
9071
9072         m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9073         if (m == NULL) {
9074                 error = ENOBUFS;
9075
9076                 /*
9077                  * If the NIC is up and running, we need to:
9078                  * - Clear RX buffer's header.
9079                  * - Restore RX descriptor settings.
9080                  */
9081                 if (init)
9082                         return (error);
9083                 else
9084                         goto back;
9085         }
9086         m->m_len = m->m_pkthdr.len = MCLBYTES;
9087
9088         bwn_dma_set_redzone(dr, m);
9089
9090         /*
9091          * Try to load RX buf into temporary DMA map
9092          */
9093         error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9094             bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9095         if (error) {
9096                 m_freem(m);
9097
9098                 /*
9099                  * See the comment above
9100                  */
9101                 if (init)
9102                         return (error);
9103                 else
9104                         goto back;
9105         }
9106
9107         if (!init)
9108                 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9109         meta->mt_m = m;
9110         meta->mt_paddr = paddr;
9111
9112         /*
9113          * Swap RX buf's DMA map with the loaded temporary one
9114          */
9115         map = meta->mt_dmap;
9116         meta->mt_dmap = dr->dr_spare_dmap;
9117         dr->dr_spare_dmap = map;
9118
9119 back:
9120         /*
9121          * Clear RX buf header
9122          */
9123         hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9124         bzero(hdr, sizeof(*hdr));
9125         bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9126             BUS_DMASYNC_PREWRITE);
9127
9128         /*
9129          * Setup RX buf descriptor
9130          */
9131         dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len -
9132             sizeof(*hdr), 0, 0, 0);
9133         return (error);
9134 }
9135
9136 static void
9137 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9138                  bus_size_t mapsz __unused, int error)
9139 {
9140
9141         if (!error) {
9142                 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9143                 *((bus_addr_t *)arg) = seg->ds_addr;
9144         }
9145 }
9146
9147 static int
9148 bwn_hwrate2ieeerate(int rate)
9149 {
9150
9151         switch (rate) {
9152         case BWN_CCK_RATE_1MB:
9153                 return (2);
9154         case BWN_CCK_RATE_2MB:
9155                 return (4);
9156         case BWN_CCK_RATE_5MB:
9157                 return (11);
9158         case BWN_CCK_RATE_11MB:
9159                 return (22);
9160         case BWN_OFDM_RATE_6MB:
9161                 return (12);
9162         case BWN_OFDM_RATE_9MB:
9163                 return (18);
9164         case BWN_OFDM_RATE_12MB:
9165                 return (24);
9166         case BWN_OFDM_RATE_18MB:
9167                 return (36);
9168         case BWN_OFDM_RATE_24MB:
9169                 return (48);
9170         case BWN_OFDM_RATE_36MB:
9171                 return (72);
9172         case BWN_OFDM_RATE_48MB:
9173                 return (96);
9174         case BWN_OFDM_RATE_54MB:
9175                 return (108);
9176         default:
9177                 printf("Ooops\n");
9178                 return (0);
9179         }
9180 }
9181
9182 static void
9183 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9184 {
9185         const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9186         struct bwn_plcp6 *plcp;
9187         struct bwn_softc *sc = mac->mac_sc;
9188         struct ieee80211_frame_min *wh;
9189         struct ieee80211_node *ni;
9190         struct ieee80211com *ic = &sc->sc_ic;
9191         uint32_t macstat;
9192         int padding, rate, rssi = 0, noise = 0, type;
9193         uint16_t phytype, phystat0, phystat3, chanstat;
9194         unsigned char *mp = mtod(m, unsigned char *);
9195         static int rx_mac_dec_rpt = 0;
9196
9197         BWN_ASSERT_LOCKED(sc);
9198
9199         phystat0 = le16toh(rxhdr->phy_status0);
9200         phystat3 = le16toh(rxhdr->phy_status3);
9201         macstat = le32toh(rxhdr->mac_status);
9202         chanstat = le16toh(rxhdr->channel);
9203         phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9204
9205         if (macstat & BWN_RX_MAC_FCSERR)
9206                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9207         if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9208                 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9209         if (macstat & BWN_RX_MAC_DECERR)
9210                 goto drop;
9211
9212         padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9213         if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9214                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9215                     m->m_pkthdr.len);
9216                 goto drop;
9217         }
9218         plcp = (struct bwn_plcp6 *)(mp + padding);
9219         m_adj(m, sizeof(struct bwn_plcp6) + padding);
9220         if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9221                 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9222                     m->m_pkthdr.len);
9223                 goto drop;
9224         }
9225         wh = mtod(m, struct ieee80211_frame_min *);
9226
9227         if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9228                 device_printf(sc->sc_dev,
9229                     "RX decryption attempted (old %d keyidx %#x)\n",
9230                     BWN_ISOLDFMT(mac),
9231                     (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9232
9233         /* XXX calculating RSSI & noise & antenna */
9234
9235         if (phystat0 & BWN_RX_PHYST0_OFDM)
9236                 rate = bwn_plcp_get_ofdmrate(mac, plcp,
9237                     phytype == BWN_PHYTYPE_A);
9238         else
9239                 rate = bwn_plcp_get_cckrate(mac, plcp);
9240         if (rate == -1) {
9241                 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9242                         goto drop;
9243         }
9244         sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9245
9246         /* RX radio tap */
9247         if (ieee80211_radiotap_active(ic))
9248                 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9249         m_adj(m, -IEEE80211_CRC_LEN);
9250
9251         rssi = rxhdr->phy.abg.rssi;     /* XXX incorrect RSSI calculation? */
9252         noise = mac->mac_stats.link_noise;
9253
9254         BWN_UNLOCK(sc);
9255
9256         ni = ieee80211_find_rxnode(ic, wh);
9257         if (ni != NULL) {
9258                 type = ieee80211_input(ni, m, rssi, noise);
9259                 ieee80211_free_node(ni);
9260         } else
9261                 type = ieee80211_input_all(ic, m, rssi, noise);
9262
9263         BWN_LOCK(sc);
9264         return;
9265 drop:
9266         device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9267 }
9268
9269 static void
9270 bwn_dma_handle_txeof(struct bwn_mac *mac,
9271     const struct bwn_txstatus *status)
9272 {
9273         struct bwn_dma *dma = &mac->mac_method.dma;
9274         struct bwn_dma_ring *dr;
9275         struct bwn_dmadesc_generic *desc;
9276         struct bwn_dmadesc_meta *meta;
9277         struct bwn_softc *sc = mac->mac_sc;
9278         int slot;
9279
9280         BWN_ASSERT_LOCKED(sc);
9281
9282         dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9283         if (dr == NULL) {
9284                 device_printf(sc->sc_dev, "failed to parse cookie\n");
9285                 return;
9286         }
9287         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9288
9289         while (1) {
9290                 KASSERT(slot >= 0 && slot < dr->dr_numslots,
9291                     ("%s:%d: fail", __func__, __LINE__));
9292                 dr->getdesc(dr, slot, &desc, &meta);
9293
9294                 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
9295                         bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
9296                 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
9297                         bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9298
9299                 if (meta->mt_islast) {
9300                         KASSERT(meta->mt_m != NULL,
9301                             ("%s:%d: fail", __func__, __LINE__));
9302
9303                         ieee80211_tx_complete(meta->mt_ni, meta->mt_m, 0);
9304                         meta->mt_ni = NULL;
9305                         meta->mt_m = NULL;
9306                 } else
9307                         KASSERT(meta->mt_m == NULL,
9308                             ("%s:%d: fail", __func__, __LINE__));
9309
9310                 dr->dr_usedslot--;
9311                 if (meta->mt_islast)
9312                         break;
9313                 slot = bwn_dma_nextslot(dr, slot);
9314         }
9315         sc->sc_watchdog_timer = 0;
9316         if (dr->dr_stop) {
9317                 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9318                     ("%s:%d: fail", __func__, __LINE__));
9319                 dr->dr_stop = 0;
9320         }
9321 }
9322
9323 static void
9324 bwn_pio_handle_txeof(struct bwn_mac *mac,
9325     const struct bwn_txstatus *status)
9326 {
9327         struct bwn_pio_txqueue *tq;
9328         struct bwn_pio_txpkt *tp = NULL;
9329         struct bwn_softc *sc = mac->mac_sc;
9330
9331         BWN_ASSERT_LOCKED(sc);
9332
9333         tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9334         if (tq == NULL)
9335                 return;
9336
9337         tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9338         tq->tq_free++;
9339
9340         if (tp->tp_ni != NULL) {
9341                 /*
9342                  * Do any tx complete callback.  Note this must
9343                  * be done before releasing the node reference.
9344                  */
9345                 if (tp->tp_m->m_flags & M_TXCB)
9346                         ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9347                 ieee80211_free_node(tp->tp_ni);
9348                 tp->tp_ni = NULL;
9349         }
9350         m_freem(tp->tp_m);
9351         tp->tp_m = NULL;
9352         TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9353
9354         sc->sc_watchdog_timer = 0;
9355 }
9356
9357 static void
9358 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9359 {
9360         struct bwn_softc *sc = mac->mac_sc;
9361         struct bwn_phy *phy = &mac->mac_phy;
9362         struct ieee80211com *ic = &sc->sc_ic;
9363         unsigned long now;
9364         int result;
9365
9366         BWN_GETTIME(now);
9367
9368         if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9369                 return;
9370         phy->nexttime = now + 2 * 1000;
9371
9372         if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9373             siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9374                 return;
9375
9376         if (phy->recalc_txpwr != NULL) {
9377                 result = phy->recalc_txpwr(mac,
9378                     (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9379                 if (result == BWN_TXPWR_RES_DONE)
9380                         return;
9381                 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9382                     ("%s: fail", __func__));
9383                 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9384
9385                 ieee80211_runtask(ic, &mac->mac_txpower);
9386         }
9387 }
9388
9389 static uint16_t
9390 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9391 {
9392
9393         return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9394 }
9395
9396 static uint32_t
9397 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9398 {
9399
9400         return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9401 }
9402
9403 static void
9404 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9405 {
9406
9407         BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9408 }
9409
9410 static void
9411 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9412 {
9413
9414         BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9415 }
9416
9417 static int
9418 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9419 {
9420
9421         switch (rate) {
9422         /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9423         case 12:
9424                 return (BWN_OFDM_RATE_6MB);
9425         case 18:
9426                 return (BWN_OFDM_RATE_9MB);
9427         case 24:
9428                 return (BWN_OFDM_RATE_12MB);
9429         case 36:
9430                 return (BWN_OFDM_RATE_18MB);
9431         case 48:
9432                 return (BWN_OFDM_RATE_24MB);
9433         case 72:
9434                 return (BWN_OFDM_RATE_36MB);
9435         case 96:
9436                 return (BWN_OFDM_RATE_48MB);
9437         case 108:
9438                 return (BWN_OFDM_RATE_54MB);
9439         /* CCK rates (NB: not IEEE std, device-specific) */
9440         case 2:
9441                 return (BWN_CCK_RATE_1MB);
9442         case 4:
9443                 return (BWN_CCK_RATE_2MB);
9444         case 11:
9445                 return (BWN_CCK_RATE_5MB);
9446         case 22:
9447                 return (BWN_CCK_RATE_11MB);
9448         }
9449
9450         device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9451         return (BWN_CCK_RATE_1MB);
9452 }
9453
9454 static int
9455 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9456     struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9457 {
9458         const struct bwn_phy *phy = &mac->mac_phy;
9459         struct bwn_softc *sc = mac->mac_sc;
9460         struct ieee80211_frame *wh;
9461         struct ieee80211_frame *protwh;
9462         struct ieee80211_frame_cts *cts;
9463         struct ieee80211_frame_rts *rts;
9464         const struct ieee80211_txparam *tp;
9465         struct ieee80211vap *vap = ni->ni_vap;
9466         struct ieee80211com *ic = &sc->sc_ic;
9467         struct mbuf *mprot;
9468         unsigned int len;
9469         uint32_t macctl = 0;
9470         int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9471         uint16_t phyctl = 0;
9472         uint8_t rate, rate_fb;
9473
9474         wh = mtod(m, struct ieee80211_frame *);
9475         memset(txhdr, 0, sizeof(*txhdr));
9476
9477         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9478         ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9479         isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9480
9481         /*
9482          * Find TX rate
9483          */
9484         tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9485         if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9486                 rate = rate_fb = tp->mgmtrate;
9487         else if (ismcast)
9488                 rate = rate_fb = tp->mcastrate;
9489         else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9490                 rate = rate_fb = tp->ucastrate;
9491         else {
9492                 rix = ieee80211_ratectl_rate(ni, NULL, 0);
9493                 rate = ni->ni_txrate;
9494
9495                 if (rix > 0)
9496                         rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9497                             IEEE80211_RATE_VAL;
9498                 else
9499                         rate_fb = rate;
9500         }
9501
9502         sc->sc_tx_rate = rate;
9503
9504         rate = bwn_ieeerate2hwrate(sc, rate);
9505         rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9506
9507         txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9508             bwn_plcp_getcck(rate);
9509         bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9510         bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9511
9512         if ((rate_fb == rate) ||
9513             (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9514             (*(u_int16_t *)wh->i_dur == htole16(0)))
9515                 txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9516         else
9517                 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9518                     m->m_pkthdr.len, rate, isshort);
9519
9520         /* XXX TX encryption */
9521         bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9522             (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9523             (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9524             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9525         bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9526             m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9527
9528         txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9529             BWN_TX_EFT_FB_CCK;
9530         txhdr->chan = phy->chan;
9531         phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9532             BWN_TX_PHY_ENC_CCK;
9533         if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9534              rate == BWN_CCK_RATE_11MB))
9535                 phyctl |= BWN_TX_PHY_SHORTPRMBL;
9536
9537         /* XXX TX antenna selection */
9538
9539         switch (bwn_antenna_sanitize(mac, 0)) {
9540         case 0:
9541                 phyctl |= BWN_TX_PHY_ANT01AUTO;
9542                 break;
9543         case 1:
9544                 phyctl |= BWN_TX_PHY_ANT0;
9545                 break;
9546         case 2:
9547                 phyctl |= BWN_TX_PHY_ANT1;
9548                 break;
9549         case 3:
9550                 phyctl |= BWN_TX_PHY_ANT2;
9551                 break;
9552         case 4:
9553                 phyctl |= BWN_TX_PHY_ANT3;
9554                 break;
9555         default:
9556                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9557         }
9558
9559         if (!ismcast)
9560                 macctl |= BWN_TX_MAC_ACK;
9561
9562         macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9563         if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9564             m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9565                 macctl |= BWN_TX_MAC_LONGFRAME;
9566
9567         if (ic->ic_flags & IEEE80211_F_USEPROT) {
9568                 /* XXX RTS rate is always 1MB??? */
9569                 rts_rate = BWN_CCK_RATE_1MB;
9570                 rts_rate_fb = bwn_get_fbrate(rts_rate);
9571
9572                 protdur = ieee80211_compute_duration(ic->ic_rt,
9573                     m->m_pkthdr.len, rate, isshort) +
9574                     + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9575
9576                 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9577                         cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9578                             (txhdr->body.old.rts_frame) :
9579                             (txhdr->body.new.rts_frame));
9580                         mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9581                             protdur);
9582                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9583                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9584                             mprot->m_pkthdr.len);
9585                         m_freem(mprot);
9586                         macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9587                         len = sizeof(struct ieee80211_frame_cts);
9588                 } else {
9589                         rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9590                             (txhdr->body.old.rts_frame) :
9591                             (txhdr->body.new.rts_frame));
9592                         protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9593                             isshort);
9594                         mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9595                             wh->i_addr2, protdur);
9596                         KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9597                         bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9598                             mprot->m_pkthdr.len);
9599                         m_freem(mprot);
9600                         macctl |= BWN_TX_MAC_SEND_RTSCTS;
9601                         len = sizeof(struct ieee80211_frame_rts);
9602                 }
9603                 len += IEEE80211_CRC_LEN;
9604                 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9605                     &txhdr->body.old.rts_plcp :
9606                     &txhdr->body.new.rts_plcp), len, rts_rate);
9607                 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9608                     rts_rate_fb);
9609
9610                 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9611                     (&txhdr->body.old.rts_frame) :
9612                     (&txhdr->body.new.rts_frame));
9613                 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9614
9615                 if (BWN_ISOFDMRATE(rts_rate)) {
9616                         txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9617                         txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9618                 } else {
9619                         txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9620                         txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9621                 }
9622                 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9623                     BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9624         }
9625
9626         if (BWN_ISOLDFMT(mac))
9627                 txhdr->body.old.cookie = htole16(cookie);
9628         else
9629                 txhdr->body.new.cookie = htole16(cookie);
9630
9631         txhdr->macctl = htole32(macctl);
9632         txhdr->phyctl = htole16(phyctl);
9633
9634         /*
9635          * TX radio tap
9636          */
9637         if (ieee80211_radiotap_active_vap(vap)) {
9638                 sc->sc_tx_th.wt_flags = 0;
9639                 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
9640                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9641                 if (isshort &&
9642                     (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9643                      rate == BWN_CCK_RATE_11MB))
9644                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9645                 sc->sc_tx_th.wt_rate = rate;
9646
9647                 ieee80211_radiotap_tx(vap, m);
9648         }
9649
9650         return (0);
9651 }
9652
9653 static void
9654 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9655     const uint8_t rate)
9656 {
9657         uint32_t d, plen;
9658         uint8_t *raw = plcp->o.raw;
9659
9660         if (BWN_ISOFDMRATE(rate)) {
9661                 d = bwn_plcp_getofdm(rate);
9662                 KASSERT(!(octets & 0xf000),
9663                     ("%s:%d: fail", __func__, __LINE__));
9664                 d |= (octets << 5);
9665                 plcp->o.data = htole32(d);
9666         } else {
9667                 plen = octets * 16 / rate;
9668                 if ((octets * 16 % rate) > 0) {
9669                         plen++;
9670                         if ((rate == BWN_CCK_RATE_11MB)
9671                             && ((octets * 8 % 11) < 4)) {
9672                                 raw[1] = 0x84;
9673                         } else
9674                                 raw[1] = 0x04;
9675                 } else
9676                         raw[1] = 0x04;
9677                 plcp->o.data |= htole32(plen << 16);
9678                 raw[0] = bwn_plcp_getcck(rate);
9679         }
9680 }
9681
9682 static uint8_t
9683 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9684 {
9685         struct bwn_softc *sc = mac->mac_sc;
9686         uint8_t mask;
9687
9688         if (n == 0)
9689                 return (0);
9690         if (mac->mac_phy.gmode)
9691                 mask = siba_sprom_get_ant_bg(sc->sc_dev);
9692         else
9693                 mask = siba_sprom_get_ant_a(sc->sc_dev);
9694         if (!(mask & (1 << (n - 1))))
9695                 return (0);
9696         return (n);
9697 }
9698
9699 static uint8_t
9700 bwn_get_fbrate(uint8_t bitrate)
9701 {
9702         switch (bitrate) {
9703         case BWN_CCK_RATE_1MB:
9704                 return (BWN_CCK_RATE_1MB);
9705         case BWN_CCK_RATE_2MB:
9706                 return (BWN_CCK_RATE_1MB);
9707         case BWN_CCK_RATE_5MB:
9708                 return (BWN_CCK_RATE_2MB);
9709         case BWN_CCK_RATE_11MB:
9710                 return (BWN_CCK_RATE_5MB);
9711         case BWN_OFDM_RATE_6MB:
9712                 return (BWN_CCK_RATE_5MB);
9713         case BWN_OFDM_RATE_9MB:
9714                 return (BWN_OFDM_RATE_6MB);
9715         case BWN_OFDM_RATE_12MB:
9716                 return (BWN_OFDM_RATE_9MB);
9717         case BWN_OFDM_RATE_18MB:
9718                 return (BWN_OFDM_RATE_12MB);
9719         case BWN_OFDM_RATE_24MB:
9720                 return (BWN_OFDM_RATE_18MB);
9721         case BWN_OFDM_RATE_36MB:
9722                 return (BWN_OFDM_RATE_24MB);
9723         case BWN_OFDM_RATE_48MB:
9724                 return (BWN_OFDM_RATE_36MB);
9725         case BWN_OFDM_RATE_54MB:
9726                 return (BWN_OFDM_RATE_48MB);
9727         }
9728         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9729         return (0);
9730 }
9731
9732 static uint32_t
9733 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9734     uint32_t ctl, const void *_data, int len)
9735 {
9736         struct bwn_softc *sc = mac->mac_sc;
9737         uint32_t value = 0;
9738         const uint8_t *data = _data;
9739
9740         ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9741             BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9742         bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9743
9744         siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9745             tq->tq_base + BWN_PIO8_TXDATA);
9746         if (len & 3) {
9747                 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9748                     BWN_PIO8_TXCTL_24_31);
9749                 data = &(data[len - 1]);
9750                 switch (len & 3) {
9751                 case 3:
9752                         ctl |= BWN_PIO8_TXCTL_16_23;
9753                         value |= (uint32_t)(*data) << 16;
9754                         data--;
9755                 case 2:
9756                         ctl |= BWN_PIO8_TXCTL_8_15;
9757                         value |= (uint32_t)(*data) << 8;
9758                         data--;
9759                 case 1:
9760                         value |= (uint32_t)(*data);
9761                 }
9762                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9763                 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9764         }
9765
9766         return (ctl);
9767 }
9768
9769 static void
9770 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9771     uint16_t offset, uint32_t value)
9772 {
9773
9774         BWN_WRITE_4(mac, tq->tq_base + offset, value);
9775 }
9776
9777 static uint16_t
9778 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9779     uint16_t ctl, const void *_data, int len)
9780 {
9781         struct bwn_softc *sc = mac->mac_sc;
9782         const uint8_t *data = _data;
9783
9784         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9785         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9786
9787         siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9788             tq->tq_base + BWN_PIO_TXDATA);
9789         if (len & 1) {
9790                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9791                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9792                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9793         }
9794
9795         return (ctl);
9796 }
9797
9798 static uint16_t
9799 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9800     uint16_t ctl, struct mbuf *m0)
9801 {
9802         int i, j = 0;
9803         uint16_t data = 0;
9804         const uint8_t *buf;
9805         struct mbuf *m = m0;
9806
9807         ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9808         BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9809
9810         for (; m != NULL; m = m->m_next) {
9811                 buf = mtod(m, const uint8_t *);
9812                 for (i = 0; i < m->m_len; i++) {
9813                         if (!((j++) % 2))
9814                                 data |= buf[i];
9815                         else {
9816                                 data |= (buf[i] << 8);
9817                                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9818                                 data = 0;
9819                         }
9820                 }
9821         }
9822         if (m0->m_pkthdr.len % 2) {
9823                 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9824                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9825                 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9826         }
9827
9828         return (ctl);
9829 }
9830
9831 static void
9832 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9833 {
9834
9835         if (mac->mac_phy.type != BWN_PHYTYPE_G)
9836                 return;
9837         BWN_WRITE_2(mac, 0x684, 510 + time);
9838         bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9839 }
9840
9841 static struct bwn_dma_ring *
9842 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9843 {
9844
9845         if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9846                 return (mac->mac_method.dma.wme[WME_AC_BE]);
9847
9848         switch (prio) {
9849         case 3:
9850                 return (mac->mac_method.dma.wme[WME_AC_VO]);
9851         case 2:
9852                 return (mac->mac_method.dma.wme[WME_AC_VI]);
9853         case 0:
9854                 return (mac->mac_method.dma.wme[WME_AC_BE]);
9855         case 1:
9856                 return (mac->mac_method.dma.wme[WME_AC_BK]);
9857         }
9858         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9859         return (NULL);
9860 }
9861
9862 static int
9863 bwn_dma_getslot(struct bwn_dma_ring *dr)
9864 {
9865         int slot;
9866
9867         BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
9868
9869         KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9870         KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
9871         KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
9872
9873         slot = bwn_dma_nextslot(dr, dr->dr_curslot);
9874         KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
9875         dr->dr_curslot = slot;
9876         dr->dr_usedslot++;
9877
9878         return (slot);
9879 }
9880
9881 static int
9882 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
9883 {
9884         const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
9885         unsigned int a, b, c, d;
9886         unsigned int avg;
9887         uint32_t tmp;
9888
9889         tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
9890         a = tmp & 0xff;
9891         b = (tmp >> 8) & 0xff;
9892         c = (tmp >> 16) & 0xff;
9893         d = (tmp >> 24) & 0xff;
9894         if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
9895             c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
9896                 return (ENOENT);
9897         bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
9898             BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
9899             (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
9900
9901         if (ofdm) {
9902                 a = (a + 32) & 0x3f;
9903                 b = (b + 32) & 0x3f;
9904                 c = (c + 32) & 0x3f;
9905                 d = (d + 32) & 0x3f;
9906         }
9907
9908         avg = (a + b + c + d + 2) / 4;
9909         if (ofdm) {
9910                 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
9911                     & BWN_HF_4DB_CCK_POWERBOOST)
9912                         avg = (avg >= 13) ? (avg - 13) : 0;
9913         }
9914         return (avg);
9915 }
9916
9917 static void
9918 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
9919 {
9920         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
9921         int rfatt = *rfattp;
9922         int bbatt = *bbattp;
9923
9924         while (1) {
9925                 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
9926                         break;
9927                 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
9928                         break;
9929                 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
9930                         break;
9931                 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
9932                         break;
9933                 if (bbatt > lo->bbatt.max) {
9934                         bbatt -= 4;
9935                         rfatt += 1;
9936                         continue;
9937                 }
9938                 if (bbatt < lo->bbatt.min) {
9939                         bbatt += 4;
9940                         rfatt -= 1;
9941                         continue;
9942                 }
9943                 if (rfatt > lo->rfatt.max) {
9944                         rfatt -= 1;
9945                         bbatt += 4;
9946                         continue;
9947                 }
9948                 if (rfatt < lo->rfatt.min) {
9949                         rfatt += 1;
9950                         bbatt -= 4;
9951                         continue;
9952                 }
9953                 break;
9954         }
9955
9956         *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
9957         *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
9958 }
9959
9960 static void
9961 bwn_phy_lock(struct bwn_mac *mac)
9962 {
9963         struct bwn_softc *sc = mac->mac_sc;
9964         struct ieee80211com *ic = &sc->sc_ic;
9965
9966         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
9967             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
9968
9969         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
9970                 bwn_psctl(mac, BWN_PS_AWAKE);
9971 }
9972
9973 static void
9974 bwn_phy_unlock(struct bwn_mac *mac)
9975 {
9976         struct bwn_softc *sc = mac->mac_sc;
9977         struct ieee80211com *ic = &sc->sc_ic;
9978
9979         KASSERT(siba_get_revid(sc->sc_dev) >= 3,
9980             ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
9981
9982         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
9983                 bwn_psctl(mac, 0);
9984 }
9985
9986 static void
9987 bwn_rf_lock(struct bwn_mac *mac)
9988 {
9989
9990         BWN_WRITE_4(mac, BWN_MACCTL,
9991             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
9992         BWN_READ_4(mac, BWN_MACCTL);
9993         DELAY(10);
9994 }
9995
9996 static void
9997 bwn_rf_unlock(struct bwn_mac *mac)
9998 {
9999
10000         BWN_READ_2(mac, BWN_PHYVER);
10001         BWN_WRITE_4(mac, BWN_MACCTL,
10002             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10003 }
10004
10005 static struct bwn_pio_txqueue *
10006 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10007     struct bwn_pio_txpkt **pack)
10008 {
10009         struct bwn_pio *pio = &mac->mac_method.pio;
10010         struct bwn_pio_txqueue *tq = NULL;
10011         unsigned int index;
10012
10013         switch (cookie & 0xf000) {
10014         case 0x1000:
10015                 tq = &pio->wme[WME_AC_BK];
10016                 break;
10017         case 0x2000:
10018                 tq = &pio->wme[WME_AC_BE];
10019                 break;
10020         case 0x3000:
10021                 tq = &pio->wme[WME_AC_VI];
10022                 break;
10023         case 0x4000:
10024                 tq = &pio->wme[WME_AC_VO];
10025                 break;
10026         case 0x5000:
10027                 tq = &pio->mcast;
10028                 break;
10029         }
10030         KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10031         if (tq == NULL)
10032                 return (NULL);
10033         index = (cookie & 0x0fff);
10034         KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10035         if (index >= N(tq->tq_pkts))
10036                 return (NULL);
10037         *pack = &tq->tq_pkts[index];
10038         KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10039         return (tq);
10040 }
10041
10042 static void
10043 bwn_txpwr(void *arg, int npending)
10044 {
10045         struct bwn_mac *mac = arg;
10046         struct bwn_softc *sc = mac->mac_sc;
10047
10048         BWN_LOCK(sc);
10049         if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10050             mac->mac_phy.set_txpwr != NULL)
10051                 mac->mac_phy.set_txpwr(mac);
10052         BWN_UNLOCK(sc);
10053 }
10054
10055 static void
10056 bwn_task_15s(struct bwn_mac *mac)
10057 {
10058         uint16_t reg;
10059
10060         if (mac->mac_fw.opensource) {
10061                 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10062                 if (reg) {
10063                         bwn_restart(mac, "fw watchdog");
10064                         return;
10065                 }
10066                 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10067         }
10068         if (mac->mac_phy.task_15s)
10069                 mac->mac_phy.task_15s(mac);
10070
10071         mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10072 }
10073
10074 static void
10075 bwn_task_30s(struct bwn_mac *mac)
10076 {
10077
10078         if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10079                 return;
10080         mac->mac_noise.noi_running = 1;
10081         mac->mac_noise.noi_nsamples = 0;
10082
10083         bwn_noise_gensample(mac);
10084 }
10085
10086 static void
10087 bwn_task_60s(struct bwn_mac *mac)
10088 {
10089
10090         if (mac->mac_phy.task_60s)
10091                 mac->mac_phy.task_60s(mac);
10092         bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10093 }
10094
10095 static void
10096 bwn_tasks(void *arg)
10097 {
10098         struct bwn_mac *mac = arg;
10099         struct bwn_softc *sc = mac->mac_sc;
10100
10101         BWN_ASSERT_LOCKED(sc);
10102         if (mac->mac_status != BWN_MAC_STATUS_STARTED)
10103                 return;
10104
10105         if (mac->mac_task_state % 4 == 0)
10106                 bwn_task_60s(mac);
10107         if (mac->mac_task_state % 2 == 0)
10108                 bwn_task_30s(mac);
10109         bwn_task_15s(mac);
10110
10111         mac->mac_task_state++;
10112         callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10113 }
10114
10115 static int
10116 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10117 {
10118         struct bwn_softc *sc = mac->mac_sc;
10119
10120         KASSERT(a == 0, ("not support APHY\n"));
10121
10122         switch (plcp->o.raw[0] & 0xf) {
10123         case 0xb:
10124                 return (BWN_OFDM_RATE_6MB);
10125         case 0xf:
10126                 return (BWN_OFDM_RATE_9MB);
10127         case 0xa:
10128                 return (BWN_OFDM_RATE_12MB);
10129         case 0xe:
10130                 return (BWN_OFDM_RATE_18MB);
10131         case 0x9:
10132                 return (BWN_OFDM_RATE_24MB);
10133         case 0xd:
10134                 return (BWN_OFDM_RATE_36MB);
10135         case 0x8:
10136                 return (BWN_OFDM_RATE_48MB);
10137         case 0xc:
10138                 return (BWN_OFDM_RATE_54MB);
10139         }
10140         device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10141             plcp->o.raw[0] & 0xf);
10142         return (-1);
10143 }
10144
10145 static int
10146 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10147 {
10148         struct bwn_softc *sc = mac->mac_sc;
10149
10150         switch (plcp->o.raw[0]) {
10151         case 0x0a:
10152                 return (BWN_CCK_RATE_1MB);
10153         case 0x14:
10154                 return (BWN_CCK_RATE_2MB);
10155         case 0x37:
10156                 return (BWN_CCK_RATE_5MB);
10157         case 0x6e:
10158                 return (BWN_CCK_RATE_11MB);
10159         }
10160         device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10161         return (-1);
10162 }
10163
10164 static void
10165 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10166     const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10167     int rssi, int noise)
10168 {
10169         struct bwn_softc *sc = mac->mac_sc;
10170         const struct ieee80211_frame_min *wh;
10171         uint64_t tsf;
10172         uint16_t low_mactime_now;
10173
10174         if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10175                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10176
10177         wh = mtod(m, const struct ieee80211_frame_min *);
10178         if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
10179                 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10180
10181         bwn_tsf_read(mac, &tsf);
10182         low_mactime_now = tsf;
10183         tsf = tsf & ~0xffffULL;
10184         tsf += le16toh(rxhdr->mac_time);
10185         if (low_mactime_now < le16toh(rxhdr->mac_time))
10186                 tsf -= 0x10000;
10187
10188         sc->sc_rx_th.wr_tsf = tsf;
10189         sc->sc_rx_th.wr_rate = rate;
10190         sc->sc_rx_th.wr_antsignal = rssi;
10191         sc->sc_rx_th.wr_antnoise = noise;
10192 }
10193
10194 static void
10195 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10196 {
10197         uint32_t low, high;
10198
10199         KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10200             ("%s:%d: fail", __func__, __LINE__));
10201
10202         low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10203         high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10204         *tsf = high;
10205         *tsf <<= 32;
10206         *tsf |= low;
10207 }
10208
10209 static int
10210 bwn_dma_attach(struct bwn_mac *mac)
10211 {
10212         struct bwn_dma *dma = &mac->mac_method.dma;
10213         struct bwn_softc *sc = mac->mac_sc;
10214         bus_addr_t lowaddr = 0;
10215         int error;
10216
10217         if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10218                 return (0);
10219
10220         KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10221
10222         mac->mac_flags |= BWN_MAC_FLAG_DMA;
10223
10224         dma->dmatype = bwn_dma_gettype(mac);
10225         if (dma->dmatype == BWN_DMA_30BIT)
10226                 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10227         else if (dma->dmatype == BWN_DMA_32BIT)
10228                 lowaddr = BUS_SPACE_MAXADDR_32BIT;
10229         else
10230                 lowaddr = BUS_SPACE_MAXADDR;
10231
10232         /*
10233          * Create top level DMA tag
10234          */
10235         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
10236                                BWN_ALIGN, 0,            /* alignment, bounds */
10237                                lowaddr,                 /* lowaddr */
10238                                BUS_SPACE_MAXADDR,       /* highaddr */
10239                                NULL, NULL,              /* filter, filterarg */
10240                                BUS_SPACE_MAXSIZE,       /* maxsize */
10241                                BUS_SPACE_UNRESTRICTED,  /* nsegments */
10242                                BUS_SPACE_MAXSIZE,       /* maxsegsize */
10243                                0,                       /* flags */
10244                                NULL, NULL,              /* lockfunc, lockarg */
10245                                &dma->parent_dtag);
10246         if (error) {
10247                 device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10248                 return (error);
10249         }
10250
10251         /*
10252          * Create TX/RX mbuf DMA tag
10253          */
10254         error = bus_dma_tag_create(dma->parent_dtag,
10255                                 1,
10256                                 0,
10257                                 BUS_SPACE_MAXADDR,
10258                                 BUS_SPACE_MAXADDR,
10259                                 NULL, NULL,
10260                                 MCLBYTES,
10261                                 1,
10262                                 BUS_SPACE_MAXSIZE_32BIT,
10263                                 0,
10264                                 NULL, NULL,
10265                                 &dma->rxbuf_dtag);
10266         if (error) {
10267                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10268                 goto fail0;
10269         }
10270         error = bus_dma_tag_create(dma->parent_dtag,
10271                                 1,
10272                                 0,
10273                                 BUS_SPACE_MAXADDR,
10274                                 BUS_SPACE_MAXADDR,
10275                                 NULL, NULL,
10276                                 MCLBYTES,
10277                                 1,
10278                                 BUS_SPACE_MAXSIZE_32BIT,
10279                                 0,
10280                                 NULL, NULL,
10281                                 &dma->txbuf_dtag);
10282         if (error) {
10283                 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10284                 goto fail1;
10285         }
10286
10287         dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10288         if (!dma->wme[WME_AC_BK])
10289                 goto fail2;
10290
10291         dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10292         if (!dma->wme[WME_AC_BE])
10293                 goto fail3;
10294
10295         dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10296         if (!dma->wme[WME_AC_VI])
10297                 goto fail4;
10298
10299         dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10300         if (!dma->wme[WME_AC_VO])
10301                 goto fail5;
10302
10303         dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10304         if (!dma->mcast)
10305                 goto fail6;
10306         dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10307         if (!dma->rx)
10308                 goto fail7;
10309
10310         return (error);
10311
10312 fail7:  bwn_dma_ringfree(&dma->mcast);
10313 fail6:  bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10314 fail5:  bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10315 fail4:  bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10316 fail3:  bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10317 fail2:  bus_dma_tag_destroy(dma->txbuf_dtag);
10318 fail1:  bus_dma_tag_destroy(dma->rxbuf_dtag);
10319 fail0:  bus_dma_tag_destroy(dma->parent_dtag);
10320         return (error);
10321 }
10322
10323 static struct bwn_dma_ring *
10324 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10325     uint16_t cookie, int *slot)
10326 {
10327         struct bwn_dma *dma = &mac->mac_method.dma;
10328         struct bwn_dma_ring *dr;
10329         struct bwn_softc *sc = mac->mac_sc;
10330
10331         BWN_ASSERT_LOCKED(mac->mac_sc);
10332
10333         switch (cookie & 0xf000) {
10334         case 0x1000:
10335                 dr = dma->wme[WME_AC_BK];
10336                 break;
10337         case 0x2000:
10338                 dr = dma->wme[WME_AC_BE];
10339                 break;
10340         case 0x3000:
10341                 dr = dma->wme[WME_AC_VI];
10342                 break;
10343         case 0x4000:
10344                 dr = dma->wme[WME_AC_VO];
10345                 break;
10346         case 0x5000:
10347                 dr = dma->mcast;
10348                 break;
10349         default:
10350                 dr = NULL;
10351                 KASSERT(0 == 1,
10352                     ("invalid cookie value %d", cookie & 0xf000));
10353         }
10354         *slot = (cookie & 0x0fff);
10355         if (*slot < 0 || *slot >= dr->dr_numslots) {
10356                 /*
10357                  * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10358                  * that it occurs events which have same H/W sequence numbers.
10359                  * When it's occurred just prints a WARNING msgs and ignores.
10360                  */
10361                 KASSERT(status->seq == dma->lastseq,
10362                     ("%s:%d: fail", __func__, __LINE__));
10363                 device_printf(sc->sc_dev,
10364                     "out of slot ranges (0 < %d < %d)\n", *slot,
10365                     dr->dr_numslots);
10366                 return (NULL);
10367         }
10368         dma->lastseq = status->seq;
10369         return (dr);
10370 }
10371
10372 static void
10373 bwn_dma_stop(struct bwn_mac *mac)
10374 {
10375         struct bwn_dma *dma;
10376
10377         if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10378                 return;
10379         dma = &mac->mac_method.dma;
10380
10381         bwn_dma_ringstop(&dma->rx);
10382         bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10383         bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10384         bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10385         bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10386         bwn_dma_ringstop(&dma->mcast);
10387 }
10388
10389 static void
10390 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10391 {
10392
10393         if (dr == NULL)
10394                 return;
10395
10396         bwn_dma_cleanup(*dr);
10397 }
10398
10399 static void
10400 bwn_pio_stop(struct bwn_mac *mac)
10401 {
10402         struct bwn_pio *pio;
10403
10404         if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10405                 return;
10406         pio = &mac->mac_method.pio;
10407
10408         bwn_destroy_queue_tx(&pio->mcast);
10409         bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10410         bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10411         bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10412         bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10413 }
10414
10415 static void
10416 bwn_led_attach(struct bwn_mac *mac)
10417 {
10418         struct bwn_softc *sc = mac->mac_sc;
10419         const uint8_t *led_act = NULL;
10420         uint16_t val[BWN_LED_MAX];
10421         int i;
10422
10423         sc->sc_led_idle = (2350 * hz) / 1000;
10424         sc->sc_led_blink = 1;
10425
10426         for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10427                 if (siba_get_pci_subvendor(sc->sc_dev) ==
10428                     bwn_vendor_led_act[i].vid) {
10429                         led_act = bwn_vendor_led_act[i].led_act;
10430                         break;
10431                 }
10432         }
10433         if (led_act == NULL)
10434                 led_act = bwn_default_led_act;
10435
10436         val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10437         val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10438         val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10439         val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10440
10441         for (i = 0; i < BWN_LED_MAX; ++i) {
10442                 struct bwn_led *led = &sc->sc_leds[i];
10443
10444                 if (val[i] == 0xff) {
10445                         led->led_act = led_act[i];
10446                 } else {
10447                         if (val[i] & BWN_LED_ACT_LOW)
10448                                 led->led_flags |= BWN_LED_F_ACTLOW;
10449                         led->led_act = val[i] & BWN_LED_ACT_MASK;
10450                 }
10451                 led->led_mask = (1 << i);
10452
10453                 if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10454                     led->led_act == BWN_LED_ACT_BLINK_POLL ||
10455                     led->led_act == BWN_LED_ACT_BLINK) {
10456                         led->led_flags |= BWN_LED_F_BLINK;
10457                         if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10458                                 led->led_flags |= BWN_LED_F_POLLABLE;
10459                         else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10460                                 led->led_flags |= BWN_LED_F_SLOW;
10461
10462                         if (sc->sc_blink_led == NULL) {
10463                                 sc->sc_blink_led = led;
10464                                 if (led->led_flags & BWN_LED_F_SLOW)
10465                                         BWN_LED_SLOWDOWN(sc->sc_led_idle);
10466                         }
10467                 }
10468
10469                 DPRINTF(sc, BWN_DEBUG_LED,
10470                     "%dth led, act %d, lowact %d\n", i,
10471                     led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10472         }
10473         callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
10474 }
10475
10476 static __inline uint16_t
10477 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10478 {
10479
10480         if (led->led_flags & BWN_LED_F_ACTLOW)
10481                 on = !on;
10482         if (on)
10483                 val |= led->led_mask;
10484         else
10485                 val &= ~led->led_mask;
10486         return val;
10487 }
10488
10489 static void
10490 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10491 {
10492         struct bwn_softc *sc = mac->mac_sc;
10493         struct ieee80211com *ic = &sc->sc_ic;
10494         uint16_t val;
10495         int i;
10496
10497         if (nstate == IEEE80211_S_INIT) {
10498                 callout_stop(&sc->sc_led_blink_ch);
10499                 sc->sc_led_blinking = 0;
10500         }
10501
10502         if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0)
10503                 return;
10504
10505         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10506         for (i = 0; i < BWN_LED_MAX; ++i) {
10507                 struct bwn_led *led = &sc->sc_leds[i];
10508                 int on;
10509
10510                 if (led->led_act == BWN_LED_ACT_UNKN ||
10511                     led->led_act == BWN_LED_ACT_NULL)
10512                         continue;
10513
10514                 if ((led->led_flags & BWN_LED_F_BLINK) &&
10515                     nstate != IEEE80211_S_INIT)
10516                         continue;
10517
10518                 switch (led->led_act) {
10519                 case BWN_LED_ACT_ON:    /* Always on */
10520                         on = 1;
10521                         break;
10522                 case BWN_LED_ACT_OFF:   /* Always off */
10523                 case BWN_LED_ACT_5GHZ:  /* TODO: 11A */
10524                         on = 0;
10525                         break;
10526                 default:
10527                         on = 1;
10528                         switch (nstate) {
10529                         case IEEE80211_S_INIT:
10530                                 on = 0;
10531                                 break;
10532                         case IEEE80211_S_RUN:
10533                                 if (led->led_act == BWN_LED_ACT_11G &&
10534                                     ic->ic_curmode != IEEE80211_MODE_11G)
10535                                         on = 0;
10536                                 break;
10537                         default:
10538                                 if (led->led_act == BWN_LED_ACT_ASSOC)
10539                                         on = 0;
10540                                 break;
10541                         }
10542                         break;
10543                 }
10544
10545                 val = bwn_led_onoff(led, val, on);
10546         }
10547         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10548 }
10549
10550 static void
10551 bwn_led_event(struct bwn_mac *mac, int event)
10552 {
10553         struct bwn_softc *sc = mac->mac_sc;
10554         struct bwn_led *led = sc->sc_blink_led;
10555         int rate;
10556
10557         if (event == BWN_LED_EVENT_POLL) {
10558                 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10559                         return;
10560                 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10561                         return;
10562         }
10563
10564         sc->sc_led_ticks = ticks;
10565         if (sc->sc_led_blinking)
10566                 return;
10567
10568         switch (event) {
10569         case BWN_LED_EVENT_RX:
10570                 rate = sc->sc_rx_rate;
10571                 break;
10572         case BWN_LED_EVENT_TX:
10573                 rate = sc->sc_tx_rate;
10574                 break;
10575         case BWN_LED_EVENT_POLL:
10576                 rate = 0;
10577                 break;
10578         default:
10579                 panic("unknown LED event %d\n", event);
10580                 break;
10581         }
10582         bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10583             bwn_led_duration[rate].off_dur);
10584 }
10585
10586 static void
10587 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10588 {
10589         struct bwn_softc *sc = mac->mac_sc;
10590         struct bwn_led *led = sc->sc_blink_led;
10591         uint16_t val;
10592
10593         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10594         val = bwn_led_onoff(led, val, 1);
10595         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10596
10597         if (led->led_flags & BWN_LED_F_SLOW) {
10598                 BWN_LED_SLOWDOWN(on_dur);
10599                 BWN_LED_SLOWDOWN(off_dur);
10600         }
10601
10602         sc->sc_led_blinking = 1;
10603         sc->sc_led_blink_offdur = off_dur;
10604
10605         callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10606 }
10607
10608 static void
10609 bwn_led_blink_next(void *arg)
10610 {
10611         struct bwn_mac *mac = arg;
10612         struct bwn_softc *sc = mac->mac_sc;
10613         uint16_t val;
10614
10615         val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10616         val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10617         BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10618
10619         callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10620             bwn_led_blink_end, mac);
10621 }
10622
10623 static void
10624 bwn_led_blink_end(void *arg)
10625 {
10626         struct bwn_mac *mac = arg;
10627         struct bwn_softc *sc = mac->mac_sc;
10628
10629         sc->sc_led_blinking = 0;
10630 }
10631
10632 static int
10633 bwn_suspend(device_t dev)
10634 {
10635         struct bwn_softc *sc = device_get_softc(dev);
10636
10637         BWN_LOCK(sc);
10638         bwn_stop(sc);
10639         BWN_UNLOCK(sc);
10640         return (0);
10641 }
10642
10643 static int
10644 bwn_resume(device_t dev)
10645 {
10646         struct bwn_softc *sc = device_get_softc(dev);
10647         int error = EDOOFUS;
10648
10649         BWN_LOCK(sc);
10650         if (sc->sc_ic.ic_nrunning > 0)
10651                 error = bwn_init(sc);
10652         BWN_UNLOCK(sc);
10653         if (error == 0)
10654                 ieee80211_start_all(&sc->sc_ic);
10655         return (0);
10656 }
10657
10658 static void
10659 bwn_rfswitch(void *arg)
10660 {
10661         struct bwn_softc *sc = arg;
10662         struct bwn_mac *mac = sc->sc_curmac;
10663         int cur = 0, prev = 0;
10664
10665         KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10666             ("%s: invalid MAC status %d", __func__, mac->mac_status));
10667
10668         if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10669                 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10670                         & BWN_RF_HWENABLED_HI_MASK))
10671                         cur = 1;
10672         } else {
10673                 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10674                     & BWN_RF_HWENABLED_LO_MASK)
10675                         cur = 1;
10676         }
10677
10678         if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10679                 prev = 1;
10680
10681         if (cur != prev) {
10682                 if (cur)
10683                         mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10684                 else
10685                         mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10686
10687                 device_printf(sc->sc_dev,
10688                     "status of RF switch is changed to %s\n",
10689                     cur ? "ON" : "OFF");
10690                 if (cur != mac->mac_phy.rf_on) {
10691                         if (cur)
10692                                 bwn_rf_turnon(mac);
10693                         else
10694                                 bwn_rf_turnoff(mac);
10695                 }
10696         }
10697
10698         callout_schedule(&sc->sc_rfswitch_ch, hz);
10699 }
10700
10701 static void
10702 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10703 {
10704         struct bwn_phy *phy = &mac->mac_phy;
10705         struct bwn_phy_lp *plp = &phy->phy_lp;
10706
10707         plp->plp_antenna = BWN_ANT_DEFAULT;
10708 }
10709
10710 static int
10711 bwn_phy_lp_init(struct bwn_mac *mac)
10712 {
10713         static const struct bwn_stxtable tables[] = {
10714                 { 2,  6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10715                 { 1,  8, 0x50, 0, 0x7f }, { 0,  8, 0x44, 0, 0xff },
10716                 { 1,  0, 0x4a, 0, 0xff }, { 0,  4, 0x4d, 0, 0xff },
10717                 { 1,  4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10718                 { 1,  0, 0x4f, 4, 0x0f }, { 3,  0, 0x49, 0, 0x0f },
10719                 { 4,  3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10720                 { 4,  0, 0x46, 1, 0x07 }, { 3,  8, 0x48, 4, 0x07 },
10721                 { 3, 11, 0x48, 0, 0x0f }, { 3,  4, 0x49, 4, 0x0f },
10722                 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10723                 { 6,  0, 0x52, 7, 0x01 }, { 5,  3, 0x41, 5, 0x07 },
10724                 { 5,  6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10725                 { 4, 15, 0x42, 0, 0x01 }, { 5,  0, 0x42, 1, 0x07 },
10726                 { 4, 11, 0x43, 4, 0x0f }, { 4,  7, 0x43, 0, 0x0f },
10727                 { 4,  6, 0x45, 1, 0x01 }, { 2,  7, 0x40, 4, 0x0f },
10728                 { 2, 11, 0x40, 0, 0x0f }
10729         };
10730         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10731         struct bwn_softc *sc = mac->mac_sc;
10732         const struct bwn_stxtable *st;
10733         struct ieee80211com *ic = &sc->sc_ic;
10734         int i, error;
10735         uint16_t tmp;
10736
10737         bwn_phy_lp_readsprom(mac);      /* XXX bad place */
10738         bwn_phy_lp_bbinit(mac);
10739
10740         /* initialize RF */
10741         BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10742         DELAY(1);
10743         BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10744         DELAY(1);
10745
10746         if (mac->mac_phy.rf_ver == 0x2062)
10747                 bwn_phy_lp_b2062_init(mac);
10748         else {
10749                 bwn_phy_lp_b2063_init(mac);
10750
10751                 /* synchronize stx table. */
10752                 for (i = 0; i < N(tables); i++) {
10753                         st = &tables[i];
10754                         tmp = BWN_RF_READ(mac, st->st_rfaddr);
10755                         tmp >>= st->st_rfshift;
10756                         tmp <<= st->st_physhift;
10757                         BWN_PHY_SETMASK(mac,
10758                             BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10759                             ~(st->st_mask << st->st_physhift), tmp);
10760                 }
10761
10762                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10763                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10764         }
10765
10766         /* calibrate RC */
10767         if (mac->mac_phy.rev >= 2)
10768                 bwn_phy_lp_rxcal_r2(mac);
10769         else if (!plp->plp_rccap) {
10770                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10771                         bwn_phy_lp_rccal_r12(mac);
10772         } else
10773                 bwn_phy_lp_set_rccap(mac);
10774
10775         error = bwn_phy_lp_switch_channel(mac, 7);
10776         if (error)
10777                 device_printf(sc->sc_dev,
10778                     "failed to change channel 7 (%d)\n", error);
10779         bwn_phy_lp_txpctl_init(mac);
10780         bwn_phy_lp_calib(mac);
10781         return (0);
10782 }
10783
10784 static uint16_t
10785 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10786 {
10787
10788         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10789         return (BWN_READ_2(mac, BWN_PHYDATA));
10790 }
10791
10792 static void
10793 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10794 {
10795
10796         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10797         BWN_WRITE_2(mac, BWN_PHYDATA, value);
10798 }
10799
10800 static void
10801 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10802     uint16_t set)
10803 {
10804
10805         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10806         BWN_WRITE_2(mac, BWN_PHYDATA,
10807             (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10808 }
10809
10810 static uint16_t
10811 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10812 {
10813
10814         KASSERT(reg != 1, ("unaccessible register %d", reg));
10815         if (mac->mac_phy.rev < 2 && reg != 0x4001)
10816                 reg |= 0x100;
10817         if (mac->mac_phy.rev >= 2)
10818                 reg |= 0x200;
10819         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10820         return BWN_READ_2(mac, BWN_RFDATALO);
10821 }
10822
10823 static void
10824 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10825 {
10826
10827         KASSERT(reg != 1, ("unaccessible register %d", reg));
10828         BWN_WRITE_2(mac, BWN_RFCTL, reg);
10829         BWN_WRITE_2(mac, BWN_RFDATALO, value);
10830 }
10831
10832 static void
10833 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10834 {
10835
10836         if (on) {
10837                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10838                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10839                     (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10840                 return;
10841         }
10842
10843         if (mac->mac_phy.rev >= 2) {
10844                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10845                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10846                 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10847                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10848                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
10849                 return;
10850         }
10851
10852         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
10853         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10854         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
10855         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
10856 }
10857
10858 static int
10859 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
10860 {
10861         struct bwn_phy *phy = &mac->mac_phy;
10862         struct bwn_phy_lp *plp = &phy->phy_lp;
10863         int error;
10864
10865         if (phy->rf_ver == 0x2063) {
10866                 error = bwn_phy_lp_b2063_switch_channel(mac, chan);
10867                 if (error)
10868                         return (error);
10869         } else {
10870                 error = bwn_phy_lp_b2062_switch_channel(mac, chan);
10871                 if (error)
10872                         return (error);
10873                 bwn_phy_lp_set_anafilter(mac, chan);
10874                 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
10875         }
10876
10877         plp->plp_chan = chan;
10878         BWN_WRITE_2(mac, BWN_CHANNEL, chan);
10879         return (0);
10880 }
10881
10882 static uint32_t
10883 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
10884 {
10885         struct bwn_softc *sc = mac->mac_sc;
10886         struct ieee80211com *ic = &sc->sc_ic;
10887
10888         return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
10889 }
10890
10891 static void
10892 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
10893 {
10894         struct bwn_phy *phy = &mac->mac_phy;
10895         struct bwn_phy_lp *plp = &phy->phy_lp;
10896
10897         if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
10898                 return;
10899
10900         bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
10901         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
10902         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
10903         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
10904         plp->plp_antenna = antenna;
10905 }
10906
10907 static void
10908 bwn_phy_lp_task_60s(struct bwn_mac *mac)
10909 {
10910
10911         bwn_phy_lp_calib(mac);
10912 }
10913
10914 static void
10915 bwn_phy_lp_readsprom(struct bwn_mac *mac)
10916 {
10917         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10918         struct bwn_softc *sc = mac->mac_sc;
10919         struct ieee80211com *ic = &sc->sc_ic;
10920
10921         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
10922                 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
10923                 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
10924                 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
10925                 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
10926                 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
10927                 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
10928                 return;
10929         }
10930
10931         plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
10932         plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
10933         plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
10934         plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
10935         plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
10936         plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
10937         plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
10938         plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
10939 }
10940
10941 static void
10942 bwn_phy_lp_bbinit(struct bwn_mac *mac)
10943 {
10944
10945         bwn_phy_lp_tblinit(mac);
10946         if (mac->mac_phy.rev >= 2)
10947                 bwn_phy_lp_bbinit_r2(mac);
10948         else
10949                 bwn_phy_lp_bbinit_r01(mac);
10950 }
10951
10952 static void
10953 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
10954 {
10955         struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
10956         struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
10957         struct bwn_softc *sc = mac->mac_sc;
10958         struct ieee80211com *ic = &sc->sc_ic;
10959
10960         bwn_phy_lp_set_txgain(mac,
10961             IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
10962         bwn_phy_lp_set_bbmult(mac, 150);
10963 }
10964
10965 static void
10966 bwn_phy_lp_calib(struct bwn_mac *mac)
10967 {
10968         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10969         struct bwn_softc *sc = mac->mac_sc;
10970         struct ieee80211com *ic = &sc->sc_ic;
10971         const struct bwn_rxcompco *rc = NULL;
10972         struct bwn_txgain ogain;
10973         int i, omode, oafeovr, orf, obbmult;
10974         uint8_t mode, fc = 0;
10975
10976         if (plp->plp_chanfullcal != plp->plp_chan) {
10977                 plp->plp_chanfullcal = plp->plp_chan;
10978                 fc = 1;
10979         }
10980
10981         bwn_mac_suspend(mac);
10982
10983         /* BlueTooth Coexistance Override */
10984         BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
10985         BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
10986
10987         if (mac->mac_phy.rev >= 2)
10988                 bwn_phy_lp_digflt_save(mac);
10989         bwn_phy_lp_get_txpctlmode(mac);
10990         mode = plp->plp_txpctlmode;
10991         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
10992         if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
10993                 bwn_phy_lp_bugfix(mac);
10994         if (mac->mac_phy.rev >= 2 && fc == 1) {
10995                 bwn_phy_lp_get_txpctlmode(mac);
10996                 omode = plp->plp_txpctlmode;
10997                 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
10998                 if (oafeovr)
10999                         ogain = bwn_phy_lp_get_txgain(mac);
11000                 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11001                 obbmult = bwn_phy_lp_get_bbmult(mac);
11002                 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11003                 if (oafeovr)
11004                         bwn_phy_lp_set_txgain(mac, &ogain);
11005                 bwn_phy_lp_set_bbmult(mac, obbmult);
11006                 bwn_phy_lp_set_txpctlmode(mac, omode);
11007                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11008         }
11009         bwn_phy_lp_set_txpctlmode(mac, mode);
11010         if (mac->mac_phy.rev >= 2)
11011                 bwn_phy_lp_digflt_restore(mac);
11012
11013         /* do RX IQ Calculation; assumes that noise is true. */
11014         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11015                 for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11016                         if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11017                                 rc = &bwn_rxcompco_5354[i];
11018                 }
11019         } else if (mac->mac_phy.rev >= 2)
11020                 rc = &bwn_rxcompco_r2;
11021         else {
11022                 for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11023                         if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11024                                 rc = &bwn_rxcompco_r12[i];
11025                 }
11026         }
11027         if (rc == NULL)
11028                 goto fail;
11029
11030         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11031         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11032
11033         bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11034
11035         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11036                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11037                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11038         } else {
11039                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11040                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11041         }
11042
11043         bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11044         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11045         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11046         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11047         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11048         bwn_phy_lp_set_deaf(mac, 0);
11049         /* XXX no checking return value? */
11050         (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11051         bwn_phy_lp_clear_deaf(mac, 0);
11052         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11053         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11054         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11055
11056         /* disable RX GAIN override. */
11057         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11058         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11059         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11060         if (mac->mac_phy.rev >= 2) {
11061                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11062                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11063                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11064                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11065                 }
11066         } else {
11067                 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11068         }
11069
11070         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11071         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11072 fail:
11073         bwn_mac_enable(mac);
11074 }
11075
11076 static void
11077 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11078 {
11079
11080         if (on) {
11081                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11082                 return;
11083         }
11084
11085         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11086         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11087 }
11088
11089 static int
11090 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11091 {
11092         static const struct bwn_b206x_chan *bc = NULL;
11093         struct bwn_softc *sc = mac->mac_sc;
11094         uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11095             tmp[6];
11096         uint16_t old, scale, tmp16;
11097         int i, div;
11098
11099         for (i = 0; i < N(bwn_b2063_chantable); i++) {
11100                 if (bwn_b2063_chantable[i].bc_chan == chan) {
11101                         bc = &bwn_b2063_chantable[i];
11102                         break;
11103                 }
11104         }
11105         if (bc == NULL)
11106                 return (EINVAL);
11107
11108         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11109         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11110         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11111         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11112         BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11113         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11114         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11115         BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11116         BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11117         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11118         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11119         BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11120
11121         old = BWN_RF_READ(mac, BWN_B2063_COM15);
11122         BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11123
11124         freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11125         freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11126         freqref = freqxtal * 3;
11127         div = (freqxtal <= 26000000 ? 1 : 2);
11128         timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11129         timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11130                 999999) / 1000000) + 1;
11131
11132         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11133         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11134             0xfff8, timeout >> 2);
11135         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11136             0xff9f,timeout << 5);
11137         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11138
11139         val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11140         val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11141         val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11142
11143         count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11144             (timeoutref + 1)) - 1;
11145         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11146             0xf0, count >> 8);
11147         BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11148
11149         tmp[0] = ((val[2] * 62500) / freqref) << 4;
11150         tmp[1] = ((val[2] * 62500) % freqref) << 4;
11151         while (tmp[1] >= freqref) {
11152                 tmp[0]++;
11153                 tmp[1] -= freqref;
11154         }
11155         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11156         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11157         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11158         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11159         BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11160
11161         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11162         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11163         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11164         BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11165
11166         tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11167         tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11168
11169         if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11170                 scale = 1;
11171                 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11172         } else {
11173                 scale = 0;
11174                 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11175         }
11176         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11177         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11178
11179         tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11180             (scale + 1);
11181         if (tmp[5] > 150)
11182                 tmp[5] = 0;
11183
11184         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11185         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11186
11187         BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11188         if (freqxtal > 26000000)
11189                 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11190         else
11191                 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11192
11193         if (val[0] == 45)
11194                 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11195         else
11196                 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11197
11198         BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11199         DELAY(1);
11200         BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11201
11202         /* VCO Calibration */
11203         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11204         tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11205         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11206         DELAY(1);
11207         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11208         DELAY(1);
11209         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11210         DELAY(1);
11211         BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11212         DELAY(300);
11213         BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11214
11215         BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11216         return (0);
11217 }
11218
11219 static int
11220 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11221 {
11222         struct bwn_softc *sc = mac->mac_sc;
11223         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11224         const struct bwn_b206x_chan *bc = NULL;
11225         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11226         uint32_t tmp[9];
11227         int i;
11228
11229         for (i = 0; i < N(bwn_b2062_chantable); i++) {
11230                 if (bwn_b2062_chantable[i].bc_chan == chan) {
11231                         bc = &bwn_b2062_chantable[i];
11232                         break;
11233                 }
11234         }
11235
11236         if (bc == NULL)
11237                 return (EINVAL);
11238
11239         BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11240         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11241         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11242         BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11243         BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11244         BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11245         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11246         BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11247         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11248         BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11249
11250         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11251         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11252         bwn_phy_lp_b2062_reset_pllbias(mac);
11253         tmp[0] = freqxtal / 1000;
11254         tmp[1] = plp->plp_div * 1000;
11255         tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11256         if (ieee80211_ieee2mhz(chan, 0) < 4000)
11257                 tmp[2] *= 2;
11258         tmp[3] = 48 * tmp[0];
11259         tmp[5] = tmp[2] / tmp[3];
11260         tmp[6] = tmp[2] % tmp[3];
11261         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11262         tmp[4] = tmp[6] * 0x100;
11263         tmp[5] = tmp[4] / tmp[3];
11264         tmp[6] = tmp[4] % tmp[3];
11265         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11266         tmp[4] = tmp[6] * 0x100;
11267         tmp[5] = tmp[4] / tmp[3];
11268         tmp[6] = tmp[4] % tmp[3];
11269         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11270         tmp[4] = tmp[6] * 0x100;
11271         tmp[5] = tmp[4] / tmp[3];
11272         tmp[6] = tmp[4] % tmp[3];
11273         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11274             tmp[5] + ((2 * tmp[6]) / tmp[3]));
11275         tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11276         tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11277         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11278         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11279
11280         bwn_phy_lp_b2062_vco_calib(mac);
11281         if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11282                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11283                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11284                 bwn_phy_lp_b2062_reset_pllbias(mac);
11285                 bwn_phy_lp_b2062_vco_calib(mac);
11286                 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11287                         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11288                         return (EIO);
11289                 }
11290         }
11291         BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11292         return (0);
11293 }
11294
11295 static void
11296 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11297 {
11298         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11299         uint16_t tmp = (channel == 14);
11300
11301         if (mac->mac_phy.rev < 2) {
11302                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11303                 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11304                         bwn_phy_lp_set_rccap(mac);
11305                 return;
11306         }
11307
11308         BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11309 }
11310
11311 static void
11312 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11313 {
11314         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11315         struct bwn_softc *sc = mac->mac_sc;
11316         struct ieee80211com *ic = &sc->sc_ic;
11317         uint16_t iso, tmp[3];
11318
11319         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11320
11321         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11322                 iso = plp->plp_txisoband_m;
11323         else if (freq <= 5320)
11324                 iso = plp->plp_txisoband_l;
11325         else if (freq <= 5700)
11326                 iso = plp->plp_txisoband_m;
11327         else
11328                 iso = plp->plp_txisoband_h;
11329
11330         tmp[0] = ((iso - 26) / 12) << 12;
11331         tmp[1] = tmp[0] + 0x1000;
11332         tmp[2] = tmp[0] + 0x2000;
11333
11334         bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11335         bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11336 }
11337
11338 static void
11339 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11340 {
11341         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11342         int i;
11343         static const uint16_t addr[] = {
11344                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11345                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11346                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11347                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11348                 BWN_PHY_OFDM(0xcf),
11349         };
11350         static const uint16_t val[] = {
11351                 0xde5e, 0xe832, 0xe331, 0x4d26,
11352                 0x0026, 0x1420, 0x0020, 0xfe08,
11353                 0x0008,
11354         };
11355
11356         for (i = 0; i < N(addr); i++) {
11357                 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11358                 BWN_PHY_WRITE(mac, addr[i], val[i]);
11359         }
11360 }
11361
11362 static void
11363 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11364 {
11365         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11366         struct bwn_softc *sc = mac->mac_sc;
11367         uint16_t ctl;
11368
11369         ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11370         switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11371         case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11372                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11373                 break;
11374         case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11375                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11376                 break;
11377         case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11378                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11379                 break;
11380         default:
11381                 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11382                 device_printf(sc->sc_dev, "unknown command mode\n");
11383                 break;
11384         }
11385 }
11386
11387 static void
11388 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11389 {
11390         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11391         uint16_t ctl;
11392         uint8_t old;
11393
11394         bwn_phy_lp_get_txpctlmode(mac);
11395         old = plp->plp_txpctlmode;
11396         if (old == mode)
11397                 return;
11398         plp->plp_txpctlmode = mode;
11399
11400         if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11401                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11402                     plp->plp_tssiidx);
11403                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11404                     0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11405
11406                 /* disable TX GAIN override */
11407                 if (mac->mac_phy.rev < 2)
11408                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11409                 else {
11410                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11411                         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11412                 }
11413                 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11414
11415                 plp->plp_txpwridx = -1;
11416         }
11417         if (mac->mac_phy.rev >= 2) {
11418                 if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11419                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11420                 else
11421                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11422         }
11423
11424         /* writes TX Power Control mode */
11425         switch (plp->plp_txpctlmode) {
11426         case BWN_PHYLP_TXPCTL_OFF:
11427                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11428                 break;
11429         case BWN_PHYLP_TXPCTL_ON_HW:
11430                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11431                 break;
11432         case BWN_PHYLP_TXPCTL_ON_SW:
11433                 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11434                 break;
11435         default:
11436                 ctl = 0;
11437                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11438         }
11439         BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11440             (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11441 }
11442
11443 static void
11444 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11445 {
11446         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11447         struct bwn_softc *sc = mac->mac_sc;
11448         const unsigned int size = 256;
11449         struct bwn_txgain tg;
11450         uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11451         uint16_t tssinpt, tssiidx, value[2];
11452         uint8_t mode;
11453         int8_t txpwridx;
11454
11455         tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
11456             M_NOWAIT | M_ZERO);
11457         if (tabs == NULL) {
11458                 device_printf(sc->sc_dev, "failed to allocate buffer.\n");
11459                 return;
11460         }
11461
11462         bwn_phy_lp_get_txpctlmode(mac);
11463         mode = plp->plp_txpctlmode;
11464         txpwridx = plp->plp_txpwridx;
11465         tssinpt = plp->plp_tssinpt;
11466         tssiidx = plp->plp_tssiidx;
11467
11468         bwn_tab_read_multi(mac,
11469             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11470             BWN_TAB_4(7, 0x140), size, tabs);
11471
11472         bwn_phy_lp_tblinit(mac);
11473         bwn_phy_lp_bbinit(mac);
11474         bwn_phy_lp_txpctl_init(mac);
11475         bwn_phy_lp_rf_onoff(mac, 1);
11476         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11477
11478         bwn_tab_write_multi(mac,
11479             (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11480             BWN_TAB_4(7, 0x140), size, tabs);
11481
11482         BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11483         plp->plp_tssinpt = tssinpt;
11484         plp->plp_tssiidx = tssiidx;
11485         bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11486         if (txpwridx != -1) {
11487                 /* set TX power by index */
11488                 plp->plp_txpwridx = txpwridx;
11489                 bwn_phy_lp_get_txpctlmode(mac);
11490                 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11491                         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11492                 if (mac->mac_phy.rev >= 2) {
11493                         rxcomp = bwn_tab_read(mac,
11494                             BWN_TAB_4(7, txpwridx + 320));
11495                         txgain = bwn_tab_read(mac,
11496                             BWN_TAB_4(7, txpwridx + 192));
11497                         tg.tg_pad = (txgain >> 16) & 0xff;
11498                         tg.tg_gm = txgain & 0xff;
11499                         tg.tg_pga = (txgain >> 8) & 0xff;
11500                         tg.tg_dac = (rxcomp >> 28) & 0xff;
11501                         bwn_phy_lp_set_txgain(mac, &tg);
11502                 } else {
11503                         rxcomp = bwn_tab_read(mac,
11504                             BWN_TAB_4(10, txpwridx + 320));
11505                         txgain = bwn_tab_read(mac,
11506                             BWN_TAB_4(10, txpwridx + 192));
11507                         BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11508                             0xf800, (txgain >> 4) & 0x7fff);
11509                         bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11510                         bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11511                 }
11512                 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11513
11514                 /* set TX IQCC */
11515                 value[0] = (rxcomp >> 10) & 0x3ff;
11516                 value[1] = rxcomp & 0x3ff;
11517                 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11518
11519                 coeff = bwn_tab_read(mac,
11520                     (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11521                     BWN_TAB_4(10, txpwridx + 448));
11522                 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11523                 if (mac->mac_phy.rev >= 2) {
11524                         rfpwr = bwn_tab_read(mac,
11525                             BWN_TAB_4(7, txpwridx + 576));
11526                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11527                             rfpwr & 0xffff);
11528                 }
11529                 bwn_phy_lp_set_txgain_override(mac);
11530         }
11531         if (plp->plp_rccap)
11532                 bwn_phy_lp_set_rccap(mac);
11533         bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11534         bwn_phy_lp_set_txpctlmode(mac, mode);
11535         free(tabs, M_DEVBUF);
11536 }
11537
11538 static void
11539 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11540 {
11541         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11542         int i;
11543         static const uint16_t addr[] = {
11544                 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11545                 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11546                 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11547                 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11548                 BWN_PHY_OFDM(0xcf),
11549         };
11550
11551         for (i = 0; i < N(addr); i++)
11552                 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11553 }
11554
11555 static void
11556 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11557 {
11558         uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11559
11560         if (mac->mac_phy.rev < 2) {
11561                 bwn_phy_lp_tblinit_r01(mac);
11562                 bwn_phy_lp_tblinit_txgain(mac);
11563                 bwn_phy_lp_set_gaintbl(mac, freq);
11564                 return;
11565         }
11566
11567         bwn_phy_lp_tblinit_r2(mac);
11568         bwn_phy_lp_tblinit_txgain(mac);
11569 }
11570
11571 struct bwn_wpair {
11572         uint16_t                reg;
11573         uint16_t                value;
11574 };
11575
11576 struct bwn_smpair {
11577         uint16_t                offset;
11578         uint16_t                mask;
11579         uint16_t                set;
11580 };
11581
11582 static void
11583 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11584 {
11585         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11586         struct bwn_softc *sc = mac->mac_sc;
11587         struct ieee80211com *ic = &sc->sc_ic;
11588         static const struct bwn_wpair v1[] = {
11589                 { BWN_PHY_AFE_DAC_CTL, 0x50 },
11590                 { BWN_PHY_AFE_CTL, 0x8800 },
11591                 { BWN_PHY_AFE_CTL_OVR, 0 },
11592                 { BWN_PHY_AFE_CTL_OVRVAL, 0 },
11593                 { BWN_PHY_RF_OVERRIDE_0, 0 },
11594                 { BWN_PHY_RF_OVERRIDE_2, 0 },
11595                 { BWN_PHY_OFDM(0xf9), 0 },
11596                 { BWN_PHY_TR_LOOKUP_1, 0 }
11597         };
11598         static const struct bwn_smpair v2[] = {
11599                 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11600                 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11601                 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11602                 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11603                 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11604         };
11605         static const struct bwn_smpair v3[] = {
11606                 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11607                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11608                 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11609                 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11610                 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11611                 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11612                 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11613                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11614                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11615                 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11616
11617         };
11618         int i;
11619
11620         for (i = 0; i < N(v1); i++)
11621                 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11622         BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11623         for (i = 0; i < N(v2); i++)
11624                 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11625
11626         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11627         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11628         BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11629         if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11630                 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11631                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11632         } else {
11633                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11634         }
11635         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11636         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11637         BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11638         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11639         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11640         BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11641         BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11642         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11643         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11644         BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11645         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11646         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11647             (siba_get_chiprev(sc->sc_dev) == 0)) {
11648                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11649                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11650         } else {
11651                 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11652                 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11653         }
11654         for (i = 0; i < N(v3); i++)
11655                 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11656         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11657             (siba_get_chiprev(sc->sc_dev) == 0)) {
11658                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11659                 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11660         }
11661
11662         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11663                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11664                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11665                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11666                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11667                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11668                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11669         } else
11670                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11671
11672         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11673         BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11674         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11675         BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11676         BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11677         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11678         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11679             0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11680             ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11681
11682         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11683             (siba_get_chiprev(sc->sc_dev) == 0)) {
11684                 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11685                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11686                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11687         }
11688
11689         bwn_phy_lp_digflt_save(mac);
11690 }
11691
11692 static void
11693 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11694 {
11695         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11696         struct bwn_softc *sc = mac->mac_sc;
11697         struct ieee80211com *ic = &sc->sc_ic;
11698         static const struct bwn_smpair v1[] = {
11699                 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11700                 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11701                 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11702                 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11703                 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11704                 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11705                 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11706         };
11707         static const struct bwn_smpair v2[] = {
11708                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11709                 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11710                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11711                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11712                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11713                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11714                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11715                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11716                 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11717                 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11718                 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11719                 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11720                 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11721                 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11722                 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11723                 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11724         };
11725         static const struct bwn_smpair v3[] = {
11726                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11727                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11728                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11729                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11730                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11731                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11732                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11733                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11734         };
11735         static const struct bwn_smpair v4[] = {
11736                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11737                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11738                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11739                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11740                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11741                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11742                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11743                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11744         };
11745         static const struct bwn_smpair v5[] = {
11746                 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11747                 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11748                 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11749                 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11750                 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11751                 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11752                 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11753                 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11754         };
11755         int i;
11756         uint16_t tmp, tmp2;
11757
11758         BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11759         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11760         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11761         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11762         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11763         BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11764         BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11765         BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11766         BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11767         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11768         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11769         BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11770         BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11771         BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11772         BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11773         for (i = 0; i < N(v1); i++)
11774                 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11775         BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11776             0xff00, plp->plp_rxpwroffset);
11777         if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11778             ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11779            (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11780                 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11781                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11782                 if (mac->mac_phy.rev == 0)
11783                         BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11784                             0xffcf, 0x0010);
11785                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11786         } else {
11787                 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11788                 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11789                 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11790         }
11791         tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11792         BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11793         if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11794                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11795         else
11796                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11797         bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11798         BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11799             0xfff9, (plp->plp_bxarch << 1));
11800         if (mac->mac_phy.rev == 1 &&
11801             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11802                 for (i = 0; i < N(v2); i++)
11803                         BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11804                             v2[i].set);
11805         } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11806             (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11807             ((mac->mac_phy.rev == 0) &&
11808              (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11809                 for (i = 0; i < N(v3); i++)
11810                         BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11811                             v3[i].set);
11812         } else if (mac->mac_phy.rev == 1 ||
11813                   (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11814                 for (i = 0; i < N(v4); i++)
11815                         BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11816                             v4[i].set);
11817         } else {
11818                 for (i = 0; i < N(v5); i++)
11819                         BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11820                             v5[i].set);
11821         }
11822         if (mac->mac_phy.rev == 1 &&
11823             (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11824                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11825                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11826                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11827                 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11828         }
11829         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11830             (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11831             (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11832                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11833                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11834                 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11835                 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11836         }
11837         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11838                 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11839                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11840                 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11841                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11842                 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11843                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
11844                 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
11845                 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11846         } else {
11847                 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
11848                 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
11849         }
11850         if (mac->mac_phy.rev == 1) {
11851                 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
11852                 tmp2 = (tmp & 0x03e0) >> 5;
11853                 tmp2 |= tmp2 << 5;
11854                 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
11855                 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
11856                 tmp2 = (tmp & 0x1f00) >> 8;
11857                 tmp2 |= tmp2 << 5;
11858                 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
11859                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
11860                 tmp2 = tmp & 0x00ff;
11861                 tmp2 |= tmp << 8;
11862                 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
11863         }
11864 }
11865
11866 struct bwn_b2062_freq {
11867         uint16_t                freq;
11868         uint8_t                 value[6];
11869 };
11870
11871 static void
11872 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
11873 {
11874 #define CALC_CTL7(freq, div)                                            \
11875         (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
11876 #define CALC_CTL18(freq, div)                                           \
11877         ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
11878 #define CALC_CTL19(freq, div)                                           \
11879         ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
11880         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11881         struct bwn_softc *sc = mac->mac_sc;
11882         struct ieee80211com *ic = &sc->sc_ic;
11883         static const struct bwn_b2062_freq freqdata_tab[] = {
11884                 { 12000, { 6, 6, 6, 6, 10, 6 } },
11885                 { 13000, { 4, 4, 4, 4, 11, 7 } },
11886                 { 14400, { 3, 3, 3, 3, 12, 7 } },
11887                 { 16200, { 3, 3, 3, 3, 13, 8 } },
11888                 { 18000, { 2, 2, 2, 2, 14, 8 } },
11889                 { 19200, { 1, 1, 1, 1, 14, 9 } }
11890         };
11891         static const struct bwn_wpair v1[] = {
11892                 { BWN_B2062_N_TXCTL3, 0 },
11893                 { BWN_B2062_N_TXCTL4, 0 },
11894                 { BWN_B2062_N_TXCTL5, 0 },
11895                 { BWN_B2062_N_TXCTL6, 0 },
11896                 { BWN_B2062_N_PDNCTL0, 0x40 },
11897                 { BWN_B2062_N_PDNCTL0, 0 },
11898                 { BWN_B2062_N_CALIB_TS, 0x10 },
11899                 { BWN_B2062_N_CALIB_TS, 0 }
11900         };
11901         const struct bwn_b2062_freq *f = NULL;
11902         uint32_t xtalfreq, ref;
11903         unsigned int i;
11904
11905         bwn_phy_lp_b2062_tblinit(mac);
11906
11907         for (i = 0; i < N(v1); i++)
11908                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
11909         if (mac->mac_phy.rev > 0)
11910                 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
11911                     (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
11912         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11913                 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
11914         else
11915                 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
11916
11917         KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
11918             ("%s:%d: fail", __func__, __LINE__));
11919         xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11920         KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
11921
11922         if (xtalfreq <= 30000000) {
11923                 plp->plp_div = 1;
11924                 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
11925         } else {
11926                 plp->plp_div = 2;
11927                 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
11928         }
11929
11930         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
11931             CALC_CTL7(xtalfreq, plp->plp_div));
11932         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
11933             CALC_CTL18(xtalfreq, plp->plp_div));
11934         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
11935             CALC_CTL19(xtalfreq, plp->plp_div));
11936
11937         ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
11938         ref &= 0xffff;
11939         for (i = 0; i < N(freqdata_tab); i++) {
11940                 if (ref < freqdata_tab[i].freq) {
11941                         f = &freqdata_tab[i];
11942                         break;
11943                 }
11944         }
11945         if (f == NULL)
11946                 f = &freqdata_tab[N(freqdata_tab) - 1];
11947         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
11948             ((uint16_t)(f->value[1]) << 4) | f->value[0]);
11949         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
11950             ((uint16_t)(f->value[3]) << 4) | f->value[2]);
11951         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
11952         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
11953 #undef CALC_CTL7
11954 #undef CALC_CTL18
11955 #undef CALC_CTL19
11956 }
11957
11958 static void
11959 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
11960 {
11961
11962         bwn_phy_lp_b2063_tblinit(mac);
11963         BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
11964         BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
11965         BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
11966         BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
11967         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
11968         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
11969         BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
11970         if (mac->mac_phy.rev == 2) {
11971                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
11972                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
11973                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
11974         } else {
11975                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
11976                 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
11977         }
11978 }
11979
11980 static void
11981 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
11982 {
11983         struct bwn_softc *sc = mac->mac_sc;
11984         static const struct bwn_wpair v1[] = {
11985                 { BWN_B2063_RX_BB_SP8, 0x0 },
11986                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
11987                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
11988                 { BWN_B2063_RC_CALIB_CTL2, 0x15 },
11989                 { BWN_B2063_RC_CALIB_CTL3, 0x70 },
11990                 { BWN_B2063_RC_CALIB_CTL4, 0x52 },
11991                 { BWN_B2063_RC_CALIB_CTL5, 0x1 },
11992                 { BWN_B2063_RC_CALIB_CTL1, 0x7d }
11993         };
11994         static const struct bwn_wpair v2[] = {
11995                 { BWN_B2063_TX_BB_SP3, 0x0 },
11996                 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
11997                 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
11998                 { BWN_B2063_RC_CALIB_CTL2, 0x55 },
11999                 { BWN_B2063_RC_CALIB_CTL3, 0x76 }
12000         };
12001         uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12002         int i;
12003         uint8_t tmp;
12004
12005         tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12006
12007         for (i = 0; i < 2; i++)
12008                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12009         BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12010         for (i = 2; i < N(v1); i++)
12011                 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12012         for (i = 0; i < 10000; i++) {
12013                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12014                         break;
12015                 DELAY(1000);
12016         }
12017
12018         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12019                 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12020
12021         tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12022
12023         for (i = 0; i < N(v2); i++)
12024                 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12025         if (freqxtal == 24000000) {
12026                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12027                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12028         } else {
12029                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12030                 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12031         }
12032         BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12033         for (i = 0; i < 10000; i++) {
12034                 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12035                         break;
12036                 DELAY(1000);
12037         }
12038         if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12039                 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12040         BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12041 }
12042
12043 static void
12044 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12045 {
12046         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12047         struct bwn_softc *sc = mac->mac_sc;
12048         struct bwn_phy_lp_iq_est ie;
12049         struct bwn_txgain tx_gains;
12050         static const uint32_t pwrtbl[21] = {
12051                 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12052                 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12053                 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12054                 0x0004c, 0x0002c, 0x0001a,
12055         };
12056         uint32_t npwr, ipwr, sqpwr, tmp;
12057         int loopback, i, j, sum, error;
12058         uint16_t save[7];
12059         uint8_t txo, bbmult, txpctlmode;
12060
12061         error = bwn_phy_lp_switch_channel(mac, 7);
12062         if (error)
12063                 device_printf(sc->sc_dev,
12064                     "failed to change channel to 7 (%d)\n", error);
12065         txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12066         bbmult = bwn_phy_lp_get_bbmult(mac);
12067         if (txo)
12068                 tx_gains = bwn_phy_lp_get_txgain(mac);
12069
12070         save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12071         save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12072         save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12073         save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12074         save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12075         save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12076         save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12077
12078         bwn_phy_lp_get_txpctlmode(mac);
12079         txpctlmode = plp->plp_txpctlmode;
12080         bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12081
12082         /* disable CRS */
12083         bwn_phy_lp_set_deaf(mac, 1);
12084         bwn_phy_lp_set_trsw_over(mac, 0, 1);
12085         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12086         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12087         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12088         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12089         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12090         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12091         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12092         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12093         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12094         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12095         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12096         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12097         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12098         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12099         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12100         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12101         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12102         BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12103         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12104         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12105         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12106         BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12107         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12108
12109         loopback = bwn_phy_lp_loopback(mac);
12110         if (loopback == -1)
12111                 goto done;
12112         bwn_phy_lp_set_rxgain_idx(mac, loopback);
12113         BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12114         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12115         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12116         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12117
12118         tmp = 0;
12119         memset(&ie, 0, sizeof(ie));
12120         for (i = 128; i <= 159; i++) {
12121                 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12122                 sum = 0;
12123                 for (j = 5; j <= 25; j++) {
12124                         bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12125                         if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12126                                 goto done;
12127                         sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12128                         ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12129                         npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12130                             12);
12131                         sum += ((ipwr - npwr) * (ipwr - npwr));
12132                         if ((i == 128) || (sum < tmp)) {
12133                                 plp->plp_rccap = i;
12134                                 tmp = sum;
12135                         }
12136                 }
12137         }
12138         bwn_phy_lp_ddfs_turnoff(mac);
12139 done:
12140         /* restore CRS */
12141         bwn_phy_lp_clear_deaf(mac, 1);
12142         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12143         BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12144
12145         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12146         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12147         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12148         BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12149         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12150         BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12151         BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12152
12153         bwn_phy_lp_set_bbmult(mac, bbmult);
12154         if (txo)
12155                 bwn_phy_lp_set_txgain(mac, &tx_gains);
12156         bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12157         if (plp->plp_rccap)
12158                 bwn_phy_lp_set_rccap(mac);
12159 }
12160
12161 static void
12162 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12163 {
12164         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12165         uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12166
12167         if (mac->mac_phy.rev == 1)
12168                 rc_cap = MIN(rc_cap + 5, 15);
12169
12170         BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12171             MAX(plp->plp_rccap - 4, 0x80));
12172         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12173         BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12174             ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12175 }
12176
12177 static uint32_t
12178 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12179 {
12180         uint32_t i, q, r;
12181
12182         if (div == 0)
12183                 return (0);
12184
12185         for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12186                 q <<= 1;
12187                 if (r << 1 >= div) {
12188                         q++;
12189                         r = (r << 1) - div;
12190                 }
12191         }
12192         if (r << 1 >= div)
12193                 q++;
12194         return (q);
12195 }
12196
12197 static void
12198 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12199 {
12200         struct bwn_softc *sc = mac->mac_sc;
12201
12202         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12203         DELAY(20);
12204         if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12205                 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12206                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12207         } else {
12208                 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12209         }
12210         DELAY(5);
12211 }
12212
12213 static void
12214 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12215 {
12216
12217         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12218         BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12219         DELAY(200);
12220 }
12221
12222 static void
12223 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12224 {
12225 #define FLAG_A  0x01
12226 #define FLAG_G  0x02
12227         struct bwn_softc *sc = mac->mac_sc;
12228         struct ieee80211com *ic = &sc->sc_ic;
12229         static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12230                 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12231                 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12232                 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12233                 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12234                 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12235                 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12236                 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12237                 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12238                 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12239                 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12240                 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12241                 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12242                 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12243                 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12244                 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12245                 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12246                 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12247                 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12248                 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12249                 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12250                 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12251                 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12252                 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12253                 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12254                 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12255                 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12256                 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12257                 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12258                 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12259                 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12260                 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12261                 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12262                 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12263                 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12264                 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12265                 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12266                 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12267                 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12268                 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12269                 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12270                 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12271                 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12272                 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12273                 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12274                 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12275                 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12276                 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12277         };
12278         const struct bwn_b206x_rfinit_entry *br;
12279         unsigned int i;
12280
12281         for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12282                 br = &bwn_b2062_init_tab[i];
12283                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12284                         if (br->br_flags & FLAG_G)
12285                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12286                 } else {
12287                         if (br->br_flags & FLAG_A)
12288                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12289                 }
12290         }
12291 #undef FLAG_A
12292 #undef FLAG_B
12293 }
12294
12295 static void
12296 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12297 {
12298 #define FLAG_A  0x01
12299 #define FLAG_G  0x02
12300         struct bwn_softc *sc = mac->mac_sc;
12301         struct ieee80211com *ic = &sc->sc_ic;
12302         static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12303                 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12304                 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12305                 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12306                 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12307                 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12308                 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12309                 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12310                 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12311                 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12312                 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12313                 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12314                 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12315                 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12316                 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12317                 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12318                 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12319                 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12320                 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12321                 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12322                 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12323                 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12324                 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12325                 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12326                 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12327                 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12328                 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12329                 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12330                 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12331                 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12332                 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12333                 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12334                 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12335                 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12336                 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12337                 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12338                 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12339                 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12340                 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12341                 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12342                 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12343                 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12344                 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12345         };
12346         const struct bwn_b206x_rfinit_entry *br;
12347         unsigned int i;
12348
12349         for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12350                 br = &bwn_b2063_init_tab[i];
12351                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12352                         if (br->br_flags & FLAG_G)
12353                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12354                 } else {
12355                         if (br->br_flags & FLAG_A)
12356                                 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12357                 }
12358         }
12359 #undef FLAG_A
12360 #undef FLAG_B
12361 }
12362
12363 static void
12364 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12365     int count, void *_data)
12366 {
12367         unsigned int i;
12368         uint32_t offset, type;
12369         uint8_t *data = _data;
12370
12371         type = BWN_TAB_GETTYPE(typenoffset);
12372         offset = BWN_TAB_GETOFFSET(typenoffset);
12373         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12374
12375         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12376
12377         for (i = 0; i < count; i++) {
12378                 switch (type) {
12379                 case BWN_TAB_8BIT:
12380                         *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12381                         data++;
12382                         break;
12383                 case BWN_TAB_16BIT:
12384                         *((uint16_t *)data) = BWN_PHY_READ(mac,
12385                             BWN_PHY_TABLEDATALO);
12386                         data += 2;
12387                         break;
12388                 case BWN_TAB_32BIT:
12389                         *((uint32_t *)data) = BWN_PHY_READ(mac,
12390                             BWN_PHY_TABLEDATAHI);
12391                         *((uint32_t *)data) <<= 16;
12392                         *((uint32_t *)data) |= BWN_PHY_READ(mac,
12393                             BWN_PHY_TABLEDATALO);
12394                         data += 4;
12395                         break;
12396                 default:
12397                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12398                 }
12399         }
12400 }
12401
12402 static void
12403 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12404     int count, const void *_data)
12405 {
12406         uint32_t offset, type, value;
12407         const uint8_t *data = _data;
12408         unsigned int i;
12409
12410         type = BWN_TAB_GETTYPE(typenoffset);
12411         offset = BWN_TAB_GETOFFSET(typenoffset);
12412         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12413
12414         BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12415
12416         for (i = 0; i < count; i++) {
12417                 switch (type) {
12418                 case BWN_TAB_8BIT:
12419                         value = *data;
12420                         data++;
12421                         KASSERT(!(value & ~0xff),
12422                             ("%s:%d: fail", __func__, __LINE__));
12423                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12424                         break;
12425                 case BWN_TAB_16BIT:
12426                         value = *((const uint16_t *)data);
12427                         data += 2;
12428                         KASSERT(!(value & ~0xffff),
12429                             ("%s:%d: fail", __func__, __LINE__));
12430                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12431                         break;
12432                 case BWN_TAB_32BIT:
12433                         value = *((const uint32_t *)data);
12434                         data += 4;
12435                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12436                         BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12437                         break;
12438                 default:
12439                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12440                 }
12441         }
12442 }
12443
12444 static struct bwn_txgain
12445 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12446 {
12447         struct bwn_txgain tg;
12448         uint16_t tmp;
12449
12450         tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12451         if (mac->mac_phy.rev < 2) {
12452                 tmp = BWN_PHY_READ(mac,
12453                     BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12454                 tg.tg_gm = tmp & 0x0007;
12455                 tg.tg_pga = (tmp & 0x0078) >> 3;
12456                 tg.tg_pad = (tmp & 0x780) >> 7;
12457                 return (tg);
12458         }
12459
12460         tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12461         tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12462         tg.tg_gm = tmp & 0xff;
12463         tg.tg_pga = (tmp >> 8) & 0xff;
12464         return (tg);
12465 }
12466
12467 static uint8_t
12468 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12469 {
12470
12471         return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12472 }
12473
12474 static void
12475 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12476 {
12477         uint16_t pa;
12478
12479         if (mac->mac_phy.rev < 2) {
12480                 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12481                     (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12482                 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12483                 bwn_phy_lp_set_txgain_override(mac);
12484                 return;
12485         }
12486
12487         pa = bwn_phy_lp_get_pa_gain(mac);
12488         BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12489             (tg->tg_pga << 8) | tg->tg_gm);
12490         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12491             tg->tg_pad | (pa << 6));
12492         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12493         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12494             tg->tg_pad | (pa << 8));
12495         bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12496         bwn_phy_lp_set_txgain_override(mac);
12497 }
12498
12499 static void
12500 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12501 {
12502
12503         bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12504 }
12505
12506 static void
12507 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12508 {
12509         uint16_t trsw = (tx << 1) | rx;
12510
12511         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12512         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12513 }
12514
12515 static void
12516 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12517 {
12518         struct bwn_softc *sc = mac->mac_sc;
12519         struct ieee80211com *ic = &sc->sc_ic;
12520         uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12521
12522         if (mac->mac_phy.rev < 2) {
12523                 trsw = gain & 0x1;
12524                 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12525                 ext_lna = (gain & 2) >> 1;
12526
12527                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12528                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12529                     0xfbff, ext_lna << 10);
12530                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12531                     0xf7ff, ext_lna << 11);
12532                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12533         } else {
12534                 low_gain = gain & 0xffff;
12535                 high_gain = (gain >> 16) & 0xf;
12536                 ext_lna = (gain >> 21) & 0x1;
12537                 trsw = ~(gain >> 20) & 0x1;
12538
12539                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12540                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12541                     0xfdff, ext_lna << 9);
12542                 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12543                     0xfbff, ext_lna << 10);
12544                 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12545                 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12546                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12547                         tmp = (gain >> 2) & 0x3;
12548                         BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12549                             0xe7ff, tmp<<11);
12550                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12551                             tmp << 3);
12552                 }
12553         }
12554
12555         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12556         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12557         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12558         if (mac->mac_phy.rev >= 2) {
12559                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12560                 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12561                         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12562                         BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12563                 }
12564                 return;
12565         }
12566         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12567 }
12568
12569 static void
12570 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12571 {
12572         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12573
12574         if (user)
12575                 plp->plp_crsusr_off = 1;
12576         else
12577                 plp->plp_crssys_off = 1;
12578
12579         BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12580 }
12581
12582 static void
12583 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12584 {
12585         struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12586         struct bwn_softc *sc = mac->mac_sc;
12587         struct ieee80211com *ic = &sc->sc_ic;
12588
12589         if (user)
12590                 plp->plp_crsusr_off = 0;
12591         else
12592                 plp->plp_crssys_off = 0;
12593
12594         if (plp->plp_crsusr_off || plp->plp_crssys_off)
12595                 return;
12596
12597         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12598                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12599         else
12600                 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12601 }
12602
12603 static unsigned int
12604 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12605 {
12606         /* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12607         static uint8_t sqrt_table[256] = {
12608                 10, 14, 17, 20, 22, 24, 26, 28,
12609                 30, 31, 33, 34, 36, 37, 38, 40,
12610                 41, 42, 43, 44, 45, 46, 47, 48,
12611                 50, 50, 51, 52, 53, 54, 55, 56,
12612                 57, 58, 59, 60, 60, 61, 62, 63,
12613                 64, 64, 65, 66, 67, 67, 68, 69,
12614                 70, 70, 71, 72, 72, 73, 74, 74,
12615                 75, 76, 76, 77, 78, 78, 79, 80,
12616                 80, 81, 81, 82, 83, 83, 84, 84,
12617                 85, 86, 86, 87, 87, 88, 88, 89,
12618                 90, 90, 91, 91, 92, 92, 93, 93,
12619                 94, 94, 95, 95, 96, 96, 97, 97,
12620                 98, 98, 99, 100, 100, 100, 101, 101,
12621                 102, 102, 103, 103, 104, 104, 105, 105,
12622                 106, 106, 107, 107, 108, 108, 109, 109,
12623                 110, 110, 110, 111, 111, 112, 112, 113,
12624                 113, 114, 114, 114, 115, 115, 116, 116,
12625                 117, 117, 117, 118, 118, 119, 119, 120,
12626                 120, 120, 121, 121, 122, 122, 122, 123,
12627                 123, 124, 124, 124, 125, 125, 126, 126,
12628                 126, 127, 127, 128, 128, 128, 129, 129,
12629                 130, 130, 130, 131, 131, 131, 132, 132,
12630                 133, 133, 133, 134, 134, 134, 135, 135,
12631                 136, 136, 136, 137, 137, 137, 138, 138,
12632                 138, 139, 139, 140, 140, 140, 141, 141,
12633                 141, 142, 142, 142, 143, 143, 143, 144,
12634                 144, 144, 145, 145, 145, 146, 146, 146,
12635                 147, 147, 147, 148, 148, 148, 149, 149,
12636                 150, 150, 150, 150, 151, 151, 151, 152,
12637                 152, 152, 153, 153, 153, 154, 154, 154,
12638                 155, 155, 155, 156, 156, 156, 157, 157,
12639                 157, 158, 158, 158, 159, 159, 159, 160
12640         };
12641
12642         if (x == 0)
12643                 return (0);
12644         if (x >= 256) {
12645                 unsigned int tmp;
12646
12647                 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12648                         /* do nothing */ ;
12649                 return (tmp);
12650         }
12651         return (sqrt_table[x - 1] / 10);
12652 }
12653
12654 static int
12655 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12656 {
12657 #define CALC_COEFF(_v, _x, _y, _z)      do {                            \
12658         int _t;                                                         \
12659         _t = _x - 20;                                                   \
12660         if (_t >= 0) {                                                  \
12661                 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12662         } else {                                                        \
12663                 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12664         }                                                               \
12665 } while (0)
12666 #define CALC_COEFF2(_v, _x, _y, _z)     do {                            \
12667         int _t;                                                         \
12668         _t = _x - 11;                                                   \
12669         if (_t >= 0)                                                    \
12670                 _v = (_y << (31 - _x)) / (_z >> _t);                    \
12671         else                                                            \
12672                 _v = (_y << (31 - _x)) / (_z << -_t);                   \
12673 } while (0)
12674         struct bwn_phy_lp_iq_est ie;
12675         uint16_t v0, v1;
12676         int tmp[2], ret;
12677
12678         v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12679         v0 = v1 >> 8;
12680         v1 |= 0xff;
12681
12682         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12683         BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12684
12685         ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12686         if (ret == 0)
12687                 goto done;
12688
12689         if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12690                 ret = 0;
12691                 goto done;
12692         }
12693
12694         CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12695         CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12696
12697         tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12698         v0 = tmp[0] >> 3;
12699         v1 = tmp[1] >> 4;
12700 done:
12701         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12702         BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12703         return ret;
12704 #undef CALC_COEFF
12705 #undef CALC_COEFF2
12706 }
12707
12708 static void
12709 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12710 {
12711         static const uint16_t noisescale[] = {
12712                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12713                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12714                 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12715                 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12716                 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12717         };
12718         static const uint16_t crsgainnft[] = {
12719                 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12720                 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12721                 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12722                 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12723                 0x013d,
12724         };
12725         static const uint16_t filterctl[] = {
12726                 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12727                 0xff53, 0x0127,
12728         };
12729         static const uint32_t psctl[] = {
12730                 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12731                 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12732                 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12733                 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12734                 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12735                 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12736                 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12737                 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12738         };
12739         static const uint16_t ofdmcckgain_r0[] = {
12740                 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12741                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12742                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12743                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12744                 0x755d,
12745         };
12746         static const uint16_t ofdmcckgain_r1[] = {
12747                 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12748                 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12749                 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12750                 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12751                 0x755d,
12752         };
12753         static const uint16_t gaindelta[] = {
12754                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12755                 0x0000,
12756         };
12757         static const uint32_t txpwrctl[] = {
12758                 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12759                 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12760                 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12761                 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12762                 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12763                 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12764                 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12765                 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12766                 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12767                 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12768                 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12769                 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12770                 0x00000014, 0x00000013, 0x00000012, 0x00000011, 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, 0x00000000, 0x00000000, 0x00000000,
12796                 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12797                 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12798                 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12799                 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12800                 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12801                 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12802                 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12803                 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12804                 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12805                 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12806                 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12807                 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12808                 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12809                 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12810                 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12811                 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12812                 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12813                 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12814                 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12815                 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12816                 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12817                 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12818                 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12819                 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12820                 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12821                 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12822                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12823                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12824                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12825                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12826                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12827                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12828                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12829                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12830                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12831                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12832                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12833                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12834                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12835                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12836                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12837                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12838                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12839                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12840                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12841                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12842                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12843                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12844                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12845                 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12846                 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12847                 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
12848                 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
12849                 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
12850                 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
12851                 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
12852                 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
12853                 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
12854                 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
12855                 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
12856                 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
12857                 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
12858                 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
12859                 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
12860                 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
12861                 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
12862                 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
12863                 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
12864                 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
12865                 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
12866                 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
12867                 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
12868                 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
12869                 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
12870                 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
12871                 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
12872                 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
12873                 0x00000702,
12874         };
12875
12876         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
12877
12878         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
12879             bwn_tab_sigsq_tbl);
12880         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
12881         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
12882         bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
12883         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
12884         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
12885             bwn_tab_pllfrac_tbl);
12886         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
12887             bwn_tabl_iqlocal_tbl);
12888         if (mac->mac_phy.rev == 0) {
12889                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
12890                     ofdmcckgain_r0);
12891                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
12892                     ofdmcckgain_r0);
12893         } else {
12894                 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
12895                     ofdmcckgain_r1);
12896                 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
12897                     ofdmcckgain_r1);
12898         }
12899         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
12900         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
12901 }
12902
12903 static void
12904 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
12905 {
12906         struct bwn_softc *sc = mac->mac_sc;
12907         int i;
12908         static const uint16_t noisescale[] = {
12909                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12910                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12911                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12912                 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12913                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12914                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12915                 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
12916         };
12917         static const uint32_t filterctl[] = {
12918                 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
12919                 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
12920         };
12921         static const uint32_t psctl[] = {
12922                 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
12923                 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
12924                 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
12925                 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
12926         };
12927         static const uint32_t gainidx[] = {
12928                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12929                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12930                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12931                 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
12932                 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
12933                 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
12934                 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
12935                 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
12936                 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
12937                 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
12938                 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
12939                 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
12940                 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
12941                 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
12942                 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
12943                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12944                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12945                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12946                 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
12947                 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
12948                 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
12949                 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
12950                 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
12951                 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
12952                 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
12953                 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
12954                 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
12955                 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
12956                 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
12957                 0x0000001a, 0x64ca55ad, 0x0000001a
12958         };
12959         static const uint16_t auxgainidx[] = {
12960                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12961                 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
12962                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
12963                 0x0004, 0x0016
12964         };
12965         static const uint16_t swctl[] = {
12966                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
12967                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
12968                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
12969                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
12970                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
12971                 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
12972                 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
12973                 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
12974         };
12975         static const uint8_t hf[] = {
12976                 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
12977                 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
12978         };
12979         static const uint32_t gainval[] = {
12980                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
12981                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
12982                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
12983                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
12984                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
12985                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
12986                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12987                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12988                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
12989                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
12990                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
12991                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
12992                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
12993                 0x000000f1, 0x00000000, 0x00000000
12994         };
12995         static const uint16_t gain[] = {
12996                 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
12997                 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
12998                 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
12999                 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13000                 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13001                 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 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                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13008         };
13009         static const uint32_t papdeps[] = {
13010                 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13011                 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13012                 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13013                 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13014                 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13015                 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13016                 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13017                 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13018                 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13019                 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13020                 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13021                 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13022                 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13023         };
13024         static const uint32_t papdmult[] = {
13025                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13026                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13027                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13028                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13029                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13030                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13031                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13032                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13033                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13034                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13035                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13036                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13037                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13038         };
13039         static const uint32_t gainidx_a0[] = {
13040                 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13041                 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13042                 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13043                 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13044                 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13045                 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13046                 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13047                 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13048                 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13049                 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13050                 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13051                 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13052                 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13053         };
13054         static const uint16_t auxgainidx_a0[] = {
13055                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13056                 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13057                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13058                 0x0002, 0x0014
13059         };
13060         static const uint32_t gainval_a0[] = {
13061                 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13062                 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13063                 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13064                 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13065                 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13066                 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13067                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13068                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13069                 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13070                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13071                 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13072                 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13073                 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13074                 0x000000f7, 0x00000000, 0x00000000
13075         };
13076         static const uint16_t gain_a0[] = {
13077                 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13078                 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13079                 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13080                 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13081                 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13082                 0x035f, 0x075f, 0x0b5f, 0x0f5f, 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                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13089         };
13090
13091         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13092
13093         for (i = 0; i < 704; i++)
13094                 bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13095
13096         bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13097             bwn_tab_sigsq_tbl);
13098         bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13099         bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13100         bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13101         bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13102         bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13103         bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13104         bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13105         bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13106         bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13107         bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13108             bwn_tab_pllfrac_tbl);
13109         bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13110             bwn_tabl_iqlocal_tbl);
13111         bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13112         bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13113
13114         if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13115             (siba_get_chiprev(sc->sc_dev) == 0)) {
13116                 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13117                     gainidx_a0);
13118                 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13119                     auxgainidx_a0);
13120                 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13121                     gainval_a0);
13122                 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13123         }
13124 }
13125
13126 static void
13127 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13128 {
13129         struct bwn_softc *sc = mac->mac_sc;
13130         struct ieee80211com *ic = &sc->sc_ic;
13131         static struct bwn_txgain_entry txgain_r2[] = {
13132                 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13133                 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13134                 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13135                 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13136                 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13137                 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13138                 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13139                 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13140                 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13141                 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13142                 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13143                 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13144                 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13145                 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13146                 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13147                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13148                 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13149                 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13150                 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13151                 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13152                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13153                 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13154                 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13155                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13156                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13157                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13158                 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13159                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13160                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13161                 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13162                 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13163                 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13164                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13165                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13166                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13167                 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13168                 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13169                 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13170                 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13171                 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13172                 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13173                 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13174                 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13175                 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13176                 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13177                 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13178                 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13179                 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13180                 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13181                 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13182                 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13183                 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13184                 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13185                 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13186                 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13187                 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13188                 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13189                 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13190                 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13191                 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13192                 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13193                 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13194                 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13195                 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13196         };
13197         static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13198                 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13199                 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13200                 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13201                 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13202                 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13203                 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13204                 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13205                 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13206                 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13207                 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13208                 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13209                 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13210                 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13211                 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13212                 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13213                 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13214                 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13215                 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13216                 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13217                 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13218                 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13219                 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13220                 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13221                 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13222                 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13223                 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13224                 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13225                 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13226                 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13227                 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13228                 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13229                 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13230                 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13231                 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13232                 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13233                 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13234                 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13235                 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13236                 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13237                 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13238                 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13239                 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13240                 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13241                 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13242                 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13243                 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13244                 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13245                 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13246                 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13247                 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13248                 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13249                 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13250                 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13251                 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13252                 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13253                 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13254                 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13255                 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13256                 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13257                 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13258                 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13259                 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13260                 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13261                 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13262         };
13263         static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13264                 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13265                 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13266                 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13267                 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13268                 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13269                 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13270                 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13271                 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13272                 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13273                 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13274                 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13275                 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13276                 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13277                 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13278                 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13279                 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13280                 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13281                 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13282                 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13283                 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13284                 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13285                 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13286                 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13287                 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13288                 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13289                 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13290                 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13291                 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13292                 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13293                 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13294                 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13295                 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13296                 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13297                 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13298                 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13299                 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13300                 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13301                 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13302                 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13303                 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13304                 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13305                 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13306                 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13307                 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13308                 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13309                 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13310                 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13311                 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13312                 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13313                 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13314                 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13315                 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13316                 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13317                 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13318                 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13319                 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13320                 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13321                 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13322                 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13323                 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13324                 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13325                 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13326                 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13327                 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13328         };
13329         static struct bwn_txgain_entry txgain_r0[] = {
13330                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13331                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13332                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13333                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13334                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13335                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13336                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13337                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13338                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13339                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13340                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13341                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13342                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13343                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13344                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13345                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13346                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13347                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13348                 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13349                 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13350                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13351                 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13352                 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13353                 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13354                 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13355                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13356                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13357                 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13358                 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13359                 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13360                 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13361                 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13362                 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13363                 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13364                 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13365                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13366                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13367                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13368                 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13369                 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13370                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13371                 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13372                 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13373                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13374                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13375                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13376                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13377                 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13378                 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13379                 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13380                 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13381                 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13382                 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13383                 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13384                 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13385                 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13386                 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13387                 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13388                 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13389                 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13390                 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13391                 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13392                 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13393                 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13394         };
13395         static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13396                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13397                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13398                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13399                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13400                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13401                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13402                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13403                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13404                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13405                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13406                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13407                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13408                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13409                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13410                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13411                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13412                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13413                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13414                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13415                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13416                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13417                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13418                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13419                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13420                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13421                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13422                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13423                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13424                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13425                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13426                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13427                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13428                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13429                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13430                 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13431                 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13432                 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13433                 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13434                 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13435                 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13436                 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13437                 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13438                 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13439                 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13440                 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13441                 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13442                 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13443                 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13444                 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13445                 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13446                 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13447                 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13448                 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13449                 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13450                 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13451                 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13452                 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13453                 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13454                 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13455                 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13456                 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13457                 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13458                 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13459                 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13460         };
13461         static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13462                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13463                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13464                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13465                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13466                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13467                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13468                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13469                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13470                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13471                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13472                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13473                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13474                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13475                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13476                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13477                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13478                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13479                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13480                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13481                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13482                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13483                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13484                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13485                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13486                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13487                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13488                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13489                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13490                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13491                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13492                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13493                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13494                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13495                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13496                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13497                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13498                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13499                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13500                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13501                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13502                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13503                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13504                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13505                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13506                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13507                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13508                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13509                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13510                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13511                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13512                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13513                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13514                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13515                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13516                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13517                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13518                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13519                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13520                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13521                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13522                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13523                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13524                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13525                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13526         };
13527         static struct bwn_txgain_entry txgain_r1[] = {
13528                 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13529                 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13530                 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13531                 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13532                 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13533                 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13534                 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13535                 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13536                 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13537                 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13538                 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13539                 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13540                 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13541                 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13542                 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13543                 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13544                 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13545                 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13546                 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13547                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13548                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13549                 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13550                 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13551                 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13552                 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13553                 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13554                 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13555                 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13556                 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13557                 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13558                 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13559                 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13560                 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13561                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13562                 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13563                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13564                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13565                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13566                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13567                 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13568                 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13569                 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13570                 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13571                 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13572                 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13573                 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13574                 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13575                 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13576                 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13577                 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13578                 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13579                 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13580                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13581                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13582                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13583                 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13584                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13585                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13586                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13587                 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13588                 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13589                 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13590                 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13591                 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13592                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13593                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13594                 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13595                 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13596                 { 7, 11, 6, 0, 71 }
13597         };
13598         static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13599                 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13600                 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13601                 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13602                 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13603                 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13604                 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13605                 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13606                 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13607                 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13608                 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13609                 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13610                 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13611                 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13612                 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13613                 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13614                 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13615                 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13616                 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13617                 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13618                 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13619                 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13620                 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13621                 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13622                 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13623                 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13624                 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13625                 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13626                 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13627                 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13628                 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13629                 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13630                 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13631                 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13632                 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13633                 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13634                 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13635                 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13636                 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13637                 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13638                 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13639                 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13640                 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13641                 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13642                 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13643                 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13644                 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13645                 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13646                 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13647                 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13648                 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13649                 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13650                 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13651                 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13652                 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13653                 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13654                 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13655                 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13656                 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13657                 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13658                 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13659                 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13660                 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13661                 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13662                 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13663         };
13664         static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13665                 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13666                 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13667                 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13668                 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13669                 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13670                 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13671                 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13672                 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13673                 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13674                 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13675                 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13676                 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13677                 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13678                 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13679                 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13680                 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13681                 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13682                 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13683                 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13684                 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13685                 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13686                 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13687                 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13688                 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13689                 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13690                 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13691                 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13692                 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13693                 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13694                 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13695                 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13696                 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13697                 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13698                 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13699                 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13700                 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13701                 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13702                 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13703                 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13704                 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13705                 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13706                 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13707                 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13708                 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13709                 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13710                 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13711                 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13712                 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13713                 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13714                 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13715                 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13716                 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13717                 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13718                 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13719                 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13720                 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13721                 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13722                 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13723                 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13724                 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13725                 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13726                 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13727                 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13728                 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13729         };
13730
13731         if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13732                 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13733                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13734                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13735                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13736                             txgain_2ghz_r2);
13737                 else
13738                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13739                             txgain_5ghz_r2);
13740                 return;
13741         }
13742
13743         if (mac->mac_phy.rev == 0) {
13744                 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13745                     (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13746                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13747                 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13748                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13749                             txgain_2ghz_r0);
13750                 else
13751                         bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13752                             txgain_5ghz_r0);
13753                 return;
13754         }
13755
13756         if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13757             (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13758                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13759         else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13760                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13761         else
13762                 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13763 }
13764
13765 static void
13766 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13767 {
13768         uint32_t offset, type;
13769
13770         type = BWN_TAB_GETTYPE(typeoffset);
13771         offset = BWN_TAB_GETOFFSET(typeoffset);
13772         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13773
13774         switch (type) {
13775         case BWN_TAB_8BIT:
13776                 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13777                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13778                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13779                 break;
13780         case BWN_TAB_16BIT:
13781                 KASSERT(!(value & ~0xffff),
13782                     ("%s:%d: fail", __func__, __LINE__));
13783                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13784                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13785                 break;
13786         case BWN_TAB_32BIT:
13787                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13788                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13789                 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13790                 break;
13791         default:
13792                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13793         }
13794 }
13795
13796 static int
13797 bwn_phy_lp_loopback(struct bwn_mac *mac)
13798 {
13799         struct bwn_phy_lp_iq_est ie;
13800         int i, index = -1;
13801         uint32_t tmp;
13802
13803         memset(&ie, 0, sizeof(ie));
13804
13805         bwn_phy_lp_set_trsw_over(mac, 1, 1);
13806         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13807         BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13808         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13809         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13810         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13811         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13812         BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13813         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13814         BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13815         for (i = 0; i < 32; i++) {
13816                 bwn_phy_lp_set_rxgain_idx(mac, i);
13817                 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13818                 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13819                         continue;
13820                 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13821                 if ((tmp > 4000) && (tmp < 10000)) {
13822                         index = i;
13823                         break;
13824                 }
13825         }
13826         bwn_phy_lp_ddfs_turnoff(mac);
13827         return (index);
13828 }
13829
13830 static void
13831 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13832 {
13833
13834         bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
13835 }
13836
13837 static void
13838 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
13839     int incr1, int incr2, int scale_idx)
13840 {
13841
13842         bwn_phy_lp_ddfs_turnoff(mac);
13843         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
13844         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
13845         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
13846         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
13847         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
13848         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
13849         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
13850         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
13851         BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
13852         BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
13853 }
13854
13855 static uint8_t
13856 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
13857     struct bwn_phy_lp_iq_est *ie)
13858 {
13859         int i;
13860
13861         BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
13862         BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
13863         BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
13864         BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
13865         BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
13866
13867         for (i = 0; i < 500; i++) {
13868                 if (!(BWN_PHY_READ(mac,
13869                     BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
13870                         break;
13871                 DELAY(1000);
13872         }
13873         if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
13874                 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
13875                 return 0;
13876         }
13877
13878         ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
13879         ie->ie_iqprod <<= 16;
13880         ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
13881         ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
13882         ie->ie_ipwr <<= 16;
13883         ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
13884         ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
13885         ie->ie_qpwr <<= 16;
13886         ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
13887
13888         BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
13889         return 1;
13890 }
13891
13892 static uint32_t
13893 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
13894 {
13895         uint32_t offset, type, value;
13896
13897         type = BWN_TAB_GETTYPE(typeoffset);
13898         offset = BWN_TAB_GETOFFSET(typeoffset);
13899         KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13900
13901         switch (type) {
13902         case BWN_TAB_8BIT:
13903                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13904                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
13905                 break;
13906         case BWN_TAB_16BIT:
13907                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13908                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
13909                 break;
13910         case BWN_TAB_32BIT:
13911                 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13912                 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
13913                 value <<= 16;
13914                 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
13915                 break;
13916         default:
13917                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13918                 value = 0;
13919         }
13920
13921         return (value);
13922 }
13923
13924 static void
13925 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
13926 {
13927
13928         BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
13929         BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
13930 }
13931
13932 static void
13933 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
13934 {
13935         uint16_t ctl;
13936
13937         ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
13938         ctl |= dac << 7;
13939         BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
13940 }
13941
13942 static void
13943 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
13944 {
13945
13946         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
13947         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
13948 }
13949
13950 static void
13951 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
13952 {
13953
13954         if (mac->mac_phy.rev < 2)
13955                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
13956         else {
13957                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
13958                 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
13959         }
13960         BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
13961 }
13962
13963 static uint16_t
13964 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
13965 {
13966
13967         return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
13968 }
13969
13970 static uint8_t
13971 bwn_nbits(int32_t val)
13972 {
13973         uint32_t tmp;
13974         uint8_t nbits = 0;
13975
13976         for (tmp = abs(val); tmp != 0; tmp >>= 1)
13977                 nbits++;
13978         return (nbits);
13979 }
13980
13981 static void
13982 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
13983     struct bwn_txgain_entry *table)
13984 {
13985         int i;
13986
13987         for (i = offset; i < count; i++)
13988                 bwn_phy_lp_gaintbl_write(mac, i, table[i]);
13989 }
13990
13991 static void
13992 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
13993     struct bwn_txgain_entry data)
13994 {
13995
13996         if (mac->mac_phy.rev >= 2)
13997                 bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
13998         else
13999                 bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14000 }
14001
14002 static void
14003 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14004     struct bwn_txgain_entry te)
14005 {
14006         struct bwn_softc *sc = mac->mac_sc;
14007         struct ieee80211com *ic = &sc->sc_ic;
14008         uint32_t tmp;
14009
14010         KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14011
14012         tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14013         if (mac->mac_phy.rev >= 3) {
14014                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14015                     (0x10 << 24) : (0x70 << 24));
14016         } else {
14017                 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14018                     (0x14 << 24) : (0x7f << 24));
14019         }
14020         bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14021         bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14022             te.te_bbmult << 20 | te.te_dac << 28);
14023 }
14024
14025 static void
14026 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14027     struct bwn_txgain_entry te)
14028 {
14029
14030         KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14031
14032         bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14033             (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm  << 4) |
14034             te.te_dac);
14035         bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14036 }
14037
14038 static void
14039 bwn_sysctl_node(struct bwn_softc *sc)
14040 {
14041         device_t dev = sc->sc_dev;
14042         struct bwn_mac *mac;
14043         struct bwn_stats *stats;
14044
14045         /* XXX assume that count of MAC is only 1. */
14046
14047         if ((mac = sc->sc_curmac) == NULL)
14048                 return;
14049         stats = &mac->mac_stats;
14050
14051         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14052             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14053             "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14054         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14055             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14056             "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14057         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14058             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14059             "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14060
14061 #ifdef BWN_DEBUG
14062         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14063             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14064             "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14065 #endif
14066 }
14067
14068 static device_method_t bwn_methods[] = {
14069         /* Device interface */
14070         DEVMETHOD(device_probe,         bwn_probe),
14071         DEVMETHOD(device_attach,        bwn_attach),
14072         DEVMETHOD(device_detach,        bwn_detach),
14073         DEVMETHOD(device_suspend,       bwn_suspend),
14074         DEVMETHOD(device_resume,        bwn_resume),
14075         DEVMETHOD_END
14076 };
14077 static driver_t bwn_driver = {
14078         "bwn",
14079         bwn_methods,
14080         sizeof(struct bwn_softc)
14081 };
14082 static devclass_t bwn_devclass;
14083 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
14084 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14085 MODULE_DEPEND(bwn, wlan, 1, 1, 1);              /* 802.11 media layer */
14086 MODULE_DEPEND(bwn, firmware, 1, 1, 1);          /* firmware support */
14087 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);