2 * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
34 * The Broadcom Wireless LAN controller driver.
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>
45 #include <sys/mutex.h>
46 #include <machine/bus.h>
47 #include <machine/resource.h>
50 #include <sys/socket.h>
51 #include <sys/sockio.h>
53 #include <net/ethernet.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>
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>
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>
74 #include <dev/bwn/if_bwnreg.h>
75 #include <dev/bwn/if_bwnvar.h>
77 static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0,
78 "Broadcom driver parameters");
81 * Tunable & sysctl variables.
85 static int bwn_debug = 0;
86 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RWTUN, &bwn_debug, 0,
87 "Broadcom debugging printfs");
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
109 #define DPRINTF(sc, m, fmt, ...) do { \
110 if (sc->sc_debug & (m)) \
111 printf(fmt, __VA_ARGS__); \
114 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
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,
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,
136 static int 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 void bwn_init(void *);
140 static int bwn_init_locked(struct bwn_softc *);
141 static int bwn_ioctl(struct ifnet *, u_long, caddr_t);
142 static void bwn_start(struct ifnet *);
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,
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,
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,
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,
178 static void bwn_shm_ctlword(struct bwn_mac *, 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 *, int);
201 static void bwn_stop_locked(struct bwn_softc *, int);
202 static int bwn_core_init(struct bwn_mac *);
203 static void bwn_core_start(struct bwn_mac *);
204 static void bwn_core_exit(struct bwn_mac *);
205 static void bwn_bt_disable(struct bwn_mac *);
206 static int bwn_chip_init(struct bwn_mac *);
207 static uint64_t bwn_hf_read(struct bwn_mac *);
208 static void bwn_hf_write(struct bwn_mac *, uint64_t);
209 static void bwn_set_txretry(struct bwn_mac *, int, int);
210 static void bwn_rate_init(struct bwn_mac *);
211 static void bwn_set_phytxctl(struct bwn_mac *);
212 static void bwn_spu_setdelay(struct bwn_mac *, int);
213 static void bwn_bt_enable(struct bwn_mac *);
214 static void bwn_set_macaddr(struct bwn_mac *);
215 static void bwn_crypt_init(struct bwn_mac *);
216 static void bwn_chip_exit(struct bwn_mac *);
217 static int bwn_fw_fillinfo(struct bwn_mac *);
218 static int bwn_fw_loaducode(struct bwn_mac *);
219 static int bwn_gpio_init(struct bwn_mac *);
220 static int bwn_fw_loadinitvals(struct bwn_mac *);
221 static int bwn_phy_init(struct bwn_mac *);
222 static void bwn_set_txantenna(struct bwn_mac *, int);
223 static void bwn_set_opmode(struct bwn_mac *);
224 static void bwn_rate_write(struct bwn_mac *, uint16_t, int);
225 static uint8_t bwn_plcp_getcck(const uint8_t);
226 static uint8_t bwn_plcp_getofdm(const uint8_t);
227 static void bwn_pio_init(struct bwn_mac *);
228 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int);
229 static void bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *,
231 static void bwn_pio_setupqueue_rx(struct bwn_mac *,
232 struct bwn_pio_rxqueue *, int);
233 static void bwn_destroy_queue_tx(struct bwn_pio_txqueue *);
234 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *,
236 static void bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *);
237 static int bwn_pio_rx(struct bwn_pio_rxqueue *);
238 static uint8_t bwn_pio_rxeof(struct bwn_pio_rxqueue *);
239 static void bwn_pio_handle_txeof(struct bwn_mac *,
240 const struct bwn_txstatus *);
241 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t);
242 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t);
243 static void bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t,
245 static void bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t,
247 static int bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *,
249 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t);
250 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *,
251 struct bwn_pio_txqueue *, uint32_t, const void *, int);
252 static void bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *,
254 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *,
255 struct bwn_pio_txqueue *, uint16_t, const void *, int);
256 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *,
257 struct bwn_pio_txqueue *, uint16_t, struct mbuf *);
258 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *,
259 uint16_t, struct bwn_pio_txpkt **);
260 static void bwn_dma_init(struct bwn_mac *);
261 static void bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t);
262 static int bwn_dma_mask2type(uint64_t);
263 static uint64_t bwn_dma_mask(struct bwn_mac *);
264 static uint16_t bwn_dma_base(int, int);
265 static void bwn_dma_ringfree(struct bwn_dma_ring **);
266 static void bwn_dma_32_getdesc(struct bwn_dma_ring *,
267 int, struct bwn_dmadesc_generic **,
268 struct bwn_dmadesc_meta **);
269 static void bwn_dma_32_setdesc(struct bwn_dma_ring *,
270 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
272 static void bwn_dma_32_start_transfer(struct bwn_dma_ring *, int);
273 static void bwn_dma_32_suspend(struct bwn_dma_ring *);
274 static void bwn_dma_32_resume(struct bwn_dma_ring *);
275 static int bwn_dma_32_get_curslot(struct bwn_dma_ring *);
276 static void bwn_dma_32_set_curslot(struct bwn_dma_ring *, int);
277 static void bwn_dma_64_getdesc(struct bwn_dma_ring *,
278 int, struct bwn_dmadesc_generic **,
279 struct bwn_dmadesc_meta **);
280 static void bwn_dma_64_setdesc(struct bwn_dma_ring *,
281 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
283 static void bwn_dma_64_start_transfer(struct bwn_dma_ring *, int);
284 static void bwn_dma_64_suspend(struct bwn_dma_ring *);
285 static void bwn_dma_64_resume(struct bwn_dma_ring *);
286 static int bwn_dma_64_get_curslot(struct bwn_dma_ring *);
287 static void bwn_dma_64_set_curslot(struct bwn_dma_ring *, int);
288 static int bwn_dma_allocringmemory(struct bwn_dma_ring *);
289 static void bwn_dma_setup(struct bwn_dma_ring *);
290 static void bwn_dma_free_ringmemory(struct bwn_dma_ring *);
291 static void bwn_dma_cleanup(struct bwn_dma_ring *);
292 static void bwn_dma_free_descbufs(struct bwn_dma_ring *);
293 static int bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int);
294 static void bwn_dma_rx(struct bwn_dma_ring *);
295 static int bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int);
296 static void bwn_dma_free_descbuf(struct bwn_dma_ring *,
297 struct bwn_dmadesc_meta *);
298 static void bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *);
299 static int bwn_dma_gettype(struct bwn_mac *);
300 static void bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int);
301 static int bwn_dma_freeslot(struct bwn_dma_ring *);
302 static int bwn_dma_nextslot(struct bwn_dma_ring *, int);
303 static void bwn_dma_rxeof(struct bwn_dma_ring *, int *);
304 static int bwn_dma_newbuf(struct bwn_dma_ring *,
305 struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *,
307 static void bwn_dma_buf_addr(void *, bus_dma_segment_t *, int,
309 static uint8_t bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *);
310 static void bwn_dma_handle_txeof(struct bwn_mac *,
311 const struct bwn_txstatus *);
312 static int bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *,
314 static int bwn_dma_getslot(struct bwn_dma_ring *);
315 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *,
317 static int bwn_dma_attach(struct bwn_mac *);
318 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *,
320 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *,
321 const struct bwn_txstatus *, uint16_t, int *);
322 static void bwn_dma_free(struct bwn_mac *);
323 static void bwn_phy_g_init_sub(struct bwn_mac *);
324 static uint8_t bwn_has_hwpctl(struct bwn_mac *);
325 static void bwn_phy_init_b5(struct bwn_mac *);
326 static void bwn_phy_init_b6(struct bwn_mac *);
327 static void bwn_phy_init_a(struct bwn_mac *);
328 static void bwn_loopback_calcgain(struct bwn_mac *);
329 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *);
330 static void bwn_lo_g_init(struct bwn_mac *);
331 static void bwn_lo_g_adjust(struct bwn_mac *);
332 static void bwn_lo_get_powervector(struct bwn_mac *);
333 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *,
334 const struct bwn_bbatt *, const struct bwn_rfatt *);
335 static void bwn_lo_write(struct bwn_mac *, struct bwn_loctl *);
336 static void bwn_phy_hwpctl_init(struct bwn_mac *);
337 static void bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t);
338 static void bwn_phy_g_set_txpwr_sub(struct bwn_mac *,
339 const struct bwn_bbatt *, const struct bwn_rfatt *,
341 static void bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t);
342 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t);
343 static void bwn_spu_workaround(struct bwn_mac *, uint8_t);
344 static void bwn_wa_init(struct bwn_mac *);
345 static void bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t,
347 static void bwn_dummy_transmission(struct bwn_mac *, int, int);
348 static void bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t,
350 static void bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t,
352 static void bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t);
353 static void bwn_mac_suspend(struct bwn_mac *);
354 static void bwn_mac_enable(struct bwn_mac *);
355 static void bwn_psctl(struct bwn_mac *, uint32_t);
356 static int16_t bwn_nrssi_read(struct bwn_mac *, uint16_t);
357 static void bwn_nrssi_offset(struct bwn_mac *);
358 static void bwn_nrssi_threshold(struct bwn_mac *);
359 static void bwn_nrssi_slope_11g(struct bwn_mac *);
360 static void bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t,
362 static void bwn_set_original_gains(struct bwn_mac *);
363 static void bwn_hwpctl_early_init(struct bwn_mac *);
364 static void bwn_hwpctl_init_gphy(struct bwn_mac *);
365 static uint16_t bwn_phy_g_chan2freq(uint8_t);
366 static int bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype);
367 static int bwn_fw_get(struct bwn_mac *, enum bwn_fwtype,
368 const char *, struct bwn_fwfile *);
369 static void bwn_release_firmware(struct bwn_mac *);
370 static void bwn_do_release_fw(struct bwn_fwfile *);
371 static uint16_t bwn_fwcaps_read(struct bwn_mac *);
372 static int bwn_fwinitvals_write(struct bwn_mac *,
373 const struct bwn_fwinitvals *, size_t, size_t);
374 static int bwn_switch_channel(struct bwn_mac *, int);
375 static uint16_t bwn_ant2phy(int);
376 static void bwn_mac_write_bssid(struct bwn_mac *);
377 static void bwn_mac_setfilter(struct bwn_mac *, uint16_t,
379 static void bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t,
380 const uint8_t *, size_t, const uint8_t *);
381 static void bwn_key_macwrite(struct bwn_mac *, uint8_t,
383 static void bwn_key_write(struct bwn_mac *, uint8_t, uint8_t,
385 static void bwn_phy_exit(struct bwn_mac *);
386 static void bwn_core_stop(struct bwn_mac *);
387 static int bwn_switch_band(struct bwn_softc *,
388 struct ieee80211_channel *);
389 static void bwn_phy_reset(struct bwn_mac *);
390 static int bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
391 static void bwn_set_pretbtt(struct bwn_mac *);
392 static int bwn_intr(void *);
393 static void bwn_intrtask(void *, int);
394 static void bwn_restart(struct bwn_mac *, const char *);
395 static void bwn_intr_ucode_debug(struct bwn_mac *);
396 static void bwn_intr_tbtt_indication(struct bwn_mac *);
397 static void bwn_intr_atim_end(struct bwn_mac *);
398 static void bwn_intr_beacon(struct bwn_mac *);
399 static void bwn_intr_pmq(struct bwn_mac *);
400 static void bwn_intr_noise(struct bwn_mac *);
401 static void bwn_intr_txeof(struct bwn_mac *);
402 static void bwn_hwreset(void *, int);
403 static void bwn_handle_fwpanic(struct bwn_mac *);
404 static void bwn_load_beacon0(struct bwn_mac *);
405 static void bwn_load_beacon1(struct bwn_mac *);
406 static uint32_t bwn_jssi_read(struct bwn_mac *);
407 static void bwn_noise_gensample(struct bwn_mac *);
408 static void bwn_handle_txeof(struct bwn_mac *,
409 const struct bwn_txstatus *);
410 static void bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *);
411 static void bwn_phy_txpower_check(struct bwn_mac *, uint32_t);
412 static void bwn_start_locked(struct ifnet *);
413 static int bwn_tx_start(struct bwn_softc *, struct ieee80211_node *,
415 static int bwn_tx_isfull(struct bwn_softc *, struct mbuf *);
416 static int bwn_set_txhdr(struct bwn_mac *,
417 struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *,
419 static void bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t,
421 static uint8_t bwn_antenna_sanitize(struct bwn_mac *, uint8_t);
422 static uint8_t bwn_get_fbrate(uint8_t);
423 static int bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t);
424 static void bwn_phy_g_setatt(struct bwn_mac *, int *, int *);
425 static void bwn_phy_lock(struct bwn_mac *);
426 static void bwn_phy_unlock(struct bwn_mac *);
427 static void bwn_rf_lock(struct bwn_mac *);
428 static void bwn_rf_unlock(struct bwn_mac *);
429 static void bwn_txpwr(void *, int);
430 static void bwn_tasks(void *);
431 static void bwn_task_15s(struct bwn_mac *);
432 static void bwn_task_30s(struct bwn_mac *);
433 static void bwn_task_60s(struct bwn_mac *);
434 static int bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *,
436 static int bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *);
437 static void bwn_rx_radiotap(struct bwn_mac *, struct mbuf *,
438 const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int,
440 static void bwn_tsf_read(struct bwn_mac *, uint64_t *);
441 static void bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t);
442 static void bwn_set_slot_time(struct bwn_mac *, uint16_t);
443 static void bwn_watchdog(void *);
444 static void bwn_dma_stop(struct bwn_mac *);
445 static void bwn_pio_stop(struct bwn_mac *);
446 static void bwn_dma_ringstop(struct bwn_dma_ring **);
447 static void bwn_led_attach(struct bwn_mac *);
448 static void bwn_led_newstate(struct bwn_mac *, enum ieee80211_state);
449 static void bwn_led_event(struct bwn_mac *, int);
450 static void bwn_led_blink_start(struct bwn_mac *, int, int);
451 static void bwn_led_blink_next(void *);
452 static void bwn_led_blink_end(void *);
453 static void bwn_rfswitch(void *);
454 static void bwn_rf_turnon(struct bwn_mac *);
455 static void bwn_rf_turnoff(struct bwn_mac *);
456 static void bwn_phy_lp_init_pre(struct bwn_mac *);
457 static int bwn_phy_lp_init(struct bwn_mac *);
458 static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t);
459 static void bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t);
460 static void bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t,
462 static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t);
463 static void bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t);
464 static void bwn_phy_lp_rf_onoff(struct bwn_mac *, int);
465 static int bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t);
466 static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *);
467 static void bwn_phy_lp_set_antenna(struct bwn_mac *, int);
468 static void bwn_phy_lp_task_60s(struct bwn_mac *);
469 static void bwn_phy_lp_readsprom(struct bwn_mac *);
470 static void bwn_phy_lp_bbinit(struct bwn_mac *);
471 static void bwn_phy_lp_txpctl_init(struct bwn_mac *);
472 static void bwn_phy_lp_calib(struct bwn_mac *);
473 static void bwn_phy_lp_switch_analog(struct bwn_mac *, int);
474 static int bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t);
475 static int bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t);
476 static void bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t);
477 static void bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t);
478 static void bwn_phy_lp_digflt_save(struct bwn_mac *);
479 static void bwn_phy_lp_get_txpctlmode(struct bwn_mac *);
480 static void bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t);
481 static void bwn_phy_lp_bugfix(struct bwn_mac *);
482 static void bwn_phy_lp_digflt_restore(struct bwn_mac *);
483 static void bwn_phy_lp_tblinit(struct bwn_mac *);
484 static void bwn_phy_lp_bbinit_r2(struct bwn_mac *);
485 static void bwn_phy_lp_bbinit_r01(struct bwn_mac *);
486 static void bwn_phy_lp_b2062_init(struct bwn_mac *);
487 static void bwn_phy_lp_b2063_init(struct bwn_mac *);
488 static void bwn_phy_lp_rxcal_r2(struct bwn_mac *);
489 static void bwn_phy_lp_rccal_r12(struct bwn_mac *);
490 static void bwn_phy_lp_set_rccap(struct bwn_mac *);
491 static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t);
492 static void bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *);
493 static void bwn_phy_lp_b2062_vco_calib(struct bwn_mac *);
494 static void bwn_tab_write_multi(struct bwn_mac *, uint32_t, int,
496 static void bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *);
497 static struct bwn_txgain
498 bwn_phy_lp_get_txgain(struct bwn_mac *);
499 static uint8_t bwn_phy_lp_get_bbmult(struct bwn_mac *);
500 static void bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *);
501 static void bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t);
502 static void bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t);
503 static void bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t);
504 static void bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t);
505 static int bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t);
506 static void bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t);
507 static void bwn_phy_lp_tblinit_r01(struct bwn_mac *);
508 static void bwn_phy_lp_tblinit_r2(struct bwn_mac *);
509 static void bwn_phy_lp_tblinit_txgain(struct bwn_mac *);
510 static void bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t);
511 static void bwn_phy_lp_b2062_tblinit(struct bwn_mac *);
512 static void bwn_phy_lp_b2063_tblinit(struct bwn_mac *);
513 static int bwn_phy_lp_loopback(struct bwn_mac *);
514 static void bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t);
515 static void bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int,
517 static uint8_t bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t,
518 struct bwn_phy_lp_iq_est *);
519 static void bwn_phy_lp_ddfs_turnoff(struct bwn_mac *);
520 static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t);
521 static void bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t);
522 static void bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t);
523 static void bwn_phy_lp_set_txgain_override(struct bwn_mac *);
524 static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *);
525 static uint8_t bwn_nbits(int32_t);
526 static void bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int,
527 struct bwn_txgain_entry *);
528 static void bwn_phy_lp_gaintbl_write(struct bwn_mac *, int,
529 struct bwn_txgain_entry);
530 static void bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int,
531 struct bwn_txgain_entry);
532 static void bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int,
533 struct bwn_txgain_entry);
534 static void bwn_sysctl_node(struct bwn_softc *);
536 static struct resource_spec bwn_res_spec_legacy[] = {
537 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE },
541 static struct resource_spec bwn_res_spec_msi[] = {
542 { SYS_RES_IRQ, 1, RF_ACTIVE },
546 static const struct bwn_channelinfo bwn_chantable_bg = {
548 { 2412, 1, 30 }, { 2417, 2, 30 }, { 2422, 3, 30 },
549 { 2427, 4, 30 }, { 2432, 5, 30 }, { 2437, 6, 30 },
550 { 2442, 7, 30 }, { 2447, 8, 30 }, { 2452, 9, 30 },
551 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 },
552 { 2472, 13, 30 }, { 2484, 14, 30 } },
556 static const struct bwn_channelinfo bwn_chantable_a = {
558 { 5170, 34, 30 }, { 5180, 36, 30 }, { 5190, 38, 30 },
559 { 5200, 40, 30 }, { 5210, 42, 30 }, { 5220, 44, 30 },
560 { 5230, 46, 30 }, { 5240, 48, 30 }, { 5260, 52, 30 },
561 { 5280, 56, 30 }, { 5300, 60, 30 }, { 5320, 64, 30 },
562 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 },
563 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 },
564 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 },
565 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 },
566 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 },
567 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 },
568 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 },
569 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 },
574 static const struct bwn_channelinfo bwn_chantable_n = {
576 { 5160, 32, 30 }, { 5170, 34, 30 }, { 5180, 36, 30 },
577 { 5190, 38, 30 }, { 5200, 40, 30 }, { 5210, 42, 30 },
578 { 5220, 44, 30 }, { 5230, 46, 30 }, { 5240, 48, 30 },
579 { 5250, 50, 30 }, { 5260, 52, 30 }, { 5270, 54, 30 },
580 { 5280, 56, 30 }, { 5290, 58, 30 }, { 5300, 60, 30 },
581 { 5310, 62, 30 }, { 5320, 64, 30 }, { 5330, 66, 30 },
582 { 5340, 68, 30 }, { 5350, 70, 30 }, { 5360, 72, 30 },
583 { 5370, 74, 30 }, { 5380, 76, 30 }, { 5390, 78, 30 },
584 { 5400, 80, 30 }, { 5410, 82, 30 }, { 5420, 84, 30 },
585 { 5430, 86, 30 }, { 5440, 88, 30 }, { 5450, 90, 30 },
586 { 5460, 92, 30 }, { 5470, 94, 30 }, { 5480, 96, 30 },
587 { 5490, 98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 },
588 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 },
589 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 },
590 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 },
591 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 },
592 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 },
593 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 },
594 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 },
595 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 },
596 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 },
597 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 },
598 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 },
599 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 },
600 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 },
601 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 },
602 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 },
603 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 },
604 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 },
605 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 },
606 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 },
607 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 },
608 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
609 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
610 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
611 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
612 { 6130, 226, 30 }, { 6140, 228, 30 } },
616 static const uint8_t bwn_b2063_chantable_data[33][12] = {
617 { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
618 { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
619 { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
620 { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
621 { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
622 { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 },
623 { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 },
624 { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 },
625 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 },
626 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 },
627 { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 },
628 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 },
629 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 },
630 { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 },
631 { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
632 { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
633 { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 },
634 { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 },
635 { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 },
636 { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
637 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
638 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
639 { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
640 { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
641 { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 },
642 { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
643 { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
644 { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
645 { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
646 { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
647 { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
648 { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
649 { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }
652 static const struct bwn_b206x_chan bwn_b2063_chantable[] = {
653 { 1, 2412, bwn_b2063_chantable_data[0] },
654 { 2, 2417, bwn_b2063_chantable_data[0] },
655 { 3, 2422, bwn_b2063_chantable_data[0] },
656 { 4, 2427, bwn_b2063_chantable_data[1] },
657 { 5, 2432, bwn_b2063_chantable_data[1] },
658 { 6, 2437, bwn_b2063_chantable_data[1] },
659 { 7, 2442, bwn_b2063_chantable_data[1] },
660 { 8, 2447, bwn_b2063_chantable_data[1] },
661 { 9, 2452, bwn_b2063_chantable_data[2] },
662 { 10, 2457, bwn_b2063_chantable_data[2] },
663 { 11, 2462, bwn_b2063_chantable_data[3] },
664 { 12, 2467, bwn_b2063_chantable_data[3] },
665 { 13, 2472, bwn_b2063_chantable_data[3] },
666 { 14, 2484, bwn_b2063_chantable_data[4] },
667 { 34, 5170, bwn_b2063_chantable_data[5] },
668 { 36, 5180, bwn_b2063_chantable_data[6] },
669 { 38, 5190, bwn_b2063_chantable_data[7] },
670 { 40, 5200, bwn_b2063_chantable_data[8] },
671 { 42, 5210, bwn_b2063_chantable_data[9] },
672 { 44, 5220, bwn_b2063_chantable_data[10] },
673 { 46, 5230, bwn_b2063_chantable_data[11] },
674 { 48, 5240, bwn_b2063_chantable_data[12] },
675 { 52, 5260, bwn_b2063_chantable_data[13] },
676 { 56, 5280, bwn_b2063_chantable_data[14] },
677 { 60, 5300, bwn_b2063_chantable_data[14] },
678 { 64, 5320, bwn_b2063_chantable_data[15] },
679 { 100, 5500, bwn_b2063_chantable_data[16] },
680 { 104, 5520, bwn_b2063_chantable_data[17] },
681 { 108, 5540, bwn_b2063_chantable_data[18] },
682 { 112, 5560, bwn_b2063_chantable_data[19] },
683 { 116, 5580, bwn_b2063_chantable_data[20] },
684 { 120, 5600, bwn_b2063_chantable_data[21] },
685 { 124, 5620, bwn_b2063_chantable_data[21] },
686 { 128, 5640, bwn_b2063_chantable_data[22] },
687 { 132, 5660, bwn_b2063_chantable_data[22] },
688 { 136, 5680, bwn_b2063_chantable_data[22] },
689 { 140, 5700, bwn_b2063_chantable_data[23] },
690 { 149, 5745, bwn_b2063_chantable_data[23] },
691 { 153, 5765, bwn_b2063_chantable_data[23] },
692 { 157, 5785, bwn_b2063_chantable_data[23] },
693 { 161, 5805, bwn_b2063_chantable_data[23] },
694 { 165, 5825, bwn_b2063_chantable_data[23] },
695 { 184, 4920, bwn_b2063_chantable_data[24] },
696 { 188, 4940, bwn_b2063_chantable_data[25] },
697 { 192, 4960, bwn_b2063_chantable_data[26] },
698 { 196, 4980, bwn_b2063_chantable_data[27] },
699 { 200, 5000, bwn_b2063_chantable_data[28] },
700 { 204, 5020, bwn_b2063_chantable_data[29] },
701 { 208, 5040, bwn_b2063_chantable_data[30] },
702 { 212, 5060, bwn_b2063_chantable_data[31] },
703 { 216, 5080, bwn_b2063_chantable_data[32] }
706 static const uint8_t bwn_b2062_chantable_data[22][12] = {
707 { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 },
708 { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
709 { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
710 { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
711 { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
712 { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
713 { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
714 { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
715 { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
716 { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
717 { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
718 { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
719 { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
720 { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
721 { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
722 { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
723 { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
724 { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
725 { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
726 { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
727 { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
728 { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }
731 static const struct bwn_b206x_chan bwn_b2062_chantable[] = {
732 { 1, 2412, bwn_b2062_chantable_data[0] },
733 { 2, 2417, bwn_b2062_chantable_data[0] },
734 { 3, 2422, bwn_b2062_chantable_data[0] },
735 { 4, 2427, bwn_b2062_chantable_data[0] },
736 { 5, 2432, bwn_b2062_chantable_data[0] },
737 { 6, 2437, bwn_b2062_chantable_data[0] },
738 { 7, 2442, bwn_b2062_chantable_data[0] },
739 { 8, 2447, bwn_b2062_chantable_data[0] },
740 { 9, 2452, bwn_b2062_chantable_data[0] },
741 { 10, 2457, bwn_b2062_chantable_data[0] },
742 { 11, 2462, bwn_b2062_chantable_data[0] },
743 { 12, 2467, bwn_b2062_chantable_data[0] },
744 { 13, 2472, bwn_b2062_chantable_data[0] },
745 { 14, 2484, bwn_b2062_chantable_data[0] },
746 { 34, 5170, bwn_b2062_chantable_data[1] },
747 { 38, 5190, bwn_b2062_chantable_data[2] },
748 { 42, 5210, bwn_b2062_chantable_data[2] },
749 { 46, 5230, bwn_b2062_chantable_data[3] },
750 { 36, 5180, bwn_b2062_chantable_data[4] },
751 { 40, 5200, bwn_b2062_chantable_data[5] },
752 { 44, 5220, bwn_b2062_chantable_data[6] },
753 { 48, 5240, bwn_b2062_chantable_data[3] },
754 { 52, 5260, bwn_b2062_chantable_data[3] },
755 { 56, 5280, bwn_b2062_chantable_data[3] },
756 { 60, 5300, bwn_b2062_chantable_data[7] },
757 { 64, 5320, bwn_b2062_chantable_data[8] },
758 { 100, 5500, bwn_b2062_chantable_data[9] },
759 { 104, 5520, bwn_b2062_chantable_data[10] },
760 { 108, 5540, bwn_b2062_chantable_data[10] },
761 { 112, 5560, bwn_b2062_chantable_data[10] },
762 { 116, 5580, bwn_b2062_chantable_data[11] },
763 { 120, 5600, bwn_b2062_chantable_data[12] },
764 { 124, 5620, bwn_b2062_chantable_data[12] },
765 { 128, 5640, bwn_b2062_chantable_data[12] },
766 { 132, 5660, bwn_b2062_chantable_data[12] },
767 { 136, 5680, bwn_b2062_chantable_data[12] },
768 { 140, 5700, bwn_b2062_chantable_data[12] },
769 { 149, 5745, bwn_b2062_chantable_data[12] },
770 { 153, 5765, bwn_b2062_chantable_data[12] },
771 { 157, 5785, bwn_b2062_chantable_data[12] },
772 { 161, 5805, bwn_b2062_chantable_data[12] },
773 { 165, 5825, bwn_b2062_chantable_data[12] },
774 { 184, 4920, bwn_b2062_chantable_data[13] },
775 { 188, 4940, bwn_b2062_chantable_data[14] },
776 { 192, 4960, bwn_b2062_chantable_data[15] },
777 { 196, 4980, bwn_b2062_chantable_data[16] },
778 { 200, 5000, bwn_b2062_chantable_data[17] },
779 { 204, 5020, bwn_b2062_chantable_data[18] },
780 { 208, 5040, bwn_b2062_chantable_data[19] },
781 { 212, 5060, bwn_b2062_chantable_data[20] },
782 { 216, 5080, bwn_b2062_chantable_data[21] }
786 static const struct bwn_rxcompco bwn_rxcompco_5354[] = {
787 { 1, -66, 15 }, { 2, -66, 15 }, { 3, -66, 15 }, { 4, -66, 15 },
788 { 5, -66, 15 }, { 6, -66, 15 }, { 7, -66, 14 }, { 8, -66, 14 },
789 { 9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 },
790 { 13, -66, 13 }, { 14, -66, 13 },
794 static const struct bwn_rxcompco bwn_rxcompco_r12[] = {
795 { 1, -64, 13 }, { 2, -64, 13 }, { 3, -64, 13 }, { 4, -64, 13 },
796 { 5, -64, 12 }, { 6, -64, 12 }, { 7, -64, 12 }, { 8, -64, 12 },
797 { 9, -64, 12 }, { 10, -64, 11 }, { 11, -64, 11 }, { 12, -64, 11 },
798 { 13, -64, 11 }, { 14, -64, 10 }, { 34, -62, 24 }, { 38, -62, 24 },
799 { 42, -62, 24 }, { 46, -62, 23 }, { 36, -62, 24 }, { 40, -62, 24 },
800 { 44, -62, 23 }, { 48, -62, 23 }, { 52, -62, 23 }, { 56, -62, 22 },
801 { 60, -62, 22 }, { 64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 },
802 { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 },
803 { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 },
804 { 140, -62, 10 }, { 149, -61, 9 }, { 153, -61, 9 }, { 157, -61, 9 },
805 { 161, -61, 8 }, { 165, -61, 8 }, { 184, -62, 25 }, { 188, -62, 25 },
806 { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 },
807 { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 },
810 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 };
812 static const uint8_t bwn_tab_sigsq_tbl[] = {
813 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd,
814 0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
815 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00,
816 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
817 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
818 0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
821 static const uint8_t bwn_tab_pllfrac_tbl[] = {
822 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80,
823 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
826 static const uint16_t bwn_tabl_iqlocal_tbl[] = {
827 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002,
828 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
829 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
830 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
831 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006,
832 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
833 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
834 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
835 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
836 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
837 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
838 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
841 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
842 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
843 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
844 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
845 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
846 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
848 #define VENDOR_LED_ACT(vendor) \
850 .vid = PCI_VENDOR_##vendor, \
851 .led_act = { BWN_VENDOR_LED_ACT_##vendor } \
854 static const struct {
856 uint8_t led_act[BWN_LED_MAX];
857 } bwn_vendor_led_act[] = {
858 VENDOR_LED_ACT(COMPAQ),
859 VENDOR_LED_ACT(ASUSTEK)
862 static const uint8_t bwn_default_led_act[BWN_LED_MAX] =
863 { BWN_VENDOR_LED_ACT_DEFAULT };
865 #undef VENDOR_LED_ACT
867 static const struct {
870 } bwn_led_duration[109] = {
886 static const uint16_t bwn_wme_shm_offsets[] = {
887 [0] = BWN_WME_BESTEFFORT,
888 [1] = BWN_WME_BACKGROUND,
893 static const struct siba_devid bwn_devs[] = {
894 SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"),
895 SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"),
896 SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"),
897 SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"),
898 SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"),
899 SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"),
900 SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"),
901 SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"),
902 SIBA_DEV(BROADCOM, 80211, 16, "Revision 16")
906 bwn_probe(device_t dev)
910 for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) {
911 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor &&
912 siba_get_device(dev) == bwn_devs[i].sd_device &&
913 siba_get_revid(dev) == bwn_devs[i].sd_rev)
914 return (BUS_PROBE_DEFAULT);
921 bwn_attach(device_t dev)
924 struct bwn_softc *sc = device_get_softc(dev);
925 int error, i, msic, reg;
929 sc->sc_debug = bwn_debug;
932 if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
933 error = bwn_attach_pre(sc);
936 bwn_sprom_bugfixes(dev);
937 sc->sc_flags |= BWN_FLAG_ATTACHED;
940 if (!TAILQ_EMPTY(&sc->sc_maclist)) {
941 if (siba_get_pci_device(dev) != 0x4313 &&
942 siba_get_pci_device(dev) != 0x431a &&
943 siba_get_pci_device(dev) != 0x4321) {
944 device_printf(sc->sc_dev,
945 "skip 802.11 cores\n");
950 mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF,
955 mac->mac_status = BWN_MAC_STATUS_UNINIT;
957 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
959 TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac);
960 TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac);
961 TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac);
963 error = bwn_attach_core(mac);
968 device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) "
969 "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
970 siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev),
971 mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev,
972 mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver,
973 mac->mac_phy.rf_rev);
974 if (mac->mac_flags & BWN_MAC_FLAG_DMA)
975 device_printf(sc->sc_dev, "DMA (%d bits)\n",
976 mac->mac_method.dma.dmatype);
978 device_printf(sc->sc_dev, "PIO\n");
981 * setup PCI resources and interrupt.
983 if (pci_find_cap(dev, PCIY_EXPRESS, ®) == 0) {
984 msic = pci_msi_count(dev);
986 device_printf(sc->sc_dev, "MSI count : %d\n", msic);
990 mac->mac_intr_spec = bwn_res_spec_legacy;
991 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) {
992 if (pci_alloc_msi(dev, &msic) == 0) {
993 device_printf(sc->sc_dev,
994 "Using %d MSI messages\n", msic);
995 mac->mac_intr_spec = bwn_res_spec_msi;
1000 error = bus_alloc_resources(dev, mac->mac_intr_spec,
1003 device_printf(sc->sc_dev,
1004 "couldn't allocate IRQ resources (%d)\n", error);
1008 if (mac->mac_msi == 0)
1009 error = bus_setup_intr(dev, mac->mac_res_irq[0],
1010 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1011 &mac->mac_intrhand[0]);
1013 for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1014 error = bus_setup_intr(dev, mac->mac_res_irq[i],
1015 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1016 &mac->mac_intrhand[i]);
1018 device_printf(sc->sc_dev,
1019 "couldn't setup interrupt (%d)\n", error);
1025 TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list);
1028 * calls attach-post routine
1030 if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0)
1031 bwn_attach_post(sc);
1035 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0)
1036 pci_release_msi(dev);
1038 free(mac, M_DEVBUF);
1043 bwn_is_valid_ether_addr(uint8_t *addr)
1045 char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
1047 if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN)))
1054 bwn_attach_post(struct bwn_softc *sc)
1056 struct ieee80211com *ic;
1057 struct ifnet *ifp = sc->sc_ifp;
1062 ic->ic_name = device_get_nameunit(sc->sc_dev);
1063 /* XXX not right but it's not used anywhere important */
1064 ic->ic_phytype = IEEE80211_T_OFDM;
1065 ic->ic_opmode = IEEE80211_M_STA;
1067 IEEE80211_C_STA /* station mode supported */
1068 | IEEE80211_C_MONITOR /* monitor mode */
1069 | IEEE80211_C_AHDEMO /* adhoc demo mode */
1070 | IEEE80211_C_SHPREAMBLE /* short preamble supported */
1071 | IEEE80211_C_SHSLOT /* short slot time supported */
1072 | IEEE80211_C_WME /* WME/WMM supported */
1073 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */
1074 | IEEE80211_C_BGSCAN /* capable of bg scanning */
1075 | IEEE80211_C_TXPMGT /* capable of txpow mgt */
1078 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */
1080 /* call MI attach routine. */
1081 ieee80211_ifattach(ic,
1082 bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
1083 siba_sprom_get_mac_80211a(sc->sc_dev) :
1084 siba_sprom_get_mac_80211bg(sc->sc_dev));
1086 ic->ic_headroom = sizeof(struct bwn_txhdr);
1088 /* override default methods */
1089 ic->ic_raw_xmit = bwn_raw_xmit;
1090 ic->ic_updateslot = bwn_updateslot;
1091 ic->ic_update_promisc = bwn_update_promisc;
1092 ic->ic_wme.wme_update = bwn_wme_update;
1094 ic->ic_scan_start = bwn_scan_start;
1095 ic->ic_scan_end = bwn_scan_end;
1096 ic->ic_set_channel = bwn_set_channel;
1098 ic->ic_vap_create = bwn_vap_create;
1099 ic->ic_vap_delete = bwn_vap_delete;
1101 ieee80211_radiotap_attach(ic,
1102 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
1103 BWN_TX_RADIOTAP_PRESENT,
1104 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
1105 BWN_RX_RADIOTAP_PRESENT);
1107 bwn_sysctl_node(sc);
1110 ieee80211_announce(ic);
1115 bwn_phy_detach(struct bwn_mac *mac)
1118 if (mac->mac_phy.detach != NULL)
1119 mac->mac_phy.detach(mac);
1123 bwn_detach(device_t dev)
1125 struct bwn_softc *sc = device_get_softc(dev);
1126 struct bwn_mac *mac = sc->sc_curmac;
1127 struct ifnet *ifp = sc->sc_ifp;
1128 struct ieee80211com *ic = ifp->if_l2com;
1131 sc->sc_flags |= BWN_FLAG_INVALID;
1133 if (device_is_attached(sc->sc_dev)) {
1136 callout_drain(&sc->sc_led_blink_ch);
1137 callout_drain(&sc->sc_rfswitch_ch);
1138 callout_drain(&sc->sc_task_ch);
1139 callout_drain(&sc->sc_watchdog_ch);
1140 bwn_phy_detach(mac);
1142 ieee80211_draintask(ic, &mac->mac_hwreset);
1143 ieee80211_draintask(ic, &mac->mac_txpower);
1144 ieee80211_ifdetach(ic);
1148 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
1149 taskqueue_free(sc->sc_tq);
1151 for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1152 if (mac->mac_intrhand[i] != NULL) {
1153 bus_teardown_intr(dev, mac->mac_res_irq[i],
1154 mac->mac_intrhand[i]);
1155 mac->mac_intrhand[i] = NULL;
1158 bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq);
1159 if (mac->mac_msi != 0)
1160 pci_release_msi(dev);
1162 BWN_LOCK_DESTROY(sc);
1167 bwn_attach_pre(struct bwn_softc *sc)
1173 TAILQ_INIT(&sc->sc_maclist);
1174 callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0);
1175 callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0);
1176 callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0);
1178 sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT,
1179 taskqueue_thread_enqueue, &sc->sc_tq);
1180 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
1181 "%s taskq", device_get_nameunit(sc->sc_dev));
1183 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
1185 device_printf(sc->sc_dev, "can not if_alloc()\n");
1190 /* set these up early for if_printf use */
1191 if_initname(ifp, device_get_name(sc->sc_dev),
1192 device_get_unit(sc->sc_dev));
1195 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1196 ifp->if_init = bwn_init;
1197 ifp->if_ioctl = bwn_ioctl;
1198 ifp->if_start = bwn_start;
1199 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
1200 ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
1201 IFQ_SET_READY(&ifp->if_snd);
1205 fail: BWN_LOCK_DESTROY(sc);
1210 bwn_sprom_bugfixes(device_t dev)
1212 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \
1213 ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \
1214 (siba_get_pci_device(dev) == _device) && \
1215 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \
1216 (siba_get_pci_subdevice(dev) == _subdevice))
1218 if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
1219 siba_get_pci_subdevice(dev) == 0x4e &&
1220 siba_get_pci_revid(dev) > 0x40)
1221 siba_sprom_set_bf_lo(dev,
1222 siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
1223 if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
1224 siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
1225 siba_sprom_set_bf_lo(dev,
1226 siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
1227 if (siba_get_type(dev) == SIBA_TYPE_PCI) {
1228 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1229 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1230 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1231 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1232 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1233 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1234 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1235 siba_sprom_set_bf_lo(dev,
1236 siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
1242 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1244 #define IS_RUNNING(ifp) \
1245 ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
1246 struct bwn_softc *sc = ifp->if_softc;
1247 struct ieee80211com *ic = ifp->if_l2com;
1248 struct ifreq *ifr = (struct ifreq *)data;
1249 int error = 0, startall;
1254 if (IS_RUNNING(ifp)) {
1255 bwn_update_promisc(ic);
1256 } else if (ifp->if_flags & IFF_UP) {
1257 if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
1264 ieee80211_start_all(ic);
1267 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1270 error = ether_ioctl(ifp, cmd, data);
1280 bwn_start(struct ifnet *ifp)
1282 struct bwn_softc *sc = ifp->if_softc;
1285 bwn_start_locked(ifp);
1290 bwn_start_locked(struct ifnet *ifp)
1292 struct bwn_softc *sc = ifp->if_softc;
1293 struct bwn_mac *mac = sc->sc_curmac;
1294 struct ieee80211_frame *wh;
1295 struct ieee80211_node *ni;
1296 struct ieee80211_key *k;
1299 BWN_ASSERT_LOCKED(sc);
1301 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL ||
1302 mac->mac_status < BWN_MAC_STATUS_STARTED)
1306 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */
1310 if (bwn_tx_isfull(sc, m))
1312 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1314 device_printf(sc->sc_dev, "unexpected NULL ni\n");
1316 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
1319 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
1320 wh = mtod(m, struct ieee80211_frame *);
1321 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1322 k = ieee80211_crypto_encap(ni, m);
1324 ieee80211_free_node(ni);
1326 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
1330 wh = NULL; /* Catch any invalid use */
1332 if (bwn_tx_start(sc, ni, m) != 0) {
1334 ieee80211_free_node(ni);
1335 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
1339 sc->sc_watchdog_timer = 5;
1344 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1346 struct bwn_dma_ring *dr;
1347 struct bwn_mac *mac = sc->sc_curmac;
1348 struct bwn_pio_txqueue *tq;
1349 struct ifnet *ifp = sc->sc_ifp;
1350 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1352 BWN_ASSERT_LOCKED(sc);
1354 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1355 dr = bwn_dma_select(mac, M_WME_GETAC(m));
1356 if (dr->dr_stop == 1 ||
1357 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1362 tq = bwn_pio_select(mac, M_WME_GETAC(m));
1363 if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1364 pktlen > (tq->tq_size - tq->tq_used)) {
1371 IFQ_DRV_PREPEND(&ifp->if_snd, m);
1372 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1377 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1379 struct bwn_mac *mac = sc->sc_curmac;
1382 BWN_ASSERT_LOCKED(sc);
1384 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1389 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1390 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1399 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1401 struct bwn_pio_txpkt *tp;
1402 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1403 struct bwn_softc *sc = mac->mac_sc;
1404 struct bwn_txhdr txhdr;
1410 BWN_ASSERT_LOCKED(sc);
1412 /* XXX TODO send packets after DTIM */
1414 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1415 tp = TAILQ_FIRST(&tq->tq_pktlist);
1419 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1421 device_printf(sc->sc_dev, "tx fail\n");
1425 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1426 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1429 if (siba_get_revid(sc->sc_dev) >= 8) {
1431 * XXX please removes m_defrag(9)
1433 m_new = m_defrag(m, M_NOWAIT);
1434 if (m_new == NULL) {
1435 device_printf(sc->sc_dev,
1436 "%s: can't defrag TX buffer\n",
1440 if (m_new->m_next != NULL)
1441 device_printf(sc->sc_dev,
1442 "TODO: fragmented packets for PIO\n");
1446 ctl32 = bwn_pio_write_multi_4(mac, tq,
1447 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1448 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1449 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1451 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1452 mtod(m_new, const void *), m_new->m_pkthdr.len);
1453 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1454 ctl32 | BWN_PIO8_TXCTL_EOF);
1456 ctl16 = bwn_pio_write_multi_2(mac, tq,
1457 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1458 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1459 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1460 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1461 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1462 ctl16 | BWN_PIO_TXCTL_EOF);
1468 static struct bwn_pio_txqueue *
1469 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1472 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1473 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1477 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1479 return (&mac->mac_method.pio.wme[WME_AC_BK]);
1481 return (&mac->mac_method.pio.wme[WME_AC_VI]);
1483 return (&mac->mac_method.pio.wme[WME_AC_VO]);
1485 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1490 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1492 #define BWN_GET_TXHDRCACHE(slot) \
1493 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)])
1494 struct bwn_dma *dma = &mac->mac_method.dma;
1495 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1496 struct bwn_dmadesc_generic *desc;
1497 struct bwn_dmadesc_meta *mt;
1498 struct bwn_softc *sc = mac->mac_sc;
1499 struct ifnet *ifp = sc->sc_ifp;
1500 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1501 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1503 BWN_ASSERT_LOCKED(sc);
1504 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1506 /* XXX send after DTIM */
1508 slot = bwn_dma_getslot(dr);
1509 dr->getdesc(dr, slot, &desc, &mt);
1510 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1511 ("%s:%d: fail", __func__, __LINE__));
1513 error = bwn_set_txhdr(dr->dr_mac, ni, m,
1514 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1515 BWN_DMA_COOKIE(dr, slot));
1518 error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap,
1519 BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr,
1520 &mt->mt_paddr, BUS_DMA_NOWAIT);
1522 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1526 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1527 BUS_DMASYNC_PREWRITE);
1528 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1529 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1530 BUS_DMASYNC_PREWRITE);
1532 slot = bwn_dma_getslot(dr);
1533 dr->getdesc(dr, slot, &desc, &mt);
1534 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1535 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1539 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1540 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1541 if (error && error != EFBIG) {
1542 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1546 if (error) { /* error == EFBIG */
1549 m_new = m_defrag(m, M_NOWAIT);
1550 if (m_new == NULL) {
1551 if_printf(ifp, "%s: can't defrag TX buffer\n",
1560 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1561 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1563 if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
1568 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1569 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1570 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1571 BUS_DMASYNC_PREWRITE);
1573 /* XXX send after DTIM */
1575 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1578 dr->dr_curslot = backup[0];
1579 dr->dr_usedslot = backup[1];
1581 #undef BWN_GET_TXHDRCACHE
1585 bwn_watchdog(void *arg)
1587 struct bwn_softc *sc = arg;
1588 struct ifnet *ifp = sc->sc_ifp;
1590 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1591 if_printf(ifp, "device timeout\n");
1592 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
1594 callout_schedule(&sc->sc_watchdog_ch, hz);
1598 bwn_attach_core(struct bwn_mac *mac)
1600 struct bwn_softc *sc = mac->mac_sc;
1601 int error, have_bg = 0, have_a = 0;
1604 KASSERT(siba_get_revid(sc->sc_dev) >= 5,
1605 ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
1607 siba_powerup(sc->sc_dev, 0);
1609 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
1611 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1612 error = bwn_phy_getinfo(mac, high);
1616 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1617 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1618 if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
1619 siba_get_pci_device(sc->sc_dev) != 0x4319 &&
1620 siba_get_pci_device(sc->sc_dev) != 0x4324) {
1621 have_a = have_bg = 0;
1622 if (mac->mac_phy.type == BWN_PHYTYPE_A)
1624 else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1625 mac->mac_phy.type == BWN_PHYTYPE_N ||
1626 mac->mac_phy.type == BWN_PHYTYPE_LP)
1629 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1630 mac->mac_phy.type));
1632 /* XXX turns off PHY A because it's not supported */
1633 if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1634 mac->mac_phy.type != BWN_PHYTYPE_N) {
1639 if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1640 mac->mac_phy.attach = bwn_phy_g_attach;
1641 mac->mac_phy.detach = bwn_phy_g_detach;
1642 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1643 mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1644 mac->mac_phy.init = bwn_phy_g_init;
1645 mac->mac_phy.exit = bwn_phy_g_exit;
1646 mac->mac_phy.phy_read = bwn_phy_g_read;
1647 mac->mac_phy.phy_write = bwn_phy_g_write;
1648 mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1649 mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1650 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1651 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1652 mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1653 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1654 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1655 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1656 mac->mac_phy.set_im = bwn_phy_g_im;
1657 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1658 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1659 mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1660 mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1661 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1662 mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1663 mac->mac_phy.init = bwn_phy_lp_init;
1664 mac->mac_phy.phy_read = bwn_phy_lp_read;
1665 mac->mac_phy.phy_write = bwn_phy_lp_write;
1666 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1667 mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1668 mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1669 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1670 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1671 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1672 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1673 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1674 mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1676 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1682 mac->mac_phy.gmode = have_bg;
1683 if (mac->mac_phy.attach != NULL) {
1684 error = mac->mac_phy.attach(mac);
1686 device_printf(sc->sc_dev, "failed\n");
1691 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1693 error = bwn_chiptest(mac);
1696 error = bwn_setup_channels(mac, have_bg, have_a);
1698 device_printf(sc->sc_dev, "failed to setup channels\n");
1702 if (sc->sc_curmac == NULL)
1703 sc->sc_curmac = mac;
1705 error = bwn_dma_attach(mac);
1707 device_printf(sc->sc_dev, "failed to initialize DMA\n");
1711 mac->mac_phy.switch_analog(mac, 0);
1713 siba_dev_down(sc->sc_dev, 0);
1715 siba_powerdown(sc->sc_dev);
1720 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1722 struct bwn_softc *sc = mac->mac_sc;
1725 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1727 siba_dev_up(sc->sc_dev, flags);
1730 low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1731 ~BWN_TGSLOW_PHYRESET;
1732 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
1733 siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1735 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1736 siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1739 if (mac->mac_phy.switch_analog != NULL)
1740 mac->mac_phy.switch_analog(mac, 1);
1742 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1743 if (flags & BWN_TGSLOW_SUPPORT_G)
1744 ctl |= BWN_MACCTL_GMODE;
1745 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1749 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1751 struct bwn_phy *phy = &mac->mac_phy;
1752 struct bwn_softc *sc = mac->mac_sc;
1756 tmp = BWN_READ_2(mac, BWN_PHYVER);
1757 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1759 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1760 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1761 phy->rev = (tmp & BWN_PHYVER_VERSION);
1762 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1763 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1764 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1765 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1766 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1767 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1771 if (siba_get_chipid(sc->sc_dev) == 0x4317) {
1772 if (siba_get_chiprev(sc->sc_dev) == 0)
1774 else if (siba_get_chiprev(sc->sc_dev) == 1)
1779 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1780 tmp = BWN_READ_2(mac, BWN_RFDATALO);
1781 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1782 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1784 phy->rf_rev = (tmp & 0xf0000000) >> 28;
1785 phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1786 phy->rf_manuf = (tmp & 0x00000fff);
1787 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */
1789 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1790 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1791 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1792 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1793 (phy->type == BWN_PHYTYPE_N &&
1794 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1795 (phy->type == BWN_PHYTYPE_LP &&
1796 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1801 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1803 phy->type, phy->rev, phy->analog);
1806 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1808 phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1813 bwn_chiptest(struct bwn_mac *mac)
1815 #define TESTVAL0 0x55aaaa55
1816 #define TESTVAL1 0xaa5555aa
1817 struct bwn_softc *sc = mac->mac_sc;
1822 backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1824 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1825 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1827 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1828 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1831 bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1833 if ((siba_get_revid(sc->sc_dev) >= 3) &&
1834 (siba_get_revid(sc->sc_dev) <= 10)) {
1835 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1836 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1837 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1839 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1842 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1844 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1845 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1852 device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1856 #define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1857 #define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1860 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1862 struct bwn_softc *sc = mac->mac_sc;
1863 struct ifnet *ifp = sc->sc_ifp;
1864 struct ieee80211com *ic = ifp->if_l2com;
1866 memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1870 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1871 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1872 if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1874 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1875 &ic->ic_nchans, &bwn_chantable_n,
1876 IEEE80211_CHAN_HTA);
1879 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1880 &ic->ic_nchans, &bwn_chantable_a,
1884 mac->mac_phy.supports_2ghz = have_bg;
1885 mac->mac_phy.supports_5ghz = have_a;
1887 return (ic->ic_nchans == 0 ? ENXIO : 0);
1891 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1895 BWN_ASSERT_LOCKED(mac->mac_sc);
1897 if (way == BWN_SHARED) {
1898 KASSERT((offset & 0x0001) == 0,
1899 ("%s:%d warn", __func__, __LINE__));
1900 if (offset & 0x0003) {
1901 bwn_shm_ctlword(mac, way, offset >> 2);
1902 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1904 bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1905 ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1910 bwn_shm_ctlword(mac, way, offset);
1911 ret = BWN_READ_4(mac, BWN_SHM_DATA);
1917 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1921 BWN_ASSERT_LOCKED(mac->mac_sc);
1923 if (way == BWN_SHARED) {
1924 KASSERT((offset & 0x0001) == 0,
1925 ("%s:%d warn", __func__, __LINE__));
1926 if (offset & 0x0003) {
1927 bwn_shm_ctlword(mac, way, offset >> 2);
1928 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1933 bwn_shm_ctlword(mac, way, offset);
1934 ret = BWN_READ_2(mac, BWN_SHM_DATA);
1941 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1949 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1953 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1956 BWN_ASSERT_LOCKED(mac->mac_sc);
1958 if (way == BWN_SHARED) {
1959 KASSERT((offset & 0x0001) == 0,
1960 ("%s:%d warn", __func__, __LINE__));
1961 if (offset & 0x0003) {
1962 bwn_shm_ctlword(mac, way, offset >> 2);
1963 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1964 (value >> 16) & 0xffff);
1965 bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1966 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1971 bwn_shm_ctlword(mac, way, offset);
1972 BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1976 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1979 BWN_ASSERT_LOCKED(mac->mac_sc);
1981 if (way == BWN_SHARED) {
1982 KASSERT((offset & 0x0001) == 0,
1983 ("%s:%d warn", __func__, __LINE__));
1984 if (offset & 0x0003) {
1985 bwn_shm_ctlword(mac, way, offset >> 2);
1986 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1991 bwn_shm_ctlword(mac, way, offset);
1992 BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1996 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
2001 c->ic_flags = flags;
2004 c->ic_maxpower = 2 * txpow;
2005 c->ic_maxregpower = txpow;
2009 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
2010 const struct bwn_channelinfo *ci, int flags)
2012 struct ieee80211_channel *c;
2015 c = &chans[*nchans];
2017 for (i = 0; i < ci->nchannels; i++) {
2018 const struct bwn_channel *hc;
2020 hc = &ci->channels[i];
2021 if (*nchans >= maxchans)
2023 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
2025 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
2026 /* g channel have a separate b-only entry */
2027 if (*nchans >= maxchans)
2030 c[-1].ic_flags = IEEE80211_CHAN_B;
2033 if (flags == IEEE80211_CHAN_HTG) {
2034 /* HT g channel have a separate g-only entry */
2035 if (*nchans >= maxchans)
2037 c[-1].ic_flags = IEEE80211_CHAN_G;
2039 c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2040 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */
2043 if (flags == IEEE80211_CHAN_HTA) {
2044 /* HT a channel have a separate a-only entry */
2045 if (*nchans >= maxchans)
2047 c[-1].ic_flags = IEEE80211_CHAN_A;
2049 c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2050 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */
2057 bwn_phy_g_attach(struct bwn_mac *mac)
2059 struct bwn_softc *sc = mac->mac_sc;
2060 struct bwn_phy *phy = &mac->mac_phy;
2061 struct bwn_phy_g *pg = &phy->phy_g;
2063 int16_t pab0, pab1, pab2;
2064 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2067 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
2068 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
2069 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
2070 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
2072 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
2073 device_printf(sc->sc_dev, "not supported anymore\n");
2076 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2078 pg->pg_idletssi = 52;
2079 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2083 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2084 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
2085 if (pg->pg_tssi2dbm == NULL) {
2086 device_printf(sc->sc_dev, "failed to allocate buffer\n");
2089 for (i = 0; i < 64; i++) {
2090 int32_t m1, m2, f, q, delta;
2093 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2094 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2099 device_printf(sc->sc_dev,
2100 "failed to generate tssi2dBm\n");
2101 free(pg->pg_tssi2dbm, M_DEVBUF);
2104 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2109 } while (delta >= 2);
2111 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2115 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2120 bwn_phy_g_detach(struct bwn_mac *mac)
2122 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2124 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2125 free(pg->pg_tssi2dbm, M_DEVBUF);
2126 pg->pg_tssi2dbm = NULL;
2132 bwn_phy_g_init_pre(struct bwn_mac *mac)
2134 struct bwn_phy *phy = &mac->mac_phy;
2135 struct bwn_phy_g *pg = &phy->phy_g;
2140 tssi2dbm = pg->pg_tssi2dbm;
2141 idletssi = pg->pg_idletssi;
2143 memset(pg, 0, sizeof(*pg));
2145 pg->pg_tssi2dbm = tssi2dbm;
2146 pg->pg_idletssi = idletssi;
2148 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2150 for (i = 0; i < N(pg->pg_nrssi); i++)
2151 pg->pg_nrssi[i] = -1000;
2152 for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2153 pg->pg_nrssi_lt[i] = i;
2154 pg->pg_lofcal = 0xffff;
2155 pg->pg_initval = 0xffff;
2156 pg->pg_immode = BWN_IMMODE_NONE;
2157 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2158 pg->pg_avgtssi = 0xff;
2160 pg->pg_loctl.tx_bias = 0xff;
2161 TAILQ_INIT(&pg->pg_loctl.calib_list);
2165 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2167 struct bwn_phy *phy = &mac->mac_phy;
2168 struct bwn_phy_g *pg = &phy->phy_g;
2169 struct bwn_softc *sc = mac->mac_sc;
2170 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2171 static const struct bwn_rfatt rfatt0[] = {
2172 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
2173 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2176 static const struct bwn_rfatt rfatt1[] = {
2177 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2180 static const struct bwn_rfatt rfatt2[] = {
2181 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2184 static const struct bwn_bbatt bbatt_0[] = {
2185 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2188 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2190 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2191 pg->pg_bbatt.att = 0;
2193 pg->pg_bbatt.att = 2;
2195 /* prepare Radio Attenuation */
2196 pg->pg_rfatt.padmix = 0;
2198 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
2199 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
2200 if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
2201 pg->pg_rfatt.att = 2;
2203 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
2204 pg->pg_rfatt.att = 3;
2209 if (phy->type == BWN_PHYTYPE_A) {
2210 pg->pg_rfatt.att = 0x60;
2214 switch (phy->rf_ver) {
2216 switch (phy->rf_rev) {
2218 pg->pg_rfatt.att = 5;
2221 if (phy->type == BWN_PHYTYPE_G) {
2222 if (siba_get_pci_subvendor(sc->sc_dev) ==
2223 SIBA_BOARDVENDOR_BCM &&
2224 siba_get_pci_subdevice(sc->sc_dev) ==
2225 SIBA_BOARD_BCM4309G &&
2226 siba_get_pci_revid(sc->sc_dev) >= 30)
2227 pg->pg_rfatt.att = 3;
2228 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2229 SIBA_BOARDVENDOR_BCM &&
2230 siba_get_pci_subdevice(sc->sc_dev) ==
2232 pg->pg_rfatt.att = 3;
2234 pg->pg_rfatt.att = 1;
2236 if (siba_get_pci_subvendor(sc->sc_dev) ==
2237 SIBA_BOARDVENDOR_BCM &&
2238 siba_get_pci_subdevice(sc->sc_dev) ==
2239 SIBA_BOARD_BCM4309G &&
2240 siba_get_pci_revid(sc->sc_dev) >= 30)
2241 pg->pg_rfatt.att = 7;
2243 pg->pg_rfatt.att = 6;
2247 if (phy->type == BWN_PHYTYPE_G) {
2248 if (siba_get_pci_subvendor(sc->sc_dev) ==
2249 SIBA_BOARDVENDOR_BCM &&
2250 siba_get_pci_subdevice(sc->sc_dev) ==
2251 SIBA_BOARD_BCM4309G &&
2252 siba_get_pci_revid(sc->sc_dev) >= 30)
2253 pg->pg_rfatt.att = 3;
2254 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2255 SIBA_BOARDVENDOR_BCM &&
2256 siba_get_pci_subdevice(sc->sc_dev) ==
2258 pg->pg_rfatt.att = 5;
2259 else if (siba_get_chipid(sc->sc_dev) == 0x4320)
2260 pg->pg_rfatt.att = 4;
2262 pg->pg_rfatt.att = 3;
2264 pg->pg_rfatt.att = 6;
2267 pg->pg_rfatt.att = 5;
2271 pg->pg_rfatt.att = 1;
2275 pg->pg_rfatt.att = 5;
2278 pg->pg_rfatt.att = 0xa;
2279 pg->pg_rfatt.padmix = 1;
2283 pg->pg_rfatt.att = 5;
2288 switch (phy->rf_rev) {
2290 pg->pg_rfatt.att = 6;
2295 pg->pg_rfatt.att = 5;
2297 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2299 if (!bwn_has_hwpctl(mac)) {
2300 lo->rfatt.array = rfatt0;
2301 lo->rfatt.len = N(rfatt0);
2306 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2307 lo->rfatt.array = rfatt1;
2308 lo->rfatt.len = N(rfatt1);
2313 lo->rfatt.array = rfatt2;
2314 lo->rfatt.len = N(rfatt2);
2318 lo->bbatt.array = bbatt_0;
2319 lo->bbatt.len = N(bbatt_0);
2323 BWN_READ_4(mac, BWN_MACCTL);
2324 if (phy->rev == 1) {
2326 bwn_reset_core(mac, 0);
2327 bwn_phy_g_init_sub(mac);
2329 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2335 bwn_phy_g_txctl(struct bwn_mac *mac)
2337 struct bwn_phy *phy = &mac->mac_phy;
2339 if (phy->rf_ver != 0x2050)
2341 if (phy->rf_rev == 1)
2342 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2343 if (phy->rf_rev < 6)
2344 return (BWN_TXCTL_PA2DB);
2345 if (phy->rf_rev == 8)
2346 return (BWN_TXCTL_TXMIX);
2351 bwn_phy_g_init(struct bwn_mac *mac)
2354 bwn_phy_g_init_sub(mac);
2359 bwn_phy_g_exit(struct bwn_mac *mac)
2361 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2362 struct bwn_lo_calib *cal, *tmp;
2366 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2367 TAILQ_REMOVE(&lo->calib_list, cal, list);
2368 free(cal, M_DEVBUF);
2373 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2376 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2377 return (BWN_READ_2(mac, BWN_PHYDATA));
2381 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2384 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2385 BWN_WRITE_2(mac, BWN_PHYDATA, value);
2389 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2392 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2393 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2394 return (BWN_READ_2(mac, BWN_RFDATALO));
2398 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2401 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2402 BWN_WRITE_2(mac, BWN_RFCTL, reg);
2403 BWN_WRITE_2(mac, BWN_RFDATALO, value);
2407 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2410 return (mac->mac_phy.rev >= 6);
2414 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2416 struct bwn_phy *phy = &mac->mac_phy;
2417 struct bwn_phy_g *pg = &phy->phy_g;
2418 unsigned int channel;
2419 uint16_t rfover, rfoverval;
2425 BWN_PHY_WRITE(mac, 0x15, 0x8000);
2426 BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2427 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2428 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2429 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2430 pg->pg_radioctx_over);
2431 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2432 pg->pg_radioctx_overval);
2433 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2435 channel = phy->chan;
2436 bwn_phy_g_switch_chan(mac, 6, 1);
2437 bwn_phy_g_switch_chan(mac, channel, 0);
2441 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2442 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2443 pg->pg_radioctx_over = rfover;
2444 pg->pg_radioctx_overval = rfoverval;
2445 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2446 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2447 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2451 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2454 if ((newchan < 1) || (newchan > 14))
2456 bwn_phy_g_switch_chan(mac, newchan, 0);
2462 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2469 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2471 struct bwn_phy *phy = &mac->mac_phy;
2476 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2479 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2480 bwn_hf_write(mac, hf);
2482 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2483 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2484 ((autodiv ? BWN_ANTAUTO1 : antenna)
2485 << BWN_PHY_BBANDCFG_RXANT_SHIFT));
2488 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2489 if (antenna == BWN_ANTAUTO1)
2490 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2492 tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2493 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2495 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2497 tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2499 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2500 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2501 if (phy->rev >= 2) {
2502 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2503 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2504 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2505 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2508 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2510 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2511 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2515 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2517 hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2518 bwn_hf_write(mac, hf);
2522 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2524 struct bwn_phy *phy = &mac->mac_phy;
2525 struct bwn_phy_g *pg = &phy->phy_g;
2527 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2528 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2530 if (phy->rev == 0 || !phy->gmode)
2533 pg->pg_aci_wlan_automatic = 0;
2538 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2540 struct bwn_phy *phy = &mac->mac_phy;
2541 struct bwn_phy_g *pg = &phy->phy_g;
2542 struct bwn_softc *sc = mac->mac_sc;
2549 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2551 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2552 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2553 if (cck < 0 && ofdm < 0) {
2554 if (ignore_tssi == 0)
2555 return (BWN_TXPWR_RES_DONE);
2559 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2560 if (pg->pg_avgtssi != 0xff)
2561 tssi = (tssi + pg->pg_avgtssi) / 2;
2562 pg->pg_avgtssi = tssi;
2563 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2565 max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2566 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2569 device_printf(sc->sc_dev, "invalid max TX-power value\n");
2571 siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2574 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2575 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2576 tssi, 0x00), 0x3f)]);
2578 return (BWN_TXPWR_RES_DONE);
2580 rfatt = -((power + 7) / 8);
2581 bbatt = (-(power / 2)) - (4 * rfatt);
2582 if ((rfatt == 0) && (bbatt == 0))
2583 return (BWN_TXPWR_RES_DONE);
2584 pg->pg_bbatt_delta = bbatt;
2585 pg->pg_rfatt_delta = rfatt;
2586 return (BWN_TXPWR_RES_NEED_ADJUST);
2590 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2592 struct bwn_phy *phy = &mac->mac_phy;
2593 struct bwn_phy_g *pg = &phy->phy_g;
2594 struct bwn_softc *sc = mac->mac_sc;
2598 bwn_mac_suspend(mac);
2600 BWN_ASSERT_LOCKED(sc);
2602 bbatt = pg->pg_bbatt.att;
2603 bbatt += pg->pg_bbatt_delta;
2604 rfatt = pg->pg_rfatt.att;
2605 rfatt += pg->pg_rfatt_delta;
2607 bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2608 txctl = pg->pg_txctl;
2609 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2612 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2615 } else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2617 bbatt += 4 * (rfatt - 2);
2620 } else if (rfatt > 4 && txctl) {
2631 pg->pg_txctl = txctl;
2632 bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2633 pg->pg_rfatt.att = rfatt;
2634 pg->pg_bbatt.att = bbatt;
2636 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2640 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2643 bwn_phy_unlock(mac);
2645 bwn_mac_enable(mac);
2649 bwn_phy_g_task_15s(struct bwn_mac *mac)
2651 struct bwn_phy *phy = &mac->mac_phy;
2652 struct bwn_phy_g *pg = &phy->phy_g;
2653 struct bwn_softc *sc = mac->mac_sc;
2654 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2655 unsigned long expire, now;
2656 struct bwn_lo_calib *cal, *tmp;
2657 uint8_t expired = 0;
2659 bwn_mac_suspend(mac);
2665 if (bwn_has_hwpctl(mac)) {
2666 expire = now - BWN_LO_PWRVEC_EXPIRE;
2667 if (time_before(lo->pwr_vec_read_time, expire)) {
2668 bwn_lo_get_powervector(mac);
2669 bwn_phy_g_dc_lookup_init(mac, 0);
2674 expire = now - BWN_LO_CALIB_EXPIRE;
2675 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2676 if (!time_before(cal->calib_time, expire))
2678 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2679 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2680 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2684 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2685 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2686 cal->ctl.i, cal->ctl.q);
2688 TAILQ_REMOVE(&lo->calib_list, cal, list);
2689 free(cal, M_DEVBUF);
2691 if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2692 cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2695 device_printf(sc->sc_dev,
2696 "failed to recalibrate LO\n");
2699 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2700 bwn_lo_write(mac, &cal->ctl);
2704 bwn_mac_enable(mac);
2708 bwn_phy_g_task_60s(struct bwn_mac *mac)
2710 struct bwn_phy *phy = &mac->mac_phy;
2711 struct bwn_softc *sc = mac->mac_sc;
2712 uint8_t old = phy->chan;
2714 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2717 bwn_mac_suspend(mac);
2718 bwn_nrssi_slope_11g(mac);
2719 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2720 bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2721 bwn_switch_channel(mac, old);
2723 bwn_mac_enable(mac);
2727 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2730 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2734 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2735 const struct ieee80211_bpf_params *params)
2737 struct ieee80211com *ic = ni->ni_ic;
2738 struct ifnet *ifp = ic->ic_ifp;
2739 struct bwn_softc *sc = ifp->if_softc;
2740 struct bwn_mac *mac = sc->sc_curmac;
2742 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
2743 mac->mac_status < BWN_MAC_STATUS_STARTED) {
2744 ieee80211_free_node(ni);
2750 if (bwn_tx_isfull(sc, m)) {
2751 ieee80211_free_node(ni);
2753 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
2758 if (bwn_tx_start(sc, ni, m) != 0) {
2760 ieee80211_free_node(ni);
2761 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
2763 sc->sc_watchdog_timer = 5;
2769 * Callback from the 802.11 layer to update the slot time
2770 * based on the current setting. We use it to notify the
2771 * firmware of ERP changes and the f/w takes care of things
2772 * like slot time and preamble.
2775 bwn_updateslot(struct ieee80211com *ic)
2777 struct bwn_softc *sc = ic->ic_softc;
2778 struct bwn_mac *mac;
2781 if (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) {
2782 mac = (struct bwn_mac *)sc->sc_curmac;
2783 bwn_set_slot_time(mac,
2784 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2790 * Callback from the 802.11 layer after a promiscuous mode change.
2791 * Note this interface does not check the operating mode as this
2792 * is an internal callback and we are expected to honor the current
2793 * state (e.g. this is used for setting the interface in promiscuous
2794 * mode when operating in hostap mode to do ACS).
2797 bwn_update_promisc(struct ieee80211com *ic)
2799 struct bwn_softc *sc = ic->ic_softc;
2800 struct bwn_mac *mac = sc->sc_curmac;
2803 mac = sc->sc_curmac;
2804 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2805 if (ic->ic_ifp->if_flags & IFF_PROMISC)
2806 sc->sc_filters |= BWN_MACCTL_PROMISC;
2808 sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2809 bwn_set_opmode(mac);
2815 * Callback from the 802.11 layer to update WME parameters.
2818 bwn_wme_update(struct ieee80211com *ic)
2820 struct bwn_softc *sc = ic->ic_ifp->if_softc;
2821 struct bwn_mac *mac = sc->sc_curmac;
2822 struct wmeParams *wmep;
2826 mac = sc->sc_curmac;
2827 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2828 bwn_mac_suspend(mac);
2829 for (i = 0; i < N(sc->sc_wmeParams); i++) {
2830 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2831 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2833 bwn_mac_enable(mac);
2840 bwn_scan_start(struct ieee80211com *ic)
2842 struct ifnet *ifp = ic->ic_ifp;
2843 struct bwn_softc *sc = ifp->if_softc;
2844 struct bwn_mac *mac;
2847 mac = sc->sc_curmac;
2848 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2849 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2850 bwn_set_opmode(mac);
2851 /* disable CFP update during scan */
2852 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2858 bwn_scan_end(struct ieee80211com *ic)
2860 struct ifnet *ifp = ic->ic_ifp;
2861 struct bwn_softc *sc = ifp->if_softc;
2862 struct bwn_mac *mac;
2865 mac = sc->sc_curmac;
2866 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2867 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2868 bwn_set_opmode(mac);
2869 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2875 bwn_set_channel(struct ieee80211com *ic)
2877 struct ifnet *ifp = ic->ic_ifp;
2878 struct bwn_softc *sc = ifp->if_softc;
2879 struct bwn_mac *mac = sc->sc_curmac;
2880 struct bwn_phy *phy = &mac->mac_phy;
2885 error = bwn_switch_band(sc, ic->ic_curchan);
2888 bwn_mac_suspend(mac);
2889 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2890 chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2891 if (chan != phy->chan)
2892 bwn_switch_channel(mac, chan);
2894 /* TX power level */
2895 if (ic->ic_curchan->ic_maxpower != 0 &&
2896 ic->ic_curchan->ic_maxpower != phy->txpower) {
2897 phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2898 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2899 BWN_TXPWR_IGNORE_TSSI);
2902 bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2903 if (phy->set_antenna)
2904 phy->set_antenna(mac, BWN_ANT_DEFAULT);
2906 if (sc->sc_rf_enabled != phy->rf_on) {
2907 if (sc->sc_rf_enabled) {
2909 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2910 device_printf(sc->sc_dev,
2911 "please turn on the RF switch\n");
2913 bwn_rf_turnoff(mac);
2916 bwn_mac_enable(mac);
2920 * Setup radio tap channel freq and flags
2922 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2923 htole16(ic->ic_curchan->ic_freq);
2924 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2925 htole16(ic->ic_curchan->ic_flags & 0xffff);
2930 static struct ieee80211vap *
2931 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
2932 enum ieee80211_opmode opmode, int flags,
2933 const uint8_t bssid[IEEE80211_ADDR_LEN],
2934 const uint8_t mac0[IEEE80211_ADDR_LEN])
2936 struct ifnet *ifp = ic->ic_ifp;
2937 struct bwn_softc *sc = ifp->if_softc;
2938 struct ieee80211vap *vap;
2939 struct bwn_vap *bvp;
2940 uint8_t mac[IEEE80211_ADDR_LEN];
2942 IEEE80211_ADDR_COPY(mac, mac0);
2944 case IEEE80211_M_HOSTAP:
2945 case IEEE80211_M_MBSS:
2946 case IEEE80211_M_STA:
2947 case IEEE80211_M_WDS:
2948 case IEEE80211_M_MONITOR:
2949 case IEEE80211_M_IBSS:
2950 case IEEE80211_M_AHDEMO:
2956 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
2958 bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap),
2959 M_80211_VAP, M_NOWAIT | M_ZERO);
2961 device_printf(sc->sc_dev, "failed to allocate a buffer\n");
2965 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
2966 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
2967 /* override with driver methods */
2968 bvp->bv_newstate = vap->iv_newstate;
2969 vap->iv_newstate = bwn_newstate;
2971 /* override max aid so sta's cannot assoc when we're out of sta id's */
2972 vap->iv_max_aid = BWN_STAID_MAX;
2974 ieee80211_ratectl_init(vap);
2976 /* complete setup */
2977 ieee80211_vap_attach(vap, ieee80211_media_change,
2978 ieee80211_media_status);
2983 bwn_vap_delete(struct ieee80211vap *vap)
2985 struct bwn_vap *bvp = BWN_VAP(vap);
2987 ieee80211_ratectl_deinit(vap);
2988 ieee80211_vap_detach(vap);
2989 free(bvp, M_80211_VAP);
2995 struct bwn_softc *sc = arg;
2996 struct ifnet *ifp = sc->sc_ifp;
2997 struct ieee80211com *ic = ifp->if_l2com;
3000 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
3001 __func__, ifp->if_flags);
3004 error = bwn_init_locked(sc);
3008 ieee80211_start_all(ic); /* start all vap's */
3012 bwn_init_locked(struct bwn_softc *sc)
3014 struct bwn_mac *mac;
3015 struct ifnet *ifp = sc->sc_ifp;
3018 BWN_ASSERT_LOCKED(sc);
3020 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
3021 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
3024 sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
3025 sc->sc_rf_enabled = 1;
3027 mac = sc->sc_curmac;
3028 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
3029 error = bwn_core_init(mac);
3033 if (mac->mac_status == BWN_MAC_STATUS_INITED)
3034 bwn_core_start(mac);
3036 bwn_set_opmode(mac);
3037 bwn_set_pretbtt(mac);
3038 bwn_spu_setdelay(mac, 0);
3039 bwn_set_macaddr(mac);
3041 ifp->if_drv_flags |= IFF_DRV_RUNNING;
3042 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
3043 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
3049 bwn_stop(struct bwn_softc *sc, int statechg)
3053 bwn_stop_locked(sc, statechg);
3058 bwn_stop_locked(struct bwn_softc *sc, int statechg)
3060 struct bwn_mac *mac = sc->sc_curmac;
3061 struct ifnet *ifp = sc->sc_ifp;
3063 BWN_ASSERT_LOCKED(sc);
3065 if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
3066 /* XXX FIXME opmode not based on VAP */
3067 bwn_set_opmode(mac);
3068 bwn_set_macaddr(mac);
3071 if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
3074 callout_stop(&sc->sc_led_blink_ch);
3075 sc->sc_led_blinking = 0;
3078 sc->sc_rf_enabled = 0;
3080 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
3084 bwn_wme_clear(struct bwn_softc *sc)
3086 #define MS(_v, _f) (((_v) & _f) >> _f##_S)
3087 struct wmeParams *p;
3090 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
3091 ("%s:%d: fail", __func__, __LINE__));
3093 for (i = 0; i < N(sc->sc_wmeParams); i++) {
3094 p = &(sc->sc_wmeParams[i]);
3096 switch (bwn_wme_shm_offsets[i]) {
3098 p->wmep_txopLimit = 0;
3100 /* XXX FIXME: log2(cwmin) */
3101 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3102 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3105 p->wmep_txopLimit = 0;
3107 /* XXX FIXME: log2(cwmin) */
3108 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3109 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3111 case BWN_WME_BESTEFFORT:
3112 p->wmep_txopLimit = 0;
3114 /* XXX FIXME: log2(cwmin) */
3115 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3116 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3118 case BWN_WME_BACKGROUND:
3119 p->wmep_txopLimit = 0;
3121 /* XXX FIXME: log2(cwmin) */
3122 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3123 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3126 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3132 bwn_core_init(struct bwn_mac *mac)
3134 struct bwn_softc *sc = mac->mac_sc;
3138 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3139 ("%s:%d: fail", __func__, __LINE__));
3141 siba_powerup(sc->sc_dev, 0);
3142 if (!siba_dev_isup(sc->sc_dev))
3144 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3146 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3147 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3148 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3149 BWN_GETTIME(mac->mac_phy.nexttime);
3150 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3151 bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3152 mac->mac_stats.link_noise = -95;
3153 mac->mac_reason_intr = 0;
3154 bzero(mac->mac_reason, sizeof(mac->mac_reason));
3155 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3157 if (sc->sc_debug & BWN_DEBUG_XMIT)
3158 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3160 mac->mac_suspended = 1;
3161 mac->mac_task_state = 0;
3162 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3164 mac->mac_phy.init_pre(mac);
3166 siba_pcicore_intr(sc->sc_dev);
3168 siba_fix_imcfglobug(sc->sc_dev);
3169 bwn_bt_disable(mac);
3170 if (mac->mac_phy.prepare_hw) {
3171 error = mac->mac_phy.prepare_hw(mac);
3175 error = bwn_chip_init(mac);
3178 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3179 siba_get_revid(sc->sc_dev));
3180 hf = bwn_hf_read(mac);
3181 if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3182 hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3183 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3184 hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3185 if (mac->mac_phy.rev == 1)
3186 hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3188 if (mac->mac_phy.rf_ver == 0x2050) {
3189 if (mac->mac_phy.rf_rev < 6)
3190 hf |= BWN_HF_FORCE_VCO_RECALC;
3191 if (mac->mac_phy.rf_rev == 6)
3192 hf |= BWN_HF_4318_TSSI;
3194 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3195 hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3196 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3197 (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3198 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3199 hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3200 bwn_hf_write(mac, hf);
3202 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3203 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3204 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3205 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3208 bwn_set_phytxctl(mac);
3210 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3211 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3212 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3214 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3219 bwn_spu_setdelay(mac, 1);
3222 siba_powerup(sc->sc_dev,
3223 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3224 bwn_set_macaddr(mac);
3225 bwn_crypt_init(mac);
3227 /* XXX LED initializatin */
3229 mac->mac_status = BWN_MAC_STATUS_INITED;
3234 siba_powerdown(sc->sc_dev);
3235 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3236 ("%s:%d: fail", __func__, __LINE__));
3241 bwn_core_start(struct bwn_mac *mac)
3243 struct bwn_softc *sc = mac->mac_sc;
3246 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3247 ("%s:%d: fail", __func__, __LINE__));
3249 if (siba_get_revid(sc->sc_dev) < 5)
3253 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3254 if (!(tmp & 0x00000001))
3256 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3259 bwn_mac_enable(mac);
3260 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3261 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3263 mac->mac_status = BWN_MAC_STATUS_STARTED;
3267 bwn_core_exit(struct bwn_mac *mac)
3269 struct bwn_softc *sc = mac->mac_sc;
3272 BWN_ASSERT_LOCKED(mac->mac_sc);
3274 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3275 ("%s:%d: fail", __func__, __LINE__));
3277 if (mac->mac_status != BWN_MAC_STATUS_INITED)
3279 mac->mac_status = BWN_MAC_STATUS_UNINIT;
3281 macctl = BWN_READ_4(mac, BWN_MACCTL);
3282 macctl &= ~BWN_MACCTL_MCODE_RUN;
3283 macctl |= BWN_MACCTL_MCODE_JMP0;
3284 BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3289 mac->mac_phy.switch_analog(mac, 0);
3290 siba_dev_down(sc->sc_dev, 0);
3291 siba_powerdown(sc->sc_dev);
3295 bwn_bt_disable(struct bwn_mac *mac)
3297 struct bwn_softc *sc = mac->mac_sc;
3300 /* XXX do nothing yet */
3304 bwn_chip_init(struct bwn_mac *mac)
3306 struct bwn_softc *sc = mac->mac_sc;
3307 struct bwn_phy *phy = &mac->mac_phy;
3311 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3313 macctl |= BWN_MACCTL_GMODE;
3314 BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3316 error = bwn_fw_fillinfo(mac);
3319 error = bwn_fw_loaducode(mac);
3323 error = bwn_gpio_init(mac);
3327 error = bwn_fw_loadinitvals(mac);
3329 siba_gpio_set(sc->sc_dev, 0);
3332 phy->switch_analog(mac, 1);
3333 error = bwn_phy_init(mac);
3335 siba_gpio_set(sc->sc_dev, 0);
3339 phy->set_im(mac, BWN_IMMODE_NONE);
3340 if (phy->set_antenna)
3341 phy->set_antenna(mac, BWN_ANT_DEFAULT);
3342 bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3344 if (phy->type == BWN_PHYTYPE_B)
3345 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3346 BWN_WRITE_4(mac, 0x0100, 0x01000000);
3347 if (siba_get_revid(sc->sc_dev) < 5)
3348 BWN_WRITE_4(mac, 0x010c, 0x01000000);
3350 BWN_WRITE_4(mac, BWN_MACCTL,
3351 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3352 BWN_WRITE_4(mac, BWN_MACCTL,
3353 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3354 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3356 bwn_set_opmode(mac);
3357 if (siba_get_revid(sc->sc_dev) < 3) {
3358 BWN_WRITE_2(mac, 0x060e, 0x0000);
3359 BWN_WRITE_2(mac, 0x0610, 0x8000);
3360 BWN_WRITE_2(mac, 0x0604, 0x0000);
3361 BWN_WRITE_2(mac, 0x0606, 0x0200);
3363 BWN_WRITE_4(mac, 0x0188, 0x80000000);
3364 BWN_WRITE_4(mac, 0x018c, 0x02000000);
3366 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3367 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
3368 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3369 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3370 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3371 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3372 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3373 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3374 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3375 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3379 /* read hostflags */
3381 bwn_hf_read(struct bwn_mac *mac)
3385 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3387 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3389 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3394 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3397 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3398 (value & 0x00000000ffffull));
3399 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3400 (value & 0x0000ffff0000ull) >> 16);
3401 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3402 (value & 0xffff00000000ULL) >> 32);
3406 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3409 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3410 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3414 bwn_rate_init(struct bwn_mac *mac)
3417 switch (mac->mac_phy.type) {
3420 case BWN_PHYTYPE_LP:
3422 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3423 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3424 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3425 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3426 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3427 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3428 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3429 if (mac->mac_phy.type == BWN_PHYTYPE_A)
3433 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3434 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3435 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3436 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3439 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3444 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3450 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3453 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3455 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3456 bwn_shm_read_2(mac, BWN_SHARED, offset));
3460 bwn_plcp_getcck(const uint8_t bitrate)
3464 case BWN_CCK_RATE_1MB:
3466 case BWN_CCK_RATE_2MB:
3468 case BWN_CCK_RATE_5MB:
3470 case BWN_CCK_RATE_11MB:
3473 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3478 bwn_plcp_getofdm(const uint8_t bitrate)
3482 case BWN_OFDM_RATE_6MB:
3484 case BWN_OFDM_RATE_9MB:
3486 case BWN_OFDM_RATE_12MB:
3488 case BWN_OFDM_RATE_18MB:
3490 case BWN_OFDM_RATE_24MB:
3492 case BWN_OFDM_RATE_36MB:
3494 case BWN_OFDM_RATE_48MB:
3496 case BWN_OFDM_RATE_54MB:
3499 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3504 bwn_set_phytxctl(struct bwn_mac *mac)
3508 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3510 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3511 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3512 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3516 bwn_pio_init(struct bwn_mac *mac)
3518 struct bwn_pio *pio = &mac->mac_method.pio;
3520 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3521 & ~BWN_MACCTL_BIGENDIAN);
3522 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3524 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3525 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3526 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3527 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3528 bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3529 bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3533 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3536 struct bwn_pio_txpkt *tp;
3537 struct bwn_softc *sc = mac->mac_sc;
3540 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3541 tq->tq_index = index;
3543 tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3544 if (siba_get_revid(sc->sc_dev) >= 8)
3547 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3551 TAILQ_INIT(&tq->tq_pktlist);
3552 for (i = 0; i < N(tq->tq_pkts); i++) {
3553 tp = &(tq->tq_pkts[i]);
3556 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3561 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3563 struct bwn_softc *sc = mac->mac_sc;
3564 static const uint16_t bases[] = {
3574 static const uint16_t bases_rev11[] = {
3583 if (siba_get_revid(sc->sc_dev) >= 11) {
3584 if (index >= N(bases_rev11))
3585 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3586 return (bases_rev11[index]);
3588 if (index >= N(bases))
3589 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3590 return (bases[index]);
3594 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3597 struct bwn_softc *sc = mac->mac_sc;
3600 prq->prq_rev = siba_get_revid(sc->sc_dev);
3601 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3602 bwn_dma_rxdirectfifo(mac, index, 1);
3606 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3610 bwn_pio_cancel_tx_packets(tq);
3614 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3617 bwn_destroy_pioqueue_tx(pio);
3621 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3625 return (BWN_READ_2(mac, tq->tq_base + offset));
3629 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3635 type = bwn_dma_mask2type(bwn_dma_mask(mac));
3636 base = bwn_dma_base(type, idx);
3637 if (type == BWN_DMA_64BIT) {
3638 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3639 ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3641 ctl |= BWN_DMA64_RXDIRECTFIFO;
3642 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3644 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3645 ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3647 ctl |= BWN_DMA32_RXDIRECTFIFO;
3648 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3653 bwn_dma_mask(struct bwn_mac *mac)
3658 tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3659 if (tmp & SIBA_TGSHIGH_DMA64)
3660 return (BWN_DMA_BIT_MASK(64));
3661 base = bwn_dma_base(0, 0);
3662 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3663 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3664 if (tmp & BWN_DMA32_TXADDREXT_MASK)
3665 return (BWN_DMA_BIT_MASK(32));
3667 return (BWN_DMA_BIT_MASK(30));
3671 bwn_dma_mask2type(uint64_t dmamask)
3674 if (dmamask == BWN_DMA_BIT_MASK(30))
3675 return (BWN_DMA_30BIT);
3676 if (dmamask == BWN_DMA_BIT_MASK(32))
3677 return (BWN_DMA_32BIT);
3678 if (dmamask == BWN_DMA_BIT_MASK(64))
3679 return (BWN_DMA_64BIT);
3680 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3681 return (BWN_DMA_30BIT);
3685 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3687 struct bwn_pio_txpkt *tp;
3690 for (i = 0; i < N(tq->tq_pkts); i++) {
3691 tp = &(tq->tq_pkts[i]);
3700 bwn_dma_base(int type, int controller_idx)
3702 static const uint16_t map64[] = {
3710 static const uint16_t map32[] = {
3719 if (type == BWN_DMA_64BIT) {
3720 KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3721 ("%s:%d: fail", __func__, __LINE__));
3722 return (map64[controller_idx]);
3724 KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3725 ("%s:%d: fail", __func__, __LINE__));
3726 return (map32[controller_idx]);
3730 bwn_dma_init(struct bwn_mac *mac)
3732 struct bwn_dma *dma = &mac->mac_method.dma;
3734 /* setup TX DMA channels. */
3735 bwn_dma_setup(dma->wme[WME_AC_BK]);
3736 bwn_dma_setup(dma->wme[WME_AC_BE]);
3737 bwn_dma_setup(dma->wme[WME_AC_VI]);
3738 bwn_dma_setup(dma->wme[WME_AC_VO]);
3739 bwn_dma_setup(dma->mcast);
3740 /* setup RX DMA channel. */
3741 bwn_dma_setup(dma->rx);
3744 static struct bwn_dma_ring *
3745 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3746 int for_tx, int type)
3748 struct bwn_dma *dma = &mac->mac_method.dma;
3749 struct bwn_dma_ring *dr;
3750 struct bwn_dmadesc_generic *desc;
3751 struct bwn_dmadesc_meta *mt;
3752 struct bwn_softc *sc = mac->mac_sc;
3755 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO);
3758 dr->dr_numslots = BWN_RXRING_SLOTS;
3760 dr->dr_numslots = BWN_TXRING_SLOTS;
3762 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3763 M_DEVBUF, M_NOWAIT | M_ZERO);
3764 if (dr->dr_meta == NULL)
3769 dr->dr_base = bwn_dma_base(type, controller_index);
3770 dr->dr_index = controller_index;
3771 if (type == BWN_DMA_64BIT) {
3772 dr->getdesc = bwn_dma_64_getdesc;
3773 dr->setdesc = bwn_dma_64_setdesc;
3774 dr->start_transfer = bwn_dma_64_start_transfer;
3775 dr->suspend = bwn_dma_64_suspend;
3776 dr->resume = bwn_dma_64_resume;
3777 dr->get_curslot = bwn_dma_64_get_curslot;
3778 dr->set_curslot = bwn_dma_64_set_curslot;
3780 dr->getdesc = bwn_dma_32_getdesc;
3781 dr->setdesc = bwn_dma_32_setdesc;
3782 dr->start_transfer = bwn_dma_32_start_transfer;
3783 dr->suspend = bwn_dma_32_suspend;
3784 dr->resume = bwn_dma_32_resume;
3785 dr->get_curslot = bwn_dma_32_get_curslot;
3786 dr->set_curslot = bwn_dma_32_set_curslot;
3790 dr->dr_curslot = -1;
3792 if (dr->dr_index == 0) {
3793 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3794 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3796 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3799 error = bwn_dma_allocringmemory(dr);
3805 * Assumption: BWN_TXRING_SLOTS can be divided by
3806 * BWN_TX_SLOTS_PER_FRAME
3808 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3809 ("%s:%d: fail", __func__, __LINE__));
3811 dr->dr_txhdr_cache =
3812 malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3813 BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO);
3814 KASSERT(dr->dr_txhdr_cache != NULL,
3815 ("%s:%d: fail", __func__, __LINE__));
3818 * Create TX ring DMA stuffs
3820 error = bus_dma_tag_create(dma->parent_dtag,
3827 BUS_SPACE_MAXSIZE_32BIT,
3830 &dr->dr_txring_dtag);
3832 device_printf(sc->sc_dev,
3833 "can't create TX ring DMA tag: TODO frees\n");
3837 for (i = 0; i < dr->dr_numslots; i += 2) {
3838 dr->getdesc(dr, i, &desc, &mt);
3840 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3844 error = bus_dmamap_create(dr->dr_txring_dtag, 0,
3847 device_printf(sc->sc_dev,
3848 "can't create RX buf DMA map\n");
3852 dr->getdesc(dr, i + 1, &desc, &mt);
3854 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3858 error = bus_dmamap_create(dma->txbuf_dtag, 0,
3861 device_printf(sc->sc_dev,
3862 "can't create RX buf DMA map\n");
3867 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3868 &dr->dr_spare_dmap);
3870 device_printf(sc->sc_dev,
3871 "can't create RX buf DMA map\n");
3872 goto out; /* XXX wrong! */
3875 for (i = 0; i < dr->dr_numslots; i++) {
3876 dr->getdesc(dr, i, &desc, &mt);
3878 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3881 device_printf(sc->sc_dev,
3882 "can't create RX buf DMA map\n");
3883 goto out; /* XXX wrong! */
3885 error = bwn_dma_newbuf(dr, desc, mt, 1);
3887 device_printf(sc->sc_dev,
3888 "failed to allocate RX buf\n");
3889 goto out; /* XXX wrong! */
3893 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3894 BUS_DMASYNC_PREWRITE);
3896 dr->dr_usedslot = dr->dr_numslots;
3903 free(dr->dr_txhdr_cache, M_DEVBUF);
3905 free(dr->dr_meta, M_DEVBUF);
3912 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3918 bwn_dma_free_descbufs(*dr);
3919 bwn_dma_free_ringmemory(*dr);
3921 free((*dr)->dr_txhdr_cache, M_DEVBUF);
3922 free((*dr)->dr_meta, M_DEVBUF);
3923 free(*dr, M_DEVBUF);
3929 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3930 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3932 struct bwn_dmadesc32 *desc;
3934 *meta = &(dr->dr_meta[slot]);
3935 desc = dr->dr_ring_descbase;
3936 desc = &(desc[slot]);
3938 *gdesc = (struct bwn_dmadesc_generic *)desc;
3942 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3943 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3944 int start, int end, int irq)
3946 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3947 struct bwn_softc *sc = dr->dr_mac->mac_sc;
3948 uint32_t addr, addrext, ctl;
3951 slot = (int)(&(desc->dma.dma32) - descbase);
3952 KASSERT(slot >= 0 && slot < dr->dr_numslots,
3953 ("%s:%d: fail", __func__, __LINE__));
3955 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
3956 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
3957 addr |= siba_dma_translation(sc->sc_dev);
3958 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3959 if (slot == dr->dr_numslots - 1)
3960 ctl |= BWN_DMA32_DCTL_DTABLEEND;
3962 ctl |= BWN_DMA32_DCTL_FRAMESTART;
3964 ctl |= BWN_DMA32_DCTL_FRAMEEND;
3966 ctl |= BWN_DMA32_DCTL_IRQ;
3967 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3968 & BWN_DMA32_DCTL_ADDREXT_MASK;
3970 desc->dma.dma32.control = htole32(ctl);
3971 desc->dma.dma32.address = htole32(addr);
3975 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3978 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3979 (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3983 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3986 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3987 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3991 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3994 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3995 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
3999 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
4003 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
4004 val &= BWN_DMA32_RXDPTR;
4006 return (val / sizeof(struct bwn_dmadesc32));
4010 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
4013 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
4014 (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
4018 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
4019 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
4021 struct bwn_dmadesc64 *desc;
4023 *meta = &(dr->dr_meta[slot]);
4024 desc = dr->dr_ring_descbase;
4025 desc = &(desc[slot]);
4027 *gdesc = (struct bwn_dmadesc_generic *)desc;
4031 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
4032 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
4033 int start, int end, int irq)
4035 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
4036 struct bwn_softc *sc = dr->dr_mac->mac_sc;
4038 uint32_t ctl0 = 0, ctl1 = 0;
4039 uint32_t addrlo, addrhi;
4042 slot = (int)(&(desc->dma.dma64) - descbase);
4043 KASSERT(slot >= 0 && slot < dr->dr_numslots,
4044 ("%s:%d: fail", __func__, __LINE__));
4046 addrlo = (uint32_t) (dmaaddr & 0xffffffff);
4047 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
4048 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
4050 addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
4051 if (slot == dr->dr_numslots - 1)
4052 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
4054 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
4056 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
4058 ctl0 |= BWN_DMA64_DCTL0_IRQ;
4059 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
4060 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
4061 & BWN_DMA64_DCTL1_ADDREXT_MASK;
4063 desc->dma.dma64.control0 = htole32(ctl0);
4064 desc->dma.dma64.control1 = htole32(ctl1);
4065 desc->dma.dma64.address_low = htole32(addrlo);
4066 desc->dma.dma64.address_high = htole32(addrhi);
4070 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
4073 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
4074 (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4078 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
4081 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4082 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
4086 bwn_dma_64_resume(struct bwn_dma_ring *dr)
4089 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4090 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
4094 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
4098 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
4099 val &= BWN_DMA64_RXSTATDPTR;
4101 return (val / sizeof(struct bwn_dmadesc64));
4105 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4108 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4109 (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4113 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4115 struct bwn_mac *mac = dr->dr_mac;
4116 struct bwn_dma *dma = &mac->mac_method.dma;
4117 struct bwn_softc *sc = mac->mac_sc;
4120 error = bus_dma_tag_create(dma->parent_dtag,
4125 BWN_DMA_RINGMEMSIZE,
4127 BUS_SPACE_MAXSIZE_32BIT,
4132 device_printf(sc->sc_dev,
4133 "can't create TX ring DMA tag: TODO frees\n");
4137 error = bus_dmamem_alloc(dr->dr_ring_dtag,
4138 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4141 device_printf(sc->sc_dev,
4142 "can't allocate DMA mem: TODO frees\n");
4145 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4146 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4147 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
4149 device_printf(sc->sc_dev,
4150 "can't load DMA mem: TODO free\n");
4158 bwn_dma_setup(struct bwn_dma_ring *dr)
4160 struct bwn_softc *sc = dr->dr_mac->mac_sc;
4162 uint32_t addrext, ring32, value;
4163 uint32_t trans = siba_dma_translation(sc->sc_dev);
4166 dr->dr_curslot = -1;
4168 if (dr->dr_type == BWN_DMA_64BIT) {
4169 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4170 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4172 value = BWN_DMA64_TXENABLE;
4173 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4174 & BWN_DMA64_TXADDREXT_MASK;
4175 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4176 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4177 (ring64 & 0xffffffff));
4178 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4180 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4182 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4183 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4184 value = BWN_DMA32_TXENABLE;
4185 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4186 & BWN_DMA32_TXADDREXT_MASK;
4187 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4188 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4189 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4197 dr->dr_usedslot = dr->dr_numslots;
4199 if (dr->dr_type == BWN_DMA_64BIT) {
4200 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4201 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4202 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4203 value |= BWN_DMA64_RXENABLE;
4204 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4205 & BWN_DMA64_RXADDREXT_MASK;
4206 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4207 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4208 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4209 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4211 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4212 sizeof(struct bwn_dmadesc64));
4214 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4215 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4216 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4217 value |= BWN_DMA32_RXENABLE;
4218 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4219 & BWN_DMA32_RXADDREXT_MASK;
4220 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4221 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4222 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4223 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4224 sizeof(struct bwn_dmadesc32));
4229 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4232 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4233 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4238 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4242 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4243 if (dr->dr_type == BWN_DMA_64BIT) {
4244 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4245 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4247 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4249 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4250 if (dr->dr_type == BWN_DMA_64BIT) {
4251 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4252 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4254 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4259 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4261 struct bwn_dmadesc_generic *desc;
4262 struct bwn_dmadesc_meta *meta;
4263 struct bwn_mac *mac = dr->dr_mac;
4264 struct bwn_dma *dma = &mac->mac_method.dma;
4265 struct bwn_softc *sc = mac->mac_sc;
4268 if (!dr->dr_usedslot)
4270 for (i = 0; i < dr->dr_numslots; i++) {
4271 dr->getdesc(dr, i, &desc, &meta);
4273 if (meta->mt_m == NULL) {
4275 device_printf(sc->sc_dev, "%s: not TX?\n",
4280 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
4281 bus_dmamap_unload(dr->dr_txring_dtag,
4283 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
4284 bus_dmamap_unload(dma->txbuf_dtag,
4287 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4288 bwn_dma_free_descbuf(dr, meta);
4293 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4296 struct bwn_softc *sc = mac->mac_sc;
4301 for (i = 0; i < 10; i++) {
4302 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4304 value = BWN_READ_4(mac, base + offset);
4305 if (type == BWN_DMA_64BIT) {
4306 value &= BWN_DMA64_TXSTAT;
4307 if (value == BWN_DMA64_TXSTAT_DISABLED ||
4308 value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4309 value == BWN_DMA64_TXSTAT_STOPPED)
4312 value &= BWN_DMA32_TXSTATE;
4313 if (value == BWN_DMA32_TXSTAT_DISABLED ||
4314 value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4315 value == BWN_DMA32_TXSTAT_STOPPED)
4320 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4321 BWN_WRITE_4(mac, base + offset, 0);
4322 for (i = 0; i < 10; i++) {
4323 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4325 value = BWN_READ_4(mac, base + offset);
4326 if (type == BWN_DMA_64BIT) {
4327 value &= BWN_DMA64_TXSTAT;
4328 if (value == BWN_DMA64_TXSTAT_DISABLED) {
4333 value &= BWN_DMA32_TXSTATE;
4334 if (value == BWN_DMA32_TXSTAT_DISABLED) {
4342 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4351 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4354 struct bwn_softc *sc = mac->mac_sc;
4359 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4360 BWN_WRITE_4(mac, base + offset, 0);
4361 for (i = 0; i < 10; i++) {
4362 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4364 value = BWN_READ_4(mac, base + offset);
4365 if (type == BWN_DMA_64BIT) {
4366 value &= BWN_DMA64_RXSTAT;
4367 if (value == BWN_DMA64_RXSTAT_DISABLED) {
4372 value &= BWN_DMA32_RXSTATE;
4373 if (value == BWN_DMA32_RXSTAT_DISABLED) {
4381 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4389 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4390 struct bwn_dmadesc_meta *meta)
4393 if (meta->mt_m != NULL) {
4394 m_freem(meta->mt_m);
4397 if (meta->mt_ni != NULL) {
4398 ieee80211_free_node(meta->mt_ni);
4404 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4406 struct bwn_rxhdr4 *rxhdr;
4407 unsigned char *frame;
4409 rxhdr = mtod(m, struct bwn_rxhdr4 *);
4410 rxhdr->frame_len = 0;
4412 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4413 sizeof(struct bwn_plcp6) + 2,
4414 ("%s:%d: fail", __func__, __LINE__));
4415 frame = mtod(m, char *) + dr->dr_frameoffset;
4416 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4420 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4422 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4424 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4429 bwn_wme_init(struct bwn_mac *mac)
4434 /* enable WME support. */
4435 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4436 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4437 BWN_IFSCTL_USE_EDCF);
4441 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4443 struct bwn_softc *sc = mac->mac_sc;
4444 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
4445 uint16_t delay; /* microsec */
4447 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4448 if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4450 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4451 delay = max(delay, (uint16_t)2400);
4453 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4457 bwn_bt_enable(struct bwn_mac *mac)
4459 struct bwn_softc *sc = mac->mac_sc;
4462 if (bwn_bluetooth == 0)
4464 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4466 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4469 hf = bwn_hf_read(mac);
4470 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4471 hf |= BWN_HF_BT_COEXISTALT;
4473 hf |= BWN_HF_BT_COEXIST;
4474 bwn_hf_write(mac, hf);
4478 bwn_set_macaddr(struct bwn_mac *mac)
4481 bwn_mac_write_bssid(mac);
4482 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
4486 bwn_clear_keys(struct bwn_mac *mac)
4490 for (i = 0; i < mac->mac_max_nr_keys; i++) {
4491 KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4492 ("%s:%d: fail", __func__, __LINE__));
4494 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4495 NULL, BWN_SEC_KEYSIZE, NULL);
4496 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4497 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4498 NULL, BWN_SEC_KEYSIZE, NULL);
4500 mac->mac_key[i].keyconf = NULL;
4505 bwn_crypt_init(struct bwn_mac *mac)
4507 struct bwn_softc *sc = mac->mac_sc;
4509 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4510 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4511 ("%s:%d: fail", __func__, __LINE__));
4512 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4514 if (siba_get_revid(sc->sc_dev) >= 5)
4515 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4516 bwn_clear_keys(mac);
4520 bwn_chip_exit(struct bwn_mac *mac)
4522 struct bwn_softc *sc = mac->mac_sc;
4525 siba_gpio_set(sc->sc_dev, 0);
4529 bwn_fw_fillinfo(struct bwn_mac *mac)
4533 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4536 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4543 bwn_gpio_init(struct bwn_mac *mac)
4545 struct bwn_softc *sc = mac->mac_sc;
4546 uint32_t mask = 0x1f, set = 0xf, value;
4548 BWN_WRITE_4(mac, BWN_MACCTL,
4549 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4550 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4551 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4553 if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4557 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4558 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4559 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4563 if (siba_get_revid(sc->sc_dev) >= 2)
4566 value = siba_gpio_get(sc->sc_dev);
4569 siba_gpio_set(sc->sc_dev, (value & mask) | set);
4575 bwn_fw_loadinitvals(struct bwn_mac *mac)
4577 #define GETFWOFFSET(fwp, offset) \
4578 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4579 const size_t hdr_len = sizeof(struct bwn_fwhdr);
4580 const struct bwn_fwhdr *hdr;
4581 struct bwn_fw *fw = &mac->mac_fw;
4584 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4585 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4586 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4589 if (fw->initvals_band.fw) {
4590 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4591 error = bwn_fwinitvals_write(mac,
4592 GETFWOFFSET(fw->initvals_band, hdr_len),
4594 fw->initvals_band.fw->datasize - hdr_len);
4601 bwn_phy_init(struct bwn_mac *mac)
4603 struct bwn_softc *sc = mac->mac_sc;
4606 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4607 mac->mac_phy.rf_onoff(mac, 1);
4608 error = mac->mac_phy.init(mac);
4610 device_printf(sc->sc_dev, "PHY init failed\n");
4613 error = bwn_switch_channel(mac,
4614 mac->mac_phy.get_default_chan(mac));
4616 device_printf(sc->sc_dev,
4617 "failed to switch default channel\n");
4622 if (mac->mac_phy.exit)
4623 mac->mac_phy.exit(mac);
4625 mac->mac_phy.rf_onoff(mac, 0);
4631 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4636 ant = bwn_ant2phy(antenna);
4639 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4640 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4641 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4642 /* For Probe Resposes */
4643 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4644 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4645 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4649 bwn_set_opmode(struct bwn_mac *mac)
4651 struct bwn_softc *sc = mac->mac_sc;
4652 struct ifnet *ifp = sc->sc_ifp;
4653 struct ieee80211com *ic = ifp->if_l2com;
4655 uint16_t cfp_pretbtt;
4657 ctl = BWN_READ_4(mac, BWN_MACCTL);
4658 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4659 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4660 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4661 ctl |= BWN_MACCTL_STA;
4663 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4664 ic->ic_opmode == IEEE80211_M_MBSS)
4665 ctl |= BWN_MACCTL_HOSTAP;
4666 else if (ic->ic_opmode == IEEE80211_M_IBSS)
4667 ctl &= ~BWN_MACCTL_STA;
4668 ctl |= sc->sc_filters;
4670 if (siba_get_revid(sc->sc_dev) <= 4)
4671 ctl |= BWN_MACCTL_PROMISC;
4673 BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4676 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4677 if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4678 siba_get_chiprev(sc->sc_dev) == 3)
4683 BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4687 bwn_dma_gettype(struct bwn_mac *mac)
4692 tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4693 if (tmp & SIBA_TGSHIGH_DMA64)
4694 return (BWN_DMA_64BIT);
4695 base = bwn_dma_base(0, 0);
4696 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4697 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4698 if (tmp & BWN_DMA32_TXADDREXT_MASK)
4699 return (BWN_DMA_32BIT);
4701 return (BWN_DMA_30BIT);
4705 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4708 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4709 *((bus_addr_t *)arg) = seg->ds_addr;
4714 bwn_phy_g_init_sub(struct bwn_mac *mac)
4716 struct bwn_phy *phy = &mac->mac_phy;
4717 struct bwn_phy_g *pg = &phy->phy_g;
4718 struct bwn_softc *sc = mac->mac_sc;
4722 bwn_phy_init_b5(mac);
4724 bwn_phy_init_b6(mac);
4726 if (phy->rev >= 2 || phy->gmode)
4727 bwn_phy_init_a(mac);
4729 if (phy->rev >= 2) {
4730 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4731 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4733 if (phy->rev == 2) {
4734 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4735 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4738 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4739 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4741 if (phy->gmode || phy->rev >= 2) {
4742 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4743 tmp &= BWN_PHYVER_VERSION;
4744 if (tmp == 3 || tmp == 5) {
4745 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4746 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4749 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4753 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4754 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4755 if (phy->rf_rev == 8) {
4756 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4757 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4759 if (BWN_HAS_LOOPBACK(phy))
4760 bwn_loopback_calcgain(mac);
4762 if (phy->rf_rev != 8) {
4763 if (pg->pg_initval == 0xffff)
4764 pg->pg_initval = bwn_rf_init_bcm2050(mac);
4766 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4769 if (BWN_HAS_TXMAG(phy)) {
4770 BWN_RF_WRITE(mac, 0x52,
4771 (BWN_RF_READ(mac, 0x52) & 0xff00)
4772 | pg->pg_loctl.tx_bias |
4773 pg->pg_loctl.tx_magn);
4775 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4777 if (phy->rev >= 6) {
4778 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4779 (pg->pg_loctl.tx_bias << 12));
4781 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4782 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4784 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4786 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4788 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4789 if (phy->gmode || phy->rev >= 2) {
4790 bwn_lo_g_adjust(mac);
4791 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4794 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4795 for (i = 0; i < 64; i++) {
4796 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4797 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4798 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4801 bwn_nrssi_threshold(mac);
4802 } else if (phy->gmode || phy->rev >= 2) {
4803 if (pg->pg_nrssi[0] == -1000) {
4804 KASSERT(pg->pg_nrssi[1] == -1000,
4805 ("%s:%d: fail", __func__, __LINE__));
4806 bwn_nrssi_slope_11g(mac);
4808 bwn_nrssi_threshold(mac);
4810 if (phy->rf_rev == 8)
4811 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4812 bwn_phy_hwpctl_init(mac);
4813 if ((siba_get_chipid(sc->sc_dev) == 0x4306
4814 && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4815 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4816 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4821 bwn_has_hwpctl(struct bwn_mac *mac)
4824 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4826 return (mac->mac_phy.use_hwpctl(mac));
4830 bwn_phy_init_b5(struct bwn_mac *mac)
4832 struct bwn_phy *phy = &mac->mac_phy;
4833 struct bwn_phy_g *pg = &phy->phy_g;
4834 struct bwn_softc *sc = mac->mac_sc;
4835 uint16_t offset, value;
4836 uint8_t old_channel;
4838 if (phy->analog == 1)
4839 BWN_RF_SET(mac, 0x007a, 0x0050);
4840 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4841 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4843 for (offset = 0x00a8; offset < 0x00c7; offset++) {
4844 BWN_PHY_WRITE(mac, offset, value);
4848 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4849 if (phy->rf_ver == 0x2050)
4850 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4852 if (phy->gmode || phy->rev >= 2) {
4853 if (phy->rf_ver == 0x2050) {
4854 BWN_RF_SET(mac, 0x007a, 0x0020);
4855 BWN_RF_SET(mac, 0x0051, 0x0004);
4857 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4859 BWN_PHY_SET(mac, 0x0802, 0x0100);
4860 BWN_PHY_SET(mac, 0x042b, 0x2000);
4862 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4864 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4865 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4866 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4869 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4870 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4872 if (phy->analog == 1) {
4873 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4874 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4875 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4876 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4877 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4879 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4880 BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4881 BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4883 if (phy->analog == 1)
4884 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4886 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4888 if (phy->analog == 0)
4889 BWN_WRITE_2(mac, 0x03e4, 0x3000);
4891 old_channel = phy->chan;
4892 bwn_phy_g_switch_chan(mac, 7, 0);
4894 if (phy->rf_ver != 0x2050) {
4895 BWN_RF_WRITE(mac, 0x0075, 0x0080);
4896 BWN_RF_WRITE(mac, 0x0079, 0x0081);
4899 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4900 BWN_RF_WRITE(mac, 0x0050, 0x0023);
4902 if (phy->rf_ver == 0x2050) {
4903 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4904 BWN_RF_WRITE(mac, 0x005a, 0x0070);
4907 BWN_RF_WRITE(mac, 0x005b, 0x007b);
4908 BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4909 BWN_RF_SET(mac, 0x007a, 0x0007);
4911 bwn_phy_g_switch_chan(mac, old_channel, 0);
4912 BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4913 BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4914 BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4916 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4919 if (phy->rf_ver == 0x2050)
4920 BWN_RF_WRITE(mac, 0x005d, 0x000d);
4922 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4926 bwn_loopback_calcgain(struct bwn_mac *mac)
4928 struct bwn_phy *phy = &mac->mac_phy;
4929 struct bwn_phy_g *pg = &phy->phy_g;
4930 struct bwn_softc *sc = mac->mac_sc;
4931 uint16_t backup_phy[16] = { 0 };
4932 uint16_t backup_radio[3];
4933 uint16_t backup_bband;
4934 uint16_t i, j, loop_i_max;
4936 uint16_t loop1_outer_done, loop1_inner_done;
4938 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4939 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4940 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4941 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4942 if (phy->rev != 1) {
4943 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4944 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4946 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4947 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4948 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4949 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4950 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4951 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4952 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4953 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4954 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4955 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4956 backup_bband = pg->pg_bbatt.att;
4957 backup_radio[0] = BWN_RF_READ(mac, 0x52);
4958 backup_radio[1] = BWN_RF_READ(mac, 0x43);
4959 backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4961 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4962 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4963 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4964 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4965 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4966 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4967 if (phy->rev != 1) {
4968 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4969 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4970 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4971 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4973 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4974 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4975 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4976 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4978 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4979 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4980 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4982 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4983 if (phy->rev != 1) {
4984 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4985 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4987 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4989 if (phy->rf_rev == 8)
4990 BWN_RF_WRITE(mac, 0x43, 0x000f);
4992 BWN_RF_WRITE(mac, 0x52, 0);
4993 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4995 bwn_phy_g_set_bbatt(mac, 11);
4998 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5000 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5001 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5003 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
5004 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
5006 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
5007 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
5009 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
5010 if (phy->rev >= 7) {
5011 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
5012 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
5015 BWN_RF_MASK(mac, 0x7a, 0x00f7);
5018 loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
5019 for (i = 0; i < loop_i_max; i++) {
5020 for (j = 0; j < 16; j++) {
5021 BWN_RF_WRITE(mac, 0x43, i);
5022 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
5024 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5025 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5027 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5032 loop1_outer_done = i;
5033 loop1_inner_done = j;
5035 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
5037 for (j = j - 8; j < 16; j++) {
5038 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
5039 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5040 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5043 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5050 if (phy->rev != 1) {
5051 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
5052 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
5054 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
5055 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
5056 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
5057 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
5058 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
5059 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
5060 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
5061 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
5062 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
5064 bwn_phy_g_set_bbatt(mac, backup_bband);
5066 BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
5067 BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
5068 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
5070 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
5072 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
5073 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
5074 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
5075 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
5077 pg->pg_max_lb_gain =
5078 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
5079 pg->pg_trsw_rx_gain = trsw_rx * 2;
5083 bwn_rf_init_bcm2050(struct bwn_mac *mac)
5085 struct bwn_phy *phy = &mac->mac_phy;
5086 uint32_t tmp1 = 0, tmp2 = 0;
5087 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
5088 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
5089 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
5090 static const uint8_t rcc_table[] = {
5091 0x02, 0x03, 0x01, 0x0f,
5092 0x06, 0x07, 0x05, 0x0f,
5093 0x0a, 0x0b, 0x09, 0x0f,
5094 0x0e, 0x0f, 0x0d, 0x0f,
5097 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
5098 rfoverval = rfover = cck3 = 0;
5099 radio0 = BWN_RF_READ(mac, 0x43);
5100 radio1 = BWN_RF_READ(mac, 0x51);
5101 radio2 = BWN_RF_READ(mac, 0x52);
5102 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5103 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5104 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5105 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5107 if (phy->type == BWN_PHYTYPE_B) {
5108 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5109 reg0 = BWN_READ_2(mac, 0x3ec);
5111 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5112 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5113 } else if (phy->gmode || phy->rev >= 2) {
5114 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5115 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5116 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5117 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5118 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5119 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5121 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5122 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5123 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5124 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5125 if (BWN_HAS_LOOPBACK(phy)) {
5126 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5127 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5129 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5131 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5132 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5135 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5136 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5138 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5139 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5141 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5143 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5144 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5145 reg1 = BWN_READ_2(mac, 0x3e6);
5146 reg2 = BWN_READ_2(mac, 0x3f4);
5148 if (phy->analog == 0)
5149 BWN_WRITE_2(mac, 0x03e6, 0x0122);
5151 if (phy->analog >= 2)
5152 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5153 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5154 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5157 reg = BWN_RF_READ(mac, 0x60);
5158 index = (reg & 0x001e) >> 1;
5159 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5161 if (phy->type == BWN_PHYTYPE_B)
5162 BWN_RF_WRITE(mac, 0x78, 0x26);
5163 if (phy->gmode || phy->rev >= 2) {
5164 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5165 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5168 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5169 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5170 if (phy->gmode || phy->rev >= 2) {
5171 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5172 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5175 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5176 BWN_RF_SET(mac, 0x51, 0x0004);
5177 if (phy->rf_rev == 8)
5178 BWN_RF_WRITE(mac, 0x43, 0x1f);
5180 BWN_RF_WRITE(mac, 0x52, 0);
5181 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5183 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5185 for (i = 0; i < 16; i++) {
5186 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5187 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5188 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5189 if (phy->gmode || phy->rev >= 2) {
5190 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5191 bwn_rf_2050_rfoverval(mac,
5192 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5194 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5196 if (phy->gmode || phy->rev >= 2) {
5197 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5198 bwn_rf_2050_rfoverval(mac,
5199 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5201 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5203 if (phy->gmode || phy->rev >= 2) {
5204 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5205 bwn_rf_2050_rfoverval(mac,
5206 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5208 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5210 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5211 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5212 if (phy->gmode || phy->rev >= 2) {
5213 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5214 bwn_rf_2050_rfoverval(mac,
5215 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5217 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5221 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5225 for (i = 0; i < 16; i++) {
5226 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5227 BWN_RF_WRITE(mac, 0x78, radio78);
5229 for (j = 0; j < 16; j++) {
5230 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5231 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5232 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5233 if (phy->gmode || phy->rev >= 2) {
5234 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5235 bwn_rf_2050_rfoverval(mac,
5236 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5238 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5240 if (phy->gmode || phy->rev >= 2) {
5241 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5242 bwn_rf_2050_rfoverval(mac,
5243 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5245 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5247 if (phy->gmode || phy->rev >= 2) {
5248 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5249 bwn_rf_2050_rfoverval(mac,
5250 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5252 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5254 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5255 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5256 if (phy->gmode || phy->rev >= 2) {
5257 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5258 bwn_rf_2050_rfoverval(mac,
5259 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5261 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5269 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5270 BWN_RF_WRITE(mac, 0x51, radio1);
5271 BWN_RF_WRITE(mac, 0x52, radio2);
5272 BWN_RF_WRITE(mac, 0x43, radio0);
5273 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5274 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5275 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5276 BWN_WRITE_2(mac, 0x3e6, reg1);
5277 if (phy->analog != 0)
5278 BWN_WRITE_2(mac, 0x3f4, reg2);
5279 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5280 bwn_spu_workaround(mac, phy->chan);
5281 if (phy->type == BWN_PHYTYPE_B) {
5282 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5283 BWN_WRITE_2(mac, 0x3ec, reg0);
5284 } else if (phy->gmode) {
5285 BWN_WRITE_2(mac, BWN_PHY_RADIO,
5286 BWN_READ_2(mac, BWN_PHY_RADIO)
5288 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5289 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5290 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5291 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5293 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5294 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5295 if (BWN_HAS_LOOPBACK(phy)) {
5296 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5297 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5301 return ((i > 15) ? radio78 : rcc);
5305 bwn_phy_init_b6(struct bwn_mac *mac)
5307 struct bwn_phy *phy = &mac->mac_phy;
5308 struct bwn_phy_g *pg = &phy->phy_g;
5309 struct bwn_softc *sc = mac->mac_sc;
5310 uint16_t offset, val;
5311 uint8_t old_channel;
5313 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5314 ("%s:%d: fail", __func__, __LINE__));
5316 BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5317 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5318 if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5319 BWN_RF_WRITE(mac, 0x51, 0x37);
5320 BWN_RF_WRITE(mac, 0x52, 0x70);
5321 BWN_RF_WRITE(mac, 0x53, 0xb3);
5322 BWN_RF_WRITE(mac, 0x54, 0x9b);
5323 BWN_RF_WRITE(mac, 0x5a, 0x88);
5324 BWN_RF_WRITE(mac, 0x5b, 0x88);
5325 BWN_RF_WRITE(mac, 0x5d, 0x88);
5326 BWN_RF_WRITE(mac, 0x5e, 0x88);
5327 BWN_RF_WRITE(mac, 0x7d, 0x88);
5329 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5331 if (phy->rf_rev == 8) {
5332 BWN_RF_WRITE(mac, 0x51, 0);
5333 BWN_RF_WRITE(mac, 0x52, 0x40);
5334 BWN_RF_WRITE(mac, 0x53, 0xb7);
5335 BWN_RF_WRITE(mac, 0x54, 0x98);
5336 BWN_RF_WRITE(mac, 0x5a, 0x88);
5337 BWN_RF_WRITE(mac, 0x5b, 0x6b);
5338 BWN_RF_WRITE(mac, 0x5c, 0x0f);
5339 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5340 BWN_RF_WRITE(mac, 0x5d, 0xfa);
5341 BWN_RF_WRITE(mac, 0x5e, 0xd8);
5343 BWN_RF_WRITE(mac, 0x5d, 0xf5);
5344 BWN_RF_WRITE(mac, 0x5e, 0xb8);
5346 BWN_RF_WRITE(mac, 0x0073, 0x0003);
5347 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5348 BWN_RF_WRITE(mac, 0x007c, 0x0001);
5349 BWN_RF_WRITE(mac, 0x007e, 0x0008);
5351 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5352 BWN_PHY_WRITE(mac, offset, val);
5355 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5356 BWN_PHY_WRITE(mac, offset, val);
5359 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5360 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5363 if (phy->type == BWN_PHYTYPE_G) {
5364 BWN_RF_SET(mac, 0x007a, 0x0020);
5365 BWN_RF_SET(mac, 0x0051, 0x0004);
5366 BWN_PHY_SET(mac, 0x0802, 0x0100);
5367 BWN_PHY_SET(mac, 0x042b, 0x2000);
5368 BWN_PHY_WRITE(mac, 0x5b, 0);
5369 BWN_PHY_WRITE(mac, 0x5c, 0);
5372 old_channel = phy->chan;
5373 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5375 BWN_RF_WRITE(mac, 0x0050, 0x0020);
5376 BWN_RF_WRITE(mac, 0x0050, 0x0023);
5378 if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5379 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5380 BWN_RF_WRITE(mac, 0x50, 0x20);
5382 if (phy->rf_rev <= 2) {
5383 BWN_RF_WRITE(mac, 0x7c, 0x20);
5384 BWN_RF_WRITE(mac, 0x5a, 0x70);
5385 BWN_RF_WRITE(mac, 0x5b, 0x7b);
5386 BWN_RF_WRITE(mac, 0x5c, 0xb0);
5388 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5390 bwn_phy_g_switch_chan(mac, old_channel, 0);
5392 BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5393 if (phy->rf_rev >= 6)
5394 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5396 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5397 BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5398 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5400 if (phy->rf_rev <= 5)
5401 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5402 if (phy->rf_rev <= 2)
5403 BWN_RF_WRITE(mac, 0x005d, 0x000d);
5405 if (phy->analog == 4) {
5406 BWN_WRITE_2(mac, 0x3e4, 9);
5407 BWN_PHY_MASK(mac, 0x61, 0x0fff);
5409 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5410 if (phy->type == BWN_PHYTYPE_B)
5411 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5412 else if (phy->type == BWN_PHYTYPE_G)
5413 BWN_WRITE_2(mac, 0x03e6, 0x0);
5417 bwn_phy_init_a(struct bwn_mac *mac)
5419 struct bwn_phy *phy = &mac->mac_phy;
5420 struct bwn_softc *sc = mac->mac_sc;
5422 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5423 ("%s:%d: fail", __func__, __LINE__));
5425 if (phy->rev >= 6) {
5426 if (phy->type == BWN_PHYTYPE_A)
5427 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5428 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5429 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5431 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5436 if (phy->type == BWN_PHYTYPE_G &&
5437 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5438 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5442 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5446 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5447 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5451 bwn_wa_agc(struct bwn_mac *mac)
5453 struct bwn_phy *phy = &mac->mac_phy;
5455 if (phy->rev == 1) {
5456 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5457 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5458 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5459 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5460 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5461 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5462 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5463 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5464 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5466 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5467 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5468 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5469 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5472 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5474 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5475 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5476 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5477 BWN_RF_SET(mac, 0x7a, 0x0008);
5478 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5479 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5480 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5481 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5483 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5484 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5485 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5486 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5487 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5488 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5489 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5490 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5491 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5492 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5493 if (phy->rev == 1) {
5494 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5495 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5497 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5498 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5499 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5500 if (phy->rev >= 6) {
5501 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5502 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5503 (uint16_t)~0xf000, 0x3000);
5506 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5507 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5508 if (phy->rev == 1) {
5509 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5510 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5511 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5512 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5513 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5514 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5515 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5516 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5518 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5519 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5520 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5521 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5523 if (phy->rev >= 6) {
5524 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5525 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5527 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5531 bwn_wa_grev1(struct bwn_mac *mac)
5533 struct bwn_phy *phy = &mac->mac_phy;
5535 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5536 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5537 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5539 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5541 /* init CRSTHRES and ANTDWELL */
5542 if (phy->rev == 1) {
5543 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5544 } else if (phy->rev == 2) {
5545 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5546 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5547 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5549 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5550 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5551 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5552 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5554 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5555 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5556 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5558 /* XXX support PHY-A??? */
5559 for (i = 0; i < N(bwn_tab_finefreqg); i++)
5560 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5561 bwn_tab_finefreqg[i]);
5563 /* XXX support PHY-A??? */
5565 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5566 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5567 bwn_tab_noise_g1[i]);
5569 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5570 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5571 bwn_tab_noise_g2[i]);
5574 for (i = 0; i < N(bwn_tab_rotor); i++)
5575 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5578 /* XXX support PHY-A??? */
5579 if (phy->rev >= 6) {
5580 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5582 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5584 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5586 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5588 for (i = 0; i < N(bwn_tab_retard); i++)
5589 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5592 if (phy->rev == 1) {
5593 for (i = 0; i < 16; i++)
5594 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5597 for (i = 0; i < 32; i++)
5598 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5605 bwn_wa_grev26789(struct bwn_mac *mac)
5607 struct bwn_phy *phy = &mac->mac_phy;
5609 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5612 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5614 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5616 /* init CRSTHRES and ANTDWELL */
5618 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5619 else if (phy->rev == 2) {
5620 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5621 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5622 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5624 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5625 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5626 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5627 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5630 for (i = 0; i < 64; i++)
5631 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5633 /* XXX support PHY-A??? */
5635 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5636 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5637 bwn_tab_noise_g1[i]);
5639 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5640 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5641 bwn_tab_noise_g2[i]);
5643 /* XXX support PHY-A??? */
5644 if (phy->rev >= 6) {
5645 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5647 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5649 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5651 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5653 for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5654 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5655 bwn_tab_sigmasqr2[i]);
5657 if (phy->rev == 1) {
5658 for (i = 0; i < 16; i++)
5659 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5662 for (i = 0; i < 32; i++)
5663 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5668 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5670 if (phy->type == BWN_PHYTYPE_A)
5671 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5673 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5675 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5676 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5677 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5680 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5681 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5685 bwn_wa_init(struct bwn_mac *mac)
5687 struct bwn_phy *phy = &mac->mac_phy;
5688 struct bwn_softc *sc = mac->mac_sc;
5690 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5701 bwn_wa_grev26789(mac);
5704 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5707 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5708 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5709 siba_get_pci_revid(sc->sc_dev) != 0x17) {
5711 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5713 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5716 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5717 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5718 if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5721 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5722 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5724 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5726 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5728 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5730 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5732 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5737 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5738 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5739 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5742 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5743 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5747 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5750 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5753 addr = table + offset;
5754 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5755 (addr - 1 != pg->pg_ofdmtab_addr)) {
5756 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5757 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5759 pg->pg_ofdmtab_addr = addr;
5760 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5764 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5767 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5770 addr = table + offset;
5771 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5772 (addr - 1 != pg->pg_ofdmtab_addr)) {
5773 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5774 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5776 pg->pg_ofdmtab_addr = addr;
5778 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5779 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5783 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5787 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5788 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5792 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5794 struct bwn_phy *phy = &mac->mac_phy;
5795 struct bwn_softc *sc = mac->mac_sc;
5796 unsigned int i, max_loop;
5798 uint32_t buffer[5] = {
5799 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5804 buffer[0] = 0x000201cc;
5807 buffer[0] = 0x000b846e;
5810 BWN_ASSERT_LOCKED(mac->mac_sc);
5812 for (i = 0; i < 5; i++)
5813 bwn_ram_write(mac, i * 4, buffer[i]);
5815 BWN_WRITE_2(mac, 0x0568, 0x0000);
5816 BWN_WRITE_2(mac, 0x07c0,
5817 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5818 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5819 BWN_WRITE_2(mac, 0x050c, value);
5820 if (phy->type == BWN_PHYTYPE_LP)
5821 BWN_WRITE_2(mac, 0x0514, 0x1a02);
5822 BWN_WRITE_2(mac, 0x0508, 0x0000);
5823 BWN_WRITE_2(mac, 0x050a, 0x0000);
5824 BWN_WRITE_2(mac, 0x054c, 0x0000);
5825 BWN_WRITE_2(mac, 0x056a, 0x0014);
5826 BWN_WRITE_2(mac, 0x0568, 0x0826);
5827 BWN_WRITE_2(mac, 0x0500, 0x0000);
5828 if (phy->type == BWN_PHYTYPE_LP)
5829 BWN_WRITE_2(mac, 0x0502, 0x0050);
5831 BWN_WRITE_2(mac, 0x0502, 0x0030);
5833 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5834 BWN_RF_WRITE(mac, 0x0051, 0x0017);
5835 for (i = 0x00; i < max_loop; i++) {
5836 value = BWN_READ_2(mac, 0x050e);
5841 for (i = 0x00; i < 0x0a; i++) {
5842 value = BWN_READ_2(mac, 0x050e);
5847 for (i = 0x00; i < 0x19; i++) {
5848 value = BWN_READ_2(mac, 0x0690);
5849 if (!(value & 0x0100))
5853 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5854 BWN_RF_WRITE(mac, 0x0051, 0x0037);
5858 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5862 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5864 macctl = BWN_READ_4(mac, BWN_MACCTL);
5865 if (macctl & BWN_MACCTL_BIGENDIAN)
5866 printf("TODO: need swap\n");
5868 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5869 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5870 BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5874 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5878 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5879 ("%s:%d: fail", __func__, __LINE__));
5881 value = (uint8_t) (ctl->q);
5882 value |= ((uint8_t) (ctl->i)) << 8;
5883 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5887 bwn_lo_calcfeed(struct bwn_mac *mac,
5888 uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5890 struct bwn_phy *phy = &mac->mac_phy;
5891 struct bwn_softc *sc = mac->mac_sc;
5893 uint16_t feedthrough;
5896 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5897 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5899 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5900 ("%s:%d: fail", __func__, __LINE__));
5901 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5902 ("%s:%d: fail", __func__, __LINE__));
5904 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5906 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5907 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5909 rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5911 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5912 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5914 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5915 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5917 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5918 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5920 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5922 pga |= BWN_PHY_PGACTL_UNKNOWN;
5923 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5925 pga |= BWN_PHY_PGACTL_LOWBANDW;
5926 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5928 pga |= BWN_PHY_PGACTL_LPF;
5929 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5932 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5934 return (feedthrough);
5938 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5939 uint16_t *value, uint16_t *pad_mix_gain)
5941 struct bwn_phy *phy = &mac->mac_phy;
5942 uint16_t reg, v, padmix;
5944 if (phy->type == BWN_PHYTYPE_B) {
5946 if (phy->rf_rev <= 5) {
5954 if (phy->rev >= 2 && phy->rf_rev == 8) {
5967 *pad_mix_gain = padmix;
5973 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5975 struct bwn_phy *phy = &mac->mac_phy;
5976 struct bwn_phy_g *pg = &phy->phy_g;
5977 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5979 uint16_t trsw_rx, pga;
5980 uint16_t rf_pctl_reg;
5982 static const uint8_t tx_bias_values[] = {
5983 0x09, 0x08, 0x0a, 0x01, 0x00,
5984 0x02, 0x05, 0x04, 0x06,
5986 static const uint8_t tx_magn_values[] = {
5990 if (!BWN_HAS_LOOPBACK(phy)) {
5998 lb_gain = pg->pg_max_lb_gain / 2;
6001 pga = abs(10 - lb_gain) / 6;
6002 pga = MIN(MAX(pga, 0), 15);
6009 if ((phy->rev >= 2) &&
6010 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
6013 if ((10 - lb_gain) < cmp_val)
6014 tmp = (10 - lb_gain);
6022 rf_pctl_reg = cmp_val;
6027 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
6028 bwn_phy_g_set_bbatt(mac, 2);
6030 reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
6032 BWN_RF_MASK(mac, reg, mask);
6034 if (BWN_HAS_TXMAG(phy)) {
6037 int min_feedth = 0xffff;
6038 uint8_t tx_magn, tx_bias;
6040 for (i = 0; i < N(tx_magn_values); i++) {
6041 tx_magn = tx_magn_values[i];
6042 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
6043 for (j = 0; j < N(tx_bias_values); j++) {
6044 tx_bias = tx_bias_values[j];
6045 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
6046 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
6048 if (feedthrough < min_feedth) {
6049 lo->tx_bias = tx_bias;
6050 lo->tx_magn = tx_magn;
6051 min_feedth = feedthrough;
6053 if (lo->tx_bias == 0)
6056 BWN_RF_WRITE(mac, 0x52,
6057 (BWN_RF_READ(mac, 0x52)
6058 & 0xff00) | lo->tx_bias | lo->
6064 BWN_RF_MASK(mac, 0x52, 0xfff0);
6067 BWN_GETTIME(lo->txctl_measured_time);
6071 bwn_lo_get_powervector(struct bwn_mac *mac)
6073 struct bwn_phy *phy = &mac->mac_phy;
6074 struct bwn_phy_g *pg = &phy->phy_g;
6075 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6078 uint64_t power_vector = 0;
6080 for (i = 0; i < 8; i += 2) {
6081 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
6082 power_vector |= (tmp << (i * 8));
6083 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
6086 lo->power_vector = power_vector;
6088 BWN_GETTIME(lo->pwr_vec_read_time);
6092 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
6095 struct bwn_phy *phy = &mac->mac_phy;
6096 struct bwn_phy_g *pg = &phy->phy_g;
6099 if (max_rx_gain < 0)
6102 if (BWN_HAS_LOOPBACK(phy)) {
6107 trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6108 if (max_rx_gain >= trsw_rx_gain) {
6109 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6113 trsw_rx_gain = max_rx_gain;
6114 if (trsw_rx_gain < 9) {
6115 pg->pg_lna_lod_gain = 0;
6117 pg->pg_lna_lod_gain = 1;
6120 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6121 pg->pg_pga_gain = trsw_rx_gain / 3;
6122 if (pg->pg_pga_gain >= 5) {
6123 pg->pg_pga_gain -= 5;
6124 pg->pg_lna_gain = 2;
6126 pg->pg_lna_gain = 0;
6128 pg->pg_lna_gain = 0;
6129 pg->pg_trsw_rx_gain = 0x20;
6130 if (max_rx_gain >= 0x14) {
6131 pg->pg_lna_lod_gain = 1;
6132 pg->pg_pga_gain = 2;
6133 } else if (max_rx_gain >= 0x12) {
6134 pg->pg_lna_lod_gain = 1;
6135 pg->pg_pga_gain = 1;
6136 } else if (max_rx_gain >= 0xf) {
6137 pg->pg_lna_lod_gain = 1;
6138 pg->pg_pga_gain = 0;
6140 pg->pg_lna_lod_gain = 0;
6141 pg->pg_pga_gain = 0;
6145 tmp = BWN_RF_READ(mac, 0x7a);
6146 if (pg->pg_lna_lod_gain == 0)
6150 BWN_RF_WRITE(mac, 0x7a, tmp);
6154 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6156 struct bwn_phy *phy = &mac->mac_phy;
6157 struct bwn_phy_g *pg = &phy->phy_g;
6158 struct bwn_softc *sc = mac->mac_sc;
6159 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6163 if (bwn_has_hwpctl(mac)) {
6164 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6165 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6166 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6167 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6168 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6170 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6171 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6172 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6173 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6175 if (phy->type == BWN_PHYTYPE_B &&
6176 phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6177 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6178 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6180 if (phy->rev >= 2) {
6181 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6182 sav->phy_analogoverval =
6183 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6184 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6185 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6186 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6187 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6188 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6190 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6191 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6192 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6193 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6194 if (phy->type == BWN_PHYTYPE_G) {
6195 if ((phy->rev >= 7) &&
6196 (siba_sprom_get_bf_lo(sc->sc_dev) &
6198 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6200 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6203 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6205 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6207 sav->reg0 = BWN_READ_2(mac, 0x3f4);
6208 sav->reg1 = BWN_READ_2(mac, 0x3e2);
6209 sav->rf0 = BWN_RF_READ(mac, 0x43);
6210 sav->rf1 = BWN_RF_READ(mac, 0x7a);
6211 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6212 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6213 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6214 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6216 if (!BWN_HAS_TXMAG(phy)) {
6217 sav->rf2 = BWN_RF_READ(mac, 0x52);
6220 if (phy->type == BWN_PHYTYPE_B) {
6221 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6222 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6223 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6224 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6226 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6229 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6233 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6234 BWN_PHY_WRITE(mac, tmp, 0x007f);
6236 tmp = sav->phy_syncctl;
6237 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6239 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6241 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6242 if (phy->type == BWN_PHYTYPE_G ||
6243 (phy->type == BWN_PHYTYPE_B &&
6244 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6245 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6247 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6249 bwn_dummy_transmission(mac, 0, 1);
6250 bwn_phy_g_switch_chan(mac, 6, 0);
6251 BWN_RF_READ(mac, 0x51);
6252 if (phy->type == BWN_PHYTYPE_G)
6253 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6256 if (time_before(lo->txctl_measured_time,
6257 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6258 bwn_lo_measure_txctl_values(mac);
6260 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6261 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6263 if (phy->type == BWN_PHYTYPE_B)
6264 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6266 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6271 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6273 struct bwn_phy *phy = &mac->mac_phy;
6274 struct bwn_phy_g *pg = &phy->phy_g;
6277 if (phy->rev >= 2) {
6278 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6279 tmp = (pg->pg_pga_gain << 8);
6280 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6282 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6284 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6286 tmp = (pg->pg_pga_gain | 0xefa0);
6287 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6289 if (phy->type == BWN_PHYTYPE_G) {
6291 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6293 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6295 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6297 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6299 BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6300 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6301 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6302 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6303 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6304 BWN_RF_WRITE(mac, 0x43, sav->rf0);
6305 BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6306 if (!BWN_HAS_TXMAG(phy)) {
6308 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6310 BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6311 if (phy->type == BWN_PHYTYPE_B &&
6312 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6313 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6314 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6316 if (phy->rev >= 2) {
6317 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6318 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6319 sav->phy_analogoverval);
6320 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6321 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6322 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6323 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6324 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6326 if (bwn_has_hwpctl(mac)) {
6327 tmp = (sav->phy_lomask & 0xbfff);
6328 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6329 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6330 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6331 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6332 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6334 bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6338 bwn_lo_probe_loctl(struct bwn_mac *mac,
6339 struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6341 struct bwn_phy *phy = &mac->mac_phy;
6342 struct bwn_phy_g *pg = &phy->phy_g;
6343 struct bwn_loctl orig, test;
6344 struct bwn_loctl prev = { -100, -100 };
6345 static const struct bwn_loctl modifiers[] = {
6346 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,},
6347 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,}
6349 int begin, end, lower = 0, i;
6352 if (d->curstate == 0) {
6355 } else if (d->curstate % 2 == 0) {
6356 begin = d->curstate - 1;
6357 end = d->curstate + 1;
6359 begin = d->curstate - 2;
6360 end = d->curstate + 2;
6367 memcpy(&orig, probe, sizeof(struct bwn_loctl));
6371 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6372 memcpy(&test, &orig, sizeof(struct bwn_loctl));
6373 test.i += modifiers[i - 1].i * d->multipler;
6374 test.q += modifiers[i - 1].q * d->multipler;
6375 if ((test.i != prev.i || test.q != prev.q) &&
6376 (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6377 bwn_lo_write(mac, &test);
6378 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6379 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6380 if (feedth < d->feedth) {
6381 memcpy(probe, &test,
6382 sizeof(struct bwn_loctl));
6385 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6389 memcpy(&prev, &test, sizeof(prev));
6403 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6405 struct bwn_phy *phy = &mac->mac_phy;
6406 struct bwn_phy_g *pg = &phy->phy_g;
6407 struct bwn_lo_g_sm d;
6408 struct bwn_loctl probe;
6409 int lower, repeat, cnt = 0;
6414 if (BWN_HAS_LOOPBACK(phy))
6417 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6418 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6421 bwn_lo_write(mac, &d.loctl);
6422 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6423 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6424 if (feedth < 0x258) {
6425 if (feedth >= 0x12c)
6429 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6430 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6435 KASSERT(d.curstate >= 0 && d.curstate <= 8,
6436 ("%s:%d: fail", __func__, __LINE__));
6437 memcpy(&probe, &d.loctl,
6438 sizeof(struct bwn_loctl));
6439 lower = bwn_lo_probe_loctl(mac, &probe, &d);
6442 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6444 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6446 } while (d.nmeasure < 24);
6447 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6449 if (BWN_HAS_LOOPBACK(phy)) {
6450 if (d.feedth > 0x1194)
6452 else if (d.feedth < 0x5dc)
6455 if (d.feedth <= 0x5dc) {
6460 } else if (cnt == 2)
6463 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6464 } while (++cnt < repeat);
6467 static struct bwn_lo_calib *
6468 bwn_lo_calibset(struct bwn_mac *mac,
6469 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6471 struct bwn_phy *phy = &mac->mac_phy;
6472 struct bwn_phy_g *pg = &phy->phy_g;
6473 struct bwn_loctl loctl = { 0, 0 };
6474 struct bwn_lo_calib *cal;
6475 struct bwn_lo_g_value sval = { 0 };
6477 uint16_t pad, reg, value;
6479 sval.old_channel = phy->chan;
6480 bwn_mac_suspend(mac);
6481 bwn_lo_save(mac, &sval);
6483 reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6484 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6485 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6487 rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6490 if (BWN_HAS_LOOPBACK(phy))
6491 rxgain += pg->pg_max_lb_gain;
6492 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6493 bwn_phy_g_set_bbatt(mac, bbatt->att);
6494 bwn_lo_probe_sm(mac, &loctl, &rxgain);
6496 bwn_lo_restore(mac, &sval);
6497 bwn_mac_enable(mac);
6499 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
6501 device_printf(mac->mac_sc->sc_dev, "out of memory\n");
6504 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6505 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6506 memcpy(&cal->ctl, &loctl, sizeof(loctl));
6508 BWN_GETTIME(cal->calib_time);
6513 static struct bwn_lo_calib *
6514 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6515 const struct bwn_rfatt *rfatt)
6517 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6518 struct bwn_lo_calib *c;
6520 TAILQ_FOREACH(c, &lo->calib_list, list) {
6521 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6523 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6528 c = bwn_lo_calibset(mac, bbatt, rfatt);
6531 TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6537 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6539 struct bwn_phy *phy = &mac->mac_phy;
6540 struct bwn_phy_g *pg = &phy->phy_g;
6541 struct bwn_softc *sc = mac->mac_sc;
6542 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6543 const struct bwn_rfatt *rfatt;
6544 const struct bwn_bbatt *bbatt;
6547 int rf_offset, bb_offset;
6548 uint8_t changed = 0;
6550 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6551 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6552 ("%s:%d: fail", __func__, __LINE__));
6554 pvector = lo->power_vector;
6555 if (!update && !pvector)
6558 bwn_mac_suspend(mac);
6560 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6561 struct bwn_lo_calib *cal;
6565 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6567 bb_offset = i / lo->rfatt.len;
6568 rf_offset = i % lo->rfatt.len;
6569 bbatt = &(lo->bbatt.array[bb_offset]);
6570 rfatt = &(lo->rfatt.array[rf_offset]);
6572 cal = bwn_lo_calibset(mac, bbatt, rfatt);
6574 device_printf(sc->sc_dev, "LO: Could not "
6575 "calibrate DC table entry\n");
6578 val = (uint8_t)(cal->ctl.q);
6579 val |= ((uint8_t)(cal->ctl.i)) << 4;
6580 free(cal, M_DEVBUF);
6584 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6585 | ((val & 0x00ff) << 8);
6587 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6592 for (i = 0; i < BWN_DC_LT_SIZE; i++)
6593 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6595 bwn_mac_enable(mac);
6599 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6604 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6609 bwn_lo_g_adjust(struct bwn_mac *mac)
6611 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6612 struct bwn_lo_calib *cal;
6613 struct bwn_rfatt rf;
6615 memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6616 bwn_lo_fixup_rfatt(&rf);
6618 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6621 bwn_lo_write(mac, &cal->ctl);
6625 bwn_lo_g_init(struct bwn_mac *mac)
6628 if (!bwn_has_hwpctl(mac))
6631 bwn_lo_get_powervector(mac);
6632 bwn_phy_g_dc_lookup_init(mac, 1);
6636 bwn_mac_suspend(struct bwn_mac *mac)
6638 struct bwn_softc *sc = mac->mac_sc;
6642 KASSERT(mac->mac_suspended >= 0,
6643 ("%s:%d: fail", __func__, __LINE__));
6645 if (mac->mac_suspended == 0) {
6646 bwn_psctl(mac, BWN_PS_AWAKE);
6647 BWN_WRITE_4(mac, BWN_MACCTL,
6648 BWN_READ_4(mac, BWN_MACCTL)
6650 BWN_READ_4(mac, BWN_MACCTL);
6651 for (i = 35; i; i--) {
6652 tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6653 if (tmp & BWN_INTR_MAC_SUSPENDED)
6657 for (i = 40; i; i--) {
6658 tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6659 if (tmp & BWN_INTR_MAC_SUSPENDED)
6663 device_printf(sc->sc_dev, "MAC suspend failed\n");
6666 mac->mac_suspended++;
6670 bwn_mac_enable(struct bwn_mac *mac)
6672 struct bwn_softc *sc = mac->mac_sc;
6675 state = bwn_shm_read_2(mac, BWN_SHARED,
6676 BWN_SHARED_UCODESTAT);
6677 if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6678 state != BWN_SHARED_UCODESTAT_SLEEP)
6679 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6681 mac->mac_suspended--;
6682 KASSERT(mac->mac_suspended >= 0,
6683 ("%s:%d: fail", __func__, __LINE__));
6684 if (mac->mac_suspended == 0) {
6685 BWN_WRITE_4(mac, BWN_MACCTL,
6686 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6687 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6688 BWN_READ_4(mac, BWN_MACCTL);
6689 BWN_READ_4(mac, BWN_INTR_REASON);
6695 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6697 struct bwn_softc *sc = mac->mac_sc;
6701 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6702 ("%s:%d: fail", __func__, __LINE__));
6703 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6704 ("%s:%d: fail", __func__, __LINE__));
6706 /* XXX forcibly awake and hwps-off */
6708 BWN_WRITE_4(mac, BWN_MACCTL,
6709 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6711 BWN_READ_4(mac, BWN_MACCTL);
6712 if (siba_get_revid(sc->sc_dev) >= 5) {
6713 for (i = 0; i < 100; i++) {
6714 ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6715 BWN_SHARED_UCODESTAT);
6716 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6724 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6727 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6728 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6732 bwn_nrssi_threshold(struct bwn_mac *mac)
6734 struct bwn_phy *phy = &mac->mac_phy;
6735 struct bwn_phy_g *pg = &phy->phy_g;
6736 struct bwn_softc *sc = mac->mac_sc;
6741 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6743 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6744 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6752 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6753 a += (pg->pg_nrssi[0] << 6);
6754 a += (a < 32) ? 31 : 32;
6756 a = MIN(MAX(a, -31), 31);
6758 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6759 b += (pg->pg_nrssi[0] << 6);
6765 b = MIN(MAX(b, -31), 31);
6767 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6768 tmpu16 |= ((uint32_t)b & 0x0000003f);
6769 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6770 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6774 tmp16 = bwn_nrssi_read(mac, 0x20);
6777 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6781 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6783 #define SAVE_RF_MAX 3
6784 #define SAVE_PHY_COMM_MAX 4
6785 #define SAVE_PHY3_MAX 8
6786 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6787 { 0x7a, 0x52, 0x43 };
6788 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6789 { 0x15, 0x5a, 0x59, 0x58 };
6790 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6791 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6792 0x0801, 0x0060, 0x0014, 0x0478
6794 struct bwn_phy *phy = &mac->mac_phy;
6795 struct bwn_phy_g *pg = &phy->phy_g;
6796 int32_t i, tmp32, phy3_idx = 0;
6797 uint16_t delta, tmp;
6798 uint16_t save_rf[SAVE_RF_MAX];
6799 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6800 uint16_t save_phy3[SAVE_PHY3_MAX];
6801 uint16_t ant_div, phy0, chan_ex;
6802 int16_t nrssi0, nrssi1;
6804 KASSERT(phy->type == BWN_PHYTYPE_G,
6805 ("%s:%d: fail", __func__, __LINE__));
6807 if (phy->rf_rev >= 9)
6809 if (phy->rf_rev == 8)
6810 bwn_nrssi_offset(mac);
6812 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6813 BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6816 * Save RF/PHY registers for later restoration
6818 ant_div = BWN_READ_2(mac, 0x03e2);
6819 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6820 for (i = 0; i < SAVE_RF_MAX; ++i)
6821 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6822 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6823 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6825 phy0 = BWN_READ_2(mac, BWN_PHY0);
6826 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6827 if (phy->rev >= 3) {
6828 for (i = 0; i < SAVE_PHY3_MAX; ++i)
6829 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6830 BWN_PHY_WRITE(mac, 0x002e, 0);
6831 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6836 BWN_PHY_SET(mac, 0x0478, 0x0100);
6837 BWN_PHY_SET(mac, 0x0801, 0x0040);
6841 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6844 BWN_PHY_SET(mac, 0x0060, 0x0040);
6845 BWN_PHY_SET(mac, 0x0014, 0x0200);
6850 BWN_RF_SET(mac, 0x007a, 0x0070);
6851 bwn_set_all_gains(mac, 0, 8, 0);
6852 BWN_RF_MASK(mac, 0x007a, 0x00f7);
6853 if (phy->rev >= 2) {
6854 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6855 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6857 BWN_RF_SET(mac, 0x007a, 0x0080);
6860 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6861 if (nrssi0 >= 0x0020)
6867 BWN_RF_MASK(mac, 0x007a, 0x007f);
6869 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6871 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6872 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6873 BWN_RF_SET(mac, 0x007a, 0x000f);
6874 BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6875 if (phy->rev >= 2) {
6876 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6877 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6880 bwn_set_all_gains(mac, 3, 0, 1);
6881 if (phy->rf_rev == 8) {
6882 BWN_RF_WRITE(mac, 0x0043, 0x001f);
6884 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6885 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6886 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6887 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6889 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6890 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6891 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6893 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6896 * Install calculated narrow RSSI values
6898 if (nrssi1 >= 0x0020)
6900 if (nrssi0 == nrssi1)
6901 pg->pg_nrssi_slope = 0x00010000;
6903 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6905 pg->pg_nrssi[0] = nrssi1;
6906 pg->pg_nrssi[1] = nrssi0;
6910 * Restore saved RF/PHY registers
6912 if (phy->rev >= 3) {
6913 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6914 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6915 save_phy3[phy3_idx]);
6918 if (phy->rev >= 2) {
6919 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6920 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6923 for (i = 0; i < SAVE_RF_MAX; ++i)
6924 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6926 BWN_WRITE_2(mac, 0x03e2, ant_div);
6927 BWN_WRITE_2(mac, 0x03e6, phy0);
6928 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6930 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6931 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6933 bwn_spu_workaround(mac, phy->chan);
6934 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6935 bwn_set_original_gains(mac);
6936 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6937 if (phy->rev >= 3) {
6938 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6939 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6940 save_phy3[phy3_idx]);
6944 delta = 0x1f - pg->pg_nrssi[0];
6945 for (i = 0; i < 64; i++) {
6946 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6947 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6948 pg->pg_nrssi_lt[i] = tmp32;
6951 bwn_nrssi_threshold(mac);
6953 #undef SAVE_PHY_COMM_MAX
6954 #undef SAVE_PHY3_MAX
6958 bwn_nrssi_offset(struct bwn_mac *mac)
6960 #define SAVE_RF_MAX 2
6961 #define SAVE_PHY_COMM_MAX 10
6962 #define SAVE_PHY6_MAX 8
6963 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6965 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6966 0x0001, 0x0811, 0x0812, 0x0814,
6967 0x0815, 0x005a, 0x0059, 0x0058,
6970 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6971 0x002e, 0x002f, 0x080f, 0x0810,
6972 0x0801, 0x0060, 0x0014, 0x0478
6974 struct bwn_phy *phy = &mac->mac_phy;
6975 int i, phy6_idx = 0;
6976 uint16_t save_rf[SAVE_RF_MAX];
6977 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6978 uint16_t save_phy6[SAVE_PHY6_MAX];
6980 uint16_t saved = 0xffff;
6982 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6983 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6984 for (i = 0; i < SAVE_RF_MAX; ++i)
6985 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6987 BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6988 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6989 BWN_PHY_SET(mac, 0x0811, 0x000c);
6990 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6991 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6992 if (phy->rev >= 6) {
6993 for (i = 0; i < SAVE_PHY6_MAX; ++i)
6994 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6996 BWN_PHY_WRITE(mac, 0x002e, 0);
6997 BWN_PHY_WRITE(mac, 0x002f, 0);
6998 BWN_PHY_WRITE(mac, 0x080f, 0);
6999 BWN_PHY_WRITE(mac, 0x0810, 0);
7000 BWN_PHY_SET(mac, 0x0478, 0x0100);
7001 BWN_PHY_SET(mac, 0x0801, 0x0040);
7002 BWN_PHY_SET(mac, 0x0060, 0x0040);
7003 BWN_PHY_SET(mac, 0x0014, 0x0200);
7005 BWN_RF_SET(mac, 0x007a, 0x0070);
7006 BWN_RF_SET(mac, 0x007a, 0x0080);
7009 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7013 for (i = 7; i >= 4; i--) {
7014 BWN_RF_WRITE(mac, 0x007b, i);
7016 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
7020 if (nrssi < 31 && saved == 0xffff)
7023 if (saved == 0xffff)
7026 BWN_RF_MASK(mac, 0x007a, 0x007f);
7027 if (phy->rev != 1) {
7028 BWN_PHY_SET(mac, 0x0814, 0x0001);
7029 BWN_PHY_MASK(mac, 0x0815, 0xfffe);
7031 BWN_PHY_SET(mac, 0x0811, 0x000c);
7032 BWN_PHY_SET(mac, 0x0812, 0x000c);
7033 BWN_PHY_SET(mac, 0x0811, 0x0030);
7034 BWN_PHY_SET(mac, 0x0812, 0x0030);
7035 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
7036 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
7037 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
7039 BWN_PHY_WRITE(mac, 0x0003, 0x0122);
7041 BWN_PHY_SET(mac, 0x000a, 0x2000);
7042 if (phy->rev != 1) {
7043 BWN_PHY_SET(mac, 0x0814, 0x0004);
7044 BWN_PHY_MASK(mac, 0x0815, 0xfffb);
7046 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
7047 BWN_RF_SET(mac, 0x007a, 0x000f);
7048 bwn_set_all_gains(mac, 3, 0, 1);
7049 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
7051 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7055 for (i = 0; i < 4; i++) {
7056 BWN_RF_WRITE(mac, 0x007b, i);
7058 nrssi = (int16_t)((BWN_PHY_READ(mac,
7059 0x047f) >> 8) & 0x003f);
7062 if (nrssi > -31 && saved == 0xffff)
7065 if (saved == 0xffff)
7070 BWN_RF_WRITE(mac, 0x007b, saved);
7073 * Restore saved RF/PHY registers
7075 if (phy->rev >= 6) {
7076 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
7077 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7078 save_phy6[phy6_idx]);
7081 if (phy->rev != 1) {
7082 for (i = 3; i < 5; i++)
7083 BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
7086 for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
7087 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
7089 for (i = SAVE_RF_MAX - 1; i >= 0; --i)
7090 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
7092 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
7093 BWN_PHY_SET(mac, 0x0429, 0x8000);
7094 bwn_set_original_gains(mac);
7095 if (phy->rev >= 6) {
7096 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
7097 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7098 save_phy6[phy6_idx]);
7102 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7103 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7104 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7108 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7111 struct bwn_phy *phy = &mac->mac_phy;
7113 uint16_t start = 0x08, end = 0x18;
7117 if (phy->rev <= 1) {
7122 table = BWN_OFDMTAB_GAINX;
7124 table = BWN_OFDMTAB_GAINX_R1;
7125 for (i = 0; i < 4; i++)
7126 bwn_ofdmtab_write_2(mac, table, i, first);
7128 for (i = start; i < end; i++)
7129 bwn_ofdmtab_write_2(mac, table, i, second);
7132 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7133 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7134 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7135 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7137 bwn_dummy_transmission(mac, 0, 1);
7141 bwn_set_original_gains(struct bwn_mac *mac)
7143 struct bwn_phy *phy = &mac->mac_phy;
7146 uint16_t start = 0x0008, end = 0x0018;
7148 if (phy->rev <= 1) {
7153 table = BWN_OFDMTAB_GAINX;
7155 table = BWN_OFDMTAB_GAINX_R1;
7156 for (i = 0; i < 4; i++) {
7158 tmp |= (i & 0x0001) << 1;
7159 tmp |= (i & 0x0002) >> 1;
7161 bwn_ofdmtab_write_2(mac, table, i, tmp);
7164 for (i = start; i < end; i++)
7165 bwn_ofdmtab_write_2(mac, table, i, i - start);
7167 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7168 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7169 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7170 bwn_dummy_transmission(mac, 0, 1);
7174 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7176 struct bwn_phy *phy = &mac->mac_phy;
7177 struct bwn_phy_g *pg = &phy->phy_g;
7178 struct bwn_rfatt old_rfatt, rfatt;
7179 struct bwn_bbatt old_bbatt, bbatt;
7180 struct bwn_softc *sc = mac->mac_sc;
7181 uint8_t old_txctl = 0;
7183 KASSERT(phy->type == BWN_PHYTYPE_G,
7184 ("%s:%d: fail", __func__, __LINE__));
7186 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7187 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7190 BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7192 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7196 bwn_hwpctl_early_init(mac);
7197 if (pg->pg_curtssi == 0) {
7198 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7199 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7201 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7202 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7203 old_txctl = pg->pg_txctl;
7206 if (phy->rf_rev == 8) {
7213 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7215 bwn_dummy_transmission(mac, 0, 1);
7216 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7217 if (phy->rf_ver == 0x2050 && phy->analog == 0)
7218 BWN_RF_MASK(mac, 0x0076, 0xff7b);
7220 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7221 &old_rfatt, old_txctl);
7223 bwn_hwpctl_init_gphy(mac);
7226 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7227 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7228 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7229 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7233 bwn_hwpctl_early_init(struct bwn_mac *mac)
7235 struct bwn_phy *phy = &mac->mac_phy;
7237 if (!bwn_has_hwpctl(mac)) {
7238 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7242 BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7243 BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7244 BWN_PHY_SET(mac, 0x047c, 0x0002);
7245 BWN_PHY_SET(mac, 0x047a, 0xf000);
7246 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7247 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7248 BWN_PHY_SET(mac, 0x005d, 0x8000);
7249 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7250 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7251 BWN_PHY_SET(mac, 0x0036, 0x0400);
7253 BWN_PHY_SET(mac, 0x0036, 0x0200);
7254 BWN_PHY_SET(mac, 0x0036, 0x0400);
7255 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7256 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7257 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7258 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7259 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7264 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7266 struct bwn_phy *phy = &mac->mac_phy;
7267 struct bwn_phy_g *pg = &phy->phy_g;
7268 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7270 uint16_t nr_written = 0, tmp, value;
7273 if (!bwn_has_hwpctl(mac)) {
7274 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7278 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7279 (pg->pg_idletssi - pg->pg_curtssi));
7280 BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7281 (pg->pg_idletssi - pg->pg_curtssi));
7283 for (i = 0; i < 32; i++)
7284 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7285 for (i = 32; i < 64; i++)
7286 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7287 for (i = 0; i < 64; i += 2) {
7288 value = (uint16_t) pg->pg_tssi2dbm[i];
7289 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7290 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7293 for (rf = 0; rf < lo->rfatt.len; rf++) {
7294 for (bb = 0; bb < lo->bbatt.len; bb++) {
7295 if (nr_written >= 0x40)
7297 tmp = lo->bbatt.array[bb].att;
7299 if (phy->rf_rev == 8)
7303 tmp |= lo->rfatt.array[rf].att;
7304 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7309 BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7310 BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7312 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7313 BWN_PHY_SET(mac, 0x0478, 0x0800);
7314 BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7315 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7317 bwn_phy_g_dc_lookup_init(mac, 1);
7318 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7322 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7324 struct bwn_softc *sc = mac->mac_sc;
7327 bwn_spu_workaround(mac, channel);
7329 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7331 if (channel == 14) {
7332 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7334 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7337 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7338 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7339 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7343 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7344 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7348 bwn_phy_g_chan2freq(uint8_t channel)
7350 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7352 KASSERT(channel >= 1 && channel <= 14,
7353 ("%s:%d: fail", __func__, __LINE__));
7355 return (bwn_phy_g_rf_channels[channel - 1]);
7359 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7360 const struct bwn_rfatt *rfatt, uint8_t txctl)
7362 struct bwn_phy *phy = &mac->mac_phy;
7363 struct bwn_phy_g *pg = &phy->phy_g;
7364 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7366 uint16_t tx_bias, tx_magn;
7370 tx_bias = lo->tx_bias;
7371 tx_magn = lo->tx_magn;
7372 if (tx_bias == 0xff)
7375 pg->pg_txctl = txctl;
7376 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7377 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7378 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7379 bwn_phy_g_set_bbatt(mac, bb);
7380 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7381 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7382 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7384 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7385 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7387 if (BWN_HAS_TXMAG(phy))
7388 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7390 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7391 bwn_lo_g_adjust(mac);
7395 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7398 struct bwn_phy *phy = &mac->mac_phy;
7400 if (phy->analog == 0) {
7401 BWN_WRITE_2(mac, BWN_PHY0,
7402 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7405 if (phy->analog > 1) {
7406 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7409 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7413 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7415 struct bwn_phy *phy = &mac->mac_phy;
7416 struct bwn_phy_g *pg = &phy->phy_g;
7417 struct bwn_softc *sc = mac->mac_sc;
7422 if (phy->gmode == 0)
7425 if (BWN_HAS_LOOPBACK(phy)) {
7426 max_lb_gain = pg->pg_max_lb_gain;
7427 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7428 if (max_lb_gain >= 0x46) {
7430 max_lb_gain -= 0x46;
7431 } else if (max_lb_gain >= 0x3a) {
7433 max_lb_gain -= 0x3a;
7434 } else if (max_lb_gain >= 0x2e) {
7436 max_lb_gain -= 0x2e;
7439 max_lb_gain -= 0x10;
7442 for (i = 0; i < 16; i++) {
7443 max_lb_gain -= (i * 6);
7444 if (max_lb_gain < 6)
7448 if ((phy->rev < 7) ||
7449 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7450 if (reg == BWN_PHY_RFOVER) {
7452 } else if (reg == BWN_PHY_RFOVERVAL) {
7455 case BWN_LPD(0, 1, 1):
7457 case BWN_LPD(0, 0, 1):
7458 case BWN_LPD(1, 0, 1):
7459 return (0x0092 | extlna);
7460 case BWN_LPD(1, 0, 0):
7461 return (0x0093 | extlna);
7464 ("%s:%d: fail", __func__, __LINE__));
7466 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7468 if (reg == BWN_PHY_RFOVER)
7470 if (reg == BWN_PHY_RFOVERVAL) {
7475 case BWN_LPD(0, 1, 1):
7477 case BWN_LPD(0, 0, 1):
7478 return (0x8092 | extlna);
7479 case BWN_LPD(1, 0, 1):
7480 return (0x2092 | extlna);
7481 case BWN_LPD(1, 0, 0):
7482 return (0x2093 | extlna);
7485 ("%s:%d: fail", __func__, __LINE__));
7487 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7492 if ((phy->rev < 7) ||
7493 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7494 if (reg == BWN_PHY_RFOVER) {
7496 } else if (reg == BWN_PHY_RFOVERVAL) {
7498 case BWN_LPD(0, 1, 1):
7500 case BWN_LPD(0, 0, 1):
7502 case BWN_LPD(1, 0, 1):
7504 case BWN_LPD(1, 0, 0):
7508 ("%s:%d: fail", __func__, __LINE__));
7510 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7512 if (reg == BWN_PHY_RFOVER) {
7514 } else if (reg == BWN_PHY_RFOVERVAL) {
7516 case BWN_LPD(0, 1, 1):
7518 case BWN_LPD(0, 0, 1):
7520 case BWN_LPD(1, 0, 1):
7522 case BWN_LPD(1, 0, 0):
7526 ("%s:%d: fail", __func__, __LINE__));
7528 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7534 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7537 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7539 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7540 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7542 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7546 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7548 struct bwn_softc *sc = mac->mac_sc;
7549 struct bwn_fw *fw = &mac->mac_fw;
7550 const uint8_t rev = siba_get_revid(sc->sc_dev);
7551 const char *filename;
7556 if (rev >= 5 && rev <= 10)
7557 filename = "ucode5";
7558 else if (rev >= 11 && rev <= 12)
7559 filename = "ucode11";
7561 filename = "ucode13";
7563 filename = "ucode14";
7565 filename = "ucode15";
7567 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7568 bwn_release_firmware(mac);
7569 return (EOPNOTSUPP);
7571 error = bwn_fw_get(mac, type, filename, &fw->ucode);
7573 bwn_release_firmware(mac);
7578 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7579 if (rev >= 5 && rev <= 10) {
7580 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7581 if (error == ENOENT)
7584 bwn_release_firmware(mac);
7587 } else if (rev < 11) {
7588 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7589 return (EOPNOTSUPP);
7593 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7594 switch (mac->mac_phy.type) {
7596 if (rev < 5 || rev > 10)
7598 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7599 filename = "a0g1initvals5";
7601 filename = "a0g0initvals5";
7604 if (rev >= 5 && rev <= 10)
7605 filename = "b0g0initvals5";
7607 filename = "b0g0initvals13";
7611 case BWN_PHYTYPE_LP:
7613 filename = "lp0initvals13";
7615 filename = "lp0initvals14";
7617 filename = "lp0initvals15";
7622 if (rev >= 11 && rev <= 12)
7623 filename = "n0initvals11";
7630 error = bwn_fw_get(mac, type, filename, &fw->initvals);
7632 bwn_release_firmware(mac);
7636 /* bandswitch initvals */
7637 switch (mac->mac_phy.type) {
7639 if (rev >= 5 && rev <= 10) {
7640 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7641 filename = "a0g1bsinitvals5";
7643 filename = "a0g0bsinitvals5";
7644 } else if (rev >= 11)
7650 if (rev >= 5 && rev <= 10)
7651 filename = "b0g0bsinitvals5";
7657 case BWN_PHYTYPE_LP:
7659 filename = "lp0bsinitvals13";
7661 filename = "lp0bsinitvals14";
7663 filename = "lp0bsinitvals15";
7668 if (rev >= 11 && rev <= 12)
7669 filename = "n0bsinitvals11";
7676 error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7678 bwn_release_firmware(mac);
7683 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7684 bwn_release_firmware(mac);
7685 return (EOPNOTSUPP);
7689 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7690 const char *name, struct bwn_fwfile *bfw)
7692 const struct bwn_fwhdr *hdr;
7693 struct bwn_softc *sc = mac->mac_sc;
7694 const struct firmware *fw;
7698 bwn_do_release_fw(bfw);
7701 if (bfw->filename != NULL) {
7702 if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7704 bwn_do_release_fw(bfw);
7707 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7708 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7709 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7710 /* XXX Sleeping on "fwload" with the non-sleepable locks held */
7711 fw = firmware_get(namebuf);
7713 device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7717 if (fw->datasize < sizeof(struct bwn_fwhdr))
7719 hdr = (const struct bwn_fwhdr *)(fw->data);
7720 switch (hdr->type) {
7721 case BWN_FWTYPE_UCODE:
7722 case BWN_FWTYPE_PCM:
7723 if (be32toh(hdr->size) !=
7724 (fw->datasize - sizeof(struct bwn_fwhdr)))
7734 bfw->filename = name;
7739 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7741 firmware_put(fw, FIRMWARE_UNLOAD);
7746 bwn_release_firmware(struct bwn_mac *mac)
7749 bwn_do_release_fw(&mac->mac_fw.ucode);
7750 bwn_do_release_fw(&mac->mac_fw.pcm);
7751 bwn_do_release_fw(&mac->mac_fw.initvals);
7752 bwn_do_release_fw(&mac->mac_fw.initvals_band);
7756 bwn_do_release_fw(struct bwn_fwfile *bfw)
7759 if (bfw->fw != NULL)
7760 firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7762 bfw->filename = NULL;
7766 bwn_fw_loaducode(struct bwn_mac *mac)
7768 #define GETFWOFFSET(fwp, offset) \
7769 ((const uint32_t *)((const char *)fwp.fw->data + offset))
7770 #define GETFWSIZE(fwp, offset) \
7771 ((fwp.fw->datasize - offset) / sizeof(uint32_t))
7772 struct bwn_softc *sc = mac->mac_sc;
7773 const uint32_t *data;
7776 uint16_t date, fwcaps, time;
7779 ctl = BWN_READ_4(mac, BWN_MACCTL);
7780 ctl |= BWN_MACCTL_MCODE_JMP0;
7781 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7783 BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7784 for (i = 0; i < 64; i++)
7785 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7786 for (i = 0; i < 4096; i += 2)
7787 bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7789 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7790 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7791 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7793 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7797 if (mac->mac_fw.pcm.fw) {
7798 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7799 bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7800 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7801 bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7802 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7803 sizeof(struct bwn_fwhdr)); i++) {
7804 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7809 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7810 BWN_WRITE_4(mac, BWN_MACCTL,
7811 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7812 BWN_MACCTL_MCODE_RUN);
7814 for (i = 0; i < 21; i++) {
7815 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7818 device_printf(sc->sc_dev, "ucode timeout\n");
7824 BWN_READ_4(mac, BWN_INTR_REASON);
7826 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7827 if (mac->mac_fw.rev <= 0x128) {
7828 device_printf(sc->sc_dev, "the firmware is too old\n");
7832 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7833 BWN_SHARED_UCODE_PATCH);
7834 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7835 mac->mac_fw.opensource = (date == 0xffff);
7837 mac->mac_flags |= BWN_MAC_FLAG_WME;
7838 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7840 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7841 if (mac->mac_fw.opensource == 0) {
7842 device_printf(sc->sc_dev,
7843 "firmware version (rev %u patch %u date %#x time %#x)\n",
7844 mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7845 if (mac->mac_fw.no_pcmfile)
7846 device_printf(sc->sc_dev,
7847 "no HW crypto acceleration due to pcm5\n");
7849 mac->mac_fw.patch = time;
7850 fwcaps = bwn_fwcaps_read(mac);
7851 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7852 device_printf(sc->sc_dev,
7853 "disabling HW crypto acceleration\n");
7854 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7856 if (!(fwcaps & BWN_FWCAPS_WME)) {
7857 device_printf(sc->sc_dev, "disabling WME support\n");
7858 mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7862 if (BWN_ISOLDFMT(mac))
7863 device_printf(sc->sc_dev, "using old firmware image\n");
7868 BWN_WRITE_4(mac, BWN_MACCTL,
7869 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7870 BWN_MACCTL_MCODE_JMP0);
7877 /* OpenFirmware only */
7879 bwn_fwcaps_read(struct bwn_mac *mac)
7882 KASSERT(mac->mac_fw.opensource == 1,
7883 ("%s:%d: fail", __func__, __LINE__));
7884 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7888 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7889 size_t count, size_t array_size)
7891 #define GET_NEXTIV16(iv) \
7892 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \
7893 sizeof(uint16_t) + sizeof(uint16_t)))
7894 #define GET_NEXTIV32(iv) \
7895 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \
7896 sizeof(uint16_t) + sizeof(uint32_t)))
7897 struct bwn_softc *sc = mac->mac_sc;
7898 const struct bwn_fwinitvals *iv;
7903 KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7904 ("%s:%d: fail", __func__, __LINE__));
7906 for (i = 0; i < count; i++) {
7907 if (array_size < sizeof(iv->offset_size))
7909 array_size -= sizeof(iv->offset_size);
7910 offset = be16toh(iv->offset_size);
7911 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7912 offset &= BWN_FWINITVALS_OFFSET_MASK;
7913 if (offset >= 0x1000)
7916 if (array_size < sizeof(iv->data.d32))
7918 array_size -= sizeof(iv->data.d32);
7919 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7920 iv = GET_NEXTIV32(iv);
7923 if (array_size < sizeof(iv->data.d16))
7925 array_size -= sizeof(iv->data.d16);
7926 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7928 iv = GET_NEXTIV16(iv);
7931 if (array_size != 0)
7935 device_printf(sc->sc_dev, "initvals: invalid format\n");
7942 bwn_switch_channel(struct bwn_mac *mac, int chan)
7944 struct bwn_phy *phy = &(mac->mac_phy);
7945 struct bwn_softc *sc = mac->mac_sc;
7946 struct ifnet *ifp = sc->sc_ifp;
7947 struct ieee80211com *ic = ifp->if_l2com;
7948 uint16_t channelcookie, savedcookie;
7952 chan = phy->get_default_chan(mac);
7954 channelcookie = chan;
7955 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
7956 channelcookie |= 0x100;
7957 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
7958 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
7959 error = phy->switch_channel(mac, chan);
7963 mac->mac_phy.chan = chan;
7967 device_printf(sc->sc_dev, "failed to switch channel\n");
7968 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
7973 bwn_ant2phy(int antenna)
7978 return (BWN_TX_PHY_ANT0);
7980 return (BWN_TX_PHY_ANT1);
7982 return (BWN_TX_PHY_ANT2);
7984 return (BWN_TX_PHY_ANT3);
7986 return (BWN_TX_PHY_ANT01AUTO);
7988 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7993 bwn_wme_load(struct bwn_mac *mac)
7995 struct bwn_softc *sc = mac->mac_sc;
7998 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
7999 ("%s:%d: fail", __func__, __LINE__));
8001 bwn_mac_suspend(mac);
8002 for (i = 0; i < N(sc->sc_wmeParams); i++)
8003 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
8004 bwn_wme_shm_offsets[i]);
8005 bwn_mac_enable(mac);
8009 bwn_wme_loadparams(struct bwn_mac *mac,
8010 const struct wmeParams *p, uint16_t shm_offset)
8012 #define SM(_v, _f) (((_v) << _f##_S) & _f)
8013 struct bwn_softc *sc = mac->mac_sc;
8014 uint16_t params[BWN_NR_WMEPARAMS];
8018 slot = BWN_READ_2(mac, BWN_RNG) &
8019 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8021 memset(¶ms, 0, sizeof(params));
8023 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
8024 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
8025 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
8027 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
8028 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8029 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
8030 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8031 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
8032 params[BWN_WMEPARAM_BSLOTS] = slot;
8033 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
8035 for (i = 0; i < N(params); i++) {
8036 if (i == BWN_WMEPARAM_STATUS) {
8037 tmp = bwn_shm_read_2(mac, BWN_SHARED,
8038 shm_offset + (i * 2));
8040 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8043 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8050 bwn_mac_write_bssid(struct bwn_mac *mac)
8052 struct bwn_softc *sc = mac->mac_sc;
8055 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
8057 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
8058 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
8059 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
8060 IEEE80211_ADDR_LEN);
8062 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
8063 tmp = (uint32_t) (mac_bssid[i + 0]);
8064 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
8065 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
8066 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
8067 bwn_ram_write(mac, 0x20 + i, tmp);
8072 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
8073 const uint8_t *macaddr)
8075 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
8082 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
8085 data |= macaddr[1] << 8;
8086 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8088 data |= macaddr[3] << 8;
8089 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8091 data |= macaddr[5] << 8;
8092 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8096 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8097 const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
8099 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
8100 uint8_t per_sta_keys_start = 8;
8102 if (BWN_SEC_NEWAPI(mac))
8103 per_sta_keys_start = 4;
8105 KASSERT(index < mac->mac_max_nr_keys,
8106 ("%s:%d: fail", __func__, __LINE__));
8107 KASSERT(key_len <= BWN_SEC_KEYSIZE,
8108 ("%s:%d: fail", __func__, __LINE__));
8110 if (index >= per_sta_keys_start)
8111 bwn_key_macwrite(mac, index, NULL);
8113 memcpy(buf, key, key_len);
8114 bwn_key_write(mac, index, algorithm, buf);
8115 if (index >= per_sta_keys_start)
8116 bwn_key_macwrite(mac, index, mac_addr);
8118 mac->mac_key[index].algorithm = algorithm;
8122 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8124 struct bwn_softc *sc = mac->mac_sc;
8125 uint32_t addrtmp[2] = { 0, 0 };
8128 if (BWN_SEC_NEWAPI(mac))
8131 KASSERT(index >= start,
8132 ("%s:%d: fail", __func__, __LINE__));
8136 addrtmp[0] = addr[0];
8137 addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8138 addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8139 addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8140 addrtmp[1] = addr[4];
8141 addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8144 if (siba_get_revid(sc->sc_dev) >= 5) {
8145 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8146 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8149 bwn_shm_write_4(mac, BWN_SHARED,
8150 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8151 bwn_shm_write_2(mac, BWN_SHARED,
8152 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8158 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8163 uint16_t kidx, value;
8165 kidx = BWN_SEC_KEY2FW(mac, index);
8166 bwn_shm_write_2(mac, BWN_SHARED,
8167 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8169 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8170 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8172 value |= (uint16_t)(key[i + 1]) << 8;
8173 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8178 bwn_phy_exit(struct bwn_mac *mac)
8181 mac->mac_phy.rf_onoff(mac, 0);
8182 if (mac->mac_phy.exit != NULL)
8183 mac->mac_phy.exit(mac);
8187 bwn_dma_free(struct bwn_mac *mac)
8189 struct bwn_dma *dma;
8191 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8193 dma = &mac->mac_method.dma;
8195 bwn_dma_ringfree(&dma->rx);
8196 bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8197 bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8198 bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8199 bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8200 bwn_dma_ringfree(&dma->mcast);
8204 bwn_core_stop(struct bwn_mac *mac)
8206 struct bwn_softc *sc = mac->mac_sc;
8208 BWN_ASSERT_LOCKED(sc);
8210 if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8213 callout_stop(&sc->sc_rfswitch_ch);
8214 callout_stop(&sc->sc_task_ch);
8215 callout_stop(&sc->sc_watchdog_ch);
8216 sc->sc_watchdog_timer = 0;
8217 BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8218 BWN_READ_4(mac, BWN_INTR_MASK);
8219 bwn_mac_suspend(mac);
8221 mac->mac_status = BWN_MAC_STATUS_INITED;
8225 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8227 struct bwn_mac *up_dev = NULL;
8228 struct bwn_mac *down_dev;
8229 struct bwn_mac *mac;
8233 BWN_ASSERT_LOCKED(sc);
8235 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8236 if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8237 mac->mac_phy.supports_2ghz) {
8240 } else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8241 mac->mac_phy.supports_5ghz) {
8245 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8251 if (up_dev == NULL) {
8252 device_printf(sc->sc_dev, "Could not find a device\n");
8255 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8258 device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8259 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8261 down_dev = sc->sc_curmac;
8262 status = down_dev->mac_status;
8263 if (status >= BWN_MAC_STATUS_STARTED)
8264 bwn_core_stop(down_dev);
8265 if (status >= BWN_MAC_STATUS_INITED)
8266 bwn_core_exit(down_dev);
8268 if (down_dev != up_dev)
8269 bwn_phy_reset(down_dev);
8271 up_dev->mac_phy.gmode = gmode;
8272 if (status >= BWN_MAC_STATUS_INITED) {
8273 err = bwn_core_init(up_dev);
8275 device_printf(sc->sc_dev,
8276 "fatal: failed to initialize for %s-GHz\n",
8277 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8281 if (status >= BWN_MAC_STATUS_STARTED)
8282 bwn_core_start(up_dev);
8283 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8284 sc->sc_curmac = up_dev;
8288 sc->sc_curmac = NULL;
8293 bwn_rf_turnon(struct bwn_mac *mac)
8296 bwn_mac_suspend(mac);
8297 mac->mac_phy.rf_onoff(mac, 1);
8298 mac->mac_phy.rf_on = 1;
8299 bwn_mac_enable(mac);
8303 bwn_rf_turnoff(struct bwn_mac *mac)
8306 bwn_mac_suspend(mac);
8307 mac->mac_phy.rf_onoff(mac, 0);
8308 mac->mac_phy.rf_on = 0;
8309 bwn_mac_enable(mac);
8313 bwn_phy_reset(struct bwn_mac *mac)
8315 struct bwn_softc *sc = mac->mac_sc;
8317 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8318 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8319 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8321 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8322 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8323 BWN_TGSLOW_PHYRESET);
8328 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8330 struct bwn_vap *bvp = BWN_VAP(vap);
8331 struct ieee80211com *ic= vap->iv_ic;
8332 struct ifnet *ifp = ic->ic_ifp;
8333 enum ieee80211_state ostate = vap->iv_state;
8334 struct bwn_softc *sc = ifp->if_softc;
8335 struct bwn_mac *mac = sc->sc_curmac;
8338 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8339 ieee80211_state_name[vap->iv_state],
8340 ieee80211_state_name[nstate]);
8342 error = bvp->bv_newstate(vap, nstate, arg);
8348 bwn_led_newstate(mac, nstate);
8351 * Clear the BSSID when we stop a STA
8353 if (vap->iv_opmode == IEEE80211_M_STA) {
8354 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8356 * Clear out the BSSID. If we reassociate to
8357 * the same AP, this will reinialize things
8360 if (ic->ic_opmode == IEEE80211_M_STA &&
8361 (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8362 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8363 bwn_set_macaddr(mac);
8368 if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8369 vap->iv_opmode == IEEE80211_M_AHDEMO) {
8370 /* XXX nothing to do? */
8371 } else if (nstate == IEEE80211_S_RUN) {
8372 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8373 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
8374 bwn_set_opmode(mac);
8375 bwn_set_pretbtt(mac);
8376 bwn_spu_setdelay(mac, 0);
8377 bwn_set_macaddr(mac);
8386 bwn_set_pretbtt(struct bwn_mac *mac)
8388 struct bwn_softc *sc = mac->mac_sc;
8389 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8392 if (ic->ic_opmode == IEEE80211_M_IBSS)
8395 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8396 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8397 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8403 struct bwn_mac *mac = arg;
8404 struct bwn_softc *sc = mac->mac_sc;
8407 if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8408 (sc->sc_flags & BWN_FLAG_INVALID))
8409 return (FILTER_STRAY);
8411 reason = BWN_READ_4(mac, BWN_INTR_REASON);
8412 if (reason == 0xffffffff) /* shared IRQ */
8413 return (FILTER_STRAY);
8414 reason &= mac->mac_intr_mask;
8416 return (FILTER_HANDLED);
8418 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
8419 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8420 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8421 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8422 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8423 BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8424 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8425 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8426 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8427 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8428 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8430 /* Disable interrupts. */
8431 BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8433 mac->mac_reason_intr = reason;
8435 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8436 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8438 taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask);
8439 return (FILTER_HANDLED);
8443 bwn_intrtask(void *arg, int npending)
8445 struct bwn_mac *mac = arg;
8446 struct bwn_softc *sc = mac->mac_sc;
8447 struct ifnet *ifp = sc->sc_ifp;
8448 uint32_t merged = 0;
8449 int i, tx = 0, rx = 0;
8452 if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8453 (sc->sc_flags & BWN_FLAG_INVALID)) {
8458 for (i = 0; i < N(mac->mac_reason); i++)
8459 merged |= mac->mac_reason[i];
8461 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8462 device_printf(sc->sc_dev, "MAC trans error\n");
8464 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8465 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8466 mac->mac_phy.txerrors--;
8467 if (mac->mac_phy.txerrors == 0) {
8468 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8469 bwn_restart(mac, "PHY TX errors");
8473 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
8474 if (merged & BWN_DMAINTR_FATALMASK) {
8475 device_printf(sc->sc_dev,
8476 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8477 mac->mac_reason[0], mac->mac_reason[1],
8478 mac->mac_reason[2], mac->mac_reason[3],
8479 mac->mac_reason[4], mac->mac_reason[5]);
8480 bwn_restart(mac, "DMA error");
8484 if (merged & BWN_DMAINTR_NONFATALMASK) {
8485 device_printf(sc->sc_dev,
8486 "DMA error: %#x %#x %#x %#x %#x %#x\n",
8487 mac->mac_reason[0], mac->mac_reason[1],
8488 mac->mac_reason[2], mac->mac_reason[3],
8489 mac->mac_reason[4], mac->mac_reason[5]);
8493 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8494 bwn_intr_ucode_debug(mac);
8495 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8496 bwn_intr_tbtt_indication(mac);
8497 if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8498 bwn_intr_atim_end(mac);
8499 if (mac->mac_reason_intr & BWN_INTR_BEACON)
8500 bwn_intr_beacon(mac);
8501 if (mac->mac_reason_intr & BWN_INTR_PMQ)
8503 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8504 bwn_intr_noise(mac);
8506 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8507 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8508 bwn_dma_rx(mac->mac_method.dma.rx);
8512 rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8514 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8515 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8516 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8517 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8518 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8520 if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8521 bwn_intr_txeof(mac);
8525 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8527 if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8528 int evt = BWN_LED_EVENT_NONE;
8531 if (sc->sc_rx_rate > sc->sc_tx_rate)
8532 evt = BWN_LED_EVENT_RX;
8534 evt = BWN_LED_EVENT_TX;
8536 evt = BWN_LED_EVENT_TX;
8538 evt = BWN_LED_EVENT_RX;
8539 } else if (rx == 0) {
8540 evt = BWN_LED_EVENT_POLL;
8543 if (evt != BWN_LED_EVENT_NONE)
8544 bwn_led_event(mac, evt);
8547 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
8548 if (!IFQ_IS_EMPTY(&ifp->if_snd))
8549 bwn_start_locked(ifp);
8552 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8553 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8559 bwn_restart(struct bwn_mac *mac, const char *msg)
8561 struct bwn_softc *sc = mac->mac_sc;
8562 struct ifnet *ifp = sc->sc_ifp;
8563 struct ieee80211com *ic = ifp->if_l2com;
8565 if (mac->mac_status < BWN_MAC_STATUS_INITED)
8568 device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8569 ieee80211_runtask(ic, &mac->mac_hwreset);
8573 bwn_intr_ucode_debug(struct bwn_mac *mac)
8575 struct bwn_softc *sc = mac->mac_sc;
8578 if (mac->mac_fw.opensource == 0)
8581 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8583 case BWN_DEBUGINTR_PANIC:
8584 bwn_handle_fwpanic(mac);
8586 case BWN_DEBUGINTR_DUMP_SHM:
8587 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8589 case BWN_DEBUGINTR_DUMP_REGS:
8590 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8592 case BWN_DEBUGINTR_MARKER:
8593 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8596 device_printf(sc->sc_dev,
8597 "ucode debug unknown reason: %#x\n", reason);
8600 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8605 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8607 struct bwn_softc *sc = mac->mac_sc;
8608 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8610 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8612 if (ic->ic_opmode == IEEE80211_M_IBSS)
8613 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8617 bwn_intr_atim_end(struct bwn_mac *mac)
8620 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8621 BWN_WRITE_4(mac, BWN_MACCMD,
8622 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8623 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8628 bwn_intr_beacon(struct bwn_mac *mac)
8630 struct bwn_softc *sc = mac->mac_sc;
8631 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8632 uint32_t cmd, beacon0, beacon1;
8634 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8635 ic->ic_opmode == IEEE80211_M_MBSS)
8638 mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8640 cmd = BWN_READ_4(mac, BWN_MACCMD);
8641 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8642 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8644 if (beacon0 && beacon1) {
8645 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8646 mac->mac_intr_mask |= BWN_INTR_BEACON;
8650 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8651 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8652 bwn_load_beacon0(mac);
8653 bwn_load_beacon1(mac);
8654 cmd = BWN_READ_4(mac, BWN_MACCMD);
8655 cmd |= BWN_MACCMD_BEACON0_VALID;
8656 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8659 bwn_load_beacon0(mac);
8660 cmd = BWN_READ_4(mac, BWN_MACCMD);
8661 cmd |= BWN_MACCMD_BEACON0_VALID;
8662 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8663 } else if (!beacon1) {
8664 bwn_load_beacon1(mac);
8665 cmd = BWN_READ_4(mac, BWN_MACCMD);
8666 cmd |= BWN_MACCMD_BEACON1_VALID;
8667 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8673 bwn_intr_pmq(struct bwn_mac *mac)
8678 tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8679 if (!(tmp & 0x00000008))
8682 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8686 bwn_intr_noise(struct bwn_mac *mac)
8688 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8694 if (mac->mac_phy.type != BWN_PHYTYPE_G)
8697 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8698 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8699 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8703 KASSERT(mac->mac_noise.noi_nsamples < 8,
8704 ("%s:%d: fail", __func__, __LINE__));
8705 i = mac->mac_noise.noi_nsamples;
8706 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8707 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8708 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8709 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8710 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8711 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8712 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8713 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8714 mac->mac_noise.noi_nsamples++;
8715 if (mac->mac_noise.noi_nsamples == 8) {
8717 for (i = 0; i < 8; i++) {
8718 for (j = 0; j < 4; j++)
8719 average += mac->mac_noise.noi_samples[i][j];
8721 average = (((average / 32) * 125) + 64) / 128;
8722 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8727 average -= (tmp == 8) ? 72 : 48;
8729 mac->mac_stats.link_noise = average;
8730 mac->mac_noise.noi_running = 0;
8734 bwn_noise_gensample(mac);
8738 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8740 struct bwn_mac *mac = prq->prq_mac;
8741 struct bwn_softc *sc = mac->mac_sc;
8744 BWN_ASSERT_LOCKED(sc);
8746 if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8749 for (i = 0; i < 5000; i++) {
8750 if (bwn_pio_rxeof(prq) == 0)
8754 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8755 return ((i > 0) ? 1 : 0);
8759 bwn_dma_rx(struct bwn_dma_ring *dr)
8763 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8764 curslot = dr->get_curslot(dr);
8765 KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8766 ("%s:%d: fail", __func__, __LINE__));
8768 slot = dr->dr_curslot;
8769 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8770 bwn_dma_rxeof(dr, &slot);
8772 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8773 BUS_DMASYNC_PREWRITE);
8775 dr->set_curslot(dr, slot);
8776 dr->dr_curslot = slot;
8780 bwn_intr_txeof(struct bwn_mac *mac)
8782 struct bwn_txstatus stat;
8783 uint32_t stat0, stat1;
8786 BWN_ASSERT_LOCKED(mac->mac_sc);
8789 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8790 if (!(stat0 & 0x00000001))
8792 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8794 stat.cookie = (stat0 >> 16);
8795 stat.seq = (stat1 & 0x0000ffff);
8796 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8797 tmp = (stat0 & 0x0000ffff);
8798 stat.framecnt = ((tmp & 0xf000) >> 12);
8799 stat.rtscnt = ((tmp & 0x0f00) >> 8);
8800 stat.sreason = ((tmp & 0x001c) >> 2);
8801 stat.pm = (tmp & 0x0080) ? 1 : 0;
8802 stat.im = (tmp & 0x0040) ? 1 : 0;
8803 stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8804 stat.ack = (tmp & 0x0002) ? 1 : 0;
8806 bwn_handle_txeof(mac, &stat);
8811 bwn_hwreset(void *arg, int npending)
8813 struct bwn_mac *mac = arg;
8814 struct bwn_softc *sc = mac->mac_sc;
8820 prev_status = mac->mac_status;
8821 if (prev_status >= BWN_MAC_STATUS_STARTED)
8823 if (prev_status >= BWN_MAC_STATUS_INITED)
8826 if (prev_status >= BWN_MAC_STATUS_INITED) {
8827 error = bwn_core_init(mac);
8831 if (prev_status >= BWN_MAC_STATUS_STARTED)
8832 bwn_core_start(mac);
8835 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8836 sc->sc_curmac = NULL;
8842 bwn_handle_fwpanic(struct bwn_mac *mac)
8844 struct bwn_softc *sc = mac->mac_sc;
8847 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8848 device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8850 if (reason == BWN_FWPANIC_RESTART)
8851 bwn_restart(mac, "ucode panic");
8855 bwn_load_beacon0(struct bwn_mac *mac)
8858 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8862 bwn_load_beacon1(struct bwn_mac *mac)
8865 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8869 bwn_jssi_read(struct bwn_mac *mac)
8873 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8875 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8881 bwn_noise_gensample(struct bwn_mac *mac)
8883 uint32_t jssi = 0x7f7f7f7f;
8885 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8886 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8887 BWN_WRITE_4(mac, BWN_MACCMD,
8888 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8892 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8894 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8896 return (dr->dr_numslots - dr->dr_usedslot);
8900 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8902 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8904 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8905 ("%s:%d: fail", __func__, __LINE__));
8906 if (slot == dr->dr_numslots - 1)
8912 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8914 struct bwn_mac *mac = dr->dr_mac;
8915 struct bwn_softc *sc = mac->mac_sc;
8916 struct bwn_dma *dma = &mac->mac_method.dma;
8917 struct bwn_dmadesc_generic *desc;
8918 struct bwn_dmadesc_meta *meta;
8919 struct bwn_rxhdr4 *rxhdr;
8920 struct ifnet *ifp = sc->sc_ifp;
8927 dr->getdesc(dr, *slot, &desc, &meta);
8929 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8932 if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8933 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
8937 rxhdr = mtod(m, struct bwn_rxhdr4 *);
8938 len = le16toh(rxhdr->frame_len);
8940 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
8943 if (bwn_dma_check_redzone(dr, m)) {
8944 device_printf(sc->sc_dev, "redzone error.\n");
8945 bwn_dma_set_redzone(dr, m);
8946 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8947 BUS_DMASYNC_PREWRITE);
8950 if (len > dr->dr_rx_bufsize) {
8953 dr->getdesc(dr, *slot, &desc, &meta);
8954 bwn_dma_set_redzone(dr, meta->mt_m);
8955 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8956 BUS_DMASYNC_PREWRITE);
8957 *slot = bwn_dma_nextslot(dr, *slot);
8959 tmp -= dr->dr_rx_bufsize;
8963 device_printf(sc->sc_dev, "too small buffer "
8964 "(len %u buffer %u dropped %d)\n",
8965 len, dr->dr_rx_bufsize, cnt);
8968 macstat = le32toh(rxhdr->mac_status);
8969 if (macstat & BWN_RX_MAC_FCSERR) {
8970 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8971 device_printf(sc->sc_dev, "RX drop\n");
8976 m->m_pkthdr.rcvif = ifp;
8977 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8978 m_adj(m, dr->dr_frameoffset);
8980 bwn_rxeof(dr->dr_mac, m, rxhdr);
8984 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8986 struct bwn_dma_ring *dr;
8987 struct bwn_dmadesc_generic *desc;
8988 struct bwn_dmadesc_meta *meta;
8989 struct bwn_pio_txqueue *tq;
8990 struct bwn_pio_txpkt *tp = NULL;
8991 struct bwn_softc *sc = mac->mac_sc;
8992 struct bwn_stats *stats = &mac->mac_stats;
8993 struct ieee80211_node *ni;
8994 struct ieee80211vap *vap;
8995 int retrycnt = 0, slot;
8997 BWN_ASSERT_LOCKED(mac->mac_sc);
9000 device_printf(sc->sc_dev, "TODO: STATUS IM\n");
9002 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
9003 if (status->rtscnt) {
9004 if (status->rtscnt == 0xf)
9010 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
9012 dr = bwn_dma_parse_cookie(mac, status,
9013 status->cookie, &slot);
9015 device_printf(sc->sc_dev,
9016 "failed to parse cookie\n");
9020 dr->getdesc(dr, slot, &desc, &meta);
9021 if (meta->mt_islast) {
9024 ieee80211_ratectl_tx_complete(vap, ni,
9026 IEEE80211_RATECTL_TX_SUCCESS :
9027 IEEE80211_RATECTL_TX_FAILURE,
9031 slot = bwn_dma_nextslot(dr, slot);
9034 bwn_dma_handle_txeof(mac, status);
9037 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9039 device_printf(sc->sc_dev,
9040 "failed to parse cookie\n");
9045 ieee80211_ratectl_tx_complete(vap, ni,
9047 IEEE80211_RATECTL_TX_SUCCESS :
9048 IEEE80211_RATECTL_TX_FAILURE,
9051 bwn_pio_handle_txeof(mac, status);
9054 bwn_phy_txpower_check(mac, 0);
9058 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
9060 struct bwn_mac *mac = prq->prq_mac;
9061 struct bwn_softc *sc = mac->mac_sc;
9062 struct bwn_rxhdr4 rxhdr;
9063 struct ifnet *ifp = sc->sc_ifp;
9065 uint32_t ctl32, macstat, v32;
9066 unsigned int i, padding;
9067 uint16_t ctl16, len, totlen, v16;
9071 memset(&rxhdr, 0, sizeof(rxhdr));
9073 if (prq->prq_rev >= 8) {
9074 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9075 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
9077 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9078 BWN_PIO8_RXCTL_FRAMEREADY);
9079 for (i = 0; i < 10; i++) {
9080 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9081 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
9086 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9087 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
9089 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
9090 BWN_PIO_RXCTL_FRAMEREADY);
9091 for (i = 0; i < 10; i++) {
9092 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9093 if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
9098 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
9101 if (prq->prq_rev >= 8)
9102 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9103 prq->prq_base + BWN_PIO8_RXDATA);
9105 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9106 prq->prq_base + BWN_PIO_RXDATA);
9107 len = le16toh(rxhdr.frame_len);
9109 device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9113 device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9117 macstat = le32toh(rxhdr.mac_status);
9118 if (macstat & BWN_RX_MAC_FCSERR) {
9119 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9120 device_printf(sc->sc_dev, "%s: FCS error", __func__);
9125 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9126 totlen = len + padding;
9127 KASSERT(totlen <= MCLBYTES, ("too big..\n"));
9128 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9130 device_printf(sc->sc_dev, "%s: out of memory", __func__);
9133 mp = mtod(m, unsigned char *);
9134 if (prq->prq_rev >= 8) {
9135 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3),
9136 prq->prq_base + BWN_PIO8_RXDATA);
9138 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9139 data = &(mp[totlen - 1]);
9140 switch (totlen & 3) {
9142 *data = (v32 >> 16);
9152 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1),
9153 prq->prq_base + BWN_PIO_RXDATA);
9155 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9156 mp[totlen - 1] = v16;
9160 m->m_pkthdr.rcvif = ifp;
9161 m->m_len = m->m_pkthdr.len = totlen;
9163 bwn_rxeof(prq->prq_mac, m, &rxhdr);
9167 if (prq->prq_rev >= 8)
9168 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9169 BWN_PIO8_RXCTL_DATAREADY);
9171 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9176 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9177 struct bwn_dmadesc_meta *meta, int init)
9179 struct bwn_mac *mac = dr->dr_mac;
9180 struct bwn_dma *dma = &mac->mac_method.dma;
9181 struct bwn_rxhdr4 *hdr;
9187 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9192 * If the NIC is up and running, we need to:
9193 * - Clear RX buffer's header.
9194 * - Restore RX descriptor settings.
9201 m->m_len = m->m_pkthdr.len = MCLBYTES;
9203 bwn_dma_set_redzone(dr, m);
9206 * Try to load RX buf into temporary DMA map
9208 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9209 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9214 * See the comment above
9223 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9225 meta->mt_paddr = paddr;
9228 * Swap RX buf's DMA map with the loaded temporary one
9230 map = meta->mt_dmap;
9231 meta->mt_dmap = dr->dr_spare_dmap;
9232 dr->dr_spare_dmap = map;
9236 * Clear RX buf header
9238 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9239 bzero(hdr, sizeof(*hdr));
9240 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9241 BUS_DMASYNC_PREWRITE);
9244 * Setup RX buf descriptor
9246 dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len -
9247 sizeof(*hdr), 0, 0, 0);
9252 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9253 bus_size_t mapsz __unused, int error)
9257 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9258 *((bus_addr_t *)arg) = seg->ds_addr;
9263 bwn_hwrate2ieeerate(int rate)
9267 case BWN_CCK_RATE_1MB:
9269 case BWN_CCK_RATE_2MB:
9271 case BWN_CCK_RATE_5MB:
9273 case BWN_CCK_RATE_11MB:
9275 case BWN_OFDM_RATE_6MB:
9277 case BWN_OFDM_RATE_9MB:
9279 case BWN_OFDM_RATE_12MB:
9281 case BWN_OFDM_RATE_18MB:
9283 case BWN_OFDM_RATE_24MB:
9285 case BWN_OFDM_RATE_36MB:
9287 case BWN_OFDM_RATE_48MB:
9289 case BWN_OFDM_RATE_54MB:
9298 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9300 const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9301 struct bwn_plcp6 *plcp;
9302 struct bwn_softc *sc = mac->mac_sc;
9303 struct ieee80211_frame_min *wh;
9304 struct ieee80211_node *ni;
9305 struct ifnet *ifp = sc->sc_ifp;
9306 struct ieee80211com *ic = ifp->if_l2com;
9308 int padding, rate, rssi = 0, noise = 0, type;
9309 uint16_t phytype, phystat0, phystat3, chanstat;
9310 unsigned char *mp = mtod(m, unsigned char *);
9311 static int rx_mac_dec_rpt = 0;
9313 BWN_ASSERT_LOCKED(sc);
9315 phystat0 = le16toh(rxhdr->phy_status0);
9316 phystat3 = le16toh(rxhdr->phy_status3);
9317 macstat = le32toh(rxhdr->mac_status);
9318 chanstat = le16toh(rxhdr->channel);
9319 phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9321 if (macstat & BWN_RX_MAC_FCSERR)
9322 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9323 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9324 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9325 if (macstat & BWN_RX_MAC_DECERR)
9328 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9329 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9330 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9334 plcp = (struct bwn_plcp6 *)(mp + padding);
9335 m_adj(m, sizeof(struct bwn_plcp6) + padding);
9336 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9337 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9341 wh = mtod(m, struct ieee80211_frame_min *);
9343 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9344 device_printf(sc->sc_dev,
9345 "RX decryption attempted (old %d keyidx %#x)\n",
9347 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9349 /* XXX calculating RSSI & noise & antenna */
9351 if (phystat0 & BWN_RX_PHYST0_OFDM)
9352 rate = bwn_plcp_get_ofdmrate(mac, plcp,
9353 phytype == BWN_PHYTYPE_A);
9355 rate = bwn_plcp_get_cckrate(mac, plcp);
9357 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9360 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9363 if (ieee80211_radiotap_active(ic))
9364 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9365 m_adj(m, -IEEE80211_CRC_LEN);
9367 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */
9368 noise = mac->mac_stats.link_noise;
9370 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
9374 ni = ieee80211_find_rxnode(ic, wh);
9376 type = ieee80211_input(ni, m, rssi, noise);
9377 ieee80211_free_node(ni);
9379 type = ieee80211_input_all(ic, m, rssi, noise);
9384 device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9388 bwn_dma_handle_txeof(struct bwn_mac *mac,
9389 const struct bwn_txstatus *status)
9391 struct bwn_dma *dma = &mac->mac_method.dma;
9392 struct bwn_dma_ring *dr;
9393 struct bwn_dmadesc_generic *desc;
9394 struct bwn_dmadesc_meta *meta;
9395 struct bwn_softc *sc = mac->mac_sc;
9396 struct ieee80211_node *ni;
9397 struct ifnet *ifp = sc->sc_ifp;
9401 BWN_ASSERT_LOCKED(sc);
9403 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9405 device_printf(sc->sc_dev, "failed to parse cookie\n");
9408 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9411 KASSERT(slot >= 0 && slot < dr->dr_numslots,
9412 ("%s:%d: fail", __func__, __LINE__));
9413 dr->getdesc(dr, slot, &desc, &meta);
9415 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
9416 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
9417 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
9418 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9420 if (meta->mt_islast) {
9421 KASSERT(meta->mt_m != NULL,
9422 ("%s:%d: fail", __func__, __LINE__));
9428 * Do any tx complete callback. Note this must
9429 * be done before releasing the node reference.
9431 if (m->m_flags & M_TXCB)
9432 ieee80211_process_callback(ni, m, 0);
9433 ieee80211_free_node(ni);
9439 KASSERT(meta->mt_m == NULL,
9440 ("%s:%d: fail", __func__, __LINE__));
9444 if (meta->mt_islast) {
9445 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
9448 slot = bwn_dma_nextslot(dr, slot);
9450 sc->sc_watchdog_timer = 0;
9452 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9453 ("%s:%d: fail", __func__, __LINE__));
9454 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9460 bwn_pio_handle_txeof(struct bwn_mac *mac,
9461 const struct bwn_txstatus *status)
9463 struct bwn_pio_txqueue *tq;
9464 struct bwn_pio_txpkt *tp = NULL;
9465 struct bwn_softc *sc = mac->mac_sc;
9466 struct ifnet *ifp = sc->sc_ifp;
9468 BWN_ASSERT_LOCKED(sc);
9470 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9474 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9477 if (tp->tp_ni != NULL) {
9479 * Do any tx complete callback. Note this must
9480 * be done before releasing the node reference.
9482 if (tp->tp_m->m_flags & M_TXCB)
9483 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9484 ieee80211_free_node(tp->tp_ni);
9489 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9491 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
9493 sc->sc_watchdog_timer = 0;
9495 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9501 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9503 struct bwn_softc *sc = mac->mac_sc;
9504 struct bwn_phy *phy = &mac->mac_phy;
9505 struct ifnet *ifp = sc->sc_ifp;
9506 struct ieee80211com *ic = ifp->if_l2com;
9512 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9514 phy->nexttime = now + 2 * 1000;
9516 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9517 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9520 if (phy->recalc_txpwr != NULL) {
9521 result = phy->recalc_txpwr(mac,
9522 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9523 if (result == BWN_TXPWR_RES_DONE)
9525 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9526 ("%s: fail", __func__));
9527 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9529 ieee80211_runtask(ic, &mac->mac_txpower);
9534 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9537 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9541 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9544 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9548 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9551 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9555 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9558 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9562 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9566 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9568 return (BWN_OFDM_RATE_6MB);
9570 return (BWN_OFDM_RATE_9MB);
9572 return (BWN_OFDM_RATE_12MB);
9574 return (BWN_OFDM_RATE_18MB);
9576 return (BWN_OFDM_RATE_24MB);
9578 return (BWN_OFDM_RATE_36MB);
9580 return (BWN_OFDM_RATE_48MB);
9582 return (BWN_OFDM_RATE_54MB);
9583 /* CCK rates (NB: not IEEE std, device-specific) */
9585 return (BWN_CCK_RATE_1MB);
9587 return (BWN_CCK_RATE_2MB);
9589 return (BWN_CCK_RATE_5MB);
9591 return (BWN_CCK_RATE_11MB);
9594 device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9595 return (BWN_CCK_RATE_1MB);
9599 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9600 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9602 const struct bwn_phy *phy = &mac->mac_phy;
9603 struct bwn_softc *sc = mac->mac_sc;
9604 struct ieee80211_frame *wh;
9605 struct ieee80211_frame *protwh;
9606 struct ieee80211_frame_cts *cts;
9607 struct ieee80211_frame_rts *rts;
9608 const struct ieee80211_txparam *tp;
9609 struct ieee80211vap *vap = ni->ni_vap;
9610 struct ifnet *ifp = sc->sc_ifp;
9611 struct ieee80211com *ic = ifp->if_l2com;
9614 uint32_t macctl = 0;
9615 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9616 uint16_t phyctl = 0;
9617 uint8_t rate, rate_fb;
9619 wh = mtod(m, struct ieee80211_frame *);
9620 memset(txhdr, 0, sizeof(*txhdr));
9622 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9623 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9624 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9629 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9630 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9631 rate = rate_fb = tp->mgmtrate;
9633 rate = rate_fb = tp->mcastrate;
9634 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9635 rate = rate_fb = tp->ucastrate;
9637 rix = ieee80211_ratectl_rate(ni, NULL, 0);
9638 rate = ni->ni_txrate;
9641 rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9647 sc->sc_tx_rate = rate;
9649 rate = bwn_ieeerate2hwrate(sc, rate);
9650 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9652 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9653 bwn_plcp_getcck(rate);
9654 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9655 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9657 if ((rate_fb == rate) ||
9658 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9659 (*(u_int16_t *)wh->i_dur == htole16(0)))
9660 txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9662 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9663 m->m_pkthdr.len, rate, isshort);
9665 /* XXX TX encryption */
9666 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9667 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9668 (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9669 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9670 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9671 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9673 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9675 txhdr->chan = phy->chan;
9676 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9678 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9679 rate == BWN_CCK_RATE_11MB))
9680 phyctl |= BWN_TX_PHY_SHORTPRMBL;
9682 /* XXX TX antenna selection */
9684 switch (bwn_antenna_sanitize(mac, 0)) {
9686 phyctl |= BWN_TX_PHY_ANT01AUTO;
9689 phyctl |= BWN_TX_PHY_ANT0;
9692 phyctl |= BWN_TX_PHY_ANT1;
9695 phyctl |= BWN_TX_PHY_ANT2;
9698 phyctl |= BWN_TX_PHY_ANT3;
9701 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9705 macctl |= BWN_TX_MAC_ACK;
9707 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9708 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9709 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9710 macctl |= BWN_TX_MAC_LONGFRAME;
9712 if (ic->ic_flags & IEEE80211_F_USEPROT) {
9713 /* XXX RTS rate is always 1MB??? */
9714 rts_rate = BWN_CCK_RATE_1MB;
9715 rts_rate_fb = bwn_get_fbrate(rts_rate);
9717 protdur = ieee80211_compute_duration(ic->ic_rt,
9718 m->m_pkthdr.len, rate, isshort) +
9719 + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9721 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9722 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9723 (txhdr->body.old.rts_frame) :
9724 (txhdr->body.new.rts_frame));
9725 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9727 KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9728 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9729 mprot->m_pkthdr.len);
9731 macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9732 len = sizeof(struct ieee80211_frame_cts);
9734 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9735 (txhdr->body.old.rts_frame) :
9736 (txhdr->body.new.rts_frame));
9737 protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9739 mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9740 wh->i_addr2, protdur);
9741 KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9742 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9743 mprot->m_pkthdr.len);
9745 macctl |= BWN_TX_MAC_SEND_RTSCTS;
9746 len = sizeof(struct ieee80211_frame_rts);
9748 len += IEEE80211_CRC_LEN;
9749 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9750 &txhdr->body.old.rts_plcp :
9751 &txhdr->body.new.rts_plcp), len, rts_rate);
9752 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9755 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9756 (&txhdr->body.old.rts_frame) :
9757 (&txhdr->body.new.rts_frame));
9758 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9760 if (BWN_ISOFDMRATE(rts_rate)) {
9761 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9762 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9764 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9765 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9767 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9768 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9771 if (BWN_ISOLDFMT(mac))
9772 txhdr->body.old.cookie = htole16(cookie);
9774 txhdr->body.new.cookie = htole16(cookie);
9776 txhdr->macctl = htole32(macctl);
9777 txhdr->phyctl = htole16(phyctl);
9782 if (ieee80211_radiotap_active_vap(vap)) {
9783 sc->sc_tx_th.wt_flags = 0;
9784 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
9785 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9787 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9788 rate == BWN_CCK_RATE_11MB))
9789 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9790 sc->sc_tx_th.wt_rate = rate;
9792 ieee80211_radiotap_tx(vap, m);
9799 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9803 uint8_t *raw = plcp->o.raw;
9805 if (BWN_ISOFDMRATE(rate)) {
9806 d = bwn_plcp_getofdm(rate);
9807 KASSERT(!(octets & 0xf000),
9808 ("%s:%d: fail", __func__, __LINE__));
9810 plcp->o.data = htole32(d);
9812 plen = octets * 16 / rate;
9813 if ((octets * 16 % rate) > 0) {
9815 if ((rate == BWN_CCK_RATE_11MB)
9816 && ((octets * 8 % 11) < 4)) {
9822 plcp->o.data |= htole32(plen << 16);
9823 raw[0] = bwn_plcp_getcck(rate);
9828 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9830 struct bwn_softc *sc = mac->mac_sc;
9835 if (mac->mac_phy.gmode)
9836 mask = siba_sprom_get_ant_bg(sc->sc_dev);
9838 mask = siba_sprom_get_ant_a(sc->sc_dev);
9839 if (!(mask & (1 << (n - 1))))
9845 bwn_get_fbrate(uint8_t bitrate)
9848 case BWN_CCK_RATE_1MB:
9849 return (BWN_CCK_RATE_1MB);
9850 case BWN_CCK_RATE_2MB:
9851 return (BWN_CCK_RATE_1MB);
9852 case BWN_CCK_RATE_5MB:
9853 return (BWN_CCK_RATE_2MB);
9854 case BWN_CCK_RATE_11MB:
9855 return (BWN_CCK_RATE_5MB);
9856 case BWN_OFDM_RATE_6MB:
9857 return (BWN_CCK_RATE_5MB);
9858 case BWN_OFDM_RATE_9MB:
9859 return (BWN_OFDM_RATE_6MB);
9860 case BWN_OFDM_RATE_12MB:
9861 return (BWN_OFDM_RATE_9MB);
9862 case BWN_OFDM_RATE_18MB:
9863 return (BWN_OFDM_RATE_12MB);
9864 case BWN_OFDM_RATE_24MB:
9865 return (BWN_OFDM_RATE_18MB);
9866 case BWN_OFDM_RATE_36MB:
9867 return (BWN_OFDM_RATE_24MB);
9868 case BWN_OFDM_RATE_48MB:
9869 return (BWN_OFDM_RATE_36MB);
9870 case BWN_OFDM_RATE_54MB:
9871 return (BWN_OFDM_RATE_48MB);
9873 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9878 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9879 uint32_t ctl, const void *_data, int len)
9881 struct bwn_softc *sc = mac->mac_sc;
9883 const uint8_t *data = _data;
9885 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9886 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9887 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9889 siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9890 tq->tq_base + BWN_PIO8_TXDATA);
9892 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9893 BWN_PIO8_TXCTL_24_31);
9894 data = &(data[len - 1]);
9897 ctl |= BWN_PIO8_TXCTL_16_23;
9898 value |= (uint32_t)(*data) << 16;
9901 ctl |= BWN_PIO8_TXCTL_8_15;
9902 value |= (uint32_t)(*data) << 8;
9905 value |= (uint32_t)(*data);
9907 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9908 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9915 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9916 uint16_t offset, uint32_t value)
9919 BWN_WRITE_4(mac, tq->tq_base + offset, value);
9923 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9924 uint16_t ctl, const void *_data, int len)
9926 struct bwn_softc *sc = mac->mac_sc;
9927 const uint8_t *data = _data;
9929 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9930 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9932 siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9933 tq->tq_base + BWN_PIO_TXDATA);
9935 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9936 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9937 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9944 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9945 uint16_t ctl, struct mbuf *m0)
9950 struct mbuf *m = m0;
9952 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9953 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9955 for (; m != NULL; m = m->m_next) {
9956 buf = mtod(m, const uint8_t *);
9957 for (i = 0; i < m->m_len; i++) {
9961 data |= (buf[i] << 8);
9962 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9967 if (m0->m_pkthdr.len % 2) {
9968 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9969 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9970 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9977 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9980 if (mac->mac_phy.type != BWN_PHYTYPE_G)
9982 BWN_WRITE_2(mac, 0x684, 510 + time);
9983 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9986 static struct bwn_dma_ring *
9987 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9990 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9991 return (mac->mac_method.dma.wme[WME_AC_BE]);
9995 return (mac->mac_method.dma.wme[WME_AC_VO]);
9997 return (mac->mac_method.dma.wme[WME_AC_VI]);
9999 return (mac->mac_method.dma.wme[WME_AC_BE]);
10001 return (mac->mac_method.dma.wme[WME_AC_BK]);
10003 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
10008 bwn_dma_getslot(struct bwn_dma_ring *dr)
10012 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
10014 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
10015 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
10016 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
10018 slot = bwn_dma_nextslot(dr, dr->dr_curslot);
10019 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
10020 dr->dr_curslot = slot;
10027 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
10029 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
10030 unsigned int a, b, c, d;
10034 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
10036 b = (tmp >> 8) & 0xff;
10037 c = (tmp >> 16) & 0xff;
10038 d = (tmp >> 24) & 0xff;
10039 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
10040 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
10042 bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
10043 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
10044 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
10047 a = (a + 32) & 0x3f;
10048 b = (b + 32) & 0x3f;
10049 c = (c + 32) & 0x3f;
10050 d = (d + 32) & 0x3f;
10053 avg = (a + b + c + d + 2) / 4;
10055 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
10056 & BWN_HF_4DB_CCK_POWERBOOST)
10057 avg = (avg >= 13) ? (avg - 13) : 0;
10063 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
10065 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
10066 int rfatt = *rfattp;
10067 int bbatt = *bbattp;
10070 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
10072 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
10074 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
10076 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
10078 if (bbatt > lo->bbatt.max) {
10083 if (bbatt < lo->bbatt.min) {
10088 if (rfatt > lo->rfatt.max) {
10093 if (rfatt < lo->rfatt.min) {
10101 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
10102 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
10106 bwn_phy_lock(struct bwn_mac *mac)
10108 struct bwn_softc *sc = mac->mac_sc;
10109 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10111 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10112 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10114 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10115 bwn_psctl(mac, BWN_PS_AWAKE);
10119 bwn_phy_unlock(struct bwn_mac *mac)
10121 struct bwn_softc *sc = mac->mac_sc;
10122 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10124 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10125 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10127 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10132 bwn_rf_lock(struct bwn_mac *mac)
10135 BWN_WRITE_4(mac, BWN_MACCTL,
10136 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
10137 BWN_READ_4(mac, BWN_MACCTL);
10142 bwn_rf_unlock(struct bwn_mac *mac)
10145 BWN_READ_2(mac, BWN_PHYVER);
10146 BWN_WRITE_4(mac, BWN_MACCTL,
10147 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10150 static struct bwn_pio_txqueue *
10151 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10152 struct bwn_pio_txpkt **pack)
10154 struct bwn_pio *pio = &mac->mac_method.pio;
10155 struct bwn_pio_txqueue *tq = NULL;
10156 unsigned int index;
10158 switch (cookie & 0xf000) {
10160 tq = &pio->wme[WME_AC_BK];
10163 tq = &pio->wme[WME_AC_BE];
10166 tq = &pio->wme[WME_AC_VI];
10169 tq = &pio->wme[WME_AC_VO];
10175 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10178 index = (cookie & 0x0fff);
10179 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10180 if (index >= N(tq->tq_pkts))
10182 *pack = &tq->tq_pkts[index];
10183 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10188 bwn_txpwr(void *arg, int npending)
10190 struct bwn_mac *mac = arg;
10191 struct bwn_softc *sc = mac->mac_sc;
10194 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10195 mac->mac_phy.set_txpwr != NULL)
10196 mac->mac_phy.set_txpwr(mac);
10201 bwn_task_15s(struct bwn_mac *mac)
10205 if (mac->mac_fw.opensource) {
10206 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10208 bwn_restart(mac, "fw watchdog");
10211 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10213 if (mac->mac_phy.task_15s)
10214 mac->mac_phy.task_15s(mac);
10216 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10220 bwn_task_30s(struct bwn_mac *mac)
10223 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10225 mac->mac_noise.noi_running = 1;
10226 mac->mac_noise.noi_nsamples = 0;
10228 bwn_noise_gensample(mac);
10232 bwn_task_60s(struct bwn_mac *mac)
10235 if (mac->mac_phy.task_60s)
10236 mac->mac_phy.task_60s(mac);
10237 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10241 bwn_tasks(void *arg)
10243 struct bwn_mac *mac = arg;
10244 struct bwn_softc *sc = mac->mac_sc;
10246 BWN_ASSERT_LOCKED(sc);
10247 if (mac->mac_status != BWN_MAC_STATUS_STARTED)
10250 if (mac->mac_task_state % 4 == 0)
10252 if (mac->mac_task_state % 2 == 0)
10256 mac->mac_task_state++;
10257 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10261 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10263 struct bwn_softc *sc = mac->mac_sc;
10265 KASSERT(a == 0, ("not support APHY\n"));
10267 switch (plcp->o.raw[0] & 0xf) {
10269 return (BWN_OFDM_RATE_6MB);
10271 return (BWN_OFDM_RATE_9MB);
10273 return (BWN_OFDM_RATE_12MB);
10275 return (BWN_OFDM_RATE_18MB);
10277 return (BWN_OFDM_RATE_24MB);
10279 return (BWN_OFDM_RATE_36MB);
10281 return (BWN_OFDM_RATE_48MB);
10283 return (BWN_OFDM_RATE_54MB);
10285 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10286 plcp->o.raw[0] & 0xf);
10291 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10293 struct bwn_softc *sc = mac->mac_sc;
10295 switch (plcp->o.raw[0]) {
10297 return (BWN_CCK_RATE_1MB);
10299 return (BWN_CCK_RATE_2MB);
10301 return (BWN_CCK_RATE_5MB);
10303 return (BWN_CCK_RATE_11MB);
10305 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10310 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10311 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10312 int rssi, int noise)
10314 struct bwn_softc *sc = mac->mac_sc;
10315 const struct ieee80211_frame_min *wh;
10317 uint16_t low_mactime_now;
10319 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10320 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10322 wh = mtod(m, const struct ieee80211_frame_min *);
10323 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
10324 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10326 bwn_tsf_read(mac, &tsf);
10327 low_mactime_now = tsf;
10328 tsf = tsf & ~0xffffULL;
10329 tsf += le16toh(rxhdr->mac_time);
10330 if (low_mactime_now < le16toh(rxhdr->mac_time))
10333 sc->sc_rx_th.wr_tsf = tsf;
10334 sc->sc_rx_th.wr_rate = rate;
10335 sc->sc_rx_th.wr_antsignal = rssi;
10336 sc->sc_rx_th.wr_antnoise = noise;
10340 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10342 uint32_t low, high;
10344 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10345 ("%s:%d: fail", __func__, __LINE__));
10347 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10348 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10355 bwn_dma_attach(struct bwn_mac *mac)
10357 struct bwn_dma *dma = &mac->mac_method.dma;
10358 struct bwn_softc *sc = mac->mac_sc;
10359 bus_addr_t lowaddr = 0;
10362 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10365 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10367 mac->mac_flags |= BWN_MAC_FLAG_DMA;
10369 dma->dmatype = bwn_dma_gettype(mac);
10370 if (dma->dmatype == BWN_DMA_30BIT)
10371 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10372 else if (dma->dmatype == BWN_DMA_32BIT)
10373 lowaddr = BUS_SPACE_MAXADDR_32BIT;
10375 lowaddr = BUS_SPACE_MAXADDR;
10378 * Create top level DMA tag
10380 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
10381 BWN_ALIGN, 0, /* alignment, bounds */
10382 lowaddr, /* lowaddr */
10383 BUS_SPACE_MAXADDR, /* highaddr */
10384 NULL, NULL, /* filter, filterarg */
10385 BUS_SPACE_MAXSIZE, /* maxsize */
10386 BUS_SPACE_UNRESTRICTED, /* nsegments */
10387 BUS_SPACE_MAXSIZE, /* maxsegsize */
10389 NULL, NULL, /* lockfunc, lockarg */
10390 &dma->parent_dtag);
10392 device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10397 * Create TX/RX mbuf DMA tag
10399 error = bus_dma_tag_create(dma->parent_dtag,
10407 BUS_SPACE_MAXSIZE_32BIT,
10412 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10415 error = bus_dma_tag_create(dma->parent_dtag,
10423 BUS_SPACE_MAXSIZE_32BIT,
10428 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10432 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10433 if (!dma->wme[WME_AC_BK])
10436 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10437 if (!dma->wme[WME_AC_BE])
10440 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10441 if (!dma->wme[WME_AC_VI])
10444 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10445 if (!dma->wme[WME_AC_VO])
10448 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10451 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10457 fail7: bwn_dma_ringfree(&dma->mcast);
10458 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10459 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10460 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10461 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10462 fail2: bus_dma_tag_destroy(dma->txbuf_dtag);
10463 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag);
10464 fail0: bus_dma_tag_destroy(dma->parent_dtag);
10468 static struct bwn_dma_ring *
10469 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10470 uint16_t cookie, int *slot)
10472 struct bwn_dma *dma = &mac->mac_method.dma;
10473 struct bwn_dma_ring *dr;
10474 struct bwn_softc *sc = mac->mac_sc;
10476 BWN_ASSERT_LOCKED(mac->mac_sc);
10478 switch (cookie & 0xf000) {
10480 dr = dma->wme[WME_AC_BK];
10483 dr = dma->wme[WME_AC_BE];
10486 dr = dma->wme[WME_AC_VI];
10489 dr = dma->wme[WME_AC_VO];
10497 ("invalid cookie value %d", cookie & 0xf000));
10499 *slot = (cookie & 0x0fff);
10500 if (*slot < 0 || *slot >= dr->dr_numslots) {
10502 * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10503 * that it occurs events which have same H/W sequence numbers.
10504 * When it's occurred just prints a WARNING msgs and ignores.
10506 KASSERT(status->seq == dma->lastseq,
10507 ("%s:%d: fail", __func__, __LINE__));
10508 device_printf(sc->sc_dev,
10509 "out of slot ranges (0 < %d < %d)\n", *slot,
10513 dma->lastseq = status->seq;
10518 bwn_dma_stop(struct bwn_mac *mac)
10520 struct bwn_dma *dma;
10522 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10524 dma = &mac->mac_method.dma;
10526 bwn_dma_ringstop(&dma->rx);
10527 bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10528 bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10529 bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10530 bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10531 bwn_dma_ringstop(&dma->mcast);
10535 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10541 bwn_dma_cleanup(*dr);
10545 bwn_pio_stop(struct bwn_mac *mac)
10547 struct bwn_pio *pio;
10549 if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10551 pio = &mac->mac_method.pio;
10553 bwn_destroy_queue_tx(&pio->mcast);
10554 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10555 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10556 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10557 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10561 bwn_led_attach(struct bwn_mac *mac)
10563 struct bwn_softc *sc = mac->mac_sc;
10564 const uint8_t *led_act = NULL;
10565 uint16_t val[BWN_LED_MAX];
10568 sc->sc_led_idle = (2350 * hz) / 1000;
10569 sc->sc_led_blink = 1;
10571 for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10572 if (siba_get_pci_subvendor(sc->sc_dev) ==
10573 bwn_vendor_led_act[i].vid) {
10574 led_act = bwn_vendor_led_act[i].led_act;
10578 if (led_act == NULL)
10579 led_act = bwn_default_led_act;
10581 val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10582 val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10583 val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10584 val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10586 for (i = 0; i < BWN_LED_MAX; ++i) {
10587 struct bwn_led *led = &sc->sc_leds[i];
10589 if (val[i] == 0xff) {
10590 led->led_act = led_act[i];
10592 if (val[i] & BWN_LED_ACT_LOW)
10593 led->led_flags |= BWN_LED_F_ACTLOW;
10594 led->led_act = val[i] & BWN_LED_ACT_MASK;
10596 led->led_mask = (1 << i);
10598 if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10599 led->led_act == BWN_LED_ACT_BLINK_POLL ||
10600 led->led_act == BWN_LED_ACT_BLINK) {
10601 led->led_flags |= BWN_LED_F_BLINK;
10602 if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10603 led->led_flags |= BWN_LED_F_POLLABLE;
10604 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10605 led->led_flags |= BWN_LED_F_SLOW;
10607 if (sc->sc_blink_led == NULL) {
10608 sc->sc_blink_led = led;
10609 if (led->led_flags & BWN_LED_F_SLOW)
10610 BWN_LED_SLOWDOWN(sc->sc_led_idle);
10614 DPRINTF(sc, BWN_DEBUG_LED,
10615 "%dth led, act %d, lowact %d\n", i,
10616 led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10618 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
10621 static __inline uint16_t
10622 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10625 if (led->led_flags & BWN_LED_F_ACTLOW)
10628 val |= led->led_mask;
10630 val &= ~led->led_mask;
10635 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10637 struct bwn_softc *sc = mac->mac_sc;
10638 struct ifnet *ifp = sc->sc_ifp;
10639 struct ieee80211com *ic = ifp->if_l2com;
10643 if (nstate == IEEE80211_S_INIT) {
10644 callout_stop(&sc->sc_led_blink_ch);
10645 sc->sc_led_blinking = 0;
10648 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
10651 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10652 for (i = 0; i < BWN_LED_MAX; ++i) {
10653 struct bwn_led *led = &sc->sc_leds[i];
10656 if (led->led_act == BWN_LED_ACT_UNKN ||
10657 led->led_act == BWN_LED_ACT_NULL)
10660 if ((led->led_flags & BWN_LED_F_BLINK) &&
10661 nstate != IEEE80211_S_INIT)
10664 switch (led->led_act) {
10665 case BWN_LED_ACT_ON: /* Always on */
10668 case BWN_LED_ACT_OFF: /* Always off */
10669 case BWN_LED_ACT_5GHZ: /* TODO: 11A */
10675 case IEEE80211_S_INIT:
10678 case IEEE80211_S_RUN:
10679 if (led->led_act == BWN_LED_ACT_11G &&
10680 ic->ic_curmode != IEEE80211_MODE_11G)
10684 if (led->led_act == BWN_LED_ACT_ASSOC)
10691 val = bwn_led_onoff(led, val, on);
10693 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10697 bwn_led_event(struct bwn_mac *mac, int event)
10699 struct bwn_softc *sc = mac->mac_sc;
10700 struct bwn_led *led = sc->sc_blink_led;
10703 if (event == BWN_LED_EVENT_POLL) {
10704 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10706 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10710 sc->sc_led_ticks = ticks;
10711 if (sc->sc_led_blinking)
10715 case BWN_LED_EVENT_RX:
10716 rate = sc->sc_rx_rate;
10718 case BWN_LED_EVENT_TX:
10719 rate = sc->sc_tx_rate;
10721 case BWN_LED_EVENT_POLL:
10725 panic("unknown LED event %d\n", event);
10728 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10729 bwn_led_duration[rate].off_dur);
10733 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10735 struct bwn_softc *sc = mac->mac_sc;
10736 struct bwn_led *led = sc->sc_blink_led;
10739 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10740 val = bwn_led_onoff(led, val, 1);
10741 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10743 if (led->led_flags & BWN_LED_F_SLOW) {
10744 BWN_LED_SLOWDOWN(on_dur);
10745 BWN_LED_SLOWDOWN(off_dur);
10748 sc->sc_led_blinking = 1;
10749 sc->sc_led_blink_offdur = off_dur;
10751 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10755 bwn_led_blink_next(void *arg)
10757 struct bwn_mac *mac = arg;
10758 struct bwn_softc *sc = mac->mac_sc;
10761 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10762 val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10763 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10765 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10766 bwn_led_blink_end, mac);
10770 bwn_led_blink_end(void *arg)
10772 struct bwn_mac *mac = arg;
10773 struct bwn_softc *sc = mac->mac_sc;
10775 sc->sc_led_blinking = 0;
10779 bwn_suspend(device_t dev)
10781 struct bwn_softc *sc = device_get_softc(dev);
10788 bwn_resume(device_t dev)
10790 struct bwn_softc *sc = device_get_softc(dev);
10791 struct ifnet *ifp = sc->sc_ifp;
10793 if (ifp->if_flags & IFF_UP)
10799 bwn_rfswitch(void *arg)
10801 struct bwn_softc *sc = arg;
10802 struct bwn_mac *mac = sc->sc_curmac;
10803 int cur = 0, prev = 0;
10805 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10806 ("%s: invalid MAC status %d", __func__, mac->mac_status));
10808 if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10809 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10810 & BWN_RF_HWENABLED_HI_MASK))
10813 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10814 & BWN_RF_HWENABLED_LO_MASK)
10818 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10823 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10825 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10827 device_printf(sc->sc_dev,
10828 "status of RF switch is changed to %s\n",
10829 cur ? "ON" : "OFF");
10830 if (cur != mac->mac_phy.rf_on) {
10832 bwn_rf_turnon(mac);
10834 bwn_rf_turnoff(mac);
10838 callout_schedule(&sc->sc_rfswitch_ch, hz);
10842 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10844 struct bwn_phy *phy = &mac->mac_phy;
10845 struct bwn_phy_lp *plp = &phy->phy_lp;
10847 plp->plp_antenna = BWN_ANT_DEFAULT;
10851 bwn_phy_lp_init(struct bwn_mac *mac)
10853 static const struct bwn_stxtable tables[] = {
10854 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10855 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff },
10856 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff },
10857 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10858 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f },
10859 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10860 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 },
10861 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f },
10862 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10863 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 },
10864 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10865 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 },
10866 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f },
10867 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f },
10868 { 2, 11, 0x40, 0, 0x0f }
10870 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10871 struct bwn_softc *sc = mac->mac_sc;
10872 const struct bwn_stxtable *st;
10873 struct ifnet *ifp = sc->sc_ifp;
10874 struct ieee80211com *ic = ifp->if_l2com;
10878 bwn_phy_lp_readsprom(mac); /* XXX bad place */
10879 bwn_phy_lp_bbinit(mac);
10881 /* initialize RF */
10882 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10884 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10887 if (mac->mac_phy.rf_ver == 0x2062)
10888 bwn_phy_lp_b2062_init(mac);
10890 bwn_phy_lp_b2063_init(mac);
10892 /* synchronize stx table. */
10893 for (i = 0; i < N(tables); i++) {
10895 tmp = BWN_RF_READ(mac, st->st_rfaddr);
10896 tmp >>= st->st_rfshift;
10897 tmp <<= st->st_physhift;
10898 BWN_PHY_SETMASK(mac,
10899 BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10900 ~(st->st_mask << st->st_physhift), tmp);
10903 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10904 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10908 if (mac->mac_phy.rev >= 2)
10909 bwn_phy_lp_rxcal_r2(mac);
10910 else if (!plp->plp_rccap) {
10911 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10912 bwn_phy_lp_rccal_r12(mac);
10914 bwn_phy_lp_set_rccap(mac);
10916 error = bwn_phy_lp_switch_channel(mac, 7);
10918 device_printf(sc->sc_dev,
10919 "failed to change channel 7 (%d)\n", error);
10920 bwn_phy_lp_txpctl_init(mac);
10921 bwn_phy_lp_calib(mac);
10926 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10929 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10930 return (BWN_READ_2(mac, BWN_PHYDATA));
10934 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10937 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10938 BWN_WRITE_2(mac, BWN_PHYDATA, value);
10942 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10946 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10947 BWN_WRITE_2(mac, BWN_PHYDATA,
10948 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10952 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10955 KASSERT(reg != 1, ("unaccessible register %d", reg));
10956 if (mac->mac_phy.rev < 2 && reg != 0x4001)
10958 if (mac->mac_phy.rev >= 2)
10960 BWN_WRITE_2(mac, BWN_RFCTL, reg);
10961 return BWN_READ_2(mac, BWN_RFDATALO);
10965 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10968 KASSERT(reg != 1, ("unaccessible register %d", reg));
10969 BWN_WRITE_2(mac, BWN_RFCTL, reg);
10970 BWN_WRITE_2(mac, BWN_RFDATALO, value);
10974 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10978 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10979 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10980 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10984 if (mac->mac_phy.rev >= 2) {
10985 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10986 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10987 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10988 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10989 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
10993 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
10994 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10995 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
10996 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
11000 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
11002 struct bwn_phy *phy = &mac->mac_phy;
11003 struct bwn_phy_lp *plp = &phy->phy_lp;
11006 if (phy->rf_ver == 0x2063) {
11007 error = bwn_phy_lp_b2063_switch_channel(mac, chan);
11011 error = bwn_phy_lp_b2062_switch_channel(mac, chan);
11014 bwn_phy_lp_set_anafilter(mac, chan);
11015 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
11018 plp->plp_chan = chan;
11019 BWN_WRITE_2(mac, BWN_CHANNEL, chan);
11024 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
11026 struct bwn_softc *sc = mac->mac_sc;
11027 struct ifnet *ifp = sc->sc_ifp;
11028 struct ieee80211com *ic = ifp->if_l2com;
11030 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
11034 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
11036 struct bwn_phy *phy = &mac->mac_phy;
11037 struct bwn_phy_lp *plp = &phy->phy_lp;
11039 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
11042 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
11043 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
11044 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
11045 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
11046 plp->plp_antenna = antenna;
11050 bwn_phy_lp_task_60s(struct bwn_mac *mac)
11053 bwn_phy_lp_calib(mac);
11057 bwn_phy_lp_readsprom(struct bwn_mac *mac)
11059 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11060 struct bwn_softc *sc = mac->mac_sc;
11061 struct ifnet *ifp = sc->sc_ifp;
11062 struct ieee80211com *ic = ifp->if_l2com;
11064 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11065 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
11066 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
11067 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
11068 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
11069 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
11070 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
11074 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
11075 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
11076 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
11077 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
11078 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
11079 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
11080 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
11081 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
11085 bwn_phy_lp_bbinit(struct bwn_mac *mac)
11088 bwn_phy_lp_tblinit(mac);
11089 if (mac->mac_phy.rev >= 2)
11090 bwn_phy_lp_bbinit_r2(mac);
11092 bwn_phy_lp_bbinit_r01(mac);
11096 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
11098 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
11099 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
11100 struct bwn_softc *sc = mac->mac_sc;
11101 struct ifnet *ifp = sc->sc_ifp;
11102 struct ieee80211com *ic = ifp->if_l2com;
11104 bwn_phy_lp_set_txgain(mac,
11105 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
11106 bwn_phy_lp_set_bbmult(mac, 150);
11110 bwn_phy_lp_calib(struct bwn_mac *mac)
11112 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11113 struct bwn_softc *sc = mac->mac_sc;
11114 struct ifnet *ifp = sc->sc_ifp;
11115 struct ieee80211com *ic = ifp->if_l2com;
11116 const struct bwn_rxcompco *rc = NULL;
11117 struct bwn_txgain ogain;
11118 int i, omode, oafeovr, orf, obbmult;
11119 uint8_t mode, fc = 0;
11121 if (plp->plp_chanfullcal != plp->plp_chan) {
11122 plp->plp_chanfullcal = plp->plp_chan;
11126 bwn_mac_suspend(mac);
11128 /* BlueTooth Coexistance Override */
11129 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
11130 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
11132 if (mac->mac_phy.rev >= 2)
11133 bwn_phy_lp_digflt_save(mac);
11134 bwn_phy_lp_get_txpctlmode(mac);
11135 mode = plp->plp_txpctlmode;
11136 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11137 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
11138 bwn_phy_lp_bugfix(mac);
11139 if (mac->mac_phy.rev >= 2 && fc == 1) {
11140 bwn_phy_lp_get_txpctlmode(mac);
11141 omode = plp->plp_txpctlmode;
11142 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11144 ogain = bwn_phy_lp_get_txgain(mac);
11145 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11146 obbmult = bwn_phy_lp_get_bbmult(mac);
11147 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11149 bwn_phy_lp_set_txgain(mac, &ogain);
11150 bwn_phy_lp_set_bbmult(mac, obbmult);
11151 bwn_phy_lp_set_txpctlmode(mac, omode);
11152 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11154 bwn_phy_lp_set_txpctlmode(mac, mode);
11155 if (mac->mac_phy.rev >= 2)
11156 bwn_phy_lp_digflt_restore(mac);
11158 /* do RX IQ Calculation; assumes that noise is true. */
11159 if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11160 for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11161 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11162 rc = &bwn_rxcompco_5354[i];
11164 } else if (mac->mac_phy.rev >= 2)
11165 rc = &bwn_rxcompco_r2;
11167 for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11168 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11169 rc = &bwn_rxcompco_r12[i];
11175 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11176 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11178 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11180 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11181 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11182 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11184 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11185 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11188 bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11189 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11190 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11191 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11192 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11193 bwn_phy_lp_set_deaf(mac, 0);
11194 /* XXX no checking return value? */
11195 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11196 bwn_phy_lp_clear_deaf(mac, 0);
11197 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11198 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11199 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11201 /* disable RX GAIN override. */
11202 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11203 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11204 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11205 if (mac->mac_phy.rev >= 2) {
11206 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11207 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11208 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11209 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11212 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11215 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11216 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11218 bwn_mac_enable(mac);
11222 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11226 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11230 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11231 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11235 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11237 static const struct bwn_b206x_chan *bc = NULL;
11238 struct bwn_softc *sc = mac->mac_sc;
11239 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11241 uint16_t old, scale, tmp16;
11244 for (i = 0; i < N(bwn_b2063_chantable); i++) {
11245 if (bwn_b2063_chantable[i].bc_chan == chan) {
11246 bc = &bwn_b2063_chantable[i];
11253 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11254 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11255 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11256 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11257 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11258 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11259 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11260 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11261 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11262 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11263 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11264 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11266 old = BWN_RF_READ(mac, BWN_B2063_COM15);
11267 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11269 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11270 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11271 freqref = freqxtal * 3;
11272 div = (freqxtal <= 26000000 ? 1 : 2);
11273 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11274 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11275 999999) / 1000000) + 1;
11277 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11278 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11279 0xfff8, timeout >> 2);
11280 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11281 0xff9f,timeout << 5);
11282 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11284 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11285 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11286 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11288 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11289 (timeoutref + 1)) - 1;
11290 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11292 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11294 tmp[0] = ((val[2] * 62500) / freqref) << 4;
11295 tmp[1] = ((val[2] * 62500) % freqref) << 4;
11296 while (tmp[1] >= freqref) {
11300 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11301 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11302 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11303 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11304 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11306 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11307 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11308 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11309 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11311 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11312 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11314 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11316 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11319 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11321 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11322 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11324 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11329 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11330 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11332 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11333 if (freqxtal > 26000000)
11334 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11336 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11339 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11341 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11343 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11345 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11347 /* VCO Calibration */
11348 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11349 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11350 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11352 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11354 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11356 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11358 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11360 BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11365 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11367 struct bwn_softc *sc = mac->mac_sc;
11368 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11369 const struct bwn_b206x_chan *bc = NULL;
11370 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11374 for (i = 0; i < N(bwn_b2062_chantable); i++) {
11375 if (bwn_b2062_chantable[i].bc_chan == chan) {
11376 bc = &bwn_b2062_chantable[i];
11384 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11385 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11386 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11387 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11388 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11389 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11390 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11391 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11392 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11393 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11395 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11396 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11397 bwn_phy_lp_b2062_reset_pllbias(mac);
11398 tmp[0] = freqxtal / 1000;
11399 tmp[1] = plp->plp_div * 1000;
11400 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11401 if (ieee80211_ieee2mhz(chan, 0) < 4000)
11403 tmp[3] = 48 * tmp[0];
11404 tmp[5] = tmp[2] / tmp[3];
11405 tmp[6] = tmp[2] % tmp[3];
11406 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11407 tmp[4] = tmp[6] * 0x100;
11408 tmp[5] = tmp[4] / tmp[3];
11409 tmp[6] = tmp[4] % tmp[3];
11410 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11411 tmp[4] = tmp[6] * 0x100;
11412 tmp[5] = tmp[4] / tmp[3];
11413 tmp[6] = tmp[4] % tmp[3];
11414 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11415 tmp[4] = tmp[6] * 0x100;
11416 tmp[5] = tmp[4] / tmp[3];
11417 tmp[6] = tmp[4] % tmp[3];
11418 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11419 tmp[5] + ((2 * tmp[6]) / tmp[3]));
11420 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11421 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11422 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11423 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11425 bwn_phy_lp_b2062_vco_calib(mac);
11426 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11427 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11428 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11429 bwn_phy_lp_b2062_reset_pllbias(mac);
11430 bwn_phy_lp_b2062_vco_calib(mac);
11431 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11432 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11436 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11441 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11443 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11444 uint16_t tmp = (channel == 14);
11446 if (mac->mac_phy.rev < 2) {
11447 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11448 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11449 bwn_phy_lp_set_rccap(mac);
11453 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11457 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11459 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11460 struct bwn_softc *sc = mac->mac_sc;
11461 struct ifnet *ifp = sc->sc_ifp;
11462 struct ieee80211com *ic = ifp->if_l2com;
11463 uint16_t iso, tmp[3];
11465 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11467 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11468 iso = plp->plp_txisoband_m;
11469 else if (freq <= 5320)
11470 iso = plp->plp_txisoband_l;
11471 else if (freq <= 5700)
11472 iso = plp->plp_txisoband_m;
11474 iso = plp->plp_txisoband_h;
11476 tmp[0] = ((iso - 26) / 12) << 12;
11477 tmp[1] = tmp[0] + 0x1000;
11478 tmp[2] = tmp[0] + 0x2000;
11480 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11481 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11485 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11487 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11489 static const uint16_t addr[] = {
11490 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11491 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11492 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11493 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11494 BWN_PHY_OFDM(0xcf),
11496 static const uint16_t val[] = {
11497 0xde5e, 0xe832, 0xe331, 0x4d26,
11498 0x0026, 0x1420, 0x0020, 0xfe08,
11502 for (i = 0; i < N(addr); i++) {
11503 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11504 BWN_PHY_WRITE(mac, addr[i], val[i]);
11509 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11511 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11512 struct bwn_softc *sc = mac->mac_sc;
11515 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11516 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11517 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11518 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11520 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11521 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11523 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11524 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11527 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11528 device_printf(sc->sc_dev, "unknown command mode\n");
11534 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11536 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11540 bwn_phy_lp_get_txpctlmode(mac);
11541 old = plp->plp_txpctlmode;
11544 plp->plp_txpctlmode = mode;
11546 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11547 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11549 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11550 0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11552 /* disable TX GAIN override */
11553 if (mac->mac_phy.rev < 2)
11554 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11556 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11557 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11559 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11561 plp->plp_txpwridx = -1;
11563 if (mac->mac_phy.rev >= 2) {
11564 if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11565 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11567 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11570 /* writes TX Power Control mode */
11571 switch (plp->plp_txpctlmode) {
11572 case BWN_PHYLP_TXPCTL_OFF:
11573 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11575 case BWN_PHYLP_TXPCTL_ON_HW:
11576 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11578 case BWN_PHYLP_TXPCTL_ON_SW:
11579 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11583 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11585 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11586 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11590 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11592 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11593 struct bwn_softc *sc = mac->mac_sc;
11594 const unsigned int size = 256;
11595 struct bwn_txgain tg;
11596 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11597 uint16_t tssinpt, tssiidx, value[2];
11601 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
11602 M_NOWAIT | M_ZERO);
11603 if (tabs == NULL) {
11604 device_printf(sc->sc_dev, "failed to allocate buffer.\n");
11608 bwn_phy_lp_get_txpctlmode(mac);
11609 mode = plp->plp_txpctlmode;
11610 txpwridx = plp->plp_txpwridx;
11611 tssinpt = plp->plp_tssinpt;
11612 tssiidx = plp->plp_tssiidx;
11614 bwn_tab_read_multi(mac,
11615 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11616 BWN_TAB_4(7, 0x140), size, tabs);
11618 bwn_phy_lp_tblinit(mac);
11619 bwn_phy_lp_bbinit(mac);
11620 bwn_phy_lp_txpctl_init(mac);
11621 bwn_phy_lp_rf_onoff(mac, 1);
11622 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11624 bwn_tab_write_multi(mac,
11625 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11626 BWN_TAB_4(7, 0x140), size, tabs);
11628 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11629 plp->plp_tssinpt = tssinpt;
11630 plp->plp_tssiidx = tssiidx;
11631 bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11632 if (txpwridx != -1) {
11633 /* set TX power by index */
11634 plp->plp_txpwridx = txpwridx;
11635 bwn_phy_lp_get_txpctlmode(mac);
11636 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11637 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11638 if (mac->mac_phy.rev >= 2) {
11639 rxcomp = bwn_tab_read(mac,
11640 BWN_TAB_4(7, txpwridx + 320));
11641 txgain = bwn_tab_read(mac,
11642 BWN_TAB_4(7, txpwridx + 192));
11643 tg.tg_pad = (txgain >> 16) & 0xff;
11644 tg.tg_gm = txgain & 0xff;
11645 tg.tg_pga = (txgain >> 8) & 0xff;
11646 tg.tg_dac = (rxcomp >> 28) & 0xff;
11647 bwn_phy_lp_set_txgain(mac, &tg);
11649 rxcomp = bwn_tab_read(mac,
11650 BWN_TAB_4(10, txpwridx + 320));
11651 txgain = bwn_tab_read(mac,
11652 BWN_TAB_4(10, txpwridx + 192));
11653 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11654 0xf800, (txgain >> 4) & 0x7fff);
11655 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11656 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11658 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11661 value[0] = (rxcomp >> 10) & 0x3ff;
11662 value[1] = rxcomp & 0x3ff;
11663 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11665 coeff = bwn_tab_read(mac,
11666 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11667 BWN_TAB_4(10, txpwridx + 448));
11668 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11669 if (mac->mac_phy.rev >= 2) {
11670 rfpwr = bwn_tab_read(mac,
11671 BWN_TAB_4(7, txpwridx + 576));
11672 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11675 bwn_phy_lp_set_txgain_override(mac);
11677 if (plp->plp_rccap)
11678 bwn_phy_lp_set_rccap(mac);
11679 bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11680 bwn_phy_lp_set_txpctlmode(mac, mode);
11681 free(tabs, M_DEVBUF);
11685 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11687 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11689 static const uint16_t addr[] = {
11690 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11691 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11692 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11693 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11694 BWN_PHY_OFDM(0xcf),
11697 for (i = 0; i < N(addr); i++)
11698 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11702 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11704 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11706 if (mac->mac_phy.rev < 2) {
11707 bwn_phy_lp_tblinit_r01(mac);
11708 bwn_phy_lp_tblinit_txgain(mac);
11709 bwn_phy_lp_set_gaintbl(mac, freq);
11713 bwn_phy_lp_tblinit_r2(mac);
11714 bwn_phy_lp_tblinit_txgain(mac);
11722 struct bwn_smpair {
11729 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11731 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11732 struct bwn_softc *sc = mac->mac_sc;
11733 struct ifnet *ifp = sc->sc_ifp;
11734 struct ieee80211com *ic = ifp->if_l2com;
11735 static const struct bwn_wpair v1[] = {
11736 { BWN_PHY_AFE_DAC_CTL, 0x50 },
11737 { BWN_PHY_AFE_CTL, 0x8800 },
11738 { BWN_PHY_AFE_CTL_OVR, 0 },
11739 { BWN_PHY_AFE_CTL_OVRVAL, 0 },
11740 { BWN_PHY_RF_OVERRIDE_0, 0 },
11741 { BWN_PHY_RF_OVERRIDE_2, 0 },
11742 { BWN_PHY_OFDM(0xf9), 0 },
11743 { BWN_PHY_TR_LOOKUP_1, 0 }
11745 static const struct bwn_smpair v2[] = {
11746 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11747 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11748 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11749 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11750 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11752 static const struct bwn_smpair v3[] = {
11753 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11754 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11755 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11756 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11757 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11758 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11759 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11760 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11761 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11762 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11767 for (i = 0; i < N(v1); i++)
11768 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11769 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11770 for (i = 0; i < N(v2); i++)
11771 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11773 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11774 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11775 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11776 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11777 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11778 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11780 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11782 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11783 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11784 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11785 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11786 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11787 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11788 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11789 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11790 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11791 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11792 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11793 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11794 (siba_get_chiprev(sc->sc_dev) == 0)) {
11795 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11796 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11798 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11799 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11801 for (i = 0; i < N(v3); i++)
11802 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11803 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11804 (siba_get_chiprev(sc->sc_dev) == 0)) {
11805 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11806 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11809 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11810 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11811 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11812 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11813 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11814 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11815 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11817 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11819 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11820 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11821 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11822 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11823 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11824 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11825 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11826 0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11827 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11829 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11830 (siba_get_chiprev(sc->sc_dev) == 0)) {
11831 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11832 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11833 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11836 bwn_phy_lp_digflt_save(mac);
11840 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11842 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11843 struct bwn_softc *sc = mac->mac_sc;
11844 struct ifnet *ifp = sc->sc_ifp;
11845 struct ieee80211com *ic = ifp->if_l2com;
11846 static const struct bwn_smpair v1[] = {
11847 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11848 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11849 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11850 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11851 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11852 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11853 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11855 static const struct bwn_smpair v2[] = {
11856 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11857 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11858 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11859 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11860 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11861 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11862 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11863 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11864 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11865 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11866 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11867 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11868 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11869 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11870 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11871 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11873 static const struct bwn_smpair v3[] = {
11874 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11875 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11876 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11877 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11878 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11879 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11880 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11881 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11883 static const struct bwn_smpair v4[] = {
11884 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11885 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11886 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11887 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11888 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11889 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11890 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11891 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11893 static const struct bwn_smpair v5[] = {
11894 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11895 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11896 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11897 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11898 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11899 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11900 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11901 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11904 uint16_t tmp, tmp2;
11906 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11907 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11908 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11909 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11910 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11911 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11912 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11913 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11914 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11915 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11916 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11917 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11918 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11919 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11920 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11921 for (i = 0; i < N(v1); i++)
11922 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11923 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11924 0xff00, plp->plp_rxpwroffset);
11925 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11926 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11927 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11928 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11929 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11930 if (mac->mac_phy.rev == 0)
11931 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11933 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11935 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11936 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11937 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11939 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11940 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11941 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11942 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11944 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11945 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11946 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11947 0xfff9, (plp->plp_bxarch << 1));
11948 if (mac->mac_phy.rev == 1 &&
11949 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11950 for (i = 0; i < N(v2); i++)
11951 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11953 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11954 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11955 ((mac->mac_phy.rev == 0) &&
11956 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11957 for (i = 0; i < N(v3); i++)
11958 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11960 } else if (mac->mac_phy.rev == 1 ||
11961 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11962 for (i = 0; i < N(v4); i++)
11963 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11966 for (i = 0; i < N(v5); i++)
11967 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11970 if (mac->mac_phy.rev == 1 &&
11971 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11972 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11973 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11974 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11975 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11977 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11978 (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11979 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11980 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11981 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11982 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11983 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11985 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11986 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11987 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11988 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11989 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11990 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11991 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
11992 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
11993 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11995 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
11996 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
11998 if (mac->mac_phy.rev == 1) {
11999 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
12000 tmp2 = (tmp & 0x03e0) >> 5;
12002 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
12003 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
12004 tmp2 = (tmp & 0x1f00) >> 8;
12006 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
12007 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
12008 tmp2 = tmp & 0x00ff;
12010 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
12014 struct bwn_b2062_freq {
12020 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
12022 #define CALC_CTL7(freq, div) \
12023 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
12024 #define CALC_CTL18(freq, div) \
12025 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
12026 #define CALC_CTL19(freq, div) \
12027 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
12028 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12029 struct bwn_softc *sc = mac->mac_sc;
12030 struct ifnet *ifp = sc->sc_ifp;
12031 struct ieee80211com *ic = ifp->if_l2com;
12032 static const struct bwn_b2062_freq freqdata_tab[] = {
12033 { 12000, { 6, 6, 6, 6, 10, 6 } },
12034 { 13000, { 4, 4, 4, 4, 11, 7 } },
12035 { 14400, { 3, 3, 3, 3, 12, 7 } },
12036 { 16200, { 3, 3, 3, 3, 13, 8 } },
12037 { 18000, { 2, 2, 2, 2, 14, 8 } },
12038 { 19200, { 1, 1, 1, 1, 14, 9 } }
12040 static const struct bwn_wpair v1[] = {
12041 { BWN_B2062_N_TXCTL3, 0 },
12042 { BWN_B2062_N_TXCTL4, 0 },
12043 { BWN_B2062_N_TXCTL5, 0 },
12044 { BWN_B2062_N_TXCTL6, 0 },
12045 { BWN_B2062_N_PDNCTL0, 0x40 },
12046 { BWN_B2062_N_PDNCTL0, 0 },
12047 { BWN_B2062_N_CALIB_TS, 0x10 },
12048 { BWN_B2062_N_CALIB_TS, 0 }
12050 const struct bwn_b2062_freq *f = NULL;
12051 uint32_t xtalfreq, ref;
12054 bwn_phy_lp_b2062_tblinit(mac);
12056 for (i = 0; i < N(v1); i++)
12057 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12058 if (mac->mac_phy.rev > 0)
12059 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
12060 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
12061 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12062 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
12064 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
12066 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
12067 ("%s:%d: fail", __func__, __LINE__));
12068 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12069 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
12071 if (xtalfreq <= 30000000) {
12073 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
12076 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
12079 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
12080 CALC_CTL7(xtalfreq, plp->plp_div));
12081 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
12082 CALC_CTL18(xtalfreq, plp->plp_div));
12083 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
12084 CALC_CTL19(xtalfreq, plp->plp_div));
12086 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
12088 for (i = 0; i < N(freqdata_tab); i++) {
12089 if (ref < freqdata_tab[i].freq) {
12090 f = &freqdata_tab[i];
12095 f = &freqdata_tab[N(freqdata_tab) - 1];
12096 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
12097 ((uint16_t)(f->value[1]) << 4) | f->value[0]);
12098 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
12099 ((uint16_t)(f->value[3]) << 4) | f->value[2]);
12100 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
12101 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
12108 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
12111 bwn_phy_lp_b2063_tblinit(mac);
12112 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
12113 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
12114 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
12115 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
12116 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
12117 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
12118 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
12119 if (mac->mac_phy.rev == 2) {
12120 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
12121 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
12122 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
12124 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
12125 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
12130 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
12132 struct bwn_softc *sc = mac->mac_sc;
12133 static const struct bwn_wpair v1[] = {
12134 { BWN_B2063_RX_BB_SP8, 0x0 },
12135 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12136 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12137 { BWN_B2063_RC_CALIB_CTL2, 0x15 },
12138 { BWN_B2063_RC_CALIB_CTL3, 0x70 },
12139 { BWN_B2063_RC_CALIB_CTL4, 0x52 },
12140 { BWN_B2063_RC_CALIB_CTL5, 0x1 },
12141 { BWN_B2063_RC_CALIB_CTL1, 0x7d }
12143 static const struct bwn_wpair v2[] = {
12144 { BWN_B2063_TX_BB_SP3, 0x0 },
12145 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12146 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12147 { BWN_B2063_RC_CALIB_CTL2, 0x55 },
12148 { BWN_B2063_RC_CALIB_CTL3, 0x76 }
12150 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12154 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12156 for (i = 0; i < 2; i++)
12157 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12158 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12159 for (i = 2; i < N(v1); i++)
12160 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12161 for (i = 0; i < 10000; i++) {
12162 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12167 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12168 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12170 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12172 for (i = 0; i < N(v2); i++)
12173 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12174 if (freqxtal == 24000000) {
12175 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12176 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12178 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12179 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12181 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12182 for (i = 0; i < 10000; i++) {
12183 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12187 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12188 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12189 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12193 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12195 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12196 struct bwn_softc *sc = mac->mac_sc;
12197 struct bwn_phy_lp_iq_est ie;
12198 struct bwn_txgain tx_gains;
12199 static const uint32_t pwrtbl[21] = {
12200 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12201 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12202 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12203 0x0004c, 0x0002c, 0x0001a,
12205 uint32_t npwr, ipwr, sqpwr, tmp;
12206 int loopback, i, j, sum, error;
12208 uint8_t txo, bbmult, txpctlmode;
12210 error = bwn_phy_lp_switch_channel(mac, 7);
12212 device_printf(sc->sc_dev,
12213 "failed to change channel to 7 (%d)\n", error);
12214 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12215 bbmult = bwn_phy_lp_get_bbmult(mac);
12217 tx_gains = bwn_phy_lp_get_txgain(mac);
12219 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12220 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12221 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12222 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12223 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12224 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12225 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12227 bwn_phy_lp_get_txpctlmode(mac);
12228 txpctlmode = plp->plp_txpctlmode;
12229 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12232 bwn_phy_lp_set_deaf(mac, 1);
12233 bwn_phy_lp_set_trsw_over(mac, 0, 1);
12234 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12235 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12236 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12237 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12238 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12239 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12240 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12241 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12242 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12243 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12244 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12245 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12246 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12247 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12248 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12249 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12250 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12251 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12252 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12253 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12254 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12255 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12256 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12258 loopback = bwn_phy_lp_loopback(mac);
12259 if (loopback == -1)
12261 bwn_phy_lp_set_rxgain_idx(mac, loopback);
12262 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12263 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12264 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12265 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12268 memset(&ie, 0, sizeof(ie));
12269 for (i = 128; i <= 159; i++) {
12270 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12272 for (j = 5; j <= 25; j++) {
12273 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12274 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12276 sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12277 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12278 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12280 sum += ((ipwr - npwr) * (ipwr - npwr));
12281 if ((i == 128) || (sum < tmp)) {
12282 plp->plp_rccap = i;
12287 bwn_phy_lp_ddfs_turnoff(mac);
12290 bwn_phy_lp_clear_deaf(mac, 1);
12291 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12292 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12294 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12295 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12296 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12297 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12298 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12299 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12300 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12302 bwn_phy_lp_set_bbmult(mac, bbmult);
12304 bwn_phy_lp_set_txgain(mac, &tx_gains);
12305 bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12306 if (plp->plp_rccap)
12307 bwn_phy_lp_set_rccap(mac);
12311 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12313 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12314 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12316 if (mac->mac_phy.rev == 1)
12317 rc_cap = MIN(rc_cap + 5, 15);
12319 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12320 MAX(plp->plp_rccap - 4, 0x80));
12321 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12322 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12323 ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12327 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12334 for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12336 if (r << 1 >= div) {
12338 r = (r << 1) - div;
12347 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12349 struct bwn_softc *sc = mac->mac_sc;
12351 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12353 if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12354 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12355 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12357 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12363 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12366 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12367 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12372 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12374 #define FLAG_A 0x01
12375 #define FLAG_G 0x02
12376 struct bwn_softc *sc = mac->mac_sc;
12377 struct ifnet *ifp = sc->sc_ifp;
12378 struct ieee80211com *ic = ifp->if_l2com;
12379 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12380 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12381 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12382 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12383 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12384 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12385 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12386 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12387 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12388 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12389 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12390 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12391 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12392 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12393 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12394 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12395 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12396 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12397 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12398 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12399 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12400 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12401 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12402 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12403 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12404 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12405 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12406 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12407 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12408 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12409 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12410 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12411 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12412 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12413 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12414 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12415 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12416 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12417 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12418 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12419 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12420 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12421 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12422 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12423 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12424 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12425 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12426 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12428 const struct bwn_b206x_rfinit_entry *br;
12431 for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12432 br = &bwn_b2062_init_tab[i];
12433 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12434 if (br->br_flags & FLAG_G)
12435 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12437 if (br->br_flags & FLAG_A)
12438 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12446 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12448 #define FLAG_A 0x01
12449 #define FLAG_G 0x02
12450 struct bwn_softc *sc = mac->mac_sc;
12451 struct ifnet *ifp = sc->sc_ifp;
12452 struct ieee80211com *ic = ifp->if_l2com;
12453 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12454 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12455 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12456 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12457 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12458 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12459 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12460 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12461 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12462 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12463 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12464 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12465 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12466 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12467 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12468 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12469 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12470 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12471 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12472 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12473 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12474 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12475 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12476 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12477 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12478 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12479 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12480 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12481 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12482 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12483 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12484 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12485 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12486 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12487 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12488 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12489 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12490 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12491 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12492 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12493 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12494 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12495 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12497 const struct bwn_b206x_rfinit_entry *br;
12500 for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12501 br = &bwn_b2063_init_tab[i];
12502 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12503 if (br->br_flags & FLAG_G)
12504 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12506 if (br->br_flags & FLAG_A)
12507 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12515 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12516 int count, void *_data)
12519 uint32_t offset, type;
12520 uint8_t *data = _data;
12522 type = BWN_TAB_GETTYPE(typenoffset);
12523 offset = BWN_TAB_GETOFFSET(typenoffset);
12524 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12526 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12528 for (i = 0; i < count; i++) {
12531 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12534 case BWN_TAB_16BIT:
12535 *((uint16_t *)data) = BWN_PHY_READ(mac,
12536 BWN_PHY_TABLEDATALO);
12539 case BWN_TAB_32BIT:
12540 *((uint32_t *)data) = BWN_PHY_READ(mac,
12541 BWN_PHY_TABLEDATAHI);
12542 *((uint32_t *)data) <<= 16;
12543 *((uint32_t *)data) |= BWN_PHY_READ(mac,
12544 BWN_PHY_TABLEDATALO);
12548 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12554 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12555 int count, const void *_data)
12557 uint32_t offset, type, value;
12558 const uint8_t *data = _data;
12561 type = BWN_TAB_GETTYPE(typenoffset);
12562 offset = BWN_TAB_GETOFFSET(typenoffset);
12563 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12565 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12567 for (i = 0; i < count; i++) {
12572 KASSERT(!(value & ~0xff),
12573 ("%s:%d: fail", __func__, __LINE__));
12574 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12576 case BWN_TAB_16BIT:
12577 value = *((const uint16_t *)data);
12579 KASSERT(!(value & ~0xffff),
12580 ("%s:%d: fail", __func__, __LINE__));
12581 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12583 case BWN_TAB_32BIT:
12584 value = *((const uint32_t *)data);
12586 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12587 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12590 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12595 static struct bwn_txgain
12596 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12598 struct bwn_txgain tg;
12601 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12602 if (mac->mac_phy.rev < 2) {
12603 tmp = BWN_PHY_READ(mac,
12604 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12605 tg.tg_gm = tmp & 0x0007;
12606 tg.tg_pga = (tmp & 0x0078) >> 3;
12607 tg.tg_pad = (tmp & 0x780) >> 7;
12611 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12612 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12613 tg.tg_gm = tmp & 0xff;
12614 tg.tg_pga = (tmp >> 8) & 0xff;
12619 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12622 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12626 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12630 if (mac->mac_phy.rev < 2) {
12631 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12632 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12633 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12634 bwn_phy_lp_set_txgain_override(mac);
12638 pa = bwn_phy_lp_get_pa_gain(mac);
12639 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12640 (tg->tg_pga << 8) | tg->tg_gm);
12641 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12642 tg->tg_pad | (pa << 6));
12643 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12644 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12645 tg->tg_pad | (pa << 8));
12646 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12647 bwn_phy_lp_set_txgain_override(mac);
12651 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12654 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12658 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12660 uint16_t trsw = (tx << 1) | rx;
12662 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12663 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12667 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12669 struct bwn_softc *sc = mac->mac_sc;
12670 struct ifnet *ifp = sc->sc_ifp;
12671 struct ieee80211com *ic = ifp->if_l2com;
12672 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12674 if (mac->mac_phy.rev < 2) {
12676 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12677 ext_lna = (gain & 2) >> 1;
12679 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12680 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12681 0xfbff, ext_lna << 10);
12682 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12683 0xf7ff, ext_lna << 11);
12684 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12686 low_gain = gain & 0xffff;
12687 high_gain = (gain >> 16) & 0xf;
12688 ext_lna = (gain >> 21) & 0x1;
12689 trsw = ~(gain >> 20) & 0x1;
12691 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12692 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12693 0xfdff, ext_lna << 9);
12694 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12695 0xfbff, ext_lna << 10);
12696 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12697 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12698 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12699 tmp = (gain >> 2) & 0x3;
12700 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12702 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12707 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12708 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12709 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12710 if (mac->mac_phy.rev >= 2) {
12711 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12712 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12713 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12714 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12718 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12722 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12724 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12727 plp->plp_crsusr_off = 1;
12729 plp->plp_crssys_off = 1;
12731 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12735 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12737 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12738 struct bwn_softc *sc = mac->mac_sc;
12739 struct ifnet *ifp = sc->sc_ifp;
12740 struct ieee80211com *ic = ifp->if_l2com;
12743 plp->plp_crsusr_off = 0;
12745 plp->plp_crssys_off = 0;
12747 if (plp->plp_crsusr_off || plp->plp_crssys_off)
12750 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12751 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12753 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12756 static unsigned int
12757 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12759 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12760 static uint8_t sqrt_table[256] = {
12761 10, 14, 17, 20, 22, 24, 26, 28,
12762 30, 31, 33, 34, 36, 37, 38, 40,
12763 41, 42, 43, 44, 45, 46, 47, 48,
12764 50, 50, 51, 52, 53, 54, 55, 56,
12765 57, 58, 59, 60, 60, 61, 62, 63,
12766 64, 64, 65, 66, 67, 67, 68, 69,
12767 70, 70, 71, 72, 72, 73, 74, 74,
12768 75, 76, 76, 77, 78, 78, 79, 80,
12769 80, 81, 81, 82, 83, 83, 84, 84,
12770 85, 86, 86, 87, 87, 88, 88, 89,
12771 90, 90, 91, 91, 92, 92, 93, 93,
12772 94, 94, 95, 95, 96, 96, 97, 97,
12773 98, 98, 99, 100, 100, 100, 101, 101,
12774 102, 102, 103, 103, 104, 104, 105, 105,
12775 106, 106, 107, 107, 108, 108, 109, 109,
12776 110, 110, 110, 111, 111, 112, 112, 113,
12777 113, 114, 114, 114, 115, 115, 116, 116,
12778 117, 117, 117, 118, 118, 119, 119, 120,
12779 120, 120, 121, 121, 122, 122, 122, 123,
12780 123, 124, 124, 124, 125, 125, 126, 126,
12781 126, 127, 127, 128, 128, 128, 129, 129,
12782 130, 130, 130, 131, 131, 131, 132, 132,
12783 133, 133, 133, 134, 134, 134, 135, 135,
12784 136, 136, 136, 137, 137, 137, 138, 138,
12785 138, 139, 139, 140, 140, 140, 141, 141,
12786 141, 142, 142, 142, 143, 143, 143, 144,
12787 144, 144, 145, 145, 145, 146, 146, 146,
12788 147, 147, 147, 148, 148, 148, 149, 149,
12789 150, 150, 150, 150, 151, 151, 151, 152,
12790 152, 152, 153, 153, 153, 154, 154, 154,
12791 155, 155, 155, 156, 156, 156, 157, 157,
12792 157, 158, 158, 158, 159, 159, 159, 160
12800 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12804 return (sqrt_table[x - 1] / 10);
12808 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12810 #define CALC_COEFF(_v, _x, _y, _z) do { \
12814 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12816 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12819 #define CALC_COEFF2(_v, _x, _y, _z) do { \
12823 _v = (_y << (31 - _x)) / (_z >> _t); \
12825 _v = (_y << (31 - _x)) / (_z << -_t); \
12827 struct bwn_phy_lp_iq_est ie;
12831 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12835 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12836 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12838 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12842 if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12847 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12848 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12850 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12854 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12855 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12862 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12864 static const uint16_t noisescale[] = {
12865 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12866 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12867 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12868 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12869 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12871 static const uint16_t crsgainnft[] = {
12872 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12873 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12874 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12875 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12878 static const uint16_t filterctl[] = {
12879 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12882 static const uint32_t psctl[] = {
12883 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12884 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12885 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12886 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12887 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12888 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12889 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12890 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12892 static const uint16_t ofdmcckgain_r0[] = {
12893 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12894 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12895 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12896 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12899 static const uint16_t ofdmcckgain_r1[] = {
12900 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12901 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12902 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12903 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12906 static const uint16_t gaindelta[] = {
12907 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12910 static const uint32_t txpwrctl[] = {
12911 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12912 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12913 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12914 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12915 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12916 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12917 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12918 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12919 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12920 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12921 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12922 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12923 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
12924 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12925 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12926 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12927 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12928 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12929 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12930 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12931 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12932 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12933 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12934 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12935 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12936 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12937 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12938 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12939 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12940 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12941 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12942 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12943 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12944 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12945 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12946 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12947 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12948 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12949 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12950 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12951 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12952 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12953 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12954 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12955 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12956 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12957 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12958 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12959 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12960 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12961 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12962 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12963 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12964 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12965 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12966 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12967 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12968 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12969 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12970 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12971 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12972 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12973 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12974 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12975 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12976 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12977 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12978 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12979 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12980 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12981 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12982 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12983 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12984 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12985 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12986 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12987 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12988 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12989 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12990 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12991 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12992 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12993 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12994 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12995 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12996 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12997 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12998 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12999 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13000 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
13001 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
13002 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
13003 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
13004 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
13005 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
13006 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
13007 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
13008 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
13009 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
13010 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
13011 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
13012 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
13013 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
13014 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
13015 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
13016 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
13017 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
13018 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
13019 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
13020 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
13021 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
13022 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
13023 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
13024 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
13025 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
13029 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13031 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13032 bwn_tab_sigsq_tbl);
13033 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13034 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
13035 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
13036 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
13037 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13038 bwn_tab_pllfrac_tbl);
13039 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13040 bwn_tabl_iqlocal_tbl);
13041 if (mac->mac_phy.rev == 0) {
13042 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
13044 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
13047 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
13049 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
13052 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
13053 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
13057 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
13059 struct bwn_softc *sc = mac->mac_sc;
13061 static const uint16_t noisescale[] = {
13062 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13063 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13064 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13065 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13066 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13067 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13068 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
13070 static const uint32_t filterctl[] = {
13071 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
13072 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
13074 static const uint32_t psctl[] = {
13075 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
13076 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
13077 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
13078 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
13080 static const uint32_t gainidx[] = {
13081 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13082 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13083 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13084 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
13085 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
13086 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
13087 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
13088 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
13089 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
13090 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
13091 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
13092 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
13093 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
13094 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
13095 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
13096 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13097 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13098 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13099 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
13100 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
13101 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
13102 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
13103 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
13104 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
13105 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
13106 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
13107 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
13108 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
13109 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
13110 0x0000001a, 0x64ca55ad, 0x0000001a
13112 static const uint16_t auxgainidx[] = {
13113 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13114 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
13115 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
13118 static const uint16_t swctl[] = {
13119 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13120 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13121 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13122 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
13123 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13124 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13125 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13126 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
13128 static const uint8_t hf[] = {
13129 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
13130 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
13132 static const uint32_t gainval[] = {
13133 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13134 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13135 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13136 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13137 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13138 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13139 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13140 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13141 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13142 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13143 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13144 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13145 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
13146 0x000000f1, 0x00000000, 0x00000000
13148 static const uint16_t gain[] = {
13149 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13150 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13151 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13152 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13153 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13154 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
13155 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13156 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13157 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13158 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13159 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13160 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13162 static const uint32_t papdeps[] = {
13163 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13164 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13165 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13166 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13167 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13168 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13169 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13170 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13171 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13172 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13173 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13174 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13175 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13177 static const uint32_t papdmult[] = {
13178 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13179 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13180 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13181 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13182 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13183 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13184 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13185 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13186 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13187 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13188 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13189 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13190 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13192 static const uint32_t gainidx_a0[] = {
13193 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13194 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13195 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13196 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13197 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13198 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13199 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13200 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13201 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13202 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13203 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13204 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13205 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13207 static const uint16_t auxgainidx_a0[] = {
13208 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13209 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13210 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13213 static const uint32_t gainval_a0[] = {
13214 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13215 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13216 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13217 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13218 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13219 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13220 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13221 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13222 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13223 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13224 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13225 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13226 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13227 0x000000f7, 0x00000000, 0x00000000
13229 static const uint16_t gain_a0[] = {
13230 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13231 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13232 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13233 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13234 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13235 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
13236 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13237 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13238 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13239 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13240 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13241 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13244 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13246 for (i = 0; i < 704; i++)
13247 bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13249 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13250 bwn_tab_sigsq_tbl);
13251 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13252 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13253 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13254 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13255 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13256 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13257 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13258 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13259 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13260 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13261 bwn_tab_pllfrac_tbl);
13262 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13263 bwn_tabl_iqlocal_tbl);
13264 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13265 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13267 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13268 (siba_get_chiprev(sc->sc_dev) == 0)) {
13269 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13271 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13273 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13275 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13280 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13282 struct bwn_softc *sc = mac->mac_sc;
13283 struct ifnet *ifp = sc->sc_ifp;
13284 struct ieee80211com *ic = ifp->if_l2com;
13285 static struct bwn_txgain_entry txgain_r2[] = {
13286 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13287 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13288 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13289 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13290 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13291 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13292 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13293 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13294 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13295 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13296 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13297 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13298 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13299 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13300 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13301 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13302 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13303 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13304 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13305 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13306 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13307 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13308 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13309 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13310 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13311 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13312 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13313 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13314 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13315 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13316 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13317 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13318 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13319 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13320 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13321 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13322 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13323 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13324 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13325 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13326 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13327 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13328 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13329 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13330 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13331 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13332 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13333 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13334 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13335 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13336 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13337 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13338 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13339 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13340 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13341 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13342 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13343 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13344 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13345 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13346 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13347 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13348 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13349 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13351 static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13352 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13353 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13354 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13355 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13356 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13357 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13358 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13359 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13360 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13361 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13362 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13363 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13364 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13365 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13366 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13367 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13368 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13369 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13370 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13371 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13372 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13373 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13374 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13375 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13376 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13377 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13378 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13379 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13380 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13381 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13382 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13383 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13384 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13385 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13386 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13387 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13388 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13389 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13390 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13391 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13392 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13393 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13394 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13395 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13396 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13397 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13398 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13399 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13400 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13401 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13402 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13403 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13404 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13405 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13406 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13407 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13408 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13409 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13410 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13411 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13412 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13413 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13414 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13415 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13417 static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13418 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13419 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13420 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13421 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13422 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13423 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13424 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13425 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13426 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13427 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13428 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13429 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13430 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13431 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13432 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13433 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13434 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13435 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13436 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13437 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13438 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13439 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13440 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13441 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13442 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13443 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13444 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13445 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13446 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13447 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13448 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13449 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13450 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13451 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13452 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13453 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13454 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13455 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13456 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13457 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13458 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13459 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13460 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13461 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13462 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13463 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13464 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13465 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13466 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13467 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13468 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13469 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13470 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13471 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13472 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13473 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13474 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13475 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13476 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13477 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13478 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13479 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13480 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13481 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13483 static struct bwn_txgain_entry txgain_r0[] = {
13484 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13485 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13486 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13487 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13488 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13489 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13490 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13491 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13492 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13493 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13494 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13495 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13496 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13497 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13498 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13499 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13500 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13501 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13502 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13503 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13504 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13505 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13506 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13507 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13508 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13509 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13510 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13511 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13512 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13513 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13514 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13515 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13516 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13517 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13518 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13519 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13520 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13521 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13522 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13523 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13524 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13525 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13526 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13527 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13528 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13529 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13530 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13531 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13532 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13533 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13534 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13535 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13536 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13537 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13538 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13539 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13540 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13541 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13542 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13543 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13544 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13545 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13546 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13547 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13549 static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13550 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13551 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13552 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13553 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13554 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13555 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13556 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13557 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13558 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13559 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13560 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13561 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13562 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13563 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13564 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13565 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13566 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13567 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13568 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13569 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13570 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13571 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13572 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13573 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13574 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13575 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13576 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13577 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13578 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13579 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13580 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13581 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13582 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13583 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13584 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13585 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13586 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13587 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13588 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13589 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13590 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13591 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13592 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13593 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13594 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13595 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13596 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13597 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13598 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13599 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13600 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13601 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13602 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13603 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13604 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13605 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13606 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13607 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13608 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13609 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13610 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13611 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13612 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13613 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13615 static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13616 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13617 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13618 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13619 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13620 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13621 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13622 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13623 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13624 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13625 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13626 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13627 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13628 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13629 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13630 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13631 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13632 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13633 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13634 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13635 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13636 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13637 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13638 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13639 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13640 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13641 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13642 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13643 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13644 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13645 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13646 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13647 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13648 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13649 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13650 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13651 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13652 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13653 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13654 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13655 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13656 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13657 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13658 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13659 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13660 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13661 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13662 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13663 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13664 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13665 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13666 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13667 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13668 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13669 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13670 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13671 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13672 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13673 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13674 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13675 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13676 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13677 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13678 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13679 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13681 static struct bwn_txgain_entry txgain_r1[] = {
13682 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13683 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13684 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13685 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13686 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13687 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13688 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13689 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13690 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13691 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13692 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13693 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13694 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13695 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13696 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13697 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13698 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13699 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13700 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13701 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13702 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13703 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13704 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13705 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13706 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13707 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13708 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13709 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13710 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13711 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13712 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13713 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13714 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13715 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13716 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13717 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13718 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13719 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13720 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13721 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13722 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13723 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13724 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13725 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13726 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13727 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13728 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13729 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13730 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13731 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13732 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13733 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13734 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13735 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13736 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13737 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13738 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13739 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13740 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13741 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13742 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13743 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13744 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13745 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13746 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13747 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13748 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13749 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13750 { 7, 11, 6, 0, 71 }
13752 static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13753 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13754 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13755 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13756 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13757 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13758 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13759 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13760 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13761 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13762 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13763 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13764 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13765 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13766 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13767 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13768 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13769 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13770 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13771 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13772 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13773 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13774 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13775 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13776 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13777 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13778 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13779 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13780 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13781 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13782 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13783 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13784 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13785 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13786 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13787 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13788 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13789 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13790 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13791 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13792 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13793 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13794 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13795 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13796 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13797 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13798 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13799 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13800 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13801 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13802 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13803 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13804 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13805 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13806 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13807 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13808 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13809 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13810 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13811 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13812 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13813 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13814 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13815 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13816 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13818 static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13819 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13820 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13821 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13822 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13823 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13824 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13825 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13826 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13827 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13828 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13829 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13830 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13831 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13832 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13833 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13834 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13835 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13836 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13837 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13838 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13839 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13840 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13841 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13842 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13843 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13844 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13845 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13846 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13847 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13848 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13849 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13850 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13851 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13852 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13853 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13854 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13855 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13856 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13857 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13858 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13859 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13860 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13861 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13862 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13863 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13864 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13865 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13866 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13867 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13868 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13869 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13870 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13871 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13872 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13873 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13874 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13875 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13876 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13877 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13878 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13879 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13880 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13881 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13882 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13885 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13886 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13887 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13888 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13889 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13892 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13897 if (mac->mac_phy.rev == 0) {
13898 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13899 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13900 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13901 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13902 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13905 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13910 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13911 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13912 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13913 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13914 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13916 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13920 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13922 uint32_t offset, type;
13924 type = BWN_TAB_GETTYPE(typeoffset);
13925 offset = BWN_TAB_GETOFFSET(typeoffset);
13926 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13930 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13931 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13932 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13934 case BWN_TAB_16BIT:
13935 KASSERT(!(value & ~0xffff),
13936 ("%s:%d: fail", __func__, __LINE__));
13937 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13938 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13940 case BWN_TAB_32BIT:
13941 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13942 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13943 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13946 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13951 bwn_phy_lp_loopback(struct bwn_mac *mac)
13953 struct bwn_phy_lp_iq_est ie;
13957 memset(&ie, 0, sizeof(ie));
13959 bwn_phy_lp_set_trsw_over(mac, 1, 1);
13960 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13961 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13962 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13963 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13964 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13965 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13966 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13967 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13968 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13969 for (i = 0; i < 32; i++) {
13970 bwn_phy_lp_set_rxgain_idx(mac, i);
13971 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13972 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13974 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13975 if ((tmp > 4000) && (tmp < 10000)) {
13980 bwn_phy_lp_ddfs_turnoff(mac);
13985 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13988 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
13992 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
13993 int incr1, int incr2, int scale_idx)
13996 bwn_phy_lp_ddfs_turnoff(mac);
13997 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
13998 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
13999 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
14000 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
14001 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
14002 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
14003 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
14004 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
14005 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
14006 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
14010 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
14011 struct bwn_phy_lp_iq_est *ie)
14015 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
14016 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
14017 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
14018 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
14019 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
14021 for (i = 0; i < 500; i++) {
14022 if (!(BWN_PHY_READ(mac,
14023 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
14027 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
14028 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14032 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
14033 ie->ie_iqprod <<= 16;
14034 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
14035 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
14036 ie->ie_ipwr <<= 16;
14037 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
14038 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
14039 ie->ie_qpwr <<= 16;
14040 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
14042 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14047 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
14049 uint32_t offset, type, value;
14051 type = BWN_TAB_GETTYPE(typeoffset);
14052 offset = BWN_TAB_GETOFFSET(typeoffset);
14053 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
14057 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14058 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
14060 case BWN_TAB_16BIT:
14061 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14062 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14064 case BWN_TAB_32BIT:
14065 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14066 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
14068 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14071 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
14079 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
14082 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
14083 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
14087 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
14091 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
14093 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
14097 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
14100 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
14101 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
14105 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
14108 if (mac->mac_phy.rev < 2)
14109 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
14111 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
14112 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
14114 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
14118 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
14121 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
14125 bwn_nbits(int32_t val)
14130 for (tmp = abs(val); tmp != 0; tmp >>= 1)
14136 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
14137 struct bwn_txgain_entry *table)
14141 for (i = offset; i < count; i++)
14142 bwn_phy_lp_gaintbl_write(mac, i, table[i]);
14146 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
14147 struct bwn_txgain_entry data)
14150 if (mac->mac_phy.rev >= 2)
14151 bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14153 bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14157 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14158 struct bwn_txgain_entry te)
14160 struct bwn_softc *sc = mac->mac_sc;
14161 struct ifnet *ifp = sc->sc_ifp;
14162 struct ieee80211com *ic = ifp->if_l2com;
14165 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14167 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14168 if (mac->mac_phy.rev >= 3) {
14169 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14170 (0x10 << 24) : (0x70 << 24));
14172 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14173 (0x14 << 24) : (0x7f << 24));
14175 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14176 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14177 te.te_bbmult << 20 | te.te_dac << 28);
14181 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14182 struct bwn_txgain_entry te)
14185 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14187 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14188 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) |
14190 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14194 bwn_sysctl_node(struct bwn_softc *sc)
14196 device_t dev = sc->sc_dev;
14197 struct bwn_mac *mac;
14198 struct bwn_stats *stats;
14200 /* XXX assume that count of MAC is only 1. */
14202 if ((mac = sc->sc_curmac) == NULL)
14204 stats = &mac->mac_stats;
14206 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14207 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14208 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14209 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14210 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14211 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14212 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14213 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14214 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14217 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14218 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14219 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14223 static device_method_t bwn_methods[] = {
14224 /* Device interface */
14225 DEVMETHOD(device_probe, bwn_probe),
14226 DEVMETHOD(device_attach, bwn_attach),
14227 DEVMETHOD(device_detach, bwn_detach),
14228 DEVMETHOD(device_suspend, bwn_suspend),
14229 DEVMETHOD(device_resume, bwn_resume),
14232 static driver_t bwn_driver = {
14235 sizeof(struct bwn_softc)
14237 static devclass_t bwn_devclass;
14238 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
14239 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14240 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */
14241 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */
14242 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);