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 ifnet *);
185 static void bwn_update_promisc(struct ifnet *);
186 static void bwn_wme_init(struct bwn_mac *);
187 static int bwn_wme_update(struct ieee80211com *);
188 static 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(ifp);
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 ifnet *ifp)
2777 struct bwn_softc *sc = ifp->if_softc;
2778 struct ieee80211com *ic = ifp->if_l2com;
2779 struct bwn_mac *mac;
2782 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
2783 mac = (struct bwn_mac *)sc->sc_curmac;
2784 bwn_set_slot_time(mac,
2785 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2791 * Callback from the 802.11 layer after a promiscuous mode change.
2792 * Note this interface does not check the operating mode as this
2793 * is an internal callback and we are expected to honor the current
2794 * state (e.g. this is used for setting the interface in promiscuous
2795 * mode when operating in hostap mode to do ACS).
2798 bwn_update_promisc(struct ifnet *ifp)
2800 struct bwn_softc *sc = ifp->if_softc;
2801 struct bwn_mac *mac = sc->sc_curmac;
2804 mac = sc->sc_curmac;
2805 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2806 if (ifp->if_flags & IFF_PROMISC)
2807 sc->sc_filters |= BWN_MACCTL_PROMISC;
2809 sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2810 bwn_set_opmode(mac);
2816 * Callback from the 802.11 layer to update WME parameters.
2819 bwn_wme_update(struct ieee80211com *ic)
2821 struct bwn_softc *sc = ic->ic_ifp->if_softc;
2822 struct bwn_mac *mac = sc->sc_curmac;
2823 struct wmeParams *wmep;
2827 mac = sc->sc_curmac;
2828 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2829 bwn_mac_suspend(mac);
2830 for (i = 0; i < N(sc->sc_wmeParams); i++) {
2831 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2832 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2834 bwn_mac_enable(mac);
2841 bwn_scan_start(struct ieee80211com *ic)
2843 struct ifnet *ifp = ic->ic_ifp;
2844 struct bwn_softc *sc = ifp->if_softc;
2845 struct bwn_mac *mac;
2848 mac = sc->sc_curmac;
2849 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2850 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2851 bwn_set_opmode(mac);
2852 /* disable CFP update during scan */
2853 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2859 bwn_scan_end(struct ieee80211com *ic)
2861 struct ifnet *ifp = ic->ic_ifp;
2862 struct bwn_softc *sc = ifp->if_softc;
2863 struct bwn_mac *mac;
2866 mac = sc->sc_curmac;
2867 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2868 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2869 bwn_set_opmode(mac);
2870 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2876 bwn_set_channel(struct ieee80211com *ic)
2878 struct ifnet *ifp = ic->ic_ifp;
2879 struct bwn_softc *sc = ifp->if_softc;
2880 struct bwn_mac *mac = sc->sc_curmac;
2881 struct bwn_phy *phy = &mac->mac_phy;
2886 error = bwn_switch_band(sc, ic->ic_curchan);
2889 bwn_mac_suspend(mac);
2890 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2891 chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2892 if (chan != phy->chan)
2893 bwn_switch_channel(mac, chan);
2895 /* TX power level */
2896 if (ic->ic_curchan->ic_maxpower != 0 &&
2897 ic->ic_curchan->ic_maxpower != phy->txpower) {
2898 phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2899 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2900 BWN_TXPWR_IGNORE_TSSI);
2903 bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2904 if (phy->set_antenna)
2905 phy->set_antenna(mac, BWN_ANT_DEFAULT);
2907 if (sc->sc_rf_enabled != phy->rf_on) {
2908 if (sc->sc_rf_enabled) {
2910 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2911 device_printf(sc->sc_dev,
2912 "please turn on the RF switch\n");
2914 bwn_rf_turnoff(mac);
2917 bwn_mac_enable(mac);
2921 * Setup radio tap channel freq and flags
2923 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2924 htole16(ic->ic_curchan->ic_freq);
2925 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2926 htole16(ic->ic_curchan->ic_flags & 0xffff);
2931 static struct ieee80211vap *
2932 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
2933 enum ieee80211_opmode opmode, int flags,
2934 const uint8_t bssid[IEEE80211_ADDR_LEN],
2935 const uint8_t mac0[IEEE80211_ADDR_LEN])
2937 struct ifnet *ifp = ic->ic_ifp;
2938 struct bwn_softc *sc = ifp->if_softc;
2939 struct ieee80211vap *vap;
2940 struct bwn_vap *bvp;
2941 uint8_t mac[IEEE80211_ADDR_LEN];
2943 IEEE80211_ADDR_COPY(mac, mac0);
2945 case IEEE80211_M_HOSTAP:
2946 case IEEE80211_M_MBSS:
2947 case IEEE80211_M_STA:
2948 case IEEE80211_M_WDS:
2949 case IEEE80211_M_MONITOR:
2950 case IEEE80211_M_IBSS:
2951 case IEEE80211_M_AHDEMO:
2957 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
2959 bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap),
2960 M_80211_VAP, M_NOWAIT | M_ZERO);
2962 device_printf(sc->sc_dev, "failed to allocate a buffer\n");
2966 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
2967 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
2968 /* override with driver methods */
2969 bvp->bv_newstate = vap->iv_newstate;
2970 vap->iv_newstate = bwn_newstate;
2972 /* override max aid so sta's cannot assoc when we're out of sta id's */
2973 vap->iv_max_aid = BWN_STAID_MAX;
2975 ieee80211_ratectl_init(vap);
2977 /* complete setup */
2978 ieee80211_vap_attach(vap, ieee80211_media_change,
2979 ieee80211_media_status);
2984 bwn_vap_delete(struct ieee80211vap *vap)
2986 struct bwn_vap *bvp = BWN_VAP(vap);
2988 ieee80211_ratectl_deinit(vap);
2989 ieee80211_vap_detach(vap);
2990 free(bvp, M_80211_VAP);
2996 struct bwn_softc *sc = arg;
2997 struct ifnet *ifp = sc->sc_ifp;
2998 struct ieee80211com *ic = ifp->if_l2com;
3001 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
3002 __func__, ifp->if_flags);
3005 error = bwn_init_locked(sc);
3009 ieee80211_start_all(ic); /* start all vap's */
3013 bwn_init_locked(struct bwn_softc *sc)
3015 struct bwn_mac *mac;
3016 struct ifnet *ifp = sc->sc_ifp;
3019 BWN_ASSERT_LOCKED(sc);
3021 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
3022 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
3025 sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
3026 sc->sc_rf_enabled = 1;
3028 mac = sc->sc_curmac;
3029 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
3030 error = bwn_core_init(mac);
3034 if (mac->mac_status == BWN_MAC_STATUS_INITED)
3035 bwn_core_start(mac);
3037 bwn_set_opmode(mac);
3038 bwn_set_pretbtt(mac);
3039 bwn_spu_setdelay(mac, 0);
3040 bwn_set_macaddr(mac);
3042 ifp->if_drv_flags |= IFF_DRV_RUNNING;
3043 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
3044 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
3050 bwn_stop(struct bwn_softc *sc, int statechg)
3054 bwn_stop_locked(sc, statechg);
3059 bwn_stop_locked(struct bwn_softc *sc, int statechg)
3061 struct bwn_mac *mac = sc->sc_curmac;
3062 struct ifnet *ifp = sc->sc_ifp;
3064 BWN_ASSERT_LOCKED(sc);
3066 if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
3067 /* XXX FIXME opmode not based on VAP */
3068 bwn_set_opmode(mac);
3069 bwn_set_macaddr(mac);
3072 if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
3075 callout_stop(&sc->sc_led_blink_ch);
3076 sc->sc_led_blinking = 0;
3079 sc->sc_rf_enabled = 0;
3081 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
3085 bwn_wme_clear(struct bwn_softc *sc)
3087 #define MS(_v, _f) (((_v) & _f) >> _f##_S)
3088 struct wmeParams *p;
3091 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
3092 ("%s:%d: fail", __func__, __LINE__));
3094 for (i = 0; i < N(sc->sc_wmeParams); i++) {
3095 p = &(sc->sc_wmeParams[i]);
3097 switch (bwn_wme_shm_offsets[i]) {
3099 p->wmep_txopLimit = 0;
3101 /* XXX FIXME: log2(cwmin) */
3102 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3103 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3106 p->wmep_txopLimit = 0;
3108 /* XXX FIXME: log2(cwmin) */
3109 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3110 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3112 case BWN_WME_BESTEFFORT:
3113 p->wmep_txopLimit = 0;
3115 /* XXX FIXME: log2(cwmin) */
3116 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3117 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3119 case BWN_WME_BACKGROUND:
3120 p->wmep_txopLimit = 0;
3122 /* XXX FIXME: log2(cwmin) */
3123 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3124 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3127 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3133 bwn_core_init(struct bwn_mac *mac)
3135 struct bwn_softc *sc = mac->mac_sc;
3139 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3140 ("%s:%d: fail", __func__, __LINE__));
3142 siba_powerup(sc->sc_dev, 0);
3143 if (!siba_dev_isup(sc->sc_dev))
3145 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3147 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3148 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3149 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3150 BWN_GETTIME(mac->mac_phy.nexttime);
3151 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3152 bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3153 mac->mac_stats.link_noise = -95;
3154 mac->mac_reason_intr = 0;
3155 bzero(mac->mac_reason, sizeof(mac->mac_reason));
3156 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3158 if (sc->sc_debug & BWN_DEBUG_XMIT)
3159 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3161 mac->mac_suspended = 1;
3162 mac->mac_task_state = 0;
3163 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3165 mac->mac_phy.init_pre(mac);
3167 siba_pcicore_intr(sc->sc_dev);
3169 siba_fix_imcfglobug(sc->sc_dev);
3170 bwn_bt_disable(mac);
3171 if (mac->mac_phy.prepare_hw) {
3172 error = mac->mac_phy.prepare_hw(mac);
3176 error = bwn_chip_init(mac);
3179 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3180 siba_get_revid(sc->sc_dev));
3181 hf = bwn_hf_read(mac);
3182 if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3183 hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3184 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3185 hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3186 if (mac->mac_phy.rev == 1)
3187 hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3189 if (mac->mac_phy.rf_ver == 0x2050) {
3190 if (mac->mac_phy.rf_rev < 6)
3191 hf |= BWN_HF_FORCE_VCO_RECALC;
3192 if (mac->mac_phy.rf_rev == 6)
3193 hf |= BWN_HF_4318_TSSI;
3195 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3196 hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3197 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3198 (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3199 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3200 hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3201 bwn_hf_write(mac, hf);
3203 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3204 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3205 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3206 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3209 bwn_set_phytxctl(mac);
3211 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3212 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3213 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3215 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3220 bwn_spu_setdelay(mac, 1);
3223 siba_powerup(sc->sc_dev,
3224 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3225 bwn_set_macaddr(mac);
3226 bwn_crypt_init(mac);
3228 /* XXX LED initializatin */
3230 mac->mac_status = BWN_MAC_STATUS_INITED;
3235 siba_powerdown(sc->sc_dev);
3236 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3237 ("%s:%d: fail", __func__, __LINE__));
3242 bwn_core_start(struct bwn_mac *mac)
3244 struct bwn_softc *sc = mac->mac_sc;
3247 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3248 ("%s:%d: fail", __func__, __LINE__));
3250 if (siba_get_revid(sc->sc_dev) < 5)
3254 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3255 if (!(tmp & 0x00000001))
3257 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3260 bwn_mac_enable(mac);
3261 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3262 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3264 mac->mac_status = BWN_MAC_STATUS_STARTED;
3268 bwn_core_exit(struct bwn_mac *mac)
3270 struct bwn_softc *sc = mac->mac_sc;
3273 BWN_ASSERT_LOCKED(mac->mac_sc);
3275 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3276 ("%s:%d: fail", __func__, __LINE__));
3278 if (mac->mac_status != BWN_MAC_STATUS_INITED)
3280 mac->mac_status = BWN_MAC_STATUS_UNINIT;
3282 macctl = BWN_READ_4(mac, BWN_MACCTL);
3283 macctl &= ~BWN_MACCTL_MCODE_RUN;
3284 macctl |= BWN_MACCTL_MCODE_JMP0;
3285 BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3290 mac->mac_phy.switch_analog(mac, 0);
3291 siba_dev_down(sc->sc_dev, 0);
3292 siba_powerdown(sc->sc_dev);
3296 bwn_bt_disable(struct bwn_mac *mac)
3298 struct bwn_softc *sc = mac->mac_sc;
3301 /* XXX do nothing yet */
3305 bwn_chip_init(struct bwn_mac *mac)
3307 struct bwn_softc *sc = mac->mac_sc;
3308 struct bwn_phy *phy = &mac->mac_phy;
3312 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3314 macctl |= BWN_MACCTL_GMODE;
3315 BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3317 error = bwn_fw_fillinfo(mac);
3320 error = bwn_fw_loaducode(mac);
3324 error = bwn_gpio_init(mac);
3328 error = bwn_fw_loadinitvals(mac);
3330 siba_gpio_set(sc->sc_dev, 0);
3333 phy->switch_analog(mac, 1);
3334 error = bwn_phy_init(mac);
3336 siba_gpio_set(sc->sc_dev, 0);
3340 phy->set_im(mac, BWN_IMMODE_NONE);
3341 if (phy->set_antenna)
3342 phy->set_antenna(mac, BWN_ANT_DEFAULT);
3343 bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3345 if (phy->type == BWN_PHYTYPE_B)
3346 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3347 BWN_WRITE_4(mac, 0x0100, 0x01000000);
3348 if (siba_get_revid(sc->sc_dev) < 5)
3349 BWN_WRITE_4(mac, 0x010c, 0x01000000);
3351 BWN_WRITE_4(mac, BWN_MACCTL,
3352 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3353 BWN_WRITE_4(mac, BWN_MACCTL,
3354 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3355 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3357 bwn_set_opmode(mac);
3358 if (siba_get_revid(sc->sc_dev) < 3) {
3359 BWN_WRITE_2(mac, 0x060e, 0x0000);
3360 BWN_WRITE_2(mac, 0x0610, 0x8000);
3361 BWN_WRITE_2(mac, 0x0604, 0x0000);
3362 BWN_WRITE_2(mac, 0x0606, 0x0200);
3364 BWN_WRITE_4(mac, 0x0188, 0x80000000);
3365 BWN_WRITE_4(mac, 0x018c, 0x02000000);
3367 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3368 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
3369 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3370 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3371 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3372 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3373 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3374 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3375 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3376 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3380 /* read hostflags */
3382 bwn_hf_read(struct bwn_mac *mac)
3386 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3388 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3390 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3395 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3398 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3399 (value & 0x00000000ffffull));
3400 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3401 (value & 0x0000ffff0000ull) >> 16);
3402 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3403 (value & 0xffff00000000ULL) >> 32);
3407 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3410 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3411 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3415 bwn_rate_init(struct bwn_mac *mac)
3418 switch (mac->mac_phy.type) {
3421 case BWN_PHYTYPE_LP:
3423 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3424 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3425 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3426 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3427 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3428 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3429 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3430 if (mac->mac_phy.type == BWN_PHYTYPE_A)
3434 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3435 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3436 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3437 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3440 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3445 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3451 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3454 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3456 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3457 bwn_shm_read_2(mac, BWN_SHARED, offset));
3461 bwn_plcp_getcck(const uint8_t bitrate)
3465 case BWN_CCK_RATE_1MB:
3467 case BWN_CCK_RATE_2MB:
3469 case BWN_CCK_RATE_5MB:
3471 case BWN_CCK_RATE_11MB:
3474 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3479 bwn_plcp_getofdm(const uint8_t bitrate)
3483 case BWN_OFDM_RATE_6MB:
3485 case BWN_OFDM_RATE_9MB:
3487 case BWN_OFDM_RATE_12MB:
3489 case BWN_OFDM_RATE_18MB:
3491 case BWN_OFDM_RATE_24MB:
3493 case BWN_OFDM_RATE_36MB:
3495 case BWN_OFDM_RATE_48MB:
3497 case BWN_OFDM_RATE_54MB:
3500 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3505 bwn_set_phytxctl(struct bwn_mac *mac)
3509 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3511 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3512 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3513 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3517 bwn_pio_init(struct bwn_mac *mac)
3519 struct bwn_pio *pio = &mac->mac_method.pio;
3521 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3522 & ~BWN_MACCTL_BIGENDIAN);
3523 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3525 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3526 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3527 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3528 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3529 bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3530 bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3534 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3537 struct bwn_pio_txpkt *tp;
3538 struct bwn_softc *sc = mac->mac_sc;
3541 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3542 tq->tq_index = index;
3544 tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3545 if (siba_get_revid(sc->sc_dev) >= 8)
3548 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3552 TAILQ_INIT(&tq->tq_pktlist);
3553 for (i = 0; i < N(tq->tq_pkts); i++) {
3554 tp = &(tq->tq_pkts[i]);
3557 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3562 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3564 struct bwn_softc *sc = mac->mac_sc;
3565 static const uint16_t bases[] = {
3575 static const uint16_t bases_rev11[] = {
3584 if (siba_get_revid(sc->sc_dev) >= 11) {
3585 if (index >= N(bases_rev11))
3586 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3587 return (bases_rev11[index]);
3589 if (index >= N(bases))
3590 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3591 return (bases[index]);
3595 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3598 struct bwn_softc *sc = mac->mac_sc;
3601 prq->prq_rev = siba_get_revid(sc->sc_dev);
3602 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3603 bwn_dma_rxdirectfifo(mac, index, 1);
3607 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3611 bwn_pio_cancel_tx_packets(tq);
3615 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3618 bwn_destroy_pioqueue_tx(pio);
3622 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3626 return (BWN_READ_2(mac, tq->tq_base + offset));
3630 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3636 type = bwn_dma_mask2type(bwn_dma_mask(mac));
3637 base = bwn_dma_base(type, idx);
3638 if (type == BWN_DMA_64BIT) {
3639 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3640 ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3642 ctl |= BWN_DMA64_RXDIRECTFIFO;
3643 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3645 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3646 ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3648 ctl |= BWN_DMA32_RXDIRECTFIFO;
3649 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3654 bwn_dma_mask(struct bwn_mac *mac)
3659 tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3660 if (tmp & SIBA_TGSHIGH_DMA64)
3661 return (BWN_DMA_BIT_MASK(64));
3662 base = bwn_dma_base(0, 0);
3663 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3664 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3665 if (tmp & BWN_DMA32_TXADDREXT_MASK)
3666 return (BWN_DMA_BIT_MASK(32));
3668 return (BWN_DMA_BIT_MASK(30));
3672 bwn_dma_mask2type(uint64_t dmamask)
3675 if (dmamask == BWN_DMA_BIT_MASK(30))
3676 return (BWN_DMA_30BIT);
3677 if (dmamask == BWN_DMA_BIT_MASK(32))
3678 return (BWN_DMA_32BIT);
3679 if (dmamask == BWN_DMA_BIT_MASK(64))
3680 return (BWN_DMA_64BIT);
3681 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3682 return (BWN_DMA_30BIT);
3686 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3688 struct bwn_pio_txpkt *tp;
3691 for (i = 0; i < N(tq->tq_pkts); i++) {
3692 tp = &(tq->tq_pkts[i]);
3701 bwn_dma_base(int type, int controller_idx)
3703 static const uint16_t map64[] = {
3711 static const uint16_t map32[] = {
3720 if (type == BWN_DMA_64BIT) {
3721 KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3722 ("%s:%d: fail", __func__, __LINE__));
3723 return (map64[controller_idx]);
3725 KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3726 ("%s:%d: fail", __func__, __LINE__));
3727 return (map32[controller_idx]);
3731 bwn_dma_init(struct bwn_mac *mac)
3733 struct bwn_dma *dma = &mac->mac_method.dma;
3735 /* setup TX DMA channels. */
3736 bwn_dma_setup(dma->wme[WME_AC_BK]);
3737 bwn_dma_setup(dma->wme[WME_AC_BE]);
3738 bwn_dma_setup(dma->wme[WME_AC_VI]);
3739 bwn_dma_setup(dma->wme[WME_AC_VO]);
3740 bwn_dma_setup(dma->mcast);
3741 /* setup RX DMA channel. */
3742 bwn_dma_setup(dma->rx);
3745 static struct bwn_dma_ring *
3746 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3747 int for_tx, int type)
3749 struct bwn_dma *dma = &mac->mac_method.dma;
3750 struct bwn_dma_ring *dr;
3751 struct bwn_dmadesc_generic *desc;
3752 struct bwn_dmadesc_meta *mt;
3753 struct bwn_softc *sc = mac->mac_sc;
3756 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO);
3759 dr->dr_numslots = BWN_RXRING_SLOTS;
3761 dr->dr_numslots = BWN_TXRING_SLOTS;
3763 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3764 M_DEVBUF, M_NOWAIT | M_ZERO);
3765 if (dr->dr_meta == NULL)
3770 dr->dr_base = bwn_dma_base(type, controller_index);
3771 dr->dr_index = controller_index;
3772 if (type == BWN_DMA_64BIT) {
3773 dr->getdesc = bwn_dma_64_getdesc;
3774 dr->setdesc = bwn_dma_64_setdesc;
3775 dr->start_transfer = bwn_dma_64_start_transfer;
3776 dr->suspend = bwn_dma_64_suspend;
3777 dr->resume = bwn_dma_64_resume;
3778 dr->get_curslot = bwn_dma_64_get_curslot;
3779 dr->set_curslot = bwn_dma_64_set_curslot;
3781 dr->getdesc = bwn_dma_32_getdesc;
3782 dr->setdesc = bwn_dma_32_setdesc;
3783 dr->start_transfer = bwn_dma_32_start_transfer;
3784 dr->suspend = bwn_dma_32_suspend;
3785 dr->resume = bwn_dma_32_resume;
3786 dr->get_curslot = bwn_dma_32_get_curslot;
3787 dr->set_curslot = bwn_dma_32_set_curslot;
3791 dr->dr_curslot = -1;
3793 if (dr->dr_index == 0) {
3794 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3795 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3797 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3800 error = bwn_dma_allocringmemory(dr);
3806 * Assumption: BWN_TXRING_SLOTS can be divided by
3807 * BWN_TX_SLOTS_PER_FRAME
3809 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3810 ("%s:%d: fail", __func__, __LINE__));
3812 dr->dr_txhdr_cache =
3813 malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3814 BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO);
3815 KASSERT(dr->dr_txhdr_cache != NULL,
3816 ("%s:%d: fail", __func__, __LINE__));
3819 * Create TX ring DMA stuffs
3821 error = bus_dma_tag_create(dma->parent_dtag,
3828 BUS_SPACE_MAXSIZE_32BIT,
3831 &dr->dr_txring_dtag);
3833 device_printf(sc->sc_dev,
3834 "can't create TX ring DMA tag: TODO frees\n");
3838 for (i = 0; i < dr->dr_numslots; i += 2) {
3839 dr->getdesc(dr, i, &desc, &mt);
3841 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3845 error = bus_dmamap_create(dr->dr_txring_dtag, 0,
3848 device_printf(sc->sc_dev,
3849 "can't create RX buf DMA map\n");
3853 dr->getdesc(dr, i + 1, &desc, &mt);
3855 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3859 error = bus_dmamap_create(dma->txbuf_dtag, 0,
3862 device_printf(sc->sc_dev,
3863 "can't create RX buf DMA map\n");
3868 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3869 &dr->dr_spare_dmap);
3871 device_printf(sc->sc_dev,
3872 "can't create RX buf DMA map\n");
3873 goto out; /* XXX wrong! */
3876 for (i = 0; i < dr->dr_numslots; i++) {
3877 dr->getdesc(dr, i, &desc, &mt);
3879 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3882 device_printf(sc->sc_dev,
3883 "can't create RX buf DMA map\n");
3884 goto out; /* XXX wrong! */
3886 error = bwn_dma_newbuf(dr, desc, mt, 1);
3888 device_printf(sc->sc_dev,
3889 "failed to allocate RX buf\n");
3890 goto out; /* XXX wrong! */
3894 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3895 BUS_DMASYNC_PREWRITE);
3897 dr->dr_usedslot = dr->dr_numslots;
3904 free(dr->dr_txhdr_cache, M_DEVBUF);
3906 free(dr->dr_meta, M_DEVBUF);
3913 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3919 bwn_dma_free_descbufs(*dr);
3920 bwn_dma_free_ringmemory(*dr);
3922 free((*dr)->dr_txhdr_cache, M_DEVBUF);
3923 free((*dr)->dr_meta, M_DEVBUF);
3924 free(*dr, M_DEVBUF);
3930 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3931 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3933 struct bwn_dmadesc32 *desc;
3935 *meta = &(dr->dr_meta[slot]);
3936 desc = dr->dr_ring_descbase;
3937 desc = &(desc[slot]);
3939 *gdesc = (struct bwn_dmadesc_generic *)desc;
3943 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3944 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3945 int start, int end, int irq)
3947 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3948 struct bwn_softc *sc = dr->dr_mac->mac_sc;
3949 uint32_t addr, addrext, ctl;
3952 slot = (int)(&(desc->dma.dma32) - descbase);
3953 KASSERT(slot >= 0 && slot < dr->dr_numslots,
3954 ("%s:%d: fail", __func__, __LINE__));
3956 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
3957 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
3958 addr |= siba_dma_translation(sc->sc_dev);
3959 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3960 if (slot == dr->dr_numslots - 1)
3961 ctl |= BWN_DMA32_DCTL_DTABLEEND;
3963 ctl |= BWN_DMA32_DCTL_FRAMESTART;
3965 ctl |= BWN_DMA32_DCTL_FRAMEEND;
3967 ctl |= BWN_DMA32_DCTL_IRQ;
3968 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3969 & BWN_DMA32_DCTL_ADDREXT_MASK;
3971 desc->dma.dma32.control = htole32(ctl);
3972 desc->dma.dma32.address = htole32(addr);
3976 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3979 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3980 (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3984 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3987 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3988 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3992 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3995 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3996 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
4000 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
4004 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
4005 val &= BWN_DMA32_RXDPTR;
4007 return (val / sizeof(struct bwn_dmadesc32));
4011 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
4014 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
4015 (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
4019 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
4020 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
4022 struct bwn_dmadesc64 *desc;
4024 *meta = &(dr->dr_meta[slot]);
4025 desc = dr->dr_ring_descbase;
4026 desc = &(desc[slot]);
4028 *gdesc = (struct bwn_dmadesc_generic *)desc;
4032 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
4033 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
4034 int start, int end, int irq)
4036 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
4037 struct bwn_softc *sc = dr->dr_mac->mac_sc;
4039 uint32_t ctl0 = 0, ctl1 = 0;
4040 uint32_t addrlo, addrhi;
4043 slot = (int)(&(desc->dma.dma64) - descbase);
4044 KASSERT(slot >= 0 && slot < dr->dr_numslots,
4045 ("%s:%d: fail", __func__, __LINE__));
4047 addrlo = (uint32_t) (dmaaddr & 0xffffffff);
4048 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
4049 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
4051 addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
4052 if (slot == dr->dr_numslots - 1)
4053 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
4055 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
4057 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
4059 ctl0 |= BWN_DMA64_DCTL0_IRQ;
4060 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
4061 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
4062 & BWN_DMA64_DCTL1_ADDREXT_MASK;
4064 desc->dma.dma64.control0 = htole32(ctl0);
4065 desc->dma.dma64.control1 = htole32(ctl1);
4066 desc->dma.dma64.address_low = htole32(addrlo);
4067 desc->dma.dma64.address_high = htole32(addrhi);
4071 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
4074 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
4075 (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4079 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
4082 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4083 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
4087 bwn_dma_64_resume(struct bwn_dma_ring *dr)
4090 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4091 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
4095 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
4099 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
4100 val &= BWN_DMA64_RXSTATDPTR;
4102 return (val / sizeof(struct bwn_dmadesc64));
4106 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4109 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4110 (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4114 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4116 struct bwn_mac *mac = dr->dr_mac;
4117 struct bwn_dma *dma = &mac->mac_method.dma;
4118 struct bwn_softc *sc = mac->mac_sc;
4121 error = bus_dma_tag_create(dma->parent_dtag,
4126 BWN_DMA_RINGMEMSIZE,
4128 BUS_SPACE_MAXSIZE_32BIT,
4133 device_printf(sc->sc_dev,
4134 "can't create TX ring DMA tag: TODO frees\n");
4138 error = bus_dmamem_alloc(dr->dr_ring_dtag,
4139 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4142 device_printf(sc->sc_dev,
4143 "can't allocate DMA mem: TODO frees\n");
4146 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4147 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4148 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
4150 device_printf(sc->sc_dev,
4151 "can't load DMA mem: TODO free\n");
4159 bwn_dma_setup(struct bwn_dma_ring *dr)
4161 struct bwn_softc *sc = dr->dr_mac->mac_sc;
4163 uint32_t addrext, ring32, value;
4164 uint32_t trans = siba_dma_translation(sc->sc_dev);
4167 dr->dr_curslot = -1;
4169 if (dr->dr_type == BWN_DMA_64BIT) {
4170 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4171 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4173 value = BWN_DMA64_TXENABLE;
4174 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4175 & BWN_DMA64_TXADDREXT_MASK;
4176 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4177 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4178 (ring64 & 0xffffffff));
4179 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4181 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4183 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4184 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4185 value = BWN_DMA32_TXENABLE;
4186 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4187 & BWN_DMA32_TXADDREXT_MASK;
4188 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4189 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4190 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4198 dr->dr_usedslot = dr->dr_numslots;
4200 if (dr->dr_type == BWN_DMA_64BIT) {
4201 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4202 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4203 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4204 value |= BWN_DMA64_RXENABLE;
4205 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4206 & BWN_DMA64_RXADDREXT_MASK;
4207 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4208 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4209 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4210 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4212 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4213 sizeof(struct bwn_dmadesc64));
4215 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4216 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4217 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4218 value |= BWN_DMA32_RXENABLE;
4219 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4220 & BWN_DMA32_RXADDREXT_MASK;
4221 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4222 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4223 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4224 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4225 sizeof(struct bwn_dmadesc32));
4230 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4233 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4234 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4239 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4243 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4244 if (dr->dr_type == BWN_DMA_64BIT) {
4245 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4246 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4248 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4250 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4251 if (dr->dr_type == BWN_DMA_64BIT) {
4252 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4253 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4255 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4260 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4262 struct bwn_dmadesc_generic *desc;
4263 struct bwn_dmadesc_meta *meta;
4264 struct bwn_mac *mac = dr->dr_mac;
4265 struct bwn_dma *dma = &mac->mac_method.dma;
4266 struct bwn_softc *sc = mac->mac_sc;
4269 if (!dr->dr_usedslot)
4271 for (i = 0; i < dr->dr_numslots; i++) {
4272 dr->getdesc(dr, i, &desc, &meta);
4274 if (meta->mt_m == NULL) {
4276 device_printf(sc->sc_dev, "%s: not TX?\n",
4281 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
4282 bus_dmamap_unload(dr->dr_txring_dtag,
4284 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
4285 bus_dmamap_unload(dma->txbuf_dtag,
4288 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4289 bwn_dma_free_descbuf(dr, meta);
4294 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4297 struct bwn_softc *sc = mac->mac_sc;
4302 for (i = 0; i < 10; i++) {
4303 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4305 value = BWN_READ_4(mac, base + offset);
4306 if (type == BWN_DMA_64BIT) {
4307 value &= BWN_DMA64_TXSTAT;
4308 if (value == BWN_DMA64_TXSTAT_DISABLED ||
4309 value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4310 value == BWN_DMA64_TXSTAT_STOPPED)
4313 value &= BWN_DMA32_TXSTATE;
4314 if (value == BWN_DMA32_TXSTAT_DISABLED ||
4315 value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4316 value == BWN_DMA32_TXSTAT_STOPPED)
4321 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4322 BWN_WRITE_4(mac, base + offset, 0);
4323 for (i = 0; i < 10; i++) {
4324 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4326 value = BWN_READ_4(mac, base + offset);
4327 if (type == BWN_DMA_64BIT) {
4328 value &= BWN_DMA64_TXSTAT;
4329 if (value == BWN_DMA64_TXSTAT_DISABLED) {
4334 value &= BWN_DMA32_TXSTATE;
4335 if (value == BWN_DMA32_TXSTAT_DISABLED) {
4343 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4352 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4355 struct bwn_softc *sc = mac->mac_sc;
4360 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4361 BWN_WRITE_4(mac, base + offset, 0);
4362 for (i = 0; i < 10; i++) {
4363 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4365 value = BWN_READ_4(mac, base + offset);
4366 if (type == BWN_DMA_64BIT) {
4367 value &= BWN_DMA64_RXSTAT;
4368 if (value == BWN_DMA64_RXSTAT_DISABLED) {
4373 value &= BWN_DMA32_RXSTATE;
4374 if (value == BWN_DMA32_RXSTAT_DISABLED) {
4382 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4390 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4391 struct bwn_dmadesc_meta *meta)
4394 if (meta->mt_m != NULL) {
4395 m_freem(meta->mt_m);
4398 if (meta->mt_ni != NULL) {
4399 ieee80211_free_node(meta->mt_ni);
4405 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4407 struct bwn_rxhdr4 *rxhdr;
4408 unsigned char *frame;
4410 rxhdr = mtod(m, struct bwn_rxhdr4 *);
4411 rxhdr->frame_len = 0;
4413 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4414 sizeof(struct bwn_plcp6) + 2,
4415 ("%s:%d: fail", __func__, __LINE__));
4416 frame = mtod(m, char *) + dr->dr_frameoffset;
4417 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4421 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4423 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4425 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4430 bwn_wme_init(struct bwn_mac *mac)
4435 /* enable WME support. */
4436 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4437 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4438 BWN_IFSCTL_USE_EDCF);
4442 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4444 struct bwn_softc *sc = mac->mac_sc;
4445 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
4446 uint16_t delay; /* microsec */
4448 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4449 if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4451 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4452 delay = max(delay, (uint16_t)2400);
4454 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4458 bwn_bt_enable(struct bwn_mac *mac)
4460 struct bwn_softc *sc = mac->mac_sc;
4463 if (bwn_bluetooth == 0)
4465 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4467 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4470 hf = bwn_hf_read(mac);
4471 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4472 hf |= BWN_HF_BT_COEXISTALT;
4474 hf |= BWN_HF_BT_COEXIST;
4475 bwn_hf_write(mac, hf);
4479 bwn_set_macaddr(struct bwn_mac *mac)
4482 bwn_mac_write_bssid(mac);
4483 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
4487 bwn_clear_keys(struct bwn_mac *mac)
4491 for (i = 0; i < mac->mac_max_nr_keys; i++) {
4492 KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4493 ("%s:%d: fail", __func__, __LINE__));
4495 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4496 NULL, BWN_SEC_KEYSIZE, NULL);
4497 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4498 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4499 NULL, BWN_SEC_KEYSIZE, NULL);
4501 mac->mac_key[i].keyconf = NULL;
4506 bwn_crypt_init(struct bwn_mac *mac)
4508 struct bwn_softc *sc = mac->mac_sc;
4510 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4511 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4512 ("%s:%d: fail", __func__, __LINE__));
4513 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4515 if (siba_get_revid(sc->sc_dev) >= 5)
4516 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4517 bwn_clear_keys(mac);
4521 bwn_chip_exit(struct bwn_mac *mac)
4523 struct bwn_softc *sc = mac->mac_sc;
4526 siba_gpio_set(sc->sc_dev, 0);
4530 bwn_fw_fillinfo(struct bwn_mac *mac)
4534 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4537 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4544 bwn_gpio_init(struct bwn_mac *mac)
4546 struct bwn_softc *sc = mac->mac_sc;
4547 uint32_t mask = 0x1f, set = 0xf, value;
4549 BWN_WRITE_4(mac, BWN_MACCTL,
4550 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4551 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4552 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4554 if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4558 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4559 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4560 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4564 if (siba_get_revid(sc->sc_dev) >= 2)
4567 value = siba_gpio_get(sc->sc_dev);
4570 siba_gpio_set(sc->sc_dev, (value & mask) | set);
4576 bwn_fw_loadinitvals(struct bwn_mac *mac)
4578 #define GETFWOFFSET(fwp, offset) \
4579 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4580 const size_t hdr_len = sizeof(struct bwn_fwhdr);
4581 const struct bwn_fwhdr *hdr;
4582 struct bwn_fw *fw = &mac->mac_fw;
4585 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4586 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4587 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4590 if (fw->initvals_band.fw) {
4591 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4592 error = bwn_fwinitvals_write(mac,
4593 GETFWOFFSET(fw->initvals_band, hdr_len),
4595 fw->initvals_band.fw->datasize - hdr_len);
4602 bwn_phy_init(struct bwn_mac *mac)
4604 struct bwn_softc *sc = mac->mac_sc;
4607 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4608 mac->mac_phy.rf_onoff(mac, 1);
4609 error = mac->mac_phy.init(mac);
4611 device_printf(sc->sc_dev, "PHY init failed\n");
4614 error = bwn_switch_channel(mac,
4615 mac->mac_phy.get_default_chan(mac));
4617 device_printf(sc->sc_dev,
4618 "failed to switch default channel\n");
4623 if (mac->mac_phy.exit)
4624 mac->mac_phy.exit(mac);
4626 mac->mac_phy.rf_onoff(mac, 0);
4632 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4637 ant = bwn_ant2phy(antenna);
4640 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4641 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4642 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4643 /* For Probe Resposes */
4644 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4645 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4646 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4650 bwn_set_opmode(struct bwn_mac *mac)
4652 struct bwn_softc *sc = mac->mac_sc;
4653 struct ifnet *ifp = sc->sc_ifp;
4654 struct ieee80211com *ic = ifp->if_l2com;
4656 uint16_t cfp_pretbtt;
4658 ctl = BWN_READ_4(mac, BWN_MACCTL);
4659 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4660 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4661 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4662 ctl |= BWN_MACCTL_STA;
4664 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4665 ic->ic_opmode == IEEE80211_M_MBSS)
4666 ctl |= BWN_MACCTL_HOSTAP;
4667 else if (ic->ic_opmode == IEEE80211_M_IBSS)
4668 ctl &= ~BWN_MACCTL_STA;
4669 ctl |= sc->sc_filters;
4671 if (siba_get_revid(sc->sc_dev) <= 4)
4672 ctl |= BWN_MACCTL_PROMISC;
4674 BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4677 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4678 if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4679 siba_get_chiprev(sc->sc_dev) == 3)
4684 BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4688 bwn_dma_gettype(struct bwn_mac *mac)
4693 tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4694 if (tmp & SIBA_TGSHIGH_DMA64)
4695 return (BWN_DMA_64BIT);
4696 base = bwn_dma_base(0, 0);
4697 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4698 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4699 if (tmp & BWN_DMA32_TXADDREXT_MASK)
4700 return (BWN_DMA_32BIT);
4702 return (BWN_DMA_30BIT);
4706 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4709 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4710 *((bus_addr_t *)arg) = seg->ds_addr;
4715 bwn_phy_g_init_sub(struct bwn_mac *mac)
4717 struct bwn_phy *phy = &mac->mac_phy;
4718 struct bwn_phy_g *pg = &phy->phy_g;
4719 struct bwn_softc *sc = mac->mac_sc;
4723 bwn_phy_init_b5(mac);
4725 bwn_phy_init_b6(mac);
4727 if (phy->rev >= 2 || phy->gmode)
4728 bwn_phy_init_a(mac);
4730 if (phy->rev >= 2) {
4731 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4732 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4734 if (phy->rev == 2) {
4735 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4736 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4739 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4740 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4742 if (phy->gmode || phy->rev >= 2) {
4743 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4744 tmp &= BWN_PHYVER_VERSION;
4745 if (tmp == 3 || tmp == 5) {
4746 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4747 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4750 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4754 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4755 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4756 if (phy->rf_rev == 8) {
4757 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4758 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4760 if (BWN_HAS_LOOPBACK(phy))
4761 bwn_loopback_calcgain(mac);
4763 if (phy->rf_rev != 8) {
4764 if (pg->pg_initval == 0xffff)
4765 pg->pg_initval = bwn_rf_init_bcm2050(mac);
4767 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4770 if (BWN_HAS_TXMAG(phy)) {
4771 BWN_RF_WRITE(mac, 0x52,
4772 (BWN_RF_READ(mac, 0x52) & 0xff00)
4773 | pg->pg_loctl.tx_bias |
4774 pg->pg_loctl.tx_magn);
4776 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4778 if (phy->rev >= 6) {
4779 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4780 (pg->pg_loctl.tx_bias << 12));
4782 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4783 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4785 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4787 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4789 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4790 if (phy->gmode || phy->rev >= 2) {
4791 bwn_lo_g_adjust(mac);
4792 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4795 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4796 for (i = 0; i < 64; i++) {
4797 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4798 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4799 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4802 bwn_nrssi_threshold(mac);
4803 } else if (phy->gmode || phy->rev >= 2) {
4804 if (pg->pg_nrssi[0] == -1000) {
4805 KASSERT(pg->pg_nrssi[1] == -1000,
4806 ("%s:%d: fail", __func__, __LINE__));
4807 bwn_nrssi_slope_11g(mac);
4809 bwn_nrssi_threshold(mac);
4811 if (phy->rf_rev == 8)
4812 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4813 bwn_phy_hwpctl_init(mac);
4814 if ((siba_get_chipid(sc->sc_dev) == 0x4306
4815 && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4816 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4817 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4822 bwn_has_hwpctl(struct bwn_mac *mac)
4825 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4827 return (mac->mac_phy.use_hwpctl(mac));
4831 bwn_phy_init_b5(struct bwn_mac *mac)
4833 struct bwn_phy *phy = &mac->mac_phy;
4834 struct bwn_phy_g *pg = &phy->phy_g;
4835 struct bwn_softc *sc = mac->mac_sc;
4836 uint16_t offset, value;
4837 uint8_t old_channel;
4839 if (phy->analog == 1)
4840 BWN_RF_SET(mac, 0x007a, 0x0050);
4841 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4842 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4844 for (offset = 0x00a8; offset < 0x00c7; offset++) {
4845 BWN_PHY_WRITE(mac, offset, value);
4849 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4850 if (phy->rf_ver == 0x2050)
4851 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4853 if (phy->gmode || phy->rev >= 2) {
4854 if (phy->rf_ver == 0x2050) {
4855 BWN_RF_SET(mac, 0x007a, 0x0020);
4856 BWN_RF_SET(mac, 0x0051, 0x0004);
4858 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4860 BWN_PHY_SET(mac, 0x0802, 0x0100);
4861 BWN_PHY_SET(mac, 0x042b, 0x2000);
4863 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4865 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4866 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4867 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4870 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4871 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4873 if (phy->analog == 1) {
4874 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4875 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4876 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4877 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4878 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4880 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4881 BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4882 BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4884 if (phy->analog == 1)
4885 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4887 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4889 if (phy->analog == 0)
4890 BWN_WRITE_2(mac, 0x03e4, 0x3000);
4892 old_channel = phy->chan;
4893 bwn_phy_g_switch_chan(mac, 7, 0);
4895 if (phy->rf_ver != 0x2050) {
4896 BWN_RF_WRITE(mac, 0x0075, 0x0080);
4897 BWN_RF_WRITE(mac, 0x0079, 0x0081);
4900 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4901 BWN_RF_WRITE(mac, 0x0050, 0x0023);
4903 if (phy->rf_ver == 0x2050) {
4904 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4905 BWN_RF_WRITE(mac, 0x005a, 0x0070);
4908 BWN_RF_WRITE(mac, 0x005b, 0x007b);
4909 BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4910 BWN_RF_SET(mac, 0x007a, 0x0007);
4912 bwn_phy_g_switch_chan(mac, old_channel, 0);
4913 BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4914 BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4915 BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4917 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4920 if (phy->rf_ver == 0x2050)
4921 BWN_RF_WRITE(mac, 0x005d, 0x000d);
4923 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4927 bwn_loopback_calcgain(struct bwn_mac *mac)
4929 struct bwn_phy *phy = &mac->mac_phy;
4930 struct bwn_phy_g *pg = &phy->phy_g;
4931 struct bwn_softc *sc = mac->mac_sc;
4932 uint16_t backup_phy[16] = { 0 };
4933 uint16_t backup_radio[3];
4934 uint16_t backup_bband;
4935 uint16_t i, j, loop_i_max;
4937 uint16_t loop1_outer_done, loop1_inner_done;
4939 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4940 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4941 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4942 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4943 if (phy->rev != 1) {
4944 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4945 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4947 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4948 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4949 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4950 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4951 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4952 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4953 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4954 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4955 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4956 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4957 backup_bband = pg->pg_bbatt.att;
4958 backup_radio[0] = BWN_RF_READ(mac, 0x52);
4959 backup_radio[1] = BWN_RF_READ(mac, 0x43);
4960 backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4962 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4963 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4964 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4965 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4966 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4967 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4968 if (phy->rev != 1) {
4969 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4970 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4971 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4972 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4974 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4975 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4976 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4977 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4979 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4980 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4981 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4983 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4984 if (phy->rev != 1) {
4985 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4986 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4988 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4990 if (phy->rf_rev == 8)
4991 BWN_RF_WRITE(mac, 0x43, 0x000f);
4993 BWN_RF_WRITE(mac, 0x52, 0);
4994 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4996 bwn_phy_g_set_bbatt(mac, 11);
4999 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5001 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5002 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5004 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
5005 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
5007 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
5008 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
5010 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
5011 if (phy->rev >= 7) {
5012 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
5013 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
5016 BWN_RF_MASK(mac, 0x7a, 0x00f7);
5019 loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
5020 for (i = 0; i < loop_i_max; i++) {
5021 for (j = 0; j < 16; j++) {
5022 BWN_RF_WRITE(mac, 0x43, i);
5023 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
5025 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5026 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5028 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5033 loop1_outer_done = i;
5034 loop1_inner_done = j;
5036 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
5038 for (j = j - 8; j < 16; j++) {
5039 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
5040 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5041 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5044 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5051 if (phy->rev != 1) {
5052 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
5053 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
5055 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
5056 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
5057 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
5058 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
5059 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
5060 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
5061 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
5062 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
5063 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
5065 bwn_phy_g_set_bbatt(mac, backup_bband);
5067 BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
5068 BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
5069 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
5071 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
5073 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
5074 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
5075 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
5076 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
5078 pg->pg_max_lb_gain =
5079 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
5080 pg->pg_trsw_rx_gain = trsw_rx * 2;
5084 bwn_rf_init_bcm2050(struct bwn_mac *mac)
5086 struct bwn_phy *phy = &mac->mac_phy;
5087 uint32_t tmp1 = 0, tmp2 = 0;
5088 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
5089 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
5090 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
5091 static const uint8_t rcc_table[] = {
5092 0x02, 0x03, 0x01, 0x0f,
5093 0x06, 0x07, 0x05, 0x0f,
5094 0x0a, 0x0b, 0x09, 0x0f,
5095 0x0e, 0x0f, 0x0d, 0x0f,
5098 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
5099 rfoverval = rfover = cck3 = 0;
5100 radio0 = BWN_RF_READ(mac, 0x43);
5101 radio1 = BWN_RF_READ(mac, 0x51);
5102 radio2 = BWN_RF_READ(mac, 0x52);
5103 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5104 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5105 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5106 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5108 if (phy->type == BWN_PHYTYPE_B) {
5109 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5110 reg0 = BWN_READ_2(mac, 0x3ec);
5112 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5113 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5114 } else if (phy->gmode || phy->rev >= 2) {
5115 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5116 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5117 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5118 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5119 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5120 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5122 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5123 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5124 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5125 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5126 if (BWN_HAS_LOOPBACK(phy)) {
5127 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5128 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5130 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5132 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5133 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5136 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5137 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5139 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5140 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5142 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5144 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5145 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5146 reg1 = BWN_READ_2(mac, 0x3e6);
5147 reg2 = BWN_READ_2(mac, 0x3f4);
5149 if (phy->analog == 0)
5150 BWN_WRITE_2(mac, 0x03e6, 0x0122);
5152 if (phy->analog >= 2)
5153 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5154 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5155 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5158 reg = BWN_RF_READ(mac, 0x60);
5159 index = (reg & 0x001e) >> 1;
5160 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5162 if (phy->type == BWN_PHYTYPE_B)
5163 BWN_RF_WRITE(mac, 0x78, 0x26);
5164 if (phy->gmode || phy->rev >= 2) {
5165 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5166 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5169 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5170 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5171 if (phy->gmode || phy->rev >= 2) {
5172 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5173 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5176 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5177 BWN_RF_SET(mac, 0x51, 0x0004);
5178 if (phy->rf_rev == 8)
5179 BWN_RF_WRITE(mac, 0x43, 0x1f);
5181 BWN_RF_WRITE(mac, 0x52, 0);
5182 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5184 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5186 for (i = 0; i < 16; i++) {
5187 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5188 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5189 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5190 if (phy->gmode || phy->rev >= 2) {
5191 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5192 bwn_rf_2050_rfoverval(mac,
5193 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5195 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5197 if (phy->gmode || phy->rev >= 2) {
5198 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5199 bwn_rf_2050_rfoverval(mac,
5200 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5202 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5204 if (phy->gmode || phy->rev >= 2) {
5205 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5206 bwn_rf_2050_rfoverval(mac,
5207 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5209 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5211 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5212 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5213 if (phy->gmode || phy->rev >= 2) {
5214 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5215 bwn_rf_2050_rfoverval(mac,
5216 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5218 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5222 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5226 for (i = 0; i < 16; i++) {
5227 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5228 BWN_RF_WRITE(mac, 0x78, radio78);
5230 for (j = 0; j < 16; j++) {
5231 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5232 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5233 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5234 if (phy->gmode || phy->rev >= 2) {
5235 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5236 bwn_rf_2050_rfoverval(mac,
5237 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5239 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5241 if (phy->gmode || phy->rev >= 2) {
5242 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5243 bwn_rf_2050_rfoverval(mac,
5244 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5246 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5248 if (phy->gmode || phy->rev >= 2) {
5249 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5250 bwn_rf_2050_rfoverval(mac,
5251 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5253 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5255 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5256 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5257 if (phy->gmode || phy->rev >= 2) {
5258 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5259 bwn_rf_2050_rfoverval(mac,
5260 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5262 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5270 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5271 BWN_RF_WRITE(mac, 0x51, radio1);
5272 BWN_RF_WRITE(mac, 0x52, radio2);
5273 BWN_RF_WRITE(mac, 0x43, radio0);
5274 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5275 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5276 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5277 BWN_WRITE_2(mac, 0x3e6, reg1);
5278 if (phy->analog != 0)
5279 BWN_WRITE_2(mac, 0x3f4, reg2);
5280 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5281 bwn_spu_workaround(mac, phy->chan);
5282 if (phy->type == BWN_PHYTYPE_B) {
5283 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5284 BWN_WRITE_2(mac, 0x3ec, reg0);
5285 } else if (phy->gmode) {
5286 BWN_WRITE_2(mac, BWN_PHY_RADIO,
5287 BWN_READ_2(mac, BWN_PHY_RADIO)
5289 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5290 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5291 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5292 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5294 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5295 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5296 if (BWN_HAS_LOOPBACK(phy)) {
5297 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5298 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5302 return ((i > 15) ? radio78 : rcc);
5306 bwn_phy_init_b6(struct bwn_mac *mac)
5308 struct bwn_phy *phy = &mac->mac_phy;
5309 struct bwn_phy_g *pg = &phy->phy_g;
5310 struct bwn_softc *sc = mac->mac_sc;
5311 uint16_t offset, val;
5312 uint8_t old_channel;
5314 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5315 ("%s:%d: fail", __func__, __LINE__));
5317 BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5318 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5319 if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5320 BWN_RF_WRITE(mac, 0x51, 0x37);
5321 BWN_RF_WRITE(mac, 0x52, 0x70);
5322 BWN_RF_WRITE(mac, 0x53, 0xb3);
5323 BWN_RF_WRITE(mac, 0x54, 0x9b);
5324 BWN_RF_WRITE(mac, 0x5a, 0x88);
5325 BWN_RF_WRITE(mac, 0x5b, 0x88);
5326 BWN_RF_WRITE(mac, 0x5d, 0x88);
5327 BWN_RF_WRITE(mac, 0x5e, 0x88);
5328 BWN_RF_WRITE(mac, 0x7d, 0x88);
5330 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5332 if (phy->rf_rev == 8) {
5333 BWN_RF_WRITE(mac, 0x51, 0);
5334 BWN_RF_WRITE(mac, 0x52, 0x40);
5335 BWN_RF_WRITE(mac, 0x53, 0xb7);
5336 BWN_RF_WRITE(mac, 0x54, 0x98);
5337 BWN_RF_WRITE(mac, 0x5a, 0x88);
5338 BWN_RF_WRITE(mac, 0x5b, 0x6b);
5339 BWN_RF_WRITE(mac, 0x5c, 0x0f);
5340 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5341 BWN_RF_WRITE(mac, 0x5d, 0xfa);
5342 BWN_RF_WRITE(mac, 0x5e, 0xd8);
5344 BWN_RF_WRITE(mac, 0x5d, 0xf5);
5345 BWN_RF_WRITE(mac, 0x5e, 0xb8);
5347 BWN_RF_WRITE(mac, 0x0073, 0x0003);
5348 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5349 BWN_RF_WRITE(mac, 0x007c, 0x0001);
5350 BWN_RF_WRITE(mac, 0x007e, 0x0008);
5352 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5353 BWN_PHY_WRITE(mac, offset, val);
5356 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5357 BWN_PHY_WRITE(mac, offset, val);
5360 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5361 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5364 if (phy->type == BWN_PHYTYPE_G) {
5365 BWN_RF_SET(mac, 0x007a, 0x0020);
5366 BWN_RF_SET(mac, 0x0051, 0x0004);
5367 BWN_PHY_SET(mac, 0x0802, 0x0100);
5368 BWN_PHY_SET(mac, 0x042b, 0x2000);
5369 BWN_PHY_WRITE(mac, 0x5b, 0);
5370 BWN_PHY_WRITE(mac, 0x5c, 0);
5373 old_channel = phy->chan;
5374 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5376 BWN_RF_WRITE(mac, 0x0050, 0x0020);
5377 BWN_RF_WRITE(mac, 0x0050, 0x0023);
5379 if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5380 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5381 BWN_RF_WRITE(mac, 0x50, 0x20);
5383 if (phy->rf_rev <= 2) {
5384 BWN_RF_WRITE(mac, 0x7c, 0x20);
5385 BWN_RF_WRITE(mac, 0x5a, 0x70);
5386 BWN_RF_WRITE(mac, 0x5b, 0x7b);
5387 BWN_RF_WRITE(mac, 0x5c, 0xb0);
5389 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5391 bwn_phy_g_switch_chan(mac, old_channel, 0);
5393 BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5394 if (phy->rf_rev >= 6)
5395 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5397 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5398 BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5399 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5401 if (phy->rf_rev <= 5)
5402 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5403 if (phy->rf_rev <= 2)
5404 BWN_RF_WRITE(mac, 0x005d, 0x000d);
5406 if (phy->analog == 4) {
5407 BWN_WRITE_2(mac, 0x3e4, 9);
5408 BWN_PHY_MASK(mac, 0x61, 0x0fff);
5410 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5411 if (phy->type == BWN_PHYTYPE_B)
5412 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5413 else if (phy->type == BWN_PHYTYPE_G)
5414 BWN_WRITE_2(mac, 0x03e6, 0x0);
5418 bwn_phy_init_a(struct bwn_mac *mac)
5420 struct bwn_phy *phy = &mac->mac_phy;
5421 struct bwn_softc *sc = mac->mac_sc;
5423 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5424 ("%s:%d: fail", __func__, __LINE__));
5426 if (phy->rev >= 6) {
5427 if (phy->type == BWN_PHYTYPE_A)
5428 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5429 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5430 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5432 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5437 if (phy->type == BWN_PHYTYPE_G &&
5438 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5439 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5443 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5447 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5448 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5452 bwn_wa_agc(struct bwn_mac *mac)
5454 struct bwn_phy *phy = &mac->mac_phy;
5456 if (phy->rev == 1) {
5457 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5458 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5459 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5460 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5461 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5462 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5463 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5464 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5465 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5467 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5468 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5469 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5470 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5473 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5475 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5476 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5477 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5478 BWN_RF_SET(mac, 0x7a, 0x0008);
5479 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5480 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5481 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5482 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5484 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5485 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5486 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5487 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5488 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5489 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5490 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5491 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5492 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5493 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5494 if (phy->rev == 1) {
5495 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5496 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5498 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5499 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5500 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5501 if (phy->rev >= 6) {
5502 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5503 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5504 (uint16_t)~0xf000, 0x3000);
5507 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5508 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5509 if (phy->rev == 1) {
5510 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5511 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5512 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5513 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5514 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5515 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5516 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5517 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5519 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5520 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5521 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5522 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5524 if (phy->rev >= 6) {
5525 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5526 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5528 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5532 bwn_wa_grev1(struct bwn_mac *mac)
5534 struct bwn_phy *phy = &mac->mac_phy;
5536 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5537 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5538 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5540 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5542 /* init CRSTHRES and ANTDWELL */
5543 if (phy->rev == 1) {
5544 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5545 } else if (phy->rev == 2) {
5546 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5547 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5548 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5550 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5551 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5552 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5553 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5555 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5556 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5557 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5559 /* XXX support PHY-A??? */
5560 for (i = 0; i < N(bwn_tab_finefreqg); i++)
5561 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5562 bwn_tab_finefreqg[i]);
5564 /* XXX support PHY-A??? */
5566 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5567 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5568 bwn_tab_noise_g1[i]);
5570 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5571 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5572 bwn_tab_noise_g2[i]);
5575 for (i = 0; i < N(bwn_tab_rotor); i++)
5576 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5579 /* XXX support PHY-A??? */
5580 if (phy->rev >= 6) {
5581 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5583 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5585 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5587 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5589 for (i = 0; i < N(bwn_tab_retard); i++)
5590 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5593 if (phy->rev == 1) {
5594 for (i = 0; i < 16; i++)
5595 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5598 for (i = 0; i < 32; i++)
5599 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5606 bwn_wa_grev26789(struct bwn_mac *mac)
5608 struct bwn_phy *phy = &mac->mac_phy;
5610 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5613 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5615 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5617 /* init CRSTHRES and ANTDWELL */
5619 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5620 else if (phy->rev == 2) {
5621 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5622 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5623 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5625 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5626 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5627 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5628 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5631 for (i = 0; i < 64; i++)
5632 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5634 /* XXX support PHY-A??? */
5636 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5637 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5638 bwn_tab_noise_g1[i]);
5640 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5641 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5642 bwn_tab_noise_g2[i]);
5644 /* XXX support PHY-A??? */
5645 if (phy->rev >= 6) {
5646 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5648 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5650 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5652 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5654 for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5655 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5656 bwn_tab_sigmasqr2[i]);
5658 if (phy->rev == 1) {
5659 for (i = 0; i < 16; i++)
5660 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5663 for (i = 0; i < 32; i++)
5664 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5669 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5671 if (phy->type == BWN_PHYTYPE_A)
5672 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5674 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5676 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5677 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5678 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5681 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5682 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5686 bwn_wa_init(struct bwn_mac *mac)
5688 struct bwn_phy *phy = &mac->mac_phy;
5689 struct bwn_softc *sc = mac->mac_sc;
5691 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5702 bwn_wa_grev26789(mac);
5705 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5708 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5709 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5710 siba_get_pci_revid(sc->sc_dev) != 0x17) {
5712 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5714 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5717 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5718 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5719 if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5722 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5723 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5725 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5727 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5729 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5731 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5733 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5738 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5739 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5740 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5743 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5744 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5748 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5751 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5754 addr = table + offset;
5755 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5756 (addr - 1 != pg->pg_ofdmtab_addr)) {
5757 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5758 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5760 pg->pg_ofdmtab_addr = addr;
5761 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5765 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5768 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5771 addr = table + offset;
5772 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5773 (addr - 1 != pg->pg_ofdmtab_addr)) {
5774 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5775 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5777 pg->pg_ofdmtab_addr = addr;
5779 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5780 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5784 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5788 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5789 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5793 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5795 struct bwn_phy *phy = &mac->mac_phy;
5796 struct bwn_softc *sc = mac->mac_sc;
5797 unsigned int i, max_loop;
5799 uint32_t buffer[5] = {
5800 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5805 buffer[0] = 0x000201cc;
5808 buffer[0] = 0x000b846e;
5811 BWN_ASSERT_LOCKED(mac->mac_sc);
5813 for (i = 0; i < 5; i++)
5814 bwn_ram_write(mac, i * 4, buffer[i]);
5816 BWN_WRITE_2(mac, 0x0568, 0x0000);
5817 BWN_WRITE_2(mac, 0x07c0,
5818 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5819 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5820 BWN_WRITE_2(mac, 0x050c, value);
5821 if (phy->type == BWN_PHYTYPE_LP)
5822 BWN_WRITE_2(mac, 0x0514, 0x1a02);
5823 BWN_WRITE_2(mac, 0x0508, 0x0000);
5824 BWN_WRITE_2(mac, 0x050a, 0x0000);
5825 BWN_WRITE_2(mac, 0x054c, 0x0000);
5826 BWN_WRITE_2(mac, 0x056a, 0x0014);
5827 BWN_WRITE_2(mac, 0x0568, 0x0826);
5828 BWN_WRITE_2(mac, 0x0500, 0x0000);
5829 if (phy->type == BWN_PHYTYPE_LP)
5830 BWN_WRITE_2(mac, 0x0502, 0x0050);
5832 BWN_WRITE_2(mac, 0x0502, 0x0030);
5834 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5835 BWN_RF_WRITE(mac, 0x0051, 0x0017);
5836 for (i = 0x00; i < max_loop; i++) {
5837 value = BWN_READ_2(mac, 0x050e);
5842 for (i = 0x00; i < 0x0a; i++) {
5843 value = BWN_READ_2(mac, 0x050e);
5848 for (i = 0x00; i < 0x19; i++) {
5849 value = BWN_READ_2(mac, 0x0690);
5850 if (!(value & 0x0100))
5854 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5855 BWN_RF_WRITE(mac, 0x0051, 0x0037);
5859 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5863 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5865 macctl = BWN_READ_4(mac, BWN_MACCTL);
5866 if (macctl & BWN_MACCTL_BIGENDIAN)
5867 printf("TODO: need swap\n");
5869 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5870 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5871 BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5875 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5879 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5880 ("%s:%d: fail", __func__, __LINE__));
5882 value = (uint8_t) (ctl->q);
5883 value |= ((uint8_t) (ctl->i)) << 8;
5884 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5888 bwn_lo_calcfeed(struct bwn_mac *mac,
5889 uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5891 struct bwn_phy *phy = &mac->mac_phy;
5892 struct bwn_softc *sc = mac->mac_sc;
5894 uint16_t feedthrough;
5897 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5898 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5900 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5901 ("%s:%d: fail", __func__, __LINE__));
5902 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5903 ("%s:%d: fail", __func__, __LINE__));
5905 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5907 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5908 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5910 rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5912 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5913 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5915 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5916 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5918 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5919 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5921 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5923 pga |= BWN_PHY_PGACTL_UNKNOWN;
5924 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5926 pga |= BWN_PHY_PGACTL_LOWBANDW;
5927 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5929 pga |= BWN_PHY_PGACTL_LPF;
5930 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5933 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5935 return (feedthrough);
5939 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5940 uint16_t *value, uint16_t *pad_mix_gain)
5942 struct bwn_phy *phy = &mac->mac_phy;
5943 uint16_t reg, v, padmix;
5945 if (phy->type == BWN_PHYTYPE_B) {
5947 if (phy->rf_rev <= 5) {
5955 if (phy->rev >= 2 && phy->rf_rev == 8) {
5968 *pad_mix_gain = padmix;
5974 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5976 struct bwn_phy *phy = &mac->mac_phy;
5977 struct bwn_phy_g *pg = &phy->phy_g;
5978 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5980 uint16_t trsw_rx, pga;
5981 uint16_t rf_pctl_reg;
5983 static const uint8_t tx_bias_values[] = {
5984 0x09, 0x08, 0x0a, 0x01, 0x00,
5985 0x02, 0x05, 0x04, 0x06,
5987 static const uint8_t tx_magn_values[] = {
5991 if (!BWN_HAS_LOOPBACK(phy)) {
5999 lb_gain = pg->pg_max_lb_gain / 2;
6002 pga = abs(10 - lb_gain) / 6;
6003 pga = MIN(MAX(pga, 0), 15);
6010 if ((phy->rev >= 2) &&
6011 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
6014 if ((10 - lb_gain) < cmp_val)
6015 tmp = (10 - lb_gain);
6023 rf_pctl_reg = cmp_val;
6028 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
6029 bwn_phy_g_set_bbatt(mac, 2);
6031 reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
6033 BWN_RF_MASK(mac, reg, mask);
6035 if (BWN_HAS_TXMAG(phy)) {
6038 int min_feedth = 0xffff;
6039 uint8_t tx_magn, tx_bias;
6041 for (i = 0; i < N(tx_magn_values); i++) {
6042 tx_magn = tx_magn_values[i];
6043 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
6044 for (j = 0; j < N(tx_bias_values); j++) {
6045 tx_bias = tx_bias_values[j];
6046 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
6047 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
6049 if (feedthrough < min_feedth) {
6050 lo->tx_bias = tx_bias;
6051 lo->tx_magn = tx_magn;
6052 min_feedth = feedthrough;
6054 if (lo->tx_bias == 0)
6057 BWN_RF_WRITE(mac, 0x52,
6058 (BWN_RF_READ(mac, 0x52)
6059 & 0xff00) | lo->tx_bias | lo->
6065 BWN_RF_MASK(mac, 0x52, 0xfff0);
6068 BWN_GETTIME(lo->txctl_measured_time);
6072 bwn_lo_get_powervector(struct bwn_mac *mac)
6074 struct bwn_phy *phy = &mac->mac_phy;
6075 struct bwn_phy_g *pg = &phy->phy_g;
6076 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6079 uint64_t power_vector = 0;
6081 for (i = 0; i < 8; i += 2) {
6082 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
6083 power_vector |= (tmp << (i * 8));
6084 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
6087 lo->power_vector = power_vector;
6089 BWN_GETTIME(lo->pwr_vec_read_time);
6093 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
6096 struct bwn_phy *phy = &mac->mac_phy;
6097 struct bwn_phy_g *pg = &phy->phy_g;
6100 if (max_rx_gain < 0)
6103 if (BWN_HAS_LOOPBACK(phy)) {
6108 trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6109 if (max_rx_gain >= trsw_rx_gain) {
6110 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6114 trsw_rx_gain = max_rx_gain;
6115 if (trsw_rx_gain < 9) {
6116 pg->pg_lna_lod_gain = 0;
6118 pg->pg_lna_lod_gain = 1;
6121 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6122 pg->pg_pga_gain = trsw_rx_gain / 3;
6123 if (pg->pg_pga_gain >= 5) {
6124 pg->pg_pga_gain -= 5;
6125 pg->pg_lna_gain = 2;
6127 pg->pg_lna_gain = 0;
6129 pg->pg_lna_gain = 0;
6130 pg->pg_trsw_rx_gain = 0x20;
6131 if (max_rx_gain >= 0x14) {
6132 pg->pg_lna_lod_gain = 1;
6133 pg->pg_pga_gain = 2;
6134 } else if (max_rx_gain >= 0x12) {
6135 pg->pg_lna_lod_gain = 1;
6136 pg->pg_pga_gain = 1;
6137 } else if (max_rx_gain >= 0xf) {
6138 pg->pg_lna_lod_gain = 1;
6139 pg->pg_pga_gain = 0;
6141 pg->pg_lna_lod_gain = 0;
6142 pg->pg_pga_gain = 0;
6146 tmp = BWN_RF_READ(mac, 0x7a);
6147 if (pg->pg_lna_lod_gain == 0)
6151 BWN_RF_WRITE(mac, 0x7a, tmp);
6155 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6157 struct bwn_phy *phy = &mac->mac_phy;
6158 struct bwn_phy_g *pg = &phy->phy_g;
6159 struct bwn_softc *sc = mac->mac_sc;
6160 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6164 if (bwn_has_hwpctl(mac)) {
6165 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6166 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6167 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6168 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6169 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6171 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6172 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6173 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6174 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6176 if (phy->type == BWN_PHYTYPE_B &&
6177 phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6178 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6179 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6181 if (phy->rev >= 2) {
6182 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6183 sav->phy_analogoverval =
6184 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6185 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6186 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6187 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6188 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6189 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6191 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6192 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6193 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6194 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6195 if (phy->type == BWN_PHYTYPE_G) {
6196 if ((phy->rev >= 7) &&
6197 (siba_sprom_get_bf_lo(sc->sc_dev) &
6199 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6201 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6204 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6206 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6208 sav->reg0 = BWN_READ_2(mac, 0x3f4);
6209 sav->reg1 = BWN_READ_2(mac, 0x3e2);
6210 sav->rf0 = BWN_RF_READ(mac, 0x43);
6211 sav->rf1 = BWN_RF_READ(mac, 0x7a);
6212 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6213 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6214 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6215 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6217 if (!BWN_HAS_TXMAG(phy)) {
6218 sav->rf2 = BWN_RF_READ(mac, 0x52);
6221 if (phy->type == BWN_PHYTYPE_B) {
6222 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6223 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6224 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6225 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6227 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6230 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6234 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6235 BWN_PHY_WRITE(mac, tmp, 0x007f);
6237 tmp = sav->phy_syncctl;
6238 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6240 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6242 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6243 if (phy->type == BWN_PHYTYPE_G ||
6244 (phy->type == BWN_PHYTYPE_B &&
6245 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6246 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6248 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6250 bwn_dummy_transmission(mac, 0, 1);
6251 bwn_phy_g_switch_chan(mac, 6, 0);
6252 BWN_RF_READ(mac, 0x51);
6253 if (phy->type == BWN_PHYTYPE_G)
6254 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6257 if (time_before(lo->txctl_measured_time,
6258 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6259 bwn_lo_measure_txctl_values(mac);
6261 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6262 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6264 if (phy->type == BWN_PHYTYPE_B)
6265 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6267 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6272 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6274 struct bwn_phy *phy = &mac->mac_phy;
6275 struct bwn_phy_g *pg = &phy->phy_g;
6278 if (phy->rev >= 2) {
6279 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6280 tmp = (pg->pg_pga_gain << 8);
6281 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6283 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6285 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6287 tmp = (pg->pg_pga_gain | 0xefa0);
6288 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6290 if (phy->type == BWN_PHYTYPE_G) {
6292 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6294 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6296 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6298 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6300 BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6301 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6302 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6303 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6304 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6305 BWN_RF_WRITE(mac, 0x43, sav->rf0);
6306 BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6307 if (!BWN_HAS_TXMAG(phy)) {
6309 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6311 BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6312 if (phy->type == BWN_PHYTYPE_B &&
6313 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6314 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6315 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6317 if (phy->rev >= 2) {
6318 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6319 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6320 sav->phy_analogoverval);
6321 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6322 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6323 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6324 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6325 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6327 if (bwn_has_hwpctl(mac)) {
6328 tmp = (sav->phy_lomask & 0xbfff);
6329 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6330 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6331 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6332 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6333 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6335 bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6339 bwn_lo_probe_loctl(struct bwn_mac *mac,
6340 struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6342 struct bwn_phy *phy = &mac->mac_phy;
6343 struct bwn_phy_g *pg = &phy->phy_g;
6344 struct bwn_loctl orig, test;
6345 struct bwn_loctl prev = { -100, -100 };
6346 static const struct bwn_loctl modifiers[] = {
6347 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,},
6348 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,}
6350 int begin, end, lower = 0, i;
6353 if (d->curstate == 0) {
6356 } else if (d->curstate % 2 == 0) {
6357 begin = d->curstate - 1;
6358 end = d->curstate + 1;
6360 begin = d->curstate - 2;
6361 end = d->curstate + 2;
6368 memcpy(&orig, probe, sizeof(struct bwn_loctl));
6372 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6373 memcpy(&test, &orig, sizeof(struct bwn_loctl));
6374 test.i += modifiers[i - 1].i * d->multipler;
6375 test.q += modifiers[i - 1].q * d->multipler;
6376 if ((test.i != prev.i || test.q != prev.q) &&
6377 (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6378 bwn_lo_write(mac, &test);
6379 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6380 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6381 if (feedth < d->feedth) {
6382 memcpy(probe, &test,
6383 sizeof(struct bwn_loctl));
6386 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6390 memcpy(&prev, &test, sizeof(prev));
6404 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6406 struct bwn_phy *phy = &mac->mac_phy;
6407 struct bwn_phy_g *pg = &phy->phy_g;
6408 struct bwn_lo_g_sm d;
6409 struct bwn_loctl probe;
6410 int lower, repeat, cnt = 0;
6415 if (BWN_HAS_LOOPBACK(phy))
6418 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6419 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6422 bwn_lo_write(mac, &d.loctl);
6423 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6424 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6425 if (feedth < 0x258) {
6426 if (feedth >= 0x12c)
6430 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6431 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6436 KASSERT(d.curstate >= 0 && d.curstate <= 8,
6437 ("%s:%d: fail", __func__, __LINE__));
6438 memcpy(&probe, &d.loctl,
6439 sizeof(struct bwn_loctl));
6440 lower = bwn_lo_probe_loctl(mac, &probe, &d);
6443 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6445 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6447 } while (d.nmeasure < 24);
6448 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6450 if (BWN_HAS_LOOPBACK(phy)) {
6451 if (d.feedth > 0x1194)
6453 else if (d.feedth < 0x5dc)
6456 if (d.feedth <= 0x5dc) {
6461 } else if (cnt == 2)
6464 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6465 } while (++cnt < repeat);
6468 static struct bwn_lo_calib *
6469 bwn_lo_calibset(struct bwn_mac *mac,
6470 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6472 struct bwn_phy *phy = &mac->mac_phy;
6473 struct bwn_phy_g *pg = &phy->phy_g;
6474 struct bwn_loctl loctl = { 0, 0 };
6475 struct bwn_lo_calib *cal;
6476 struct bwn_lo_g_value sval = { 0 };
6478 uint16_t pad, reg, value;
6480 sval.old_channel = phy->chan;
6481 bwn_mac_suspend(mac);
6482 bwn_lo_save(mac, &sval);
6484 reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6485 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6486 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6488 rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6491 if (BWN_HAS_LOOPBACK(phy))
6492 rxgain += pg->pg_max_lb_gain;
6493 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6494 bwn_phy_g_set_bbatt(mac, bbatt->att);
6495 bwn_lo_probe_sm(mac, &loctl, &rxgain);
6497 bwn_lo_restore(mac, &sval);
6498 bwn_mac_enable(mac);
6500 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
6502 device_printf(mac->mac_sc->sc_dev, "out of memory\n");
6505 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6506 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6507 memcpy(&cal->ctl, &loctl, sizeof(loctl));
6509 BWN_GETTIME(cal->calib_time);
6514 static struct bwn_lo_calib *
6515 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6516 const struct bwn_rfatt *rfatt)
6518 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6519 struct bwn_lo_calib *c;
6521 TAILQ_FOREACH(c, &lo->calib_list, list) {
6522 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6524 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6529 c = bwn_lo_calibset(mac, bbatt, rfatt);
6532 TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6538 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6540 struct bwn_phy *phy = &mac->mac_phy;
6541 struct bwn_phy_g *pg = &phy->phy_g;
6542 struct bwn_softc *sc = mac->mac_sc;
6543 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6544 const struct bwn_rfatt *rfatt;
6545 const struct bwn_bbatt *bbatt;
6548 int rf_offset, bb_offset;
6549 uint8_t changed = 0;
6551 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6552 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6553 ("%s:%d: fail", __func__, __LINE__));
6555 pvector = lo->power_vector;
6556 if (!update && !pvector)
6559 bwn_mac_suspend(mac);
6561 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6562 struct bwn_lo_calib *cal;
6566 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6568 bb_offset = i / lo->rfatt.len;
6569 rf_offset = i % lo->rfatt.len;
6570 bbatt = &(lo->bbatt.array[bb_offset]);
6571 rfatt = &(lo->rfatt.array[rf_offset]);
6573 cal = bwn_lo_calibset(mac, bbatt, rfatt);
6575 device_printf(sc->sc_dev, "LO: Could not "
6576 "calibrate DC table entry\n");
6579 val = (uint8_t)(cal->ctl.q);
6580 val |= ((uint8_t)(cal->ctl.i)) << 4;
6581 free(cal, M_DEVBUF);
6585 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6586 | ((val & 0x00ff) << 8);
6588 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6593 for (i = 0; i < BWN_DC_LT_SIZE; i++)
6594 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6596 bwn_mac_enable(mac);
6600 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6605 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6610 bwn_lo_g_adjust(struct bwn_mac *mac)
6612 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6613 struct bwn_lo_calib *cal;
6614 struct bwn_rfatt rf;
6616 memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6617 bwn_lo_fixup_rfatt(&rf);
6619 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6622 bwn_lo_write(mac, &cal->ctl);
6626 bwn_lo_g_init(struct bwn_mac *mac)
6629 if (!bwn_has_hwpctl(mac))
6632 bwn_lo_get_powervector(mac);
6633 bwn_phy_g_dc_lookup_init(mac, 1);
6637 bwn_mac_suspend(struct bwn_mac *mac)
6639 struct bwn_softc *sc = mac->mac_sc;
6643 KASSERT(mac->mac_suspended >= 0,
6644 ("%s:%d: fail", __func__, __LINE__));
6646 if (mac->mac_suspended == 0) {
6647 bwn_psctl(mac, BWN_PS_AWAKE);
6648 BWN_WRITE_4(mac, BWN_MACCTL,
6649 BWN_READ_4(mac, BWN_MACCTL)
6651 BWN_READ_4(mac, BWN_MACCTL);
6652 for (i = 35; i; i--) {
6653 tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6654 if (tmp & BWN_INTR_MAC_SUSPENDED)
6658 for (i = 40; i; i--) {
6659 tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6660 if (tmp & BWN_INTR_MAC_SUSPENDED)
6664 device_printf(sc->sc_dev, "MAC suspend failed\n");
6667 mac->mac_suspended++;
6671 bwn_mac_enable(struct bwn_mac *mac)
6673 struct bwn_softc *sc = mac->mac_sc;
6676 state = bwn_shm_read_2(mac, BWN_SHARED,
6677 BWN_SHARED_UCODESTAT);
6678 if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6679 state != BWN_SHARED_UCODESTAT_SLEEP)
6680 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6682 mac->mac_suspended--;
6683 KASSERT(mac->mac_suspended >= 0,
6684 ("%s:%d: fail", __func__, __LINE__));
6685 if (mac->mac_suspended == 0) {
6686 BWN_WRITE_4(mac, BWN_MACCTL,
6687 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6688 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6689 BWN_READ_4(mac, BWN_MACCTL);
6690 BWN_READ_4(mac, BWN_INTR_REASON);
6696 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6698 struct bwn_softc *sc = mac->mac_sc;
6702 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6703 ("%s:%d: fail", __func__, __LINE__));
6704 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6705 ("%s:%d: fail", __func__, __LINE__));
6707 /* XXX forcibly awake and hwps-off */
6709 BWN_WRITE_4(mac, BWN_MACCTL,
6710 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6712 BWN_READ_4(mac, BWN_MACCTL);
6713 if (siba_get_revid(sc->sc_dev) >= 5) {
6714 for (i = 0; i < 100; i++) {
6715 ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6716 BWN_SHARED_UCODESTAT);
6717 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6725 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6728 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6729 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6733 bwn_nrssi_threshold(struct bwn_mac *mac)
6735 struct bwn_phy *phy = &mac->mac_phy;
6736 struct bwn_phy_g *pg = &phy->phy_g;
6737 struct bwn_softc *sc = mac->mac_sc;
6742 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6744 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6745 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6753 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6754 a += (pg->pg_nrssi[0] << 6);
6755 a += (a < 32) ? 31 : 32;
6757 a = MIN(MAX(a, -31), 31);
6759 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6760 b += (pg->pg_nrssi[0] << 6);
6766 b = MIN(MAX(b, -31), 31);
6768 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6769 tmpu16 |= ((uint32_t)b & 0x0000003f);
6770 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6771 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6775 tmp16 = bwn_nrssi_read(mac, 0x20);
6778 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6782 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6784 #define SAVE_RF_MAX 3
6785 #define SAVE_PHY_COMM_MAX 4
6786 #define SAVE_PHY3_MAX 8
6787 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6788 { 0x7a, 0x52, 0x43 };
6789 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6790 { 0x15, 0x5a, 0x59, 0x58 };
6791 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6792 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6793 0x0801, 0x0060, 0x0014, 0x0478
6795 struct bwn_phy *phy = &mac->mac_phy;
6796 struct bwn_phy_g *pg = &phy->phy_g;
6797 int32_t i, tmp32, phy3_idx = 0;
6798 uint16_t delta, tmp;
6799 uint16_t save_rf[SAVE_RF_MAX];
6800 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6801 uint16_t save_phy3[SAVE_PHY3_MAX];
6802 uint16_t ant_div, phy0, chan_ex;
6803 int16_t nrssi0, nrssi1;
6805 KASSERT(phy->type == BWN_PHYTYPE_G,
6806 ("%s:%d: fail", __func__, __LINE__));
6808 if (phy->rf_rev >= 9)
6810 if (phy->rf_rev == 8)
6811 bwn_nrssi_offset(mac);
6813 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6814 BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6817 * Save RF/PHY registers for later restoration
6819 ant_div = BWN_READ_2(mac, 0x03e2);
6820 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6821 for (i = 0; i < SAVE_RF_MAX; ++i)
6822 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6823 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6824 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6826 phy0 = BWN_READ_2(mac, BWN_PHY0);
6827 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6828 if (phy->rev >= 3) {
6829 for (i = 0; i < SAVE_PHY3_MAX; ++i)
6830 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6831 BWN_PHY_WRITE(mac, 0x002e, 0);
6832 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6837 BWN_PHY_SET(mac, 0x0478, 0x0100);
6838 BWN_PHY_SET(mac, 0x0801, 0x0040);
6842 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6845 BWN_PHY_SET(mac, 0x0060, 0x0040);
6846 BWN_PHY_SET(mac, 0x0014, 0x0200);
6851 BWN_RF_SET(mac, 0x007a, 0x0070);
6852 bwn_set_all_gains(mac, 0, 8, 0);
6853 BWN_RF_MASK(mac, 0x007a, 0x00f7);
6854 if (phy->rev >= 2) {
6855 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6856 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6858 BWN_RF_SET(mac, 0x007a, 0x0080);
6861 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6862 if (nrssi0 >= 0x0020)
6868 BWN_RF_MASK(mac, 0x007a, 0x007f);
6870 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6872 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6873 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6874 BWN_RF_SET(mac, 0x007a, 0x000f);
6875 BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6876 if (phy->rev >= 2) {
6877 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6878 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6881 bwn_set_all_gains(mac, 3, 0, 1);
6882 if (phy->rf_rev == 8) {
6883 BWN_RF_WRITE(mac, 0x0043, 0x001f);
6885 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6886 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6887 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6888 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6890 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6891 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6892 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6894 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6897 * Install calculated narrow RSSI values
6899 if (nrssi1 >= 0x0020)
6901 if (nrssi0 == nrssi1)
6902 pg->pg_nrssi_slope = 0x00010000;
6904 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6906 pg->pg_nrssi[0] = nrssi1;
6907 pg->pg_nrssi[1] = nrssi0;
6911 * Restore saved RF/PHY registers
6913 if (phy->rev >= 3) {
6914 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6915 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6916 save_phy3[phy3_idx]);
6919 if (phy->rev >= 2) {
6920 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6921 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6924 for (i = 0; i < SAVE_RF_MAX; ++i)
6925 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6927 BWN_WRITE_2(mac, 0x03e2, ant_div);
6928 BWN_WRITE_2(mac, 0x03e6, phy0);
6929 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6931 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6932 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6934 bwn_spu_workaround(mac, phy->chan);
6935 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6936 bwn_set_original_gains(mac);
6937 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6938 if (phy->rev >= 3) {
6939 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6940 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6941 save_phy3[phy3_idx]);
6945 delta = 0x1f - pg->pg_nrssi[0];
6946 for (i = 0; i < 64; i++) {
6947 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6948 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6949 pg->pg_nrssi_lt[i] = tmp32;
6952 bwn_nrssi_threshold(mac);
6954 #undef SAVE_PHY_COMM_MAX
6955 #undef SAVE_PHY3_MAX
6959 bwn_nrssi_offset(struct bwn_mac *mac)
6961 #define SAVE_RF_MAX 2
6962 #define SAVE_PHY_COMM_MAX 10
6963 #define SAVE_PHY6_MAX 8
6964 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6966 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6967 0x0001, 0x0811, 0x0812, 0x0814,
6968 0x0815, 0x005a, 0x0059, 0x0058,
6971 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6972 0x002e, 0x002f, 0x080f, 0x0810,
6973 0x0801, 0x0060, 0x0014, 0x0478
6975 struct bwn_phy *phy = &mac->mac_phy;
6976 int i, phy6_idx = 0;
6977 uint16_t save_rf[SAVE_RF_MAX];
6978 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6979 uint16_t save_phy6[SAVE_PHY6_MAX];
6981 uint16_t saved = 0xffff;
6983 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6984 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6985 for (i = 0; i < SAVE_RF_MAX; ++i)
6986 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6988 BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6989 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6990 BWN_PHY_SET(mac, 0x0811, 0x000c);
6991 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6992 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6993 if (phy->rev >= 6) {
6994 for (i = 0; i < SAVE_PHY6_MAX; ++i)
6995 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6997 BWN_PHY_WRITE(mac, 0x002e, 0);
6998 BWN_PHY_WRITE(mac, 0x002f, 0);
6999 BWN_PHY_WRITE(mac, 0x080f, 0);
7000 BWN_PHY_WRITE(mac, 0x0810, 0);
7001 BWN_PHY_SET(mac, 0x0478, 0x0100);
7002 BWN_PHY_SET(mac, 0x0801, 0x0040);
7003 BWN_PHY_SET(mac, 0x0060, 0x0040);
7004 BWN_PHY_SET(mac, 0x0014, 0x0200);
7006 BWN_RF_SET(mac, 0x007a, 0x0070);
7007 BWN_RF_SET(mac, 0x007a, 0x0080);
7010 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7014 for (i = 7; i >= 4; i--) {
7015 BWN_RF_WRITE(mac, 0x007b, i);
7017 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
7021 if (nrssi < 31 && saved == 0xffff)
7024 if (saved == 0xffff)
7027 BWN_RF_MASK(mac, 0x007a, 0x007f);
7028 if (phy->rev != 1) {
7029 BWN_PHY_SET(mac, 0x0814, 0x0001);
7030 BWN_PHY_MASK(mac, 0x0815, 0xfffe);
7032 BWN_PHY_SET(mac, 0x0811, 0x000c);
7033 BWN_PHY_SET(mac, 0x0812, 0x000c);
7034 BWN_PHY_SET(mac, 0x0811, 0x0030);
7035 BWN_PHY_SET(mac, 0x0812, 0x0030);
7036 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
7037 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
7038 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
7040 BWN_PHY_WRITE(mac, 0x0003, 0x0122);
7042 BWN_PHY_SET(mac, 0x000a, 0x2000);
7043 if (phy->rev != 1) {
7044 BWN_PHY_SET(mac, 0x0814, 0x0004);
7045 BWN_PHY_MASK(mac, 0x0815, 0xfffb);
7047 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
7048 BWN_RF_SET(mac, 0x007a, 0x000f);
7049 bwn_set_all_gains(mac, 3, 0, 1);
7050 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
7052 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7056 for (i = 0; i < 4; i++) {
7057 BWN_RF_WRITE(mac, 0x007b, i);
7059 nrssi = (int16_t)((BWN_PHY_READ(mac,
7060 0x047f) >> 8) & 0x003f);
7063 if (nrssi > -31 && saved == 0xffff)
7066 if (saved == 0xffff)
7071 BWN_RF_WRITE(mac, 0x007b, saved);
7074 * Restore saved RF/PHY registers
7076 if (phy->rev >= 6) {
7077 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
7078 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7079 save_phy6[phy6_idx]);
7082 if (phy->rev != 1) {
7083 for (i = 3; i < 5; i++)
7084 BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
7087 for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
7088 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
7090 for (i = SAVE_RF_MAX - 1; i >= 0; --i)
7091 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
7093 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
7094 BWN_PHY_SET(mac, 0x0429, 0x8000);
7095 bwn_set_original_gains(mac);
7096 if (phy->rev >= 6) {
7097 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
7098 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7099 save_phy6[phy6_idx]);
7103 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7104 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7105 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7109 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7112 struct bwn_phy *phy = &mac->mac_phy;
7114 uint16_t start = 0x08, end = 0x18;
7118 if (phy->rev <= 1) {
7123 table = BWN_OFDMTAB_GAINX;
7125 table = BWN_OFDMTAB_GAINX_R1;
7126 for (i = 0; i < 4; i++)
7127 bwn_ofdmtab_write_2(mac, table, i, first);
7129 for (i = start; i < end; i++)
7130 bwn_ofdmtab_write_2(mac, table, i, second);
7133 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7134 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7135 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7136 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7138 bwn_dummy_transmission(mac, 0, 1);
7142 bwn_set_original_gains(struct bwn_mac *mac)
7144 struct bwn_phy *phy = &mac->mac_phy;
7147 uint16_t start = 0x0008, end = 0x0018;
7149 if (phy->rev <= 1) {
7154 table = BWN_OFDMTAB_GAINX;
7156 table = BWN_OFDMTAB_GAINX_R1;
7157 for (i = 0; i < 4; i++) {
7159 tmp |= (i & 0x0001) << 1;
7160 tmp |= (i & 0x0002) >> 1;
7162 bwn_ofdmtab_write_2(mac, table, i, tmp);
7165 for (i = start; i < end; i++)
7166 bwn_ofdmtab_write_2(mac, table, i, i - start);
7168 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7169 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7170 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7171 bwn_dummy_transmission(mac, 0, 1);
7175 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7177 struct bwn_phy *phy = &mac->mac_phy;
7178 struct bwn_phy_g *pg = &phy->phy_g;
7179 struct bwn_rfatt old_rfatt, rfatt;
7180 struct bwn_bbatt old_bbatt, bbatt;
7181 struct bwn_softc *sc = mac->mac_sc;
7182 uint8_t old_txctl = 0;
7184 KASSERT(phy->type == BWN_PHYTYPE_G,
7185 ("%s:%d: fail", __func__, __LINE__));
7187 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7188 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7191 BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7193 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7197 bwn_hwpctl_early_init(mac);
7198 if (pg->pg_curtssi == 0) {
7199 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7200 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7202 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7203 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7204 old_txctl = pg->pg_txctl;
7207 if (phy->rf_rev == 8) {
7214 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7216 bwn_dummy_transmission(mac, 0, 1);
7217 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7218 if (phy->rf_ver == 0x2050 && phy->analog == 0)
7219 BWN_RF_MASK(mac, 0x0076, 0xff7b);
7221 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7222 &old_rfatt, old_txctl);
7224 bwn_hwpctl_init_gphy(mac);
7227 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7228 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7229 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7230 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7234 bwn_hwpctl_early_init(struct bwn_mac *mac)
7236 struct bwn_phy *phy = &mac->mac_phy;
7238 if (!bwn_has_hwpctl(mac)) {
7239 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7243 BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7244 BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7245 BWN_PHY_SET(mac, 0x047c, 0x0002);
7246 BWN_PHY_SET(mac, 0x047a, 0xf000);
7247 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7248 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7249 BWN_PHY_SET(mac, 0x005d, 0x8000);
7250 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7251 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7252 BWN_PHY_SET(mac, 0x0036, 0x0400);
7254 BWN_PHY_SET(mac, 0x0036, 0x0200);
7255 BWN_PHY_SET(mac, 0x0036, 0x0400);
7256 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7257 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7258 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7259 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7260 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7265 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7267 struct bwn_phy *phy = &mac->mac_phy;
7268 struct bwn_phy_g *pg = &phy->phy_g;
7269 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7271 uint16_t nr_written = 0, tmp, value;
7274 if (!bwn_has_hwpctl(mac)) {
7275 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7279 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7280 (pg->pg_idletssi - pg->pg_curtssi));
7281 BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7282 (pg->pg_idletssi - pg->pg_curtssi));
7284 for (i = 0; i < 32; i++)
7285 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7286 for (i = 32; i < 64; i++)
7287 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7288 for (i = 0; i < 64; i += 2) {
7289 value = (uint16_t) pg->pg_tssi2dbm[i];
7290 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7291 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7294 for (rf = 0; rf < lo->rfatt.len; rf++) {
7295 for (bb = 0; bb < lo->bbatt.len; bb++) {
7296 if (nr_written >= 0x40)
7298 tmp = lo->bbatt.array[bb].att;
7300 if (phy->rf_rev == 8)
7304 tmp |= lo->rfatt.array[rf].att;
7305 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7310 BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7311 BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7313 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7314 BWN_PHY_SET(mac, 0x0478, 0x0800);
7315 BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7316 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7318 bwn_phy_g_dc_lookup_init(mac, 1);
7319 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7323 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7325 struct bwn_softc *sc = mac->mac_sc;
7328 bwn_spu_workaround(mac, channel);
7330 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7332 if (channel == 14) {
7333 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7335 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7338 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7339 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7340 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7344 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7345 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7349 bwn_phy_g_chan2freq(uint8_t channel)
7351 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7353 KASSERT(channel >= 1 && channel <= 14,
7354 ("%s:%d: fail", __func__, __LINE__));
7356 return (bwn_phy_g_rf_channels[channel - 1]);
7360 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7361 const struct bwn_rfatt *rfatt, uint8_t txctl)
7363 struct bwn_phy *phy = &mac->mac_phy;
7364 struct bwn_phy_g *pg = &phy->phy_g;
7365 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7367 uint16_t tx_bias, tx_magn;
7371 tx_bias = lo->tx_bias;
7372 tx_magn = lo->tx_magn;
7373 if (tx_bias == 0xff)
7376 pg->pg_txctl = txctl;
7377 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7378 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7379 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7380 bwn_phy_g_set_bbatt(mac, bb);
7381 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7382 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7383 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7385 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7386 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7388 if (BWN_HAS_TXMAG(phy))
7389 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7391 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7392 bwn_lo_g_adjust(mac);
7396 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7399 struct bwn_phy *phy = &mac->mac_phy;
7401 if (phy->analog == 0) {
7402 BWN_WRITE_2(mac, BWN_PHY0,
7403 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7406 if (phy->analog > 1) {
7407 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7410 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7414 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7416 struct bwn_phy *phy = &mac->mac_phy;
7417 struct bwn_phy_g *pg = &phy->phy_g;
7418 struct bwn_softc *sc = mac->mac_sc;
7423 if (phy->gmode == 0)
7426 if (BWN_HAS_LOOPBACK(phy)) {
7427 max_lb_gain = pg->pg_max_lb_gain;
7428 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7429 if (max_lb_gain >= 0x46) {
7431 max_lb_gain -= 0x46;
7432 } else if (max_lb_gain >= 0x3a) {
7434 max_lb_gain -= 0x3a;
7435 } else if (max_lb_gain >= 0x2e) {
7437 max_lb_gain -= 0x2e;
7440 max_lb_gain -= 0x10;
7443 for (i = 0; i < 16; i++) {
7444 max_lb_gain -= (i * 6);
7445 if (max_lb_gain < 6)
7449 if ((phy->rev < 7) ||
7450 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7451 if (reg == BWN_PHY_RFOVER) {
7453 } else if (reg == BWN_PHY_RFOVERVAL) {
7456 case BWN_LPD(0, 1, 1):
7458 case BWN_LPD(0, 0, 1):
7459 case BWN_LPD(1, 0, 1):
7460 return (0x0092 | extlna);
7461 case BWN_LPD(1, 0, 0):
7462 return (0x0093 | extlna);
7465 ("%s:%d: fail", __func__, __LINE__));
7467 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7469 if (reg == BWN_PHY_RFOVER)
7471 if (reg == BWN_PHY_RFOVERVAL) {
7476 case BWN_LPD(0, 1, 1):
7478 case BWN_LPD(0, 0, 1):
7479 return (0x8092 | extlna);
7480 case BWN_LPD(1, 0, 1):
7481 return (0x2092 | extlna);
7482 case BWN_LPD(1, 0, 0):
7483 return (0x2093 | extlna);
7486 ("%s:%d: fail", __func__, __LINE__));
7488 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7493 if ((phy->rev < 7) ||
7494 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7495 if (reg == BWN_PHY_RFOVER) {
7497 } else if (reg == BWN_PHY_RFOVERVAL) {
7499 case BWN_LPD(0, 1, 1):
7501 case BWN_LPD(0, 0, 1):
7503 case BWN_LPD(1, 0, 1):
7505 case BWN_LPD(1, 0, 0):
7509 ("%s:%d: fail", __func__, __LINE__));
7511 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7513 if (reg == BWN_PHY_RFOVER) {
7515 } else if (reg == BWN_PHY_RFOVERVAL) {
7517 case BWN_LPD(0, 1, 1):
7519 case BWN_LPD(0, 0, 1):
7521 case BWN_LPD(1, 0, 1):
7523 case BWN_LPD(1, 0, 0):
7527 ("%s:%d: fail", __func__, __LINE__));
7529 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7535 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7538 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7540 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7541 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7543 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7547 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7549 struct bwn_softc *sc = mac->mac_sc;
7550 struct bwn_fw *fw = &mac->mac_fw;
7551 const uint8_t rev = siba_get_revid(sc->sc_dev);
7552 const char *filename;
7557 if (rev >= 5 && rev <= 10)
7558 filename = "ucode5";
7559 else if (rev >= 11 && rev <= 12)
7560 filename = "ucode11";
7562 filename = "ucode13";
7564 filename = "ucode14";
7566 filename = "ucode15";
7568 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7569 bwn_release_firmware(mac);
7570 return (EOPNOTSUPP);
7572 error = bwn_fw_get(mac, type, filename, &fw->ucode);
7574 bwn_release_firmware(mac);
7579 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7580 if (rev >= 5 && rev <= 10) {
7581 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7582 if (error == ENOENT)
7585 bwn_release_firmware(mac);
7588 } else if (rev < 11) {
7589 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7590 return (EOPNOTSUPP);
7594 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7595 switch (mac->mac_phy.type) {
7597 if (rev < 5 || rev > 10)
7599 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7600 filename = "a0g1initvals5";
7602 filename = "a0g0initvals5";
7605 if (rev >= 5 && rev <= 10)
7606 filename = "b0g0initvals5";
7608 filename = "b0g0initvals13";
7612 case BWN_PHYTYPE_LP:
7614 filename = "lp0initvals13";
7616 filename = "lp0initvals14";
7618 filename = "lp0initvals15";
7623 if (rev >= 11 && rev <= 12)
7624 filename = "n0initvals11";
7631 error = bwn_fw_get(mac, type, filename, &fw->initvals);
7633 bwn_release_firmware(mac);
7637 /* bandswitch initvals */
7638 switch (mac->mac_phy.type) {
7640 if (rev >= 5 && rev <= 10) {
7641 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7642 filename = "a0g1bsinitvals5";
7644 filename = "a0g0bsinitvals5";
7645 } else if (rev >= 11)
7651 if (rev >= 5 && rev <= 10)
7652 filename = "b0g0bsinitvals5";
7658 case BWN_PHYTYPE_LP:
7660 filename = "lp0bsinitvals13";
7662 filename = "lp0bsinitvals14";
7664 filename = "lp0bsinitvals15";
7669 if (rev >= 11 && rev <= 12)
7670 filename = "n0bsinitvals11";
7677 error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7679 bwn_release_firmware(mac);
7684 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7685 bwn_release_firmware(mac);
7686 return (EOPNOTSUPP);
7690 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7691 const char *name, struct bwn_fwfile *bfw)
7693 const struct bwn_fwhdr *hdr;
7694 struct bwn_softc *sc = mac->mac_sc;
7695 const struct firmware *fw;
7699 bwn_do_release_fw(bfw);
7702 if (bfw->filename != NULL) {
7703 if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7705 bwn_do_release_fw(bfw);
7708 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7709 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7710 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7711 /* XXX Sleeping on "fwload" with the non-sleepable locks held */
7712 fw = firmware_get(namebuf);
7714 device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7718 if (fw->datasize < sizeof(struct bwn_fwhdr))
7720 hdr = (const struct bwn_fwhdr *)(fw->data);
7721 switch (hdr->type) {
7722 case BWN_FWTYPE_UCODE:
7723 case BWN_FWTYPE_PCM:
7724 if (be32toh(hdr->size) !=
7725 (fw->datasize - sizeof(struct bwn_fwhdr)))
7735 bfw->filename = name;
7740 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7742 firmware_put(fw, FIRMWARE_UNLOAD);
7747 bwn_release_firmware(struct bwn_mac *mac)
7750 bwn_do_release_fw(&mac->mac_fw.ucode);
7751 bwn_do_release_fw(&mac->mac_fw.pcm);
7752 bwn_do_release_fw(&mac->mac_fw.initvals);
7753 bwn_do_release_fw(&mac->mac_fw.initvals_band);
7757 bwn_do_release_fw(struct bwn_fwfile *bfw)
7760 if (bfw->fw != NULL)
7761 firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7763 bfw->filename = NULL;
7767 bwn_fw_loaducode(struct bwn_mac *mac)
7769 #define GETFWOFFSET(fwp, offset) \
7770 ((const uint32_t *)((const char *)fwp.fw->data + offset))
7771 #define GETFWSIZE(fwp, offset) \
7772 ((fwp.fw->datasize - offset) / sizeof(uint32_t))
7773 struct bwn_softc *sc = mac->mac_sc;
7774 const uint32_t *data;
7777 uint16_t date, fwcaps, time;
7780 ctl = BWN_READ_4(mac, BWN_MACCTL);
7781 ctl |= BWN_MACCTL_MCODE_JMP0;
7782 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7784 BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7785 for (i = 0; i < 64; i++)
7786 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7787 for (i = 0; i < 4096; i += 2)
7788 bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7790 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7791 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7792 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7794 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7798 if (mac->mac_fw.pcm.fw) {
7799 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7800 bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7801 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7802 bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7803 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7804 sizeof(struct bwn_fwhdr)); i++) {
7805 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7810 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7811 BWN_WRITE_4(mac, BWN_MACCTL,
7812 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7813 BWN_MACCTL_MCODE_RUN);
7815 for (i = 0; i < 21; i++) {
7816 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7819 device_printf(sc->sc_dev, "ucode timeout\n");
7825 BWN_READ_4(mac, BWN_INTR_REASON);
7827 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7828 if (mac->mac_fw.rev <= 0x128) {
7829 device_printf(sc->sc_dev, "the firmware is too old\n");
7833 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7834 BWN_SHARED_UCODE_PATCH);
7835 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7836 mac->mac_fw.opensource = (date == 0xffff);
7838 mac->mac_flags |= BWN_MAC_FLAG_WME;
7839 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7841 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7842 if (mac->mac_fw.opensource == 0) {
7843 device_printf(sc->sc_dev,
7844 "firmware version (rev %u patch %u date %#x time %#x)\n",
7845 mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7846 if (mac->mac_fw.no_pcmfile)
7847 device_printf(sc->sc_dev,
7848 "no HW crypto acceleration due to pcm5\n");
7850 mac->mac_fw.patch = time;
7851 fwcaps = bwn_fwcaps_read(mac);
7852 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7853 device_printf(sc->sc_dev,
7854 "disabling HW crypto acceleration\n");
7855 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7857 if (!(fwcaps & BWN_FWCAPS_WME)) {
7858 device_printf(sc->sc_dev, "disabling WME support\n");
7859 mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7863 if (BWN_ISOLDFMT(mac))
7864 device_printf(sc->sc_dev, "using old firmware image\n");
7869 BWN_WRITE_4(mac, BWN_MACCTL,
7870 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7871 BWN_MACCTL_MCODE_JMP0);
7878 /* OpenFirmware only */
7880 bwn_fwcaps_read(struct bwn_mac *mac)
7883 KASSERT(mac->mac_fw.opensource == 1,
7884 ("%s:%d: fail", __func__, __LINE__));
7885 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7889 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7890 size_t count, size_t array_size)
7892 #define GET_NEXTIV16(iv) \
7893 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \
7894 sizeof(uint16_t) + sizeof(uint16_t)))
7895 #define GET_NEXTIV32(iv) \
7896 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \
7897 sizeof(uint16_t) + sizeof(uint32_t)))
7898 struct bwn_softc *sc = mac->mac_sc;
7899 const struct bwn_fwinitvals *iv;
7904 KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7905 ("%s:%d: fail", __func__, __LINE__));
7907 for (i = 0; i < count; i++) {
7908 if (array_size < sizeof(iv->offset_size))
7910 array_size -= sizeof(iv->offset_size);
7911 offset = be16toh(iv->offset_size);
7912 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7913 offset &= BWN_FWINITVALS_OFFSET_MASK;
7914 if (offset >= 0x1000)
7917 if (array_size < sizeof(iv->data.d32))
7919 array_size -= sizeof(iv->data.d32);
7920 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7921 iv = GET_NEXTIV32(iv);
7924 if (array_size < sizeof(iv->data.d16))
7926 array_size -= sizeof(iv->data.d16);
7927 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7929 iv = GET_NEXTIV16(iv);
7932 if (array_size != 0)
7936 device_printf(sc->sc_dev, "initvals: invalid format\n");
7943 bwn_switch_channel(struct bwn_mac *mac, int chan)
7945 struct bwn_phy *phy = &(mac->mac_phy);
7946 struct bwn_softc *sc = mac->mac_sc;
7947 struct ifnet *ifp = sc->sc_ifp;
7948 struct ieee80211com *ic = ifp->if_l2com;
7949 uint16_t channelcookie, savedcookie;
7953 chan = phy->get_default_chan(mac);
7955 channelcookie = chan;
7956 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
7957 channelcookie |= 0x100;
7958 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
7959 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
7960 error = phy->switch_channel(mac, chan);
7964 mac->mac_phy.chan = chan;
7968 device_printf(sc->sc_dev, "failed to switch channel\n");
7969 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
7974 bwn_ant2phy(int antenna)
7979 return (BWN_TX_PHY_ANT0);
7981 return (BWN_TX_PHY_ANT1);
7983 return (BWN_TX_PHY_ANT2);
7985 return (BWN_TX_PHY_ANT3);
7987 return (BWN_TX_PHY_ANT01AUTO);
7989 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7994 bwn_wme_load(struct bwn_mac *mac)
7996 struct bwn_softc *sc = mac->mac_sc;
7999 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
8000 ("%s:%d: fail", __func__, __LINE__));
8002 bwn_mac_suspend(mac);
8003 for (i = 0; i < N(sc->sc_wmeParams); i++)
8004 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
8005 bwn_wme_shm_offsets[i]);
8006 bwn_mac_enable(mac);
8010 bwn_wme_loadparams(struct bwn_mac *mac,
8011 const struct wmeParams *p, uint16_t shm_offset)
8013 #define SM(_v, _f) (((_v) << _f##_S) & _f)
8014 struct bwn_softc *sc = mac->mac_sc;
8015 uint16_t params[BWN_NR_WMEPARAMS];
8019 slot = BWN_READ_2(mac, BWN_RNG) &
8020 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8022 memset(¶ms, 0, sizeof(params));
8024 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
8025 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
8026 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
8028 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
8029 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8030 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
8031 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8032 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
8033 params[BWN_WMEPARAM_BSLOTS] = slot;
8034 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
8036 for (i = 0; i < N(params); i++) {
8037 if (i == BWN_WMEPARAM_STATUS) {
8038 tmp = bwn_shm_read_2(mac, BWN_SHARED,
8039 shm_offset + (i * 2));
8041 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8044 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8051 bwn_mac_write_bssid(struct bwn_mac *mac)
8053 struct bwn_softc *sc = mac->mac_sc;
8056 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
8058 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
8059 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
8060 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
8061 IEEE80211_ADDR_LEN);
8063 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
8064 tmp = (uint32_t) (mac_bssid[i + 0]);
8065 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
8066 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
8067 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
8068 bwn_ram_write(mac, 0x20 + i, tmp);
8073 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
8074 const uint8_t *macaddr)
8076 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
8083 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
8086 data |= macaddr[1] << 8;
8087 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8089 data |= macaddr[3] << 8;
8090 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8092 data |= macaddr[5] << 8;
8093 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8097 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8098 const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
8100 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
8101 uint8_t per_sta_keys_start = 8;
8103 if (BWN_SEC_NEWAPI(mac))
8104 per_sta_keys_start = 4;
8106 KASSERT(index < mac->mac_max_nr_keys,
8107 ("%s:%d: fail", __func__, __LINE__));
8108 KASSERT(key_len <= BWN_SEC_KEYSIZE,
8109 ("%s:%d: fail", __func__, __LINE__));
8111 if (index >= per_sta_keys_start)
8112 bwn_key_macwrite(mac, index, NULL);
8114 memcpy(buf, key, key_len);
8115 bwn_key_write(mac, index, algorithm, buf);
8116 if (index >= per_sta_keys_start)
8117 bwn_key_macwrite(mac, index, mac_addr);
8119 mac->mac_key[index].algorithm = algorithm;
8123 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8125 struct bwn_softc *sc = mac->mac_sc;
8126 uint32_t addrtmp[2] = { 0, 0 };
8129 if (BWN_SEC_NEWAPI(mac))
8132 KASSERT(index >= start,
8133 ("%s:%d: fail", __func__, __LINE__));
8137 addrtmp[0] = addr[0];
8138 addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8139 addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8140 addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8141 addrtmp[1] = addr[4];
8142 addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8145 if (siba_get_revid(sc->sc_dev) >= 5) {
8146 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8147 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8150 bwn_shm_write_4(mac, BWN_SHARED,
8151 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8152 bwn_shm_write_2(mac, BWN_SHARED,
8153 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8159 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8164 uint16_t kidx, value;
8166 kidx = BWN_SEC_KEY2FW(mac, index);
8167 bwn_shm_write_2(mac, BWN_SHARED,
8168 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8170 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8171 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8173 value |= (uint16_t)(key[i + 1]) << 8;
8174 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8179 bwn_phy_exit(struct bwn_mac *mac)
8182 mac->mac_phy.rf_onoff(mac, 0);
8183 if (mac->mac_phy.exit != NULL)
8184 mac->mac_phy.exit(mac);
8188 bwn_dma_free(struct bwn_mac *mac)
8190 struct bwn_dma *dma;
8192 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8194 dma = &mac->mac_method.dma;
8196 bwn_dma_ringfree(&dma->rx);
8197 bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8198 bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8199 bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8200 bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8201 bwn_dma_ringfree(&dma->mcast);
8205 bwn_core_stop(struct bwn_mac *mac)
8207 struct bwn_softc *sc = mac->mac_sc;
8209 BWN_ASSERT_LOCKED(sc);
8211 if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8214 callout_stop(&sc->sc_rfswitch_ch);
8215 callout_stop(&sc->sc_task_ch);
8216 callout_stop(&sc->sc_watchdog_ch);
8217 sc->sc_watchdog_timer = 0;
8218 BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8219 BWN_READ_4(mac, BWN_INTR_MASK);
8220 bwn_mac_suspend(mac);
8222 mac->mac_status = BWN_MAC_STATUS_INITED;
8226 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8228 struct bwn_mac *up_dev = NULL;
8229 struct bwn_mac *down_dev;
8230 struct bwn_mac *mac;
8234 BWN_ASSERT_LOCKED(sc);
8236 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8237 if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8238 mac->mac_phy.supports_2ghz) {
8241 } else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8242 mac->mac_phy.supports_5ghz) {
8246 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8252 if (up_dev == NULL) {
8253 device_printf(sc->sc_dev, "Could not find a device\n");
8256 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8259 device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8260 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8262 down_dev = sc->sc_curmac;
8263 status = down_dev->mac_status;
8264 if (status >= BWN_MAC_STATUS_STARTED)
8265 bwn_core_stop(down_dev);
8266 if (status >= BWN_MAC_STATUS_INITED)
8267 bwn_core_exit(down_dev);
8269 if (down_dev != up_dev)
8270 bwn_phy_reset(down_dev);
8272 up_dev->mac_phy.gmode = gmode;
8273 if (status >= BWN_MAC_STATUS_INITED) {
8274 err = bwn_core_init(up_dev);
8276 device_printf(sc->sc_dev,
8277 "fatal: failed to initialize for %s-GHz\n",
8278 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8282 if (status >= BWN_MAC_STATUS_STARTED)
8283 bwn_core_start(up_dev);
8284 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8285 sc->sc_curmac = up_dev;
8289 sc->sc_curmac = NULL;
8294 bwn_rf_turnon(struct bwn_mac *mac)
8297 bwn_mac_suspend(mac);
8298 mac->mac_phy.rf_onoff(mac, 1);
8299 mac->mac_phy.rf_on = 1;
8300 bwn_mac_enable(mac);
8304 bwn_rf_turnoff(struct bwn_mac *mac)
8307 bwn_mac_suspend(mac);
8308 mac->mac_phy.rf_onoff(mac, 0);
8309 mac->mac_phy.rf_on = 0;
8310 bwn_mac_enable(mac);
8314 bwn_phy_reset(struct bwn_mac *mac)
8316 struct bwn_softc *sc = mac->mac_sc;
8318 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8319 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8320 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8322 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8323 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8324 BWN_TGSLOW_PHYRESET);
8329 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8331 struct bwn_vap *bvp = BWN_VAP(vap);
8332 struct ieee80211com *ic= vap->iv_ic;
8333 struct ifnet *ifp = ic->ic_ifp;
8334 enum ieee80211_state ostate = vap->iv_state;
8335 struct bwn_softc *sc = ifp->if_softc;
8336 struct bwn_mac *mac = sc->sc_curmac;
8339 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8340 ieee80211_state_name[vap->iv_state],
8341 ieee80211_state_name[nstate]);
8343 error = bvp->bv_newstate(vap, nstate, arg);
8349 bwn_led_newstate(mac, nstate);
8352 * Clear the BSSID when we stop a STA
8354 if (vap->iv_opmode == IEEE80211_M_STA) {
8355 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8357 * Clear out the BSSID. If we reassociate to
8358 * the same AP, this will reinialize things
8361 if (ic->ic_opmode == IEEE80211_M_STA &&
8362 (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8363 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8364 bwn_set_macaddr(mac);
8369 if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8370 vap->iv_opmode == IEEE80211_M_AHDEMO) {
8371 /* XXX nothing to do? */
8372 } else if (nstate == IEEE80211_S_RUN) {
8373 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8374 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
8375 bwn_set_opmode(mac);
8376 bwn_set_pretbtt(mac);
8377 bwn_spu_setdelay(mac, 0);
8378 bwn_set_macaddr(mac);
8387 bwn_set_pretbtt(struct bwn_mac *mac)
8389 struct bwn_softc *sc = mac->mac_sc;
8390 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8393 if (ic->ic_opmode == IEEE80211_M_IBSS)
8396 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8397 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8398 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8404 struct bwn_mac *mac = arg;
8405 struct bwn_softc *sc = mac->mac_sc;
8408 if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8409 (sc->sc_flags & BWN_FLAG_INVALID))
8410 return (FILTER_STRAY);
8412 reason = BWN_READ_4(mac, BWN_INTR_REASON);
8413 if (reason == 0xffffffff) /* shared IRQ */
8414 return (FILTER_STRAY);
8415 reason &= mac->mac_intr_mask;
8417 return (FILTER_HANDLED);
8419 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
8420 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8421 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8422 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8423 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8424 BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8425 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8426 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8427 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8428 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8429 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8431 /* Disable interrupts. */
8432 BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8434 mac->mac_reason_intr = reason;
8436 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8437 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8439 taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask);
8440 return (FILTER_HANDLED);
8444 bwn_intrtask(void *arg, int npending)
8446 struct bwn_mac *mac = arg;
8447 struct bwn_softc *sc = mac->mac_sc;
8448 struct ifnet *ifp = sc->sc_ifp;
8449 uint32_t merged = 0;
8450 int i, tx = 0, rx = 0;
8453 if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8454 (sc->sc_flags & BWN_FLAG_INVALID)) {
8459 for (i = 0; i < N(mac->mac_reason); i++)
8460 merged |= mac->mac_reason[i];
8462 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8463 device_printf(sc->sc_dev, "MAC trans error\n");
8465 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8466 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8467 mac->mac_phy.txerrors--;
8468 if (mac->mac_phy.txerrors == 0) {
8469 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8470 bwn_restart(mac, "PHY TX errors");
8474 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
8475 if (merged & BWN_DMAINTR_FATALMASK) {
8476 device_printf(sc->sc_dev,
8477 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8478 mac->mac_reason[0], mac->mac_reason[1],
8479 mac->mac_reason[2], mac->mac_reason[3],
8480 mac->mac_reason[4], mac->mac_reason[5]);
8481 bwn_restart(mac, "DMA error");
8485 if (merged & BWN_DMAINTR_NONFATALMASK) {
8486 device_printf(sc->sc_dev,
8487 "DMA error: %#x %#x %#x %#x %#x %#x\n",
8488 mac->mac_reason[0], mac->mac_reason[1],
8489 mac->mac_reason[2], mac->mac_reason[3],
8490 mac->mac_reason[4], mac->mac_reason[5]);
8494 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8495 bwn_intr_ucode_debug(mac);
8496 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8497 bwn_intr_tbtt_indication(mac);
8498 if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8499 bwn_intr_atim_end(mac);
8500 if (mac->mac_reason_intr & BWN_INTR_BEACON)
8501 bwn_intr_beacon(mac);
8502 if (mac->mac_reason_intr & BWN_INTR_PMQ)
8504 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8505 bwn_intr_noise(mac);
8507 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8508 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8509 bwn_dma_rx(mac->mac_method.dma.rx);
8513 rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8515 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8516 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8517 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8518 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8519 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8521 if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8522 bwn_intr_txeof(mac);
8526 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8528 if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8529 int evt = BWN_LED_EVENT_NONE;
8532 if (sc->sc_rx_rate > sc->sc_tx_rate)
8533 evt = BWN_LED_EVENT_RX;
8535 evt = BWN_LED_EVENT_TX;
8537 evt = BWN_LED_EVENT_TX;
8539 evt = BWN_LED_EVENT_RX;
8540 } else if (rx == 0) {
8541 evt = BWN_LED_EVENT_POLL;
8544 if (evt != BWN_LED_EVENT_NONE)
8545 bwn_led_event(mac, evt);
8548 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
8549 if (!IFQ_IS_EMPTY(&ifp->if_snd))
8550 bwn_start_locked(ifp);
8553 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8554 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8560 bwn_restart(struct bwn_mac *mac, const char *msg)
8562 struct bwn_softc *sc = mac->mac_sc;
8563 struct ifnet *ifp = sc->sc_ifp;
8564 struct ieee80211com *ic = ifp->if_l2com;
8566 if (mac->mac_status < BWN_MAC_STATUS_INITED)
8569 device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8570 ieee80211_runtask(ic, &mac->mac_hwreset);
8574 bwn_intr_ucode_debug(struct bwn_mac *mac)
8576 struct bwn_softc *sc = mac->mac_sc;
8579 if (mac->mac_fw.opensource == 0)
8582 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8584 case BWN_DEBUGINTR_PANIC:
8585 bwn_handle_fwpanic(mac);
8587 case BWN_DEBUGINTR_DUMP_SHM:
8588 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8590 case BWN_DEBUGINTR_DUMP_REGS:
8591 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8593 case BWN_DEBUGINTR_MARKER:
8594 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8597 device_printf(sc->sc_dev,
8598 "ucode debug unknown reason: %#x\n", reason);
8601 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8606 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8608 struct bwn_softc *sc = mac->mac_sc;
8609 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8611 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8613 if (ic->ic_opmode == IEEE80211_M_IBSS)
8614 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8618 bwn_intr_atim_end(struct bwn_mac *mac)
8621 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8622 BWN_WRITE_4(mac, BWN_MACCMD,
8623 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8624 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8629 bwn_intr_beacon(struct bwn_mac *mac)
8631 struct bwn_softc *sc = mac->mac_sc;
8632 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8633 uint32_t cmd, beacon0, beacon1;
8635 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8636 ic->ic_opmode == IEEE80211_M_MBSS)
8639 mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8641 cmd = BWN_READ_4(mac, BWN_MACCMD);
8642 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8643 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8645 if (beacon0 && beacon1) {
8646 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8647 mac->mac_intr_mask |= BWN_INTR_BEACON;
8651 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8652 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8653 bwn_load_beacon0(mac);
8654 bwn_load_beacon1(mac);
8655 cmd = BWN_READ_4(mac, BWN_MACCMD);
8656 cmd |= BWN_MACCMD_BEACON0_VALID;
8657 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8660 bwn_load_beacon0(mac);
8661 cmd = BWN_READ_4(mac, BWN_MACCMD);
8662 cmd |= BWN_MACCMD_BEACON0_VALID;
8663 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8664 } else if (!beacon1) {
8665 bwn_load_beacon1(mac);
8666 cmd = BWN_READ_4(mac, BWN_MACCMD);
8667 cmd |= BWN_MACCMD_BEACON1_VALID;
8668 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8674 bwn_intr_pmq(struct bwn_mac *mac)
8679 tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8680 if (!(tmp & 0x00000008))
8683 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8687 bwn_intr_noise(struct bwn_mac *mac)
8689 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8695 if (mac->mac_phy.type != BWN_PHYTYPE_G)
8698 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8699 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8700 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8704 KASSERT(mac->mac_noise.noi_nsamples < 8,
8705 ("%s:%d: fail", __func__, __LINE__));
8706 i = mac->mac_noise.noi_nsamples;
8707 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8708 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8709 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8710 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8711 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8712 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8713 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8714 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8715 mac->mac_noise.noi_nsamples++;
8716 if (mac->mac_noise.noi_nsamples == 8) {
8718 for (i = 0; i < 8; i++) {
8719 for (j = 0; j < 4; j++)
8720 average += mac->mac_noise.noi_samples[i][j];
8722 average = (((average / 32) * 125) + 64) / 128;
8723 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8728 average -= (tmp == 8) ? 72 : 48;
8730 mac->mac_stats.link_noise = average;
8731 mac->mac_noise.noi_running = 0;
8735 bwn_noise_gensample(mac);
8739 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8741 struct bwn_mac *mac = prq->prq_mac;
8742 struct bwn_softc *sc = mac->mac_sc;
8745 BWN_ASSERT_LOCKED(sc);
8747 if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8750 for (i = 0; i < 5000; i++) {
8751 if (bwn_pio_rxeof(prq) == 0)
8755 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8756 return ((i > 0) ? 1 : 0);
8760 bwn_dma_rx(struct bwn_dma_ring *dr)
8764 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8765 curslot = dr->get_curslot(dr);
8766 KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8767 ("%s:%d: fail", __func__, __LINE__));
8769 slot = dr->dr_curslot;
8770 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8771 bwn_dma_rxeof(dr, &slot);
8773 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8774 BUS_DMASYNC_PREWRITE);
8776 dr->set_curslot(dr, slot);
8777 dr->dr_curslot = slot;
8781 bwn_intr_txeof(struct bwn_mac *mac)
8783 struct bwn_txstatus stat;
8784 uint32_t stat0, stat1;
8787 BWN_ASSERT_LOCKED(mac->mac_sc);
8790 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8791 if (!(stat0 & 0x00000001))
8793 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8795 stat.cookie = (stat0 >> 16);
8796 stat.seq = (stat1 & 0x0000ffff);
8797 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8798 tmp = (stat0 & 0x0000ffff);
8799 stat.framecnt = ((tmp & 0xf000) >> 12);
8800 stat.rtscnt = ((tmp & 0x0f00) >> 8);
8801 stat.sreason = ((tmp & 0x001c) >> 2);
8802 stat.pm = (tmp & 0x0080) ? 1 : 0;
8803 stat.im = (tmp & 0x0040) ? 1 : 0;
8804 stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8805 stat.ack = (tmp & 0x0002) ? 1 : 0;
8807 bwn_handle_txeof(mac, &stat);
8812 bwn_hwreset(void *arg, int npending)
8814 struct bwn_mac *mac = arg;
8815 struct bwn_softc *sc = mac->mac_sc;
8821 prev_status = mac->mac_status;
8822 if (prev_status >= BWN_MAC_STATUS_STARTED)
8824 if (prev_status >= BWN_MAC_STATUS_INITED)
8827 if (prev_status >= BWN_MAC_STATUS_INITED) {
8828 error = bwn_core_init(mac);
8832 if (prev_status >= BWN_MAC_STATUS_STARTED)
8833 bwn_core_start(mac);
8836 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8837 sc->sc_curmac = NULL;
8843 bwn_handle_fwpanic(struct bwn_mac *mac)
8845 struct bwn_softc *sc = mac->mac_sc;
8848 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8849 device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8851 if (reason == BWN_FWPANIC_RESTART)
8852 bwn_restart(mac, "ucode panic");
8856 bwn_load_beacon0(struct bwn_mac *mac)
8859 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8863 bwn_load_beacon1(struct bwn_mac *mac)
8866 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8870 bwn_jssi_read(struct bwn_mac *mac)
8874 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8876 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8882 bwn_noise_gensample(struct bwn_mac *mac)
8884 uint32_t jssi = 0x7f7f7f7f;
8886 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8887 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8888 BWN_WRITE_4(mac, BWN_MACCMD,
8889 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8893 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8895 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8897 return (dr->dr_numslots - dr->dr_usedslot);
8901 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8903 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8905 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8906 ("%s:%d: fail", __func__, __LINE__));
8907 if (slot == dr->dr_numslots - 1)
8913 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8915 struct bwn_mac *mac = dr->dr_mac;
8916 struct bwn_softc *sc = mac->mac_sc;
8917 struct bwn_dma *dma = &mac->mac_method.dma;
8918 struct bwn_dmadesc_generic *desc;
8919 struct bwn_dmadesc_meta *meta;
8920 struct bwn_rxhdr4 *rxhdr;
8921 struct ifnet *ifp = sc->sc_ifp;
8928 dr->getdesc(dr, *slot, &desc, &meta);
8930 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8933 if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8934 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
8938 rxhdr = mtod(m, struct bwn_rxhdr4 *);
8939 len = le16toh(rxhdr->frame_len);
8941 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
8944 if (bwn_dma_check_redzone(dr, m)) {
8945 device_printf(sc->sc_dev, "redzone error.\n");
8946 bwn_dma_set_redzone(dr, m);
8947 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8948 BUS_DMASYNC_PREWRITE);
8951 if (len > dr->dr_rx_bufsize) {
8954 dr->getdesc(dr, *slot, &desc, &meta);
8955 bwn_dma_set_redzone(dr, meta->mt_m);
8956 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8957 BUS_DMASYNC_PREWRITE);
8958 *slot = bwn_dma_nextslot(dr, *slot);
8960 tmp -= dr->dr_rx_bufsize;
8964 device_printf(sc->sc_dev, "too small buffer "
8965 "(len %u buffer %u dropped %d)\n",
8966 len, dr->dr_rx_bufsize, cnt);
8969 macstat = le32toh(rxhdr->mac_status);
8970 if (macstat & BWN_RX_MAC_FCSERR) {
8971 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8972 device_printf(sc->sc_dev, "RX drop\n");
8977 m->m_pkthdr.rcvif = ifp;
8978 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8979 m_adj(m, dr->dr_frameoffset);
8981 bwn_rxeof(dr->dr_mac, m, rxhdr);
8985 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8987 struct bwn_dma_ring *dr;
8988 struct bwn_dmadesc_generic *desc;
8989 struct bwn_dmadesc_meta *meta;
8990 struct bwn_pio_txqueue *tq;
8991 struct bwn_pio_txpkt *tp = NULL;
8992 struct bwn_softc *sc = mac->mac_sc;
8993 struct bwn_stats *stats = &mac->mac_stats;
8994 struct ieee80211_node *ni;
8995 struct ieee80211vap *vap;
8996 int retrycnt = 0, slot;
8998 BWN_ASSERT_LOCKED(mac->mac_sc);
9001 device_printf(sc->sc_dev, "TODO: STATUS IM\n");
9003 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
9004 if (status->rtscnt) {
9005 if (status->rtscnt == 0xf)
9011 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
9013 dr = bwn_dma_parse_cookie(mac, status,
9014 status->cookie, &slot);
9016 device_printf(sc->sc_dev,
9017 "failed to parse cookie\n");
9021 dr->getdesc(dr, slot, &desc, &meta);
9022 if (meta->mt_islast) {
9025 ieee80211_ratectl_tx_complete(vap, ni,
9027 IEEE80211_RATECTL_TX_SUCCESS :
9028 IEEE80211_RATECTL_TX_FAILURE,
9032 slot = bwn_dma_nextslot(dr, slot);
9035 bwn_dma_handle_txeof(mac, status);
9038 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9040 device_printf(sc->sc_dev,
9041 "failed to parse cookie\n");
9046 ieee80211_ratectl_tx_complete(vap, ni,
9048 IEEE80211_RATECTL_TX_SUCCESS :
9049 IEEE80211_RATECTL_TX_FAILURE,
9052 bwn_pio_handle_txeof(mac, status);
9055 bwn_phy_txpower_check(mac, 0);
9059 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
9061 struct bwn_mac *mac = prq->prq_mac;
9062 struct bwn_softc *sc = mac->mac_sc;
9063 struct bwn_rxhdr4 rxhdr;
9064 struct ifnet *ifp = sc->sc_ifp;
9066 uint32_t ctl32, macstat, v32;
9067 unsigned int i, padding;
9068 uint16_t ctl16, len, totlen, v16;
9072 memset(&rxhdr, 0, sizeof(rxhdr));
9074 if (prq->prq_rev >= 8) {
9075 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9076 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
9078 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9079 BWN_PIO8_RXCTL_FRAMEREADY);
9080 for (i = 0; i < 10; i++) {
9081 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9082 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
9087 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9088 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
9090 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
9091 BWN_PIO_RXCTL_FRAMEREADY);
9092 for (i = 0; i < 10; i++) {
9093 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9094 if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
9099 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
9102 if (prq->prq_rev >= 8)
9103 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9104 prq->prq_base + BWN_PIO8_RXDATA);
9106 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9107 prq->prq_base + BWN_PIO_RXDATA);
9108 len = le16toh(rxhdr.frame_len);
9110 device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9114 device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9118 macstat = le32toh(rxhdr.mac_status);
9119 if (macstat & BWN_RX_MAC_FCSERR) {
9120 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9121 device_printf(sc->sc_dev, "%s: FCS error", __func__);
9126 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9127 totlen = len + padding;
9128 KASSERT(totlen <= MCLBYTES, ("too big..\n"));
9129 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9131 device_printf(sc->sc_dev, "%s: out of memory", __func__);
9134 mp = mtod(m, unsigned char *);
9135 if (prq->prq_rev >= 8) {
9136 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3),
9137 prq->prq_base + BWN_PIO8_RXDATA);
9139 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9140 data = &(mp[totlen - 1]);
9141 switch (totlen & 3) {
9143 *data = (v32 >> 16);
9153 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1),
9154 prq->prq_base + BWN_PIO_RXDATA);
9156 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9157 mp[totlen - 1] = v16;
9161 m->m_pkthdr.rcvif = ifp;
9162 m->m_len = m->m_pkthdr.len = totlen;
9164 bwn_rxeof(prq->prq_mac, m, &rxhdr);
9168 if (prq->prq_rev >= 8)
9169 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9170 BWN_PIO8_RXCTL_DATAREADY);
9172 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9177 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9178 struct bwn_dmadesc_meta *meta, int init)
9180 struct bwn_mac *mac = dr->dr_mac;
9181 struct bwn_dma *dma = &mac->mac_method.dma;
9182 struct bwn_rxhdr4 *hdr;
9188 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9193 * If the NIC is up and running, we need to:
9194 * - Clear RX buffer's header.
9195 * - Restore RX descriptor settings.
9202 m->m_len = m->m_pkthdr.len = MCLBYTES;
9204 bwn_dma_set_redzone(dr, m);
9207 * Try to load RX buf into temporary DMA map
9209 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9210 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9215 * See the comment above
9224 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9226 meta->mt_paddr = paddr;
9229 * Swap RX buf's DMA map with the loaded temporary one
9231 map = meta->mt_dmap;
9232 meta->mt_dmap = dr->dr_spare_dmap;
9233 dr->dr_spare_dmap = map;
9237 * Clear RX buf header
9239 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9240 bzero(hdr, sizeof(*hdr));
9241 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9242 BUS_DMASYNC_PREWRITE);
9245 * Setup RX buf descriptor
9247 dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len -
9248 sizeof(*hdr), 0, 0, 0);
9253 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9254 bus_size_t mapsz __unused, int error)
9258 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9259 *((bus_addr_t *)arg) = seg->ds_addr;
9264 bwn_hwrate2ieeerate(int rate)
9268 case BWN_CCK_RATE_1MB:
9270 case BWN_CCK_RATE_2MB:
9272 case BWN_CCK_RATE_5MB:
9274 case BWN_CCK_RATE_11MB:
9276 case BWN_OFDM_RATE_6MB:
9278 case BWN_OFDM_RATE_9MB:
9280 case BWN_OFDM_RATE_12MB:
9282 case BWN_OFDM_RATE_18MB:
9284 case BWN_OFDM_RATE_24MB:
9286 case BWN_OFDM_RATE_36MB:
9288 case BWN_OFDM_RATE_48MB:
9290 case BWN_OFDM_RATE_54MB:
9299 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9301 const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9302 struct bwn_plcp6 *plcp;
9303 struct bwn_softc *sc = mac->mac_sc;
9304 struct ieee80211_frame_min *wh;
9305 struct ieee80211_node *ni;
9306 struct ifnet *ifp = sc->sc_ifp;
9307 struct ieee80211com *ic = ifp->if_l2com;
9309 int padding, rate, rssi = 0, noise = 0, type;
9310 uint16_t phytype, phystat0, phystat3, chanstat;
9311 unsigned char *mp = mtod(m, unsigned char *);
9312 static int rx_mac_dec_rpt = 0;
9314 BWN_ASSERT_LOCKED(sc);
9316 phystat0 = le16toh(rxhdr->phy_status0);
9317 phystat3 = le16toh(rxhdr->phy_status3);
9318 macstat = le32toh(rxhdr->mac_status);
9319 chanstat = le16toh(rxhdr->channel);
9320 phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9322 if (macstat & BWN_RX_MAC_FCSERR)
9323 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9324 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9325 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9326 if (macstat & BWN_RX_MAC_DECERR)
9329 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9330 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9331 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9335 plcp = (struct bwn_plcp6 *)(mp + padding);
9336 m_adj(m, sizeof(struct bwn_plcp6) + padding);
9337 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9338 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9342 wh = mtod(m, struct ieee80211_frame_min *);
9344 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9345 device_printf(sc->sc_dev,
9346 "RX decryption attempted (old %d keyidx %#x)\n",
9348 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9350 /* XXX calculating RSSI & noise & antenna */
9352 if (phystat0 & BWN_RX_PHYST0_OFDM)
9353 rate = bwn_plcp_get_ofdmrate(mac, plcp,
9354 phytype == BWN_PHYTYPE_A);
9356 rate = bwn_plcp_get_cckrate(mac, plcp);
9358 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9361 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9364 if (ieee80211_radiotap_active(ic))
9365 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9366 m_adj(m, -IEEE80211_CRC_LEN);
9368 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */
9369 noise = mac->mac_stats.link_noise;
9371 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
9375 ni = ieee80211_find_rxnode(ic, wh);
9377 type = ieee80211_input(ni, m, rssi, noise);
9378 ieee80211_free_node(ni);
9380 type = ieee80211_input_all(ic, m, rssi, noise);
9385 device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9389 bwn_dma_handle_txeof(struct bwn_mac *mac,
9390 const struct bwn_txstatus *status)
9392 struct bwn_dma *dma = &mac->mac_method.dma;
9393 struct bwn_dma_ring *dr;
9394 struct bwn_dmadesc_generic *desc;
9395 struct bwn_dmadesc_meta *meta;
9396 struct bwn_softc *sc = mac->mac_sc;
9397 struct ieee80211_node *ni;
9398 struct ifnet *ifp = sc->sc_ifp;
9402 BWN_ASSERT_LOCKED(sc);
9404 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9406 device_printf(sc->sc_dev, "failed to parse cookie\n");
9409 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9412 KASSERT(slot >= 0 && slot < dr->dr_numslots,
9413 ("%s:%d: fail", __func__, __LINE__));
9414 dr->getdesc(dr, slot, &desc, &meta);
9416 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
9417 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
9418 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
9419 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9421 if (meta->mt_islast) {
9422 KASSERT(meta->mt_m != NULL,
9423 ("%s:%d: fail", __func__, __LINE__));
9429 * Do any tx complete callback. Note this must
9430 * be done before releasing the node reference.
9432 if (m->m_flags & M_TXCB)
9433 ieee80211_process_callback(ni, m, 0);
9434 ieee80211_free_node(ni);
9440 KASSERT(meta->mt_m == NULL,
9441 ("%s:%d: fail", __func__, __LINE__));
9445 if (meta->mt_islast) {
9446 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
9449 slot = bwn_dma_nextslot(dr, slot);
9451 sc->sc_watchdog_timer = 0;
9453 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9454 ("%s:%d: fail", __func__, __LINE__));
9455 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9461 bwn_pio_handle_txeof(struct bwn_mac *mac,
9462 const struct bwn_txstatus *status)
9464 struct bwn_pio_txqueue *tq;
9465 struct bwn_pio_txpkt *tp = NULL;
9466 struct bwn_softc *sc = mac->mac_sc;
9467 struct ifnet *ifp = sc->sc_ifp;
9469 BWN_ASSERT_LOCKED(sc);
9471 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9475 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9478 if (tp->tp_ni != NULL) {
9480 * Do any tx complete callback. Note this must
9481 * be done before releasing the node reference.
9483 if (tp->tp_m->m_flags & M_TXCB)
9484 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9485 ieee80211_free_node(tp->tp_ni);
9490 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9492 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
9494 sc->sc_watchdog_timer = 0;
9496 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9502 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9504 struct bwn_softc *sc = mac->mac_sc;
9505 struct bwn_phy *phy = &mac->mac_phy;
9506 struct ifnet *ifp = sc->sc_ifp;
9507 struct ieee80211com *ic = ifp->if_l2com;
9513 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9515 phy->nexttime = now + 2 * 1000;
9517 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9518 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9521 if (phy->recalc_txpwr != NULL) {
9522 result = phy->recalc_txpwr(mac,
9523 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9524 if (result == BWN_TXPWR_RES_DONE)
9526 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9527 ("%s: fail", __func__));
9528 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9530 ieee80211_runtask(ic, &mac->mac_txpower);
9535 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9538 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9542 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9545 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9549 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9552 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9556 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9559 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9563 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9567 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9569 return (BWN_OFDM_RATE_6MB);
9571 return (BWN_OFDM_RATE_9MB);
9573 return (BWN_OFDM_RATE_12MB);
9575 return (BWN_OFDM_RATE_18MB);
9577 return (BWN_OFDM_RATE_24MB);
9579 return (BWN_OFDM_RATE_36MB);
9581 return (BWN_OFDM_RATE_48MB);
9583 return (BWN_OFDM_RATE_54MB);
9584 /* CCK rates (NB: not IEEE std, device-specific) */
9586 return (BWN_CCK_RATE_1MB);
9588 return (BWN_CCK_RATE_2MB);
9590 return (BWN_CCK_RATE_5MB);
9592 return (BWN_CCK_RATE_11MB);
9595 device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9596 return (BWN_CCK_RATE_1MB);
9600 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9601 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9603 const struct bwn_phy *phy = &mac->mac_phy;
9604 struct bwn_softc *sc = mac->mac_sc;
9605 struct ieee80211_frame *wh;
9606 struct ieee80211_frame *protwh;
9607 struct ieee80211_frame_cts *cts;
9608 struct ieee80211_frame_rts *rts;
9609 const struct ieee80211_txparam *tp;
9610 struct ieee80211vap *vap = ni->ni_vap;
9611 struct ifnet *ifp = sc->sc_ifp;
9612 struct ieee80211com *ic = ifp->if_l2com;
9615 uint32_t macctl = 0;
9616 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9617 uint16_t phyctl = 0;
9618 uint8_t rate, rate_fb;
9620 wh = mtod(m, struct ieee80211_frame *);
9621 memset(txhdr, 0, sizeof(*txhdr));
9623 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9624 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9625 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9630 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9631 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9632 rate = rate_fb = tp->mgmtrate;
9634 rate = rate_fb = tp->mcastrate;
9635 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9636 rate = rate_fb = tp->ucastrate;
9638 rix = ieee80211_ratectl_rate(ni, NULL, 0);
9639 rate = ni->ni_txrate;
9642 rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9648 sc->sc_tx_rate = rate;
9650 rate = bwn_ieeerate2hwrate(sc, rate);
9651 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9653 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9654 bwn_plcp_getcck(rate);
9655 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9656 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9658 if ((rate_fb == rate) ||
9659 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9660 (*(u_int16_t *)wh->i_dur == htole16(0)))
9661 txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9663 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9664 m->m_pkthdr.len, rate, isshort);
9666 /* XXX TX encryption */
9667 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9668 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9669 (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9670 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9671 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9672 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9674 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9676 txhdr->chan = phy->chan;
9677 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9679 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9680 rate == BWN_CCK_RATE_11MB))
9681 phyctl |= BWN_TX_PHY_SHORTPRMBL;
9683 /* XXX TX antenna selection */
9685 switch (bwn_antenna_sanitize(mac, 0)) {
9687 phyctl |= BWN_TX_PHY_ANT01AUTO;
9690 phyctl |= BWN_TX_PHY_ANT0;
9693 phyctl |= BWN_TX_PHY_ANT1;
9696 phyctl |= BWN_TX_PHY_ANT2;
9699 phyctl |= BWN_TX_PHY_ANT3;
9702 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9706 macctl |= BWN_TX_MAC_ACK;
9708 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9709 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9710 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9711 macctl |= BWN_TX_MAC_LONGFRAME;
9713 if (ic->ic_flags & IEEE80211_F_USEPROT) {
9714 /* XXX RTS rate is always 1MB??? */
9715 rts_rate = BWN_CCK_RATE_1MB;
9716 rts_rate_fb = bwn_get_fbrate(rts_rate);
9718 protdur = ieee80211_compute_duration(ic->ic_rt,
9719 m->m_pkthdr.len, rate, isshort) +
9720 + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9722 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9723 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9724 (txhdr->body.old.rts_frame) :
9725 (txhdr->body.new.rts_frame));
9726 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9728 KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9729 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9730 mprot->m_pkthdr.len);
9732 macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9733 len = sizeof(struct ieee80211_frame_cts);
9735 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9736 (txhdr->body.old.rts_frame) :
9737 (txhdr->body.new.rts_frame));
9738 protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9740 mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9741 wh->i_addr2, protdur);
9742 KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9743 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9744 mprot->m_pkthdr.len);
9746 macctl |= BWN_TX_MAC_SEND_RTSCTS;
9747 len = sizeof(struct ieee80211_frame_rts);
9749 len += IEEE80211_CRC_LEN;
9750 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9751 &txhdr->body.old.rts_plcp :
9752 &txhdr->body.new.rts_plcp), len, rts_rate);
9753 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9756 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9757 (&txhdr->body.old.rts_frame) :
9758 (&txhdr->body.new.rts_frame));
9759 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9761 if (BWN_ISOFDMRATE(rts_rate)) {
9762 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9763 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9765 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9766 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9768 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9769 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9772 if (BWN_ISOLDFMT(mac))
9773 txhdr->body.old.cookie = htole16(cookie);
9775 txhdr->body.new.cookie = htole16(cookie);
9777 txhdr->macctl = htole32(macctl);
9778 txhdr->phyctl = htole16(phyctl);
9783 if (ieee80211_radiotap_active_vap(vap)) {
9784 sc->sc_tx_th.wt_flags = 0;
9785 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
9786 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9788 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9789 rate == BWN_CCK_RATE_11MB))
9790 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9791 sc->sc_tx_th.wt_rate = rate;
9793 ieee80211_radiotap_tx(vap, m);
9800 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9804 uint8_t *raw = plcp->o.raw;
9806 if (BWN_ISOFDMRATE(rate)) {
9807 d = bwn_plcp_getofdm(rate);
9808 KASSERT(!(octets & 0xf000),
9809 ("%s:%d: fail", __func__, __LINE__));
9811 plcp->o.data = htole32(d);
9813 plen = octets * 16 / rate;
9814 if ((octets * 16 % rate) > 0) {
9816 if ((rate == BWN_CCK_RATE_11MB)
9817 && ((octets * 8 % 11) < 4)) {
9823 plcp->o.data |= htole32(plen << 16);
9824 raw[0] = bwn_plcp_getcck(rate);
9829 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9831 struct bwn_softc *sc = mac->mac_sc;
9836 if (mac->mac_phy.gmode)
9837 mask = siba_sprom_get_ant_bg(sc->sc_dev);
9839 mask = siba_sprom_get_ant_a(sc->sc_dev);
9840 if (!(mask & (1 << (n - 1))))
9846 bwn_get_fbrate(uint8_t bitrate)
9849 case BWN_CCK_RATE_1MB:
9850 return (BWN_CCK_RATE_1MB);
9851 case BWN_CCK_RATE_2MB:
9852 return (BWN_CCK_RATE_1MB);
9853 case BWN_CCK_RATE_5MB:
9854 return (BWN_CCK_RATE_2MB);
9855 case BWN_CCK_RATE_11MB:
9856 return (BWN_CCK_RATE_5MB);
9857 case BWN_OFDM_RATE_6MB:
9858 return (BWN_CCK_RATE_5MB);
9859 case BWN_OFDM_RATE_9MB:
9860 return (BWN_OFDM_RATE_6MB);
9861 case BWN_OFDM_RATE_12MB:
9862 return (BWN_OFDM_RATE_9MB);
9863 case BWN_OFDM_RATE_18MB:
9864 return (BWN_OFDM_RATE_12MB);
9865 case BWN_OFDM_RATE_24MB:
9866 return (BWN_OFDM_RATE_18MB);
9867 case BWN_OFDM_RATE_36MB:
9868 return (BWN_OFDM_RATE_24MB);
9869 case BWN_OFDM_RATE_48MB:
9870 return (BWN_OFDM_RATE_36MB);
9871 case BWN_OFDM_RATE_54MB:
9872 return (BWN_OFDM_RATE_48MB);
9874 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9879 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9880 uint32_t ctl, const void *_data, int len)
9882 struct bwn_softc *sc = mac->mac_sc;
9884 const uint8_t *data = _data;
9886 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9887 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9888 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9890 siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9891 tq->tq_base + BWN_PIO8_TXDATA);
9893 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9894 BWN_PIO8_TXCTL_24_31);
9895 data = &(data[len - 1]);
9898 ctl |= BWN_PIO8_TXCTL_16_23;
9899 value |= (uint32_t)(*data) << 16;
9902 ctl |= BWN_PIO8_TXCTL_8_15;
9903 value |= (uint32_t)(*data) << 8;
9906 value |= (uint32_t)(*data);
9908 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9909 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9916 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9917 uint16_t offset, uint32_t value)
9920 BWN_WRITE_4(mac, tq->tq_base + offset, value);
9924 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9925 uint16_t ctl, const void *_data, int len)
9927 struct bwn_softc *sc = mac->mac_sc;
9928 const uint8_t *data = _data;
9930 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9931 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9933 siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9934 tq->tq_base + BWN_PIO_TXDATA);
9936 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9937 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9938 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9945 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9946 uint16_t ctl, struct mbuf *m0)
9951 struct mbuf *m = m0;
9953 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9954 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9956 for (; m != NULL; m = m->m_next) {
9957 buf = mtod(m, const uint8_t *);
9958 for (i = 0; i < m->m_len; i++) {
9962 data |= (buf[i] << 8);
9963 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9968 if (m0->m_pkthdr.len % 2) {
9969 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9970 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9971 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9978 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9981 if (mac->mac_phy.type != BWN_PHYTYPE_G)
9983 BWN_WRITE_2(mac, 0x684, 510 + time);
9984 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9987 static struct bwn_dma_ring *
9988 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9991 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9992 return (mac->mac_method.dma.wme[WME_AC_BE]);
9996 return (mac->mac_method.dma.wme[WME_AC_VO]);
9998 return (mac->mac_method.dma.wme[WME_AC_VI]);
10000 return (mac->mac_method.dma.wme[WME_AC_BE]);
10002 return (mac->mac_method.dma.wme[WME_AC_BK]);
10004 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
10009 bwn_dma_getslot(struct bwn_dma_ring *dr)
10013 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
10015 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
10016 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
10017 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
10019 slot = bwn_dma_nextslot(dr, dr->dr_curslot);
10020 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
10021 dr->dr_curslot = slot;
10028 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
10030 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
10031 unsigned int a, b, c, d;
10035 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
10037 b = (tmp >> 8) & 0xff;
10038 c = (tmp >> 16) & 0xff;
10039 d = (tmp >> 24) & 0xff;
10040 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
10041 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
10043 bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
10044 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
10045 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
10048 a = (a + 32) & 0x3f;
10049 b = (b + 32) & 0x3f;
10050 c = (c + 32) & 0x3f;
10051 d = (d + 32) & 0x3f;
10054 avg = (a + b + c + d + 2) / 4;
10056 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
10057 & BWN_HF_4DB_CCK_POWERBOOST)
10058 avg = (avg >= 13) ? (avg - 13) : 0;
10064 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
10066 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
10067 int rfatt = *rfattp;
10068 int bbatt = *bbattp;
10071 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
10073 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
10075 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
10077 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
10079 if (bbatt > lo->bbatt.max) {
10084 if (bbatt < lo->bbatt.min) {
10089 if (rfatt > lo->rfatt.max) {
10094 if (rfatt < lo->rfatt.min) {
10102 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
10103 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
10107 bwn_phy_lock(struct bwn_mac *mac)
10109 struct bwn_softc *sc = mac->mac_sc;
10110 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10112 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10113 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10115 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10116 bwn_psctl(mac, BWN_PS_AWAKE);
10120 bwn_phy_unlock(struct bwn_mac *mac)
10122 struct bwn_softc *sc = mac->mac_sc;
10123 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10125 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10126 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10128 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10133 bwn_rf_lock(struct bwn_mac *mac)
10136 BWN_WRITE_4(mac, BWN_MACCTL,
10137 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
10138 BWN_READ_4(mac, BWN_MACCTL);
10143 bwn_rf_unlock(struct bwn_mac *mac)
10146 BWN_READ_2(mac, BWN_PHYVER);
10147 BWN_WRITE_4(mac, BWN_MACCTL,
10148 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10151 static struct bwn_pio_txqueue *
10152 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10153 struct bwn_pio_txpkt **pack)
10155 struct bwn_pio *pio = &mac->mac_method.pio;
10156 struct bwn_pio_txqueue *tq = NULL;
10157 unsigned int index;
10159 switch (cookie & 0xf000) {
10161 tq = &pio->wme[WME_AC_BK];
10164 tq = &pio->wme[WME_AC_BE];
10167 tq = &pio->wme[WME_AC_VI];
10170 tq = &pio->wme[WME_AC_VO];
10176 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10179 index = (cookie & 0x0fff);
10180 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10181 if (index >= N(tq->tq_pkts))
10183 *pack = &tq->tq_pkts[index];
10184 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10189 bwn_txpwr(void *arg, int npending)
10191 struct bwn_mac *mac = arg;
10192 struct bwn_softc *sc = mac->mac_sc;
10195 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10196 mac->mac_phy.set_txpwr != NULL)
10197 mac->mac_phy.set_txpwr(mac);
10202 bwn_task_15s(struct bwn_mac *mac)
10206 if (mac->mac_fw.opensource) {
10207 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10209 bwn_restart(mac, "fw watchdog");
10212 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10214 if (mac->mac_phy.task_15s)
10215 mac->mac_phy.task_15s(mac);
10217 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10221 bwn_task_30s(struct bwn_mac *mac)
10224 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10226 mac->mac_noise.noi_running = 1;
10227 mac->mac_noise.noi_nsamples = 0;
10229 bwn_noise_gensample(mac);
10233 bwn_task_60s(struct bwn_mac *mac)
10236 if (mac->mac_phy.task_60s)
10237 mac->mac_phy.task_60s(mac);
10238 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10242 bwn_tasks(void *arg)
10244 struct bwn_mac *mac = arg;
10245 struct bwn_softc *sc = mac->mac_sc;
10247 BWN_ASSERT_LOCKED(sc);
10248 if (mac->mac_status != BWN_MAC_STATUS_STARTED)
10251 if (mac->mac_task_state % 4 == 0)
10253 if (mac->mac_task_state % 2 == 0)
10257 mac->mac_task_state++;
10258 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10262 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10264 struct bwn_softc *sc = mac->mac_sc;
10266 KASSERT(a == 0, ("not support APHY\n"));
10268 switch (plcp->o.raw[0] & 0xf) {
10270 return (BWN_OFDM_RATE_6MB);
10272 return (BWN_OFDM_RATE_9MB);
10274 return (BWN_OFDM_RATE_12MB);
10276 return (BWN_OFDM_RATE_18MB);
10278 return (BWN_OFDM_RATE_24MB);
10280 return (BWN_OFDM_RATE_36MB);
10282 return (BWN_OFDM_RATE_48MB);
10284 return (BWN_OFDM_RATE_54MB);
10286 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10287 plcp->o.raw[0] & 0xf);
10292 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10294 struct bwn_softc *sc = mac->mac_sc;
10296 switch (plcp->o.raw[0]) {
10298 return (BWN_CCK_RATE_1MB);
10300 return (BWN_CCK_RATE_2MB);
10302 return (BWN_CCK_RATE_5MB);
10304 return (BWN_CCK_RATE_11MB);
10306 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10311 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10312 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10313 int rssi, int noise)
10315 struct bwn_softc *sc = mac->mac_sc;
10316 const struct ieee80211_frame_min *wh;
10318 uint16_t low_mactime_now;
10320 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10321 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10323 wh = mtod(m, const struct ieee80211_frame_min *);
10324 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
10325 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10327 bwn_tsf_read(mac, &tsf);
10328 low_mactime_now = tsf;
10329 tsf = tsf & ~0xffffULL;
10330 tsf += le16toh(rxhdr->mac_time);
10331 if (low_mactime_now < le16toh(rxhdr->mac_time))
10334 sc->sc_rx_th.wr_tsf = tsf;
10335 sc->sc_rx_th.wr_rate = rate;
10336 sc->sc_rx_th.wr_antsignal = rssi;
10337 sc->sc_rx_th.wr_antnoise = noise;
10341 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10343 uint32_t low, high;
10345 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10346 ("%s:%d: fail", __func__, __LINE__));
10348 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10349 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10356 bwn_dma_attach(struct bwn_mac *mac)
10358 struct bwn_dma *dma = &mac->mac_method.dma;
10359 struct bwn_softc *sc = mac->mac_sc;
10360 bus_addr_t lowaddr = 0;
10363 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10366 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10368 mac->mac_flags |= BWN_MAC_FLAG_DMA;
10370 dma->dmatype = bwn_dma_gettype(mac);
10371 if (dma->dmatype == BWN_DMA_30BIT)
10372 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10373 else if (dma->dmatype == BWN_DMA_32BIT)
10374 lowaddr = BUS_SPACE_MAXADDR_32BIT;
10376 lowaddr = BUS_SPACE_MAXADDR;
10379 * Create top level DMA tag
10381 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
10382 BWN_ALIGN, 0, /* alignment, bounds */
10383 lowaddr, /* lowaddr */
10384 BUS_SPACE_MAXADDR, /* highaddr */
10385 NULL, NULL, /* filter, filterarg */
10386 BUS_SPACE_MAXSIZE, /* maxsize */
10387 BUS_SPACE_UNRESTRICTED, /* nsegments */
10388 BUS_SPACE_MAXSIZE, /* maxsegsize */
10390 NULL, NULL, /* lockfunc, lockarg */
10391 &dma->parent_dtag);
10393 device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10398 * Create TX/RX mbuf DMA tag
10400 error = bus_dma_tag_create(dma->parent_dtag,
10408 BUS_SPACE_MAXSIZE_32BIT,
10413 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10416 error = bus_dma_tag_create(dma->parent_dtag,
10424 BUS_SPACE_MAXSIZE_32BIT,
10429 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10433 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10434 if (!dma->wme[WME_AC_BK])
10437 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10438 if (!dma->wme[WME_AC_BE])
10441 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10442 if (!dma->wme[WME_AC_VI])
10445 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10446 if (!dma->wme[WME_AC_VO])
10449 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10452 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10458 fail7: bwn_dma_ringfree(&dma->mcast);
10459 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10460 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10461 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10462 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10463 fail2: bus_dma_tag_destroy(dma->txbuf_dtag);
10464 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag);
10465 fail0: bus_dma_tag_destroy(dma->parent_dtag);
10469 static struct bwn_dma_ring *
10470 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10471 uint16_t cookie, int *slot)
10473 struct bwn_dma *dma = &mac->mac_method.dma;
10474 struct bwn_dma_ring *dr;
10475 struct bwn_softc *sc = mac->mac_sc;
10477 BWN_ASSERT_LOCKED(mac->mac_sc);
10479 switch (cookie & 0xf000) {
10481 dr = dma->wme[WME_AC_BK];
10484 dr = dma->wme[WME_AC_BE];
10487 dr = dma->wme[WME_AC_VI];
10490 dr = dma->wme[WME_AC_VO];
10498 ("invalid cookie value %d", cookie & 0xf000));
10500 *slot = (cookie & 0x0fff);
10501 if (*slot < 0 || *slot >= dr->dr_numslots) {
10503 * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10504 * that it occurs events which have same H/W sequence numbers.
10505 * When it's occurred just prints a WARNING msgs and ignores.
10507 KASSERT(status->seq == dma->lastseq,
10508 ("%s:%d: fail", __func__, __LINE__));
10509 device_printf(sc->sc_dev,
10510 "out of slot ranges (0 < %d < %d)\n", *slot,
10514 dma->lastseq = status->seq;
10519 bwn_dma_stop(struct bwn_mac *mac)
10521 struct bwn_dma *dma;
10523 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10525 dma = &mac->mac_method.dma;
10527 bwn_dma_ringstop(&dma->rx);
10528 bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10529 bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10530 bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10531 bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10532 bwn_dma_ringstop(&dma->mcast);
10536 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10542 bwn_dma_cleanup(*dr);
10546 bwn_pio_stop(struct bwn_mac *mac)
10548 struct bwn_pio *pio;
10550 if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10552 pio = &mac->mac_method.pio;
10554 bwn_destroy_queue_tx(&pio->mcast);
10555 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10556 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10557 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10558 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10562 bwn_led_attach(struct bwn_mac *mac)
10564 struct bwn_softc *sc = mac->mac_sc;
10565 const uint8_t *led_act = NULL;
10566 uint16_t val[BWN_LED_MAX];
10569 sc->sc_led_idle = (2350 * hz) / 1000;
10570 sc->sc_led_blink = 1;
10572 for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10573 if (siba_get_pci_subvendor(sc->sc_dev) ==
10574 bwn_vendor_led_act[i].vid) {
10575 led_act = bwn_vendor_led_act[i].led_act;
10579 if (led_act == NULL)
10580 led_act = bwn_default_led_act;
10582 val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10583 val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10584 val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10585 val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10587 for (i = 0; i < BWN_LED_MAX; ++i) {
10588 struct bwn_led *led = &sc->sc_leds[i];
10590 if (val[i] == 0xff) {
10591 led->led_act = led_act[i];
10593 if (val[i] & BWN_LED_ACT_LOW)
10594 led->led_flags |= BWN_LED_F_ACTLOW;
10595 led->led_act = val[i] & BWN_LED_ACT_MASK;
10597 led->led_mask = (1 << i);
10599 if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10600 led->led_act == BWN_LED_ACT_BLINK_POLL ||
10601 led->led_act == BWN_LED_ACT_BLINK) {
10602 led->led_flags |= BWN_LED_F_BLINK;
10603 if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10604 led->led_flags |= BWN_LED_F_POLLABLE;
10605 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10606 led->led_flags |= BWN_LED_F_SLOW;
10608 if (sc->sc_blink_led == NULL) {
10609 sc->sc_blink_led = led;
10610 if (led->led_flags & BWN_LED_F_SLOW)
10611 BWN_LED_SLOWDOWN(sc->sc_led_idle);
10615 DPRINTF(sc, BWN_DEBUG_LED,
10616 "%dth led, act %d, lowact %d\n", i,
10617 led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10619 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
10622 static __inline uint16_t
10623 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10626 if (led->led_flags & BWN_LED_F_ACTLOW)
10629 val |= led->led_mask;
10631 val &= ~led->led_mask;
10636 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10638 struct bwn_softc *sc = mac->mac_sc;
10639 struct ifnet *ifp = sc->sc_ifp;
10640 struct ieee80211com *ic = ifp->if_l2com;
10644 if (nstate == IEEE80211_S_INIT) {
10645 callout_stop(&sc->sc_led_blink_ch);
10646 sc->sc_led_blinking = 0;
10649 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
10652 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10653 for (i = 0; i < BWN_LED_MAX; ++i) {
10654 struct bwn_led *led = &sc->sc_leds[i];
10657 if (led->led_act == BWN_LED_ACT_UNKN ||
10658 led->led_act == BWN_LED_ACT_NULL)
10661 if ((led->led_flags & BWN_LED_F_BLINK) &&
10662 nstate != IEEE80211_S_INIT)
10665 switch (led->led_act) {
10666 case BWN_LED_ACT_ON: /* Always on */
10669 case BWN_LED_ACT_OFF: /* Always off */
10670 case BWN_LED_ACT_5GHZ: /* TODO: 11A */
10676 case IEEE80211_S_INIT:
10679 case IEEE80211_S_RUN:
10680 if (led->led_act == BWN_LED_ACT_11G &&
10681 ic->ic_curmode != IEEE80211_MODE_11G)
10685 if (led->led_act == BWN_LED_ACT_ASSOC)
10692 val = bwn_led_onoff(led, val, on);
10694 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10698 bwn_led_event(struct bwn_mac *mac, int event)
10700 struct bwn_softc *sc = mac->mac_sc;
10701 struct bwn_led *led = sc->sc_blink_led;
10704 if (event == BWN_LED_EVENT_POLL) {
10705 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10707 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10711 sc->sc_led_ticks = ticks;
10712 if (sc->sc_led_blinking)
10716 case BWN_LED_EVENT_RX:
10717 rate = sc->sc_rx_rate;
10719 case BWN_LED_EVENT_TX:
10720 rate = sc->sc_tx_rate;
10722 case BWN_LED_EVENT_POLL:
10726 panic("unknown LED event %d\n", event);
10729 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10730 bwn_led_duration[rate].off_dur);
10734 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10736 struct bwn_softc *sc = mac->mac_sc;
10737 struct bwn_led *led = sc->sc_blink_led;
10740 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10741 val = bwn_led_onoff(led, val, 1);
10742 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10744 if (led->led_flags & BWN_LED_F_SLOW) {
10745 BWN_LED_SLOWDOWN(on_dur);
10746 BWN_LED_SLOWDOWN(off_dur);
10749 sc->sc_led_blinking = 1;
10750 sc->sc_led_blink_offdur = off_dur;
10752 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10756 bwn_led_blink_next(void *arg)
10758 struct bwn_mac *mac = arg;
10759 struct bwn_softc *sc = mac->mac_sc;
10762 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10763 val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10764 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10766 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10767 bwn_led_blink_end, mac);
10771 bwn_led_blink_end(void *arg)
10773 struct bwn_mac *mac = arg;
10774 struct bwn_softc *sc = mac->mac_sc;
10776 sc->sc_led_blinking = 0;
10780 bwn_suspend(device_t dev)
10782 struct bwn_softc *sc = device_get_softc(dev);
10789 bwn_resume(device_t dev)
10791 struct bwn_softc *sc = device_get_softc(dev);
10792 struct ifnet *ifp = sc->sc_ifp;
10794 if (ifp->if_flags & IFF_UP)
10800 bwn_rfswitch(void *arg)
10802 struct bwn_softc *sc = arg;
10803 struct bwn_mac *mac = sc->sc_curmac;
10804 int cur = 0, prev = 0;
10806 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10807 ("%s: invalid MAC status %d", __func__, mac->mac_status));
10809 if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10810 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10811 & BWN_RF_HWENABLED_HI_MASK))
10814 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10815 & BWN_RF_HWENABLED_LO_MASK)
10819 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10824 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10826 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10828 device_printf(sc->sc_dev,
10829 "status of RF switch is changed to %s\n",
10830 cur ? "ON" : "OFF");
10831 if (cur != mac->mac_phy.rf_on) {
10833 bwn_rf_turnon(mac);
10835 bwn_rf_turnoff(mac);
10839 callout_schedule(&sc->sc_rfswitch_ch, hz);
10843 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10845 struct bwn_phy *phy = &mac->mac_phy;
10846 struct bwn_phy_lp *plp = &phy->phy_lp;
10848 plp->plp_antenna = BWN_ANT_DEFAULT;
10852 bwn_phy_lp_init(struct bwn_mac *mac)
10854 static const struct bwn_stxtable tables[] = {
10855 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10856 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff },
10857 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff },
10858 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10859 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f },
10860 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10861 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 },
10862 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f },
10863 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10864 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 },
10865 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10866 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 },
10867 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f },
10868 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f },
10869 { 2, 11, 0x40, 0, 0x0f }
10871 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10872 struct bwn_softc *sc = mac->mac_sc;
10873 const struct bwn_stxtable *st;
10874 struct ifnet *ifp = sc->sc_ifp;
10875 struct ieee80211com *ic = ifp->if_l2com;
10879 bwn_phy_lp_readsprom(mac); /* XXX bad place */
10880 bwn_phy_lp_bbinit(mac);
10882 /* initialize RF */
10883 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10885 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10888 if (mac->mac_phy.rf_ver == 0x2062)
10889 bwn_phy_lp_b2062_init(mac);
10891 bwn_phy_lp_b2063_init(mac);
10893 /* synchronize stx table. */
10894 for (i = 0; i < N(tables); i++) {
10896 tmp = BWN_RF_READ(mac, st->st_rfaddr);
10897 tmp >>= st->st_rfshift;
10898 tmp <<= st->st_physhift;
10899 BWN_PHY_SETMASK(mac,
10900 BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10901 ~(st->st_mask << st->st_physhift), tmp);
10904 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10905 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10909 if (mac->mac_phy.rev >= 2)
10910 bwn_phy_lp_rxcal_r2(mac);
10911 else if (!plp->plp_rccap) {
10912 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10913 bwn_phy_lp_rccal_r12(mac);
10915 bwn_phy_lp_set_rccap(mac);
10917 error = bwn_phy_lp_switch_channel(mac, 7);
10919 device_printf(sc->sc_dev,
10920 "failed to change channel 7 (%d)\n", error);
10921 bwn_phy_lp_txpctl_init(mac);
10922 bwn_phy_lp_calib(mac);
10927 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10930 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10931 return (BWN_READ_2(mac, BWN_PHYDATA));
10935 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10938 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10939 BWN_WRITE_2(mac, BWN_PHYDATA, value);
10943 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10947 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10948 BWN_WRITE_2(mac, BWN_PHYDATA,
10949 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10953 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10956 KASSERT(reg != 1, ("unaccessible register %d", reg));
10957 if (mac->mac_phy.rev < 2 && reg != 0x4001)
10959 if (mac->mac_phy.rev >= 2)
10961 BWN_WRITE_2(mac, BWN_RFCTL, reg);
10962 return BWN_READ_2(mac, BWN_RFDATALO);
10966 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10969 KASSERT(reg != 1, ("unaccessible register %d", reg));
10970 BWN_WRITE_2(mac, BWN_RFCTL, reg);
10971 BWN_WRITE_2(mac, BWN_RFDATALO, value);
10975 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10979 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10980 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10981 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10985 if (mac->mac_phy.rev >= 2) {
10986 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10987 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10988 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10989 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10990 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
10994 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
10995 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10996 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
10997 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
11001 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
11003 struct bwn_phy *phy = &mac->mac_phy;
11004 struct bwn_phy_lp *plp = &phy->phy_lp;
11007 if (phy->rf_ver == 0x2063) {
11008 error = bwn_phy_lp_b2063_switch_channel(mac, chan);
11012 error = bwn_phy_lp_b2062_switch_channel(mac, chan);
11015 bwn_phy_lp_set_anafilter(mac, chan);
11016 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
11019 plp->plp_chan = chan;
11020 BWN_WRITE_2(mac, BWN_CHANNEL, chan);
11025 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
11027 struct bwn_softc *sc = mac->mac_sc;
11028 struct ifnet *ifp = sc->sc_ifp;
11029 struct ieee80211com *ic = ifp->if_l2com;
11031 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
11035 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
11037 struct bwn_phy *phy = &mac->mac_phy;
11038 struct bwn_phy_lp *plp = &phy->phy_lp;
11040 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
11043 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
11044 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
11045 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
11046 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
11047 plp->plp_antenna = antenna;
11051 bwn_phy_lp_task_60s(struct bwn_mac *mac)
11054 bwn_phy_lp_calib(mac);
11058 bwn_phy_lp_readsprom(struct bwn_mac *mac)
11060 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11061 struct bwn_softc *sc = mac->mac_sc;
11062 struct ifnet *ifp = sc->sc_ifp;
11063 struct ieee80211com *ic = ifp->if_l2com;
11065 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11066 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
11067 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
11068 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
11069 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
11070 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
11071 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
11075 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
11076 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
11077 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
11078 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
11079 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
11080 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
11081 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
11082 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
11086 bwn_phy_lp_bbinit(struct bwn_mac *mac)
11089 bwn_phy_lp_tblinit(mac);
11090 if (mac->mac_phy.rev >= 2)
11091 bwn_phy_lp_bbinit_r2(mac);
11093 bwn_phy_lp_bbinit_r01(mac);
11097 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
11099 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
11100 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
11101 struct bwn_softc *sc = mac->mac_sc;
11102 struct ifnet *ifp = sc->sc_ifp;
11103 struct ieee80211com *ic = ifp->if_l2com;
11105 bwn_phy_lp_set_txgain(mac,
11106 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
11107 bwn_phy_lp_set_bbmult(mac, 150);
11111 bwn_phy_lp_calib(struct bwn_mac *mac)
11113 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11114 struct bwn_softc *sc = mac->mac_sc;
11115 struct ifnet *ifp = sc->sc_ifp;
11116 struct ieee80211com *ic = ifp->if_l2com;
11117 const struct bwn_rxcompco *rc = NULL;
11118 struct bwn_txgain ogain;
11119 int i, omode, oafeovr, orf, obbmult;
11120 uint8_t mode, fc = 0;
11122 if (plp->plp_chanfullcal != plp->plp_chan) {
11123 plp->plp_chanfullcal = plp->plp_chan;
11127 bwn_mac_suspend(mac);
11129 /* BlueTooth Coexistance Override */
11130 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
11131 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
11133 if (mac->mac_phy.rev >= 2)
11134 bwn_phy_lp_digflt_save(mac);
11135 bwn_phy_lp_get_txpctlmode(mac);
11136 mode = plp->plp_txpctlmode;
11137 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11138 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
11139 bwn_phy_lp_bugfix(mac);
11140 if (mac->mac_phy.rev >= 2 && fc == 1) {
11141 bwn_phy_lp_get_txpctlmode(mac);
11142 omode = plp->plp_txpctlmode;
11143 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11145 ogain = bwn_phy_lp_get_txgain(mac);
11146 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11147 obbmult = bwn_phy_lp_get_bbmult(mac);
11148 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11150 bwn_phy_lp_set_txgain(mac, &ogain);
11151 bwn_phy_lp_set_bbmult(mac, obbmult);
11152 bwn_phy_lp_set_txpctlmode(mac, omode);
11153 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11155 bwn_phy_lp_set_txpctlmode(mac, mode);
11156 if (mac->mac_phy.rev >= 2)
11157 bwn_phy_lp_digflt_restore(mac);
11159 /* do RX IQ Calculation; assumes that noise is true. */
11160 if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11161 for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11162 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11163 rc = &bwn_rxcompco_5354[i];
11165 } else if (mac->mac_phy.rev >= 2)
11166 rc = &bwn_rxcompco_r2;
11168 for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11169 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11170 rc = &bwn_rxcompco_r12[i];
11176 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11177 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11179 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11181 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11182 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11183 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11185 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11186 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11189 bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11190 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11191 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11192 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11193 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11194 bwn_phy_lp_set_deaf(mac, 0);
11195 /* XXX no checking return value? */
11196 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11197 bwn_phy_lp_clear_deaf(mac, 0);
11198 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11199 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11200 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11202 /* disable RX GAIN override. */
11203 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11204 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11205 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11206 if (mac->mac_phy.rev >= 2) {
11207 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11208 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11209 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11210 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11213 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11216 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11217 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11219 bwn_mac_enable(mac);
11223 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11227 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11231 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11232 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11236 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11238 static const struct bwn_b206x_chan *bc = NULL;
11239 struct bwn_softc *sc = mac->mac_sc;
11240 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11242 uint16_t old, scale, tmp16;
11245 for (i = 0; i < N(bwn_b2063_chantable); i++) {
11246 if (bwn_b2063_chantable[i].bc_chan == chan) {
11247 bc = &bwn_b2063_chantable[i];
11254 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11255 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11256 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11257 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11258 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11259 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11260 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11261 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11262 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11263 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11264 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11265 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11267 old = BWN_RF_READ(mac, BWN_B2063_COM15);
11268 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11270 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11271 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11272 freqref = freqxtal * 3;
11273 div = (freqxtal <= 26000000 ? 1 : 2);
11274 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11275 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11276 999999) / 1000000) + 1;
11278 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11279 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11280 0xfff8, timeout >> 2);
11281 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11282 0xff9f,timeout << 5);
11283 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11285 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11286 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11287 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11289 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11290 (timeoutref + 1)) - 1;
11291 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11293 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11295 tmp[0] = ((val[2] * 62500) / freqref) << 4;
11296 tmp[1] = ((val[2] * 62500) % freqref) << 4;
11297 while (tmp[1] >= freqref) {
11301 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11302 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11303 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11304 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11305 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11307 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11308 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11309 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11310 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11312 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11313 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11315 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11317 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11320 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11322 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11323 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11325 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11330 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11331 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11333 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11334 if (freqxtal > 26000000)
11335 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11337 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11340 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11342 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11344 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11346 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11348 /* VCO Calibration */
11349 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11350 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11351 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11353 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11355 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11357 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11359 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11361 BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11366 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11368 struct bwn_softc *sc = mac->mac_sc;
11369 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11370 const struct bwn_b206x_chan *bc = NULL;
11371 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11375 for (i = 0; i < N(bwn_b2062_chantable); i++) {
11376 if (bwn_b2062_chantable[i].bc_chan == chan) {
11377 bc = &bwn_b2062_chantable[i];
11385 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11386 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11387 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11388 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11389 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11390 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11391 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11392 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11393 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11394 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11396 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11397 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11398 bwn_phy_lp_b2062_reset_pllbias(mac);
11399 tmp[0] = freqxtal / 1000;
11400 tmp[1] = plp->plp_div * 1000;
11401 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11402 if (ieee80211_ieee2mhz(chan, 0) < 4000)
11404 tmp[3] = 48 * tmp[0];
11405 tmp[5] = tmp[2] / tmp[3];
11406 tmp[6] = tmp[2] % tmp[3];
11407 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11408 tmp[4] = tmp[6] * 0x100;
11409 tmp[5] = tmp[4] / tmp[3];
11410 tmp[6] = tmp[4] % tmp[3];
11411 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11412 tmp[4] = tmp[6] * 0x100;
11413 tmp[5] = tmp[4] / tmp[3];
11414 tmp[6] = tmp[4] % tmp[3];
11415 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11416 tmp[4] = tmp[6] * 0x100;
11417 tmp[5] = tmp[4] / tmp[3];
11418 tmp[6] = tmp[4] % tmp[3];
11419 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11420 tmp[5] + ((2 * tmp[6]) / tmp[3]));
11421 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11422 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11423 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11424 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11426 bwn_phy_lp_b2062_vco_calib(mac);
11427 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11428 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11429 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11430 bwn_phy_lp_b2062_reset_pllbias(mac);
11431 bwn_phy_lp_b2062_vco_calib(mac);
11432 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11433 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11437 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11442 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11444 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11445 uint16_t tmp = (channel == 14);
11447 if (mac->mac_phy.rev < 2) {
11448 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11449 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11450 bwn_phy_lp_set_rccap(mac);
11454 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11458 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11460 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11461 struct bwn_softc *sc = mac->mac_sc;
11462 struct ifnet *ifp = sc->sc_ifp;
11463 struct ieee80211com *ic = ifp->if_l2com;
11464 uint16_t iso, tmp[3];
11466 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11468 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11469 iso = plp->plp_txisoband_m;
11470 else if (freq <= 5320)
11471 iso = plp->plp_txisoband_l;
11472 else if (freq <= 5700)
11473 iso = plp->plp_txisoband_m;
11475 iso = plp->plp_txisoband_h;
11477 tmp[0] = ((iso - 26) / 12) << 12;
11478 tmp[1] = tmp[0] + 0x1000;
11479 tmp[2] = tmp[0] + 0x2000;
11481 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11482 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11486 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11488 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11490 static const uint16_t addr[] = {
11491 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11492 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11493 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11494 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11495 BWN_PHY_OFDM(0xcf),
11497 static const uint16_t val[] = {
11498 0xde5e, 0xe832, 0xe331, 0x4d26,
11499 0x0026, 0x1420, 0x0020, 0xfe08,
11503 for (i = 0; i < N(addr); i++) {
11504 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11505 BWN_PHY_WRITE(mac, addr[i], val[i]);
11510 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11512 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11513 struct bwn_softc *sc = mac->mac_sc;
11516 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11517 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11518 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11519 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11521 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11522 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11524 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11525 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11528 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11529 device_printf(sc->sc_dev, "unknown command mode\n");
11535 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11537 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11541 bwn_phy_lp_get_txpctlmode(mac);
11542 old = plp->plp_txpctlmode;
11545 plp->plp_txpctlmode = mode;
11547 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11548 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11550 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11551 0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11553 /* disable TX GAIN override */
11554 if (mac->mac_phy.rev < 2)
11555 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11557 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11558 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11560 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11562 plp->plp_txpwridx = -1;
11564 if (mac->mac_phy.rev >= 2) {
11565 if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11566 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11568 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11571 /* writes TX Power Control mode */
11572 switch (plp->plp_txpctlmode) {
11573 case BWN_PHYLP_TXPCTL_OFF:
11574 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11576 case BWN_PHYLP_TXPCTL_ON_HW:
11577 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11579 case BWN_PHYLP_TXPCTL_ON_SW:
11580 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11584 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11586 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11587 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11591 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11593 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11594 struct bwn_softc *sc = mac->mac_sc;
11595 const unsigned int size = 256;
11596 struct bwn_txgain tg;
11597 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11598 uint16_t tssinpt, tssiidx, value[2];
11602 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
11603 M_NOWAIT | M_ZERO);
11604 if (tabs == NULL) {
11605 device_printf(sc->sc_dev, "failed to allocate buffer.\n");
11609 bwn_phy_lp_get_txpctlmode(mac);
11610 mode = plp->plp_txpctlmode;
11611 txpwridx = plp->plp_txpwridx;
11612 tssinpt = plp->plp_tssinpt;
11613 tssiidx = plp->plp_tssiidx;
11615 bwn_tab_read_multi(mac,
11616 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11617 BWN_TAB_4(7, 0x140), size, tabs);
11619 bwn_phy_lp_tblinit(mac);
11620 bwn_phy_lp_bbinit(mac);
11621 bwn_phy_lp_txpctl_init(mac);
11622 bwn_phy_lp_rf_onoff(mac, 1);
11623 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11625 bwn_tab_write_multi(mac,
11626 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11627 BWN_TAB_4(7, 0x140), size, tabs);
11629 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11630 plp->plp_tssinpt = tssinpt;
11631 plp->plp_tssiidx = tssiidx;
11632 bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11633 if (txpwridx != -1) {
11634 /* set TX power by index */
11635 plp->plp_txpwridx = txpwridx;
11636 bwn_phy_lp_get_txpctlmode(mac);
11637 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11638 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11639 if (mac->mac_phy.rev >= 2) {
11640 rxcomp = bwn_tab_read(mac,
11641 BWN_TAB_4(7, txpwridx + 320));
11642 txgain = bwn_tab_read(mac,
11643 BWN_TAB_4(7, txpwridx + 192));
11644 tg.tg_pad = (txgain >> 16) & 0xff;
11645 tg.tg_gm = txgain & 0xff;
11646 tg.tg_pga = (txgain >> 8) & 0xff;
11647 tg.tg_dac = (rxcomp >> 28) & 0xff;
11648 bwn_phy_lp_set_txgain(mac, &tg);
11650 rxcomp = bwn_tab_read(mac,
11651 BWN_TAB_4(10, txpwridx + 320));
11652 txgain = bwn_tab_read(mac,
11653 BWN_TAB_4(10, txpwridx + 192));
11654 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11655 0xf800, (txgain >> 4) & 0x7fff);
11656 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11657 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11659 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11662 value[0] = (rxcomp >> 10) & 0x3ff;
11663 value[1] = rxcomp & 0x3ff;
11664 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11666 coeff = bwn_tab_read(mac,
11667 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11668 BWN_TAB_4(10, txpwridx + 448));
11669 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11670 if (mac->mac_phy.rev >= 2) {
11671 rfpwr = bwn_tab_read(mac,
11672 BWN_TAB_4(7, txpwridx + 576));
11673 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11676 bwn_phy_lp_set_txgain_override(mac);
11678 if (plp->plp_rccap)
11679 bwn_phy_lp_set_rccap(mac);
11680 bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11681 bwn_phy_lp_set_txpctlmode(mac, mode);
11682 free(tabs, M_DEVBUF);
11686 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11688 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11690 static const uint16_t addr[] = {
11691 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11692 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11693 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11694 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11695 BWN_PHY_OFDM(0xcf),
11698 for (i = 0; i < N(addr); i++)
11699 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11703 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11705 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11707 if (mac->mac_phy.rev < 2) {
11708 bwn_phy_lp_tblinit_r01(mac);
11709 bwn_phy_lp_tblinit_txgain(mac);
11710 bwn_phy_lp_set_gaintbl(mac, freq);
11714 bwn_phy_lp_tblinit_r2(mac);
11715 bwn_phy_lp_tblinit_txgain(mac);
11723 struct bwn_smpair {
11730 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11732 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11733 struct bwn_softc *sc = mac->mac_sc;
11734 struct ifnet *ifp = sc->sc_ifp;
11735 struct ieee80211com *ic = ifp->if_l2com;
11736 static const struct bwn_wpair v1[] = {
11737 { BWN_PHY_AFE_DAC_CTL, 0x50 },
11738 { BWN_PHY_AFE_CTL, 0x8800 },
11739 { BWN_PHY_AFE_CTL_OVR, 0 },
11740 { BWN_PHY_AFE_CTL_OVRVAL, 0 },
11741 { BWN_PHY_RF_OVERRIDE_0, 0 },
11742 { BWN_PHY_RF_OVERRIDE_2, 0 },
11743 { BWN_PHY_OFDM(0xf9), 0 },
11744 { BWN_PHY_TR_LOOKUP_1, 0 }
11746 static const struct bwn_smpair v2[] = {
11747 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11748 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11749 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11750 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11751 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11753 static const struct bwn_smpair v3[] = {
11754 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11755 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11756 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11757 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11758 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11759 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11760 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11761 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11762 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11763 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11768 for (i = 0; i < N(v1); i++)
11769 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11770 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11771 for (i = 0; i < N(v2); i++)
11772 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11774 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11775 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11776 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11777 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11778 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11779 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11781 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11783 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11784 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11785 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11786 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11787 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11788 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11789 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11790 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11791 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11792 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11793 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11794 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11795 (siba_get_chiprev(sc->sc_dev) == 0)) {
11796 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11797 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11799 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11800 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11802 for (i = 0; i < N(v3); i++)
11803 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11804 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11805 (siba_get_chiprev(sc->sc_dev) == 0)) {
11806 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11807 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11810 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11811 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11812 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11813 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11814 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11815 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11816 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11818 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11820 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11821 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11822 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11823 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11824 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11825 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11826 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11827 0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11828 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11830 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11831 (siba_get_chiprev(sc->sc_dev) == 0)) {
11832 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11833 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11834 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11837 bwn_phy_lp_digflt_save(mac);
11841 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11843 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11844 struct bwn_softc *sc = mac->mac_sc;
11845 struct ifnet *ifp = sc->sc_ifp;
11846 struct ieee80211com *ic = ifp->if_l2com;
11847 static const struct bwn_smpair v1[] = {
11848 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11849 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11850 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11851 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11852 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11853 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11854 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11856 static const struct bwn_smpair v2[] = {
11857 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11858 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11859 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11860 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11861 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11862 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11863 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11864 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11865 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11866 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11867 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11868 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11869 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11870 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11871 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11872 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11874 static const struct bwn_smpair v3[] = {
11875 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11876 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11877 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11878 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11879 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11880 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11881 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11882 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11884 static const struct bwn_smpair v4[] = {
11885 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11886 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11887 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11888 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11889 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11890 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11891 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11892 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11894 static const struct bwn_smpair v5[] = {
11895 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11896 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11897 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11898 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11899 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11900 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11901 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11902 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11905 uint16_t tmp, tmp2;
11907 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11908 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11909 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11910 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11911 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11912 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11913 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11914 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11915 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11916 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11917 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11918 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11919 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11920 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11921 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11922 for (i = 0; i < N(v1); i++)
11923 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11924 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11925 0xff00, plp->plp_rxpwroffset);
11926 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11927 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11928 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11929 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11930 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11931 if (mac->mac_phy.rev == 0)
11932 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11934 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11936 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11937 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11938 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11940 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11941 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11942 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11943 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11945 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11946 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11947 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11948 0xfff9, (plp->plp_bxarch << 1));
11949 if (mac->mac_phy.rev == 1 &&
11950 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11951 for (i = 0; i < N(v2); i++)
11952 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11954 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11955 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11956 ((mac->mac_phy.rev == 0) &&
11957 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11958 for (i = 0; i < N(v3); i++)
11959 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11961 } else if (mac->mac_phy.rev == 1 ||
11962 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11963 for (i = 0; i < N(v4); i++)
11964 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11967 for (i = 0; i < N(v5); i++)
11968 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11971 if (mac->mac_phy.rev == 1 &&
11972 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11973 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11974 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11975 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11976 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11978 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11979 (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11980 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11981 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11982 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11983 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11984 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11986 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11987 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11988 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11989 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11990 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11991 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11992 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
11993 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
11994 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11996 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
11997 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
11999 if (mac->mac_phy.rev == 1) {
12000 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
12001 tmp2 = (tmp & 0x03e0) >> 5;
12003 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
12004 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
12005 tmp2 = (tmp & 0x1f00) >> 8;
12007 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
12008 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
12009 tmp2 = tmp & 0x00ff;
12011 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
12015 struct bwn_b2062_freq {
12021 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
12023 #define CALC_CTL7(freq, div) \
12024 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
12025 #define CALC_CTL18(freq, div) \
12026 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
12027 #define CALC_CTL19(freq, div) \
12028 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
12029 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12030 struct bwn_softc *sc = mac->mac_sc;
12031 struct ifnet *ifp = sc->sc_ifp;
12032 struct ieee80211com *ic = ifp->if_l2com;
12033 static const struct bwn_b2062_freq freqdata_tab[] = {
12034 { 12000, { 6, 6, 6, 6, 10, 6 } },
12035 { 13000, { 4, 4, 4, 4, 11, 7 } },
12036 { 14400, { 3, 3, 3, 3, 12, 7 } },
12037 { 16200, { 3, 3, 3, 3, 13, 8 } },
12038 { 18000, { 2, 2, 2, 2, 14, 8 } },
12039 { 19200, { 1, 1, 1, 1, 14, 9 } }
12041 static const struct bwn_wpair v1[] = {
12042 { BWN_B2062_N_TXCTL3, 0 },
12043 { BWN_B2062_N_TXCTL4, 0 },
12044 { BWN_B2062_N_TXCTL5, 0 },
12045 { BWN_B2062_N_TXCTL6, 0 },
12046 { BWN_B2062_N_PDNCTL0, 0x40 },
12047 { BWN_B2062_N_PDNCTL0, 0 },
12048 { BWN_B2062_N_CALIB_TS, 0x10 },
12049 { BWN_B2062_N_CALIB_TS, 0 }
12051 const struct bwn_b2062_freq *f = NULL;
12052 uint32_t xtalfreq, ref;
12055 bwn_phy_lp_b2062_tblinit(mac);
12057 for (i = 0; i < N(v1); i++)
12058 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12059 if (mac->mac_phy.rev > 0)
12060 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
12061 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
12062 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12063 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
12065 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
12067 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
12068 ("%s:%d: fail", __func__, __LINE__));
12069 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12070 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
12072 if (xtalfreq <= 30000000) {
12074 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
12077 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
12080 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
12081 CALC_CTL7(xtalfreq, plp->plp_div));
12082 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
12083 CALC_CTL18(xtalfreq, plp->plp_div));
12084 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
12085 CALC_CTL19(xtalfreq, plp->plp_div));
12087 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
12089 for (i = 0; i < N(freqdata_tab); i++) {
12090 if (ref < freqdata_tab[i].freq) {
12091 f = &freqdata_tab[i];
12096 f = &freqdata_tab[N(freqdata_tab) - 1];
12097 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
12098 ((uint16_t)(f->value[1]) << 4) | f->value[0]);
12099 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
12100 ((uint16_t)(f->value[3]) << 4) | f->value[2]);
12101 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
12102 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
12109 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
12112 bwn_phy_lp_b2063_tblinit(mac);
12113 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
12114 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
12115 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
12116 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
12117 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
12118 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
12119 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
12120 if (mac->mac_phy.rev == 2) {
12121 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
12122 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
12123 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
12125 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
12126 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
12131 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
12133 struct bwn_softc *sc = mac->mac_sc;
12134 static const struct bwn_wpair v1[] = {
12135 { BWN_B2063_RX_BB_SP8, 0x0 },
12136 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12137 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12138 { BWN_B2063_RC_CALIB_CTL2, 0x15 },
12139 { BWN_B2063_RC_CALIB_CTL3, 0x70 },
12140 { BWN_B2063_RC_CALIB_CTL4, 0x52 },
12141 { BWN_B2063_RC_CALIB_CTL5, 0x1 },
12142 { BWN_B2063_RC_CALIB_CTL1, 0x7d }
12144 static const struct bwn_wpair v2[] = {
12145 { BWN_B2063_TX_BB_SP3, 0x0 },
12146 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12147 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12148 { BWN_B2063_RC_CALIB_CTL2, 0x55 },
12149 { BWN_B2063_RC_CALIB_CTL3, 0x76 }
12151 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12155 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12157 for (i = 0; i < 2; i++)
12158 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12159 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12160 for (i = 2; i < N(v1); i++)
12161 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12162 for (i = 0; i < 10000; i++) {
12163 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12168 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12169 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12171 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12173 for (i = 0; i < N(v2); i++)
12174 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12175 if (freqxtal == 24000000) {
12176 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12177 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12179 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12180 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12182 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12183 for (i = 0; i < 10000; i++) {
12184 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12188 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12189 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12190 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12194 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12196 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12197 struct bwn_softc *sc = mac->mac_sc;
12198 struct bwn_phy_lp_iq_est ie;
12199 struct bwn_txgain tx_gains;
12200 static const uint32_t pwrtbl[21] = {
12201 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12202 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12203 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12204 0x0004c, 0x0002c, 0x0001a,
12206 uint32_t npwr, ipwr, sqpwr, tmp;
12207 int loopback, i, j, sum, error;
12209 uint8_t txo, bbmult, txpctlmode;
12211 error = bwn_phy_lp_switch_channel(mac, 7);
12213 device_printf(sc->sc_dev,
12214 "failed to change channel to 7 (%d)\n", error);
12215 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12216 bbmult = bwn_phy_lp_get_bbmult(mac);
12218 tx_gains = bwn_phy_lp_get_txgain(mac);
12220 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12221 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12222 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12223 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12224 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12225 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12226 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12228 bwn_phy_lp_get_txpctlmode(mac);
12229 txpctlmode = plp->plp_txpctlmode;
12230 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12233 bwn_phy_lp_set_deaf(mac, 1);
12234 bwn_phy_lp_set_trsw_over(mac, 0, 1);
12235 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12236 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12237 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12238 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12239 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12240 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12241 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12242 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12243 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12244 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12245 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12246 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12247 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12248 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12249 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12250 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12251 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12252 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12253 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12254 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12255 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12256 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12257 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12259 loopback = bwn_phy_lp_loopback(mac);
12260 if (loopback == -1)
12262 bwn_phy_lp_set_rxgain_idx(mac, loopback);
12263 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12264 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12265 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12266 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12269 memset(&ie, 0, sizeof(ie));
12270 for (i = 128; i <= 159; i++) {
12271 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12273 for (j = 5; j <= 25; j++) {
12274 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12275 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12277 sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12278 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12279 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12281 sum += ((ipwr - npwr) * (ipwr - npwr));
12282 if ((i == 128) || (sum < tmp)) {
12283 plp->plp_rccap = i;
12288 bwn_phy_lp_ddfs_turnoff(mac);
12291 bwn_phy_lp_clear_deaf(mac, 1);
12292 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12293 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12295 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12296 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12297 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12298 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12299 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12300 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12301 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12303 bwn_phy_lp_set_bbmult(mac, bbmult);
12305 bwn_phy_lp_set_txgain(mac, &tx_gains);
12306 bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12307 if (plp->plp_rccap)
12308 bwn_phy_lp_set_rccap(mac);
12312 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12314 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12315 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12317 if (mac->mac_phy.rev == 1)
12318 rc_cap = MIN(rc_cap + 5, 15);
12320 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12321 MAX(plp->plp_rccap - 4, 0x80));
12322 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12323 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12324 ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12328 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12335 for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12337 if (r << 1 >= div) {
12339 r = (r << 1) - div;
12348 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12350 struct bwn_softc *sc = mac->mac_sc;
12352 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12354 if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12355 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12356 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12358 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12364 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12367 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12368 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12373 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12375 #define FLAG_A 0x01
12376 #define FLAG_G 0x02
12377 struct bwn_softc *sc = mac->mac_sc;
12378 struct ifnet *ifp = sc->sc_ifp;
12379 struct ieee80211com *ic = ifp->if_l2com;
12380 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12381 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12382 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12383 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12384 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12385 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12386 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12387 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12388 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12389 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12390 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12391 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12392 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12393 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12394 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12395 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12396 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12397 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12398 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12399 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12400 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12401 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12402 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12403 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12404 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12405 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12406 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12407 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12408 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12409 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12410 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12411 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12412 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12413 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12414 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12415 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12416 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12417 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12418 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12419 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12420 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12421 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12422 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12423 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12424 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12425 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12426 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12427 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12429 const struct bwn_b206x_rfinit_entry *br;
12432 for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12433 br = &bwn_b2062_init_tab[i];
12434 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12435 if (br->br_flags & FLAG_G)
12436 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12438 if (br->br_flags & FLAG_A)
12439 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12447 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12449 #define FLAG_A 0x01
12450 #define FLAG_G 0x02
12451 struct bwn_softc *sc = mac->mac_sc;
12452 struct ifnet *ifp = sc->sc_ifp;
12453 struct ieee80211com *ic = ifp->if_l2com;
12454 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12455 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12456 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12457 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12458 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12459 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12460 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12461 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12462 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12463 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12464 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12465 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12466 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12467 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12468 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12469 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12470 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12471 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12472 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12473 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12474 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12475 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12476 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12477 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12478 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12479 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12480 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12481 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12482 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12483 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12484 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12485 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12486 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12487 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12488 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12489 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12490 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12491 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12492 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12493 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12494 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12495 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12496 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12498 const struct bwn_b206x_rfinit_entry *br;
12501 for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12502 br = &bwn_b2063_init_tab[i];
12503 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12504 if (br->br_flags & FLAG_G)
12505 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12507 if (br->br_flags & FLAG_A)
12508 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12516 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12517 int count, void *_data)
12520 uint32_t offset, type;
12521 uint8_t *data = _data;
12523 type = BWN_TAB_GETTYPE(typenoffset);
12524 offset = BWN_TAB_GETOFFSET(typenoffset);
12525 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12527 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12529 for (i = 0; i < count; i++) {
12532 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12535 case BWN_TAB_16BIT:
12536 *((uint16_t *)data) = BWN_PHY_READ(mac,
12537 BWN_PHY_TABLEDATALO);
12540 case BWN_TAB_32BIT:
12541 *((uint32_t *)data) = BWN_PHY_READ(mac,
12542 BWN_PHY_TABLEDATAHI);
12543 *((uint32_t *)data) <<= 16;
12544 *((uint32_t *)data) |= BWN_PHY_READ(mac,
12545 BWN_PHY_TABLEDATALO);
12549 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12555 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12556 int count, const void *_data)
12558 uint32_t offset, type, value;
12559 const uint8_t *data = _data;
12562 type = BWN_TAB_GETTYPE(typenoffset);
12563 offset = BWN_TAB_GETOFFSET(typenoffset);
12564 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12566 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12568 for (i = 0; i < count; i++) {
12573 KASSERT(!(value & ~0xff),
12574 ("%s:%d: fail", __func__, __LINE__));
12575 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12577 case BWN_TAB_16BIT:
12578 value = *((const uint16_t *)data);
12580 KASSERT(!(value & ~0xffff),
12581 ("%s:%d: fail", __func__, __LINE__));
12582 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12584 case BWN_TAB_32BIT:
12585 value = *((const uint32_t *)data);
12587 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12588 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12591 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12596 static struct bwn_txgain
12597 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12599 struct bwn_txgain tg;
12602 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12603 if (mac->mac_phy.rev < 2) {
12604 tmp = BWN_PHY_READ(mac,
12605 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12606 tg.tg_gm = tmp & 0x0007;
12607 tg.tg_pga = (tmp & 0x0078) >> 3;
12608 tg.tg_pad = (tmp & 0x780) >> 7;
12612 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12613 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12614 tg.tg_gm = tmp & 0xff;
12615 tg.tg_pga = (tmp >> 8) & 0xff;
12620 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12623 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12627 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12631 if (mac->mac_phy.rev < 2) {
12632 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12633 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12634 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12635 bwn_phy_lp_set_txgain_override(mac);
12639 pa = bwn_phy_lp_get_pa_gain(mac);
12640 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12641 (tg->tg_pga << 8) | tg->tg_gm);
12642 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12643 tg->tg_pad | (pa << 6));
12644 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12645 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12646 tg->tg_pad | (pa << 8));
12647 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12648 bwn_phy_lp_set_txgain_override(mac);
12652 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12655 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12659 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12661 uint16_t trsw = (tx << 1) | rx;
12663 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12664 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12668 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12670 struct bwn_softc *sc = mac->mac_sc;
12671 struct ifnet *ifp = sc->sc_ifp;
12672 struct ieee80211com *ic = ifp->if_l2com;
12673 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12675 if (mac->mac_phy.rev < 2) {
12677 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12678 ext_lna = (gain & 2) >> 1;
12680 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12681 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12682 0xfbff, ext_lna << 10);
12683 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12684 0xf7ff, ext_lna << 11);
12685 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12687 low_gain = gain & 0xffff;
12688 high_gain = (gain >> 16) & 0xf;
12689 ext_lna = (gain >> 21) & 0x1;
12690 trsw = ~(gain >> 20) & 0x1;
12692 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12693 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12694 0xfdff, ext_lna << 9);
12695 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12696 0xfbff, ext_lna << 10);
12697 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12698 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12699 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12700 tmp = (gain >> 2) & 0x3;
12701 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12703 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12708 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12709 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12710 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12711 if (mac->mac_phy.rev >= 2) {
12712 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12713 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12714 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12715 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12719 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12723 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12725 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12728 plp->plp_crsusr_off = 1;
12730 plp->plp_crssys_off = 1;
12732 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12736 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12738 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12739 struct bwn_softc *sc = mac->mac_sc;
12740 struct ifnet *ifp = sc->sc_ifp;
12741 struct ieee80211com *ic = ifp->if_l2com;
12744 plp->plp_crsusr_off = 0;
12746 plp->plp_crssys_off = 0;
12748 if (plp->plp_crsusr_off || plp->plp_crssys_off)
12751 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12752 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12754 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12757 static unsigned int
12758 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12760 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12761 static uint8_t sqrt_table[256] = {
12762 10, 14, 17, 20, 22, 24, 26, 28,
12763 30, 31, 33, 34, 36, 37, 38, 40,
12764 41, 42, 43, 44, 45, 46, 47, 48,
12765 50, 50, 51, 52, 53, 54, 55, 56,
12766 57, 58, 59, 60, 60, 61, 62, 63,
12767 64, 64, 65, 66, 67, 67, 68, 69,
12768 70, 70, 71, 72, 72, 73, 74, 74,
12769 75, 76, 76, 77, 78, 78, 79, 80,
12770 80, 81, 81, 82, 83, 83, 84, 84,
12771 85, 86, 86, 87, 87, 88, 88, 89,
12772 90, 90, 91, 91, 92, 92, 93, 93,
12773 94, 94, 95, 95, 96, 96, 97, 97,
12774 98, 98, 99, 100, 100, 100, 101, 101,
12775 102, 102, 103, 103, 104, 104, 105, 105,
12776 106, 106, 107, 107, 108, 108, 109, 109,
12777 110, 110, 110, 111, 111, 112, 112, 113,
12778 113, 114, 114, 114, 115, 115, 116, 116,
12779 117, 117, 117, 118, 118, 119, 119, 120,
12780 120, 120, 121, 121, 122, 122, 122, 123,
12781 123, 124, 124, 124, 125, 125, 126, 126,
12782 126, 127, 127, 128, 128, 128, 129, 129,
12783 130, 130, 130, 131, 131, 131, 132, 132,
12784 133, 133, 133, 134, 134, 134, 135, 135,
12785 136, 136, 136, 137, 137, 137, 138, 138,
12786 138, 139, 139, 140, 140, 140, 141, 141,
12787 141, 142, 142, 142, 143, 143, 143, 144,
12788 144, 144, 145, 145, 145, 146, 146, 146,
12789 147, 147, 147, 148, 148, 148, 149, 149,
12790 150, 150, 150, 150, 151, 151, 151, 152,
12791 152, 152, 153, 153, 153, 154, 154, 154,
12792 155, 155, 155, 156, 156, 156, 157, 157,
12793 157, 158, 158, 158, 159, 159, 159, 160
12801 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12805 return (sqrt_table[x - 1] / 10);
12809 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12811 #define CALC_COEFF(_v, _x, _y, _z) do { \
12815 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12817 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12820 #define CALC_COEFF2(_v, _x, _y, _z) do { \
12824 _v = (_y << (31 - _x)) / (_z >> _t); \
12826 _v = (_y << (31 - _x)) / (_z << -_t); \
12828 struct bwn_phy_lp_iq_est ie;
12832 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12836 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12837 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12839 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12843 if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12848 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12849 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12851 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12855 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12856 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12863 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12865 static const uint16_t noisescale[] = {
12866 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12867 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12868 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12869 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12870 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12872 static const uint16_t crsgainnft[] = {
12873 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12874 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12875 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12876 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12879 static const uint16_t filterctl[] = {
12880 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12883 static const uint32_t psctl[] = {
12884 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12885 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12886 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12887 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12888 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12889 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12890 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12891 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12893 static const uint16_t ofdmcckgain_r0[] = {
12894 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12895 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12896 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12897 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12900 static const uint16_t ofdmcckgain_r1[] = {
12901 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12902 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12903 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12904 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12907 static const uint16_t gaindelta[] = {
12908 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12911 static const uint32_t txpwrctl[] = {
12912 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12913 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12914 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12915 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12916 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12917 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12918 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12919 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12920 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12921 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12922 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12923 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12924 0x00000014, 0x00000013, 0x00000012, 0x00000011, 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, 0x00000000, 0x00000000, 0x00000000,
12950 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12951 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12952 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12953 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12954 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12955 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12956 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12957 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12958 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12959 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12960 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12961 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12962 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12963 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12964 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12965 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12966 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12967 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12968 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12969 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12970 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12971 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12972 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12973 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12974 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12975 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12976 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12977 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12978 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12979 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12980 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12981 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12982 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12983 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12984 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12985 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12986 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12987 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12988 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12989 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12990 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12991 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12992 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12993 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12994 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12995 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12996 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12997 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12998 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12999 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13000 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13001 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
13002 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
13003 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
13004 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
13005 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
13006 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
13007 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
13008 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
13009 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
13010 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
13011 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
13012 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
13013 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
13014 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
13015 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
13016 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
13017 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
13018 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
13019 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
13020 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
13021 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
13022 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
13023 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
13024 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
13025 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
13026 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
13030 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13032 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13033 bwn_tab_sigsq_tbl);
13034 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13035 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
13036 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
13037 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
13038 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13039 bwn_tab_pllfrac_tbl);
13040 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13041 bwn_tabl_iqlocal_tbl);
13042 if (mac->mac_phy.rev == 0) {
13043 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
13045 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
13048 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
13050 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
13053 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
13054 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
13058 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
13060 struct bwn_softc *sc = mac->mac_sc;
13062 static const uint16_t noisescale[] = {
13063 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13064 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13065 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13066 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13067 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13068 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13069 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
13071 static const uint32_t filterctl[] = {
13072 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
13073 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
13075 static const uint32_t psctl[] = {
13076 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
13077 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
13078 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
13079 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
13081 static const uint32_t gainidx[] = {
13082 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13083 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13084 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13085 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
13086 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
13087 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
13088 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
13089 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
13090 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
13091 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
13092 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
13093 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
13094 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
13095 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
13096 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
13097 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13098 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13099 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13100 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
13101 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
13102 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
13103 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
13104 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
13105 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
13106 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
13107 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
13108 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
13109 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
13110 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
13111 0x0000001a, 0x64ca55ad, 0x0000001a
13113 static const uint16_t auxgainidx[] = {
13114 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13115 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
13116 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
13119 static const uint16_t swctl[] = {
13120 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13121 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13122 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13123 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
13124 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13125 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13126 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13127 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
13129 static const uint8_t hf[] = {
13130 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
13131 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
13133 static const uint32_t gainval[] = {
13134 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13135 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13136 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13137 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13138 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13139 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13140 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13141 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13142 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13143 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13144 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13145 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13146 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
13147 0x000000f1, 0x00000000, 0x00000000
13149 static const uint16_t gain[] = {
13150 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13151 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13152 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13153 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13154 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13155 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 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,
13161 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13163 static const uint32_t papdeps[] = {
13164 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13165 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13166 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13167 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13168 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13169 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13170 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13171 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13172 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13173 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13174 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13175 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13176 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13178 static const uint32_t papdmult[] = {
13179 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13180 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13181 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13182 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13183 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13184 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13185 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13186 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13187 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13188 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13189 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13190 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13191 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13193 static const uint32_t gainidx_a0[] = {
13194 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13195 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13196 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13197 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13198 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13199 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13200 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13201 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13202 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13203 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13204 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13205 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13206 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13208 static const uint16_t auxgainidx_a0[] = {
13209 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13210 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13211 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13214 static const uint32_t gainval_a0[] = {
13215 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13216 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13217 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13218 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13219 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13220 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13221 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13222 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13223 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13224 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13225 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13226 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13227 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13228 0x000000f7, 0x00000000, 0x00000000
13230 static const uint16_t gain_a0[] = {
13231 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13232 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13233 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13234 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13235 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13236 0x035f, 0x075f, 0x0b5f, 0x0f5f, 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,
13242 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13245 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13247 for (i = 0; i < 704; i++)
13248 bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13250 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13251 bwn_tab_sigsq_tbl);
13252 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13253 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13254 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13255 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13256 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13257 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13258 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13259 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13260 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13261 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13262 bwn_tab_pllfrac_tbl);
13263 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13264 bwn_tabl_iqlocal_tbl);
13265 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13266 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13268 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13269 (siba_get_chiprev(sc->sc_dev) == 0)) {
13270 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13272 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13274 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13276 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13281 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13283 struct bwn_softc *sc = mac->mac_sc;
13284 struct ifnet *ifp = sc->sc_ifp;
13285 struct ieee80211com *ic = ifp->if_l2com;
13286 static struct bwn_txgain_entry txgain_r2[] = {
13287 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13288 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13289 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13290 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13291 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13292 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13293 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13294 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13295 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13296 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13297 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13298 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13299 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13300 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13301 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13302 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13303 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13304 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13305 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13306 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13307 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13308 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13309 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13310 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13311 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13312 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13313 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13314 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13315 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13316 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13317 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13318 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13319 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13320 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13321 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13322 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13323 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13324 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13325 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13326 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13327 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13328 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13329 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13330 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13331 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13332 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13333 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13334 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13335 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13336 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13337 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13338 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13339 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13340 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13341 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13342 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13343 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13344 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13345 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13346 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13347 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13348 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13349 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13350 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13352 static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13353 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13354 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13355 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13356 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13357 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13358 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13359 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13360 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13361 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13362 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13363 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13364 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13365 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13366 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13367 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13368 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13369 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13370 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13371 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13372 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13373 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13374 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13375 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13376 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13377 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13378 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13379 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13380 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13381 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13382 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13383 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13384 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13385 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13386 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13387 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13388 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13389 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13390 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13391 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13392 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13393 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13394 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13395 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13396 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13397 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13398 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13399 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13400 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13401 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13402 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13403 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13404 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13405 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13406 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13407 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13408 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13409 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13410 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13411 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13412 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13413 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13414 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13415 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13416 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13418 static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13419 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13420 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13421 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13422 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13423 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13424 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13425 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13426 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13427 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13428 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13429 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13430 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13431 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13432 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13433 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13434 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13435 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13436 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13437 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13438 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13439 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13440 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13441 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13442 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13443 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13444 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13445 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13446 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13447 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13448 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13449 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13450 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13451 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13452 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13453 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13454 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13455 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13456 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13457 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13458 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13459 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13460 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13461 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13462 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13463 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13464 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13465 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13466 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13467 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13468 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13469 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13470 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13471 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13472 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13473 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13474 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13475 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13476 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13477 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13478 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13479 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13480 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13481 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13482 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13484 static struct bwn_txgain_entry txgain_r0[] = {
13485 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13486 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13487 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13488 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13489 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13490 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13491 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13492 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13493 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13494 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13495 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13496 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13497 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13498 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13499 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13500 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13501 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13502 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13503 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13504 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13505 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13506 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13507 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13508 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13509 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13510 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13511 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13512 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13513 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13514 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13515 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13516 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13517 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13518 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13519 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13520 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13521 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13522 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13523 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13524 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13525 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13526 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13527 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13528 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13529 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13530 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13531 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13532 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13533 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13534 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13535 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13536 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13537 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13538 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13539 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13540 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13541 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13542 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13543 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13544 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13545 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13546 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13547 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13548 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13550 static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13551 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13552 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13553 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13554 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13555 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13556 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13557 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13558 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13559 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13560 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13561 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13562 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13563 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13564 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13565 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13566 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13567 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13568 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13569 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13570 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13571 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13572 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13573 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13574 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13575 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13576 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13577 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13578 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13579 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13580 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13581 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13582 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13583 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13584 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13585 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13586 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13587 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13588 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13589 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13590 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13591 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13592 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13593 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13594 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13595 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13596 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13597 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13598 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13599 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13600 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13601 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13602 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13603 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13604 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13605 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13606 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13607 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13608 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13609 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13610 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13611 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13612 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13613 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13614 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13616 static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13617 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13618 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13619 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13620 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13621 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13622 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13623 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13624 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13625 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13626 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13627 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13628 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13629 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13630 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13631 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13632 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13633 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13634 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13635 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13636 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13637 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13638 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13639 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13640 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13641 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13642 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13643 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13644 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13645 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13646 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13647 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13648 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13649 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13650 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13651 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13652 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13653 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13654 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13655 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13656 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13657 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13658 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13659 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13660 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13661 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13662 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13663 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13664 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13665 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13666 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13667 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13668 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13669 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13670 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13671 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13672 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13673 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13674 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13675 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13676 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13677 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13678 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13679 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13680 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13682 static struct bwn_txgain_entry txgain_r1[] = {
13683 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13684 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13685 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13686 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13687 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13688 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13689 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13690 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13691 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13692 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13693 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13694 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13695 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13696 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13697 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13698 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13699 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13700 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13701 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13702 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13703 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13704 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13705 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13706 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13707 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13708 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13709 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13710 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13711 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13712 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13713 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13714 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13715 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13716 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13717 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13718 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13719 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13720 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13721 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13722 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13723 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13724 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13725 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13726 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13727 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13728 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13729 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13730 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13731 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13732 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13733 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13734 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13735 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13736 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13737 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13738 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13739 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13740 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13741 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13742 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13743 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13744 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13745 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13746 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13747 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13748 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13749 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13750 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13751 { 7, 11, 6, 0, 71 }
13753 static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13754 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13755 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13756 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13757 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13758 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13759 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13760 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13761 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13762 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13763 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13764 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13765 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13766 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13767 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13768 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13769 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13770 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13771 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13772 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13773 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13774 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13775 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13776 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13777 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13778 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13779 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13780 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13781 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13782 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13783 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13784 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13785 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13786 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13787 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13788 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13789 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13790 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13791 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13792 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13793 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13794 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13795 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13796 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13797 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13798 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13799 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13800 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13801 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13802 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13803 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13804 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13805 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13806 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13807 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13808 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13809 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13810 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13811 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13812 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13813 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13814 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13815 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13816 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13817 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13819 static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13820 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13821 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13822 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13823 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13824 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13825 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13826 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13827 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13828 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13829 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13830 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13831 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13832 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13833 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13834 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13835 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13836 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13837 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13838 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13839 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13840 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13841 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13842 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13843 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13844 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13845 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13846 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13847 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13848 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13849 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13850 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13851 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13852 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13853 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13854 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13855 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13856 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13857 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13858 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13859 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13860 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13861 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13862 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13863 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13864 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13865 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13866 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13867 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13868 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13869 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13870 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13871 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13872 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13873 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13874 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13875 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13876 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13877 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13878 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13879 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13880 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13881 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13882 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13883 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13886 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13887 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13888 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13889 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13890 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13893 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13898 if (mac->mac_phy.rev == 0) {
13899 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13900 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13901 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13902 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13903 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13906 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13911 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13912 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13913 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13914 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13915 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13917 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13921 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13923 uint32_t offset, type;
13925 type = BWN_TAB_GETTYPE(typeoffset);
13926 offset = BWN_TAB_GETOFFSET(typeoffset);
13927 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13931 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13932 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13933 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13935 case BWN_TAB_16BIT:
13936 KASSERT(!(value & ~0xffff),
13937 ("%s:%d: fail", __func__, __LINE__));
13938 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13939 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13941 case BWN_TAB_32BIT:
13942 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13943 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13944 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13947 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13952 bwn_phy_lp_loopback(struct bwn_mac *mac)
13954 struct bwn_phy_lp_iq_est ie;
13958 memset(&ie, 0, sizeof(ie));
13960 bwn_phy_lp_set_trsw_over(mac, 1, 1);
13961 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13962 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13963 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13964 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13965 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13966 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13967 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13968 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13969 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13970 for (i = 0; i < 32; i++) {
13971 bwn_phy_lp_set_rxgain_idx(mac, i);
13972 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13973 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13975 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13976 if ((tmp > 4000) && (tmp < 10000)) {
13981 bwn_phy_lp_ddfs_turnoff(mac);
13986 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13989 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
13993 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
13994 int incr1, int incr2, int scale_idx)
13997 bwn_phy_lp_ddfs_turnoff(mac);
13998 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
13999 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
14000 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
14001 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
14002 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
14003 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
14004 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
14005 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
14006 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
14007 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
14011 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
14012 struct bwn_phy_lp_iq_est *ie)
14016 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
14017 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
14018 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
14019 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
14020 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
14022 for (i = 0; i < 500; i++) {
14023 if (!(BWN_PHY_READ(mac,
14024 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
14028 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
14029 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14033 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
14034 ie->ie_iqprod <<= 16;
14035 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
14036 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
14037 ie->ie_ipwr <<= 16;
14038 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
14039 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
14040 ie->ie_qpwr <<= 16;
14041 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
14043 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14048 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
14050 uint32_t offset, type, value;
14052 type = BWN_TAB_GETTYPE(typeoffset);
14053 offset = BWN_TAB_GETOFFSET(typeoffset);
14054 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
14058 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14059 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
14061 case BWN_TAB_16BIT:
14062 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14063 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14065 case BWN_TAB_32BIT:
14066 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14067 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
14069 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14072 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
14080 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
14083 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
14084 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
14088 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
14092 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
14094 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
14098 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
14101 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
14102 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
14106 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
14109 if (mac->mac_phy.rev < 2)
14110 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
14112 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
14113 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
14115 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
14119 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
14122 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
14126 bwn_nbits(int32_t val)
14131 for (tmp = abs(val); tmp != 0; tmp >>= 1)
14137 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
14138 struct bwn_txgain_entry *table)
14142 for (i = offset; i < count; i++)
14143 bwn_phy_lp_gaintbl_write(mac, i, table[i]);
14147 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
14148 struct bwn_txgain_entry data)
14151 if (mac->mac_phy.rev >= 2)
14152 bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14154 bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14158 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14159 struct bwn_txgain_entry te)
14161 struct bwn_softc *sc = mac->mac_sc;
14162 struct ifnet *ifp = sc->sc_ifp;
14163 struct ieee80211com *ic = ifp->if_l2com;
14166 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14168 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14169 if (mac->mac_phy.rev >= 3) {
14170 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14171 (0x10 << 24) : (0x70 << 24));
14173 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14174 (0x14 << 24) : (0x7f << 24));
14176 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14177 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14178 te.te_bbmult << 20 | te.te_dac << 28);
14182 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14183 struct bwn_txgain_entry te)
14186 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14188 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14189 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) |
14191 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14195 bwn_sysctl_node(struct bwn_softc *sc)
14197 device_t dev = sc->sc_dev;
14198 struct bwn_mac *mac;
14199 struct bwn_stats *stats;
14201 /* XXX assume that count of MAC is only 1. */
14203 if ((mac = sc->sc_curmac) == NULL)
14205 stats = &mac->mac_stats;
14207 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14208 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14209 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14210 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14211 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14212 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14213 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14214 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14215 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14218 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14219 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14220 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14224 static device_method_t bwn_methods[] = {
14225 /* Device interface */
14226 DEVMETHOD(device_probe, bwn_probe),
14227 DEVMETHOD(device_attach, bwn_attach),
14228 DEVMETHOD(device_detach, bwn_detach),
14229 DEVMETHOD(device_suspend, bwn_suspend),
14230 DEVMETHOD(device_resume, bwn_resume),
14233 static driver_t bwn_driver = {
14236 sizeof(struct bwn_softc)
14238 static devclass_t bwn_devclass;
14239 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
14240 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14241 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */
14242 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */
14243 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);