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_arp.h>
56 #include <net/if_dl.h>
57 #include <net/if_llc.h>
58 #include <net/if_media.h>
59 #include <net/if_types.h>
61 #include <dev/pci/pcivar.h>
62 #include <dev/pci/pcireg.h>
63 #include <dev/siba/siba_ids.h>
64 #include <dev/siba/sibareg.h>
65 #include <dev/siba/sibavar.h>
67 #include <net80211/ieee80211_var.h>
68 #include <net80211/ieee80211_radiotap.h>
69 #include <net80211/ieee80211_regdomain.h>
70 #include <net80211/ieee80211_phy.h>
71 #include <net80211/ieee80211_ratectl.h>
73 #include <dev/bwn/if_bwnreg.h>
74 #include <dev/bwn/if_bwnvar.h>
76 static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0,
77 "Broadcom driver parameters");
80 * Tunable & sysctl variables.
84 static int bwn_debug = 0;
85 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RW, &bwn_debug, 0,
86 "Broadcom debugging printfs");
87 TUNABLE_INT("hw.bwn.debug", &bwn_debug);
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;
1061 /* XXX not right but it's not used anywhere important */
1062 ic->ic_phytype = IEEE80211_T_OFDM;
1063 ic->ic_opmode = IEEE80211_M_STA;
1065 IEEE80211_C_STA /* station mode supported */
1066 | IEEE80211_C_MONITOR /* monitor mode */
1067 | IEEE80211_C_AHDEMO /* adhoc demo mode */
1068 | IEEE80211_C_SHPREAMBLE /* short preamble supported */
1069 | IEEE80211_C_SHSLOT /* short slot time supported */
1070 | IEEE80211_C_WME /* WME/WMM supported */
1071 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */
1072 | IEEE80211_C_BGSCAN /* capable of bg scanning */
1073 | IEEE80211_C_TXPMGT /* capable of txpow mgt */
1076 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */
1078 /* call MI attach routine. */
1079 ieee80211_ifattach(ic,
1080 bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
1081 siba_sprom_get_mac_80211a(sc->sc_dev) :
1082 siba_sprom_get_mac_80211bg(sc->sc_dev));
1084 ic->ic_headroom = sizeof(struct bwn_txhdr);
1086 /* override default methods */
1087 ic->ic_raw_xmit = bwn_raw_xmit;
1088 ic->ic_updateslot = bwn_updateslot;
1089 ic->ic_update_promisc = bwn_update_promisc;
1090 ic->ic_wme.wme_update = bwn_wme_update;
1092 ic->ic_scan_start = bwn_scan_start;
1093 ic->ic_scan_end = bwn_scan_end;
1094 ic->ic_set_channel = bwn_set_channel;
1096 ic->ic_vap_create = bwn_vap_create;
1097 ic->ic_vap_delete = bwn_vap_delete;
1099 ieee80211_radiotap_attach(ic,
1100 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
1101 BWN_TX_RADIOTAP_PRESENT,
1102 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
1103 BWN_RX_RADIOTAP_PRESENT);
1105 bwn_sysctl_node(sc);
1108 ieee80211_announce(ic);
1113 bwn_phy_detach(struct bwn_mac *mac)
1116 if (mac->mac_phy.detach != NULL)
1117 mac->mac_phy.detach(mac);
1121 bwn_detach(device_t dev)
1123 struct bwn_softc *sc = device_get_softc(dev);
1124 struct bwn_mac *mac = sc->sc_curmac;
1125 struct ifnet *ifp = sc->sc_ifp;
1126 struct ieee80211com *ic = ifp->if_l2com;
1129 sc->sc_flags |= BWN_FLAG_INVALID;
1131 if (device_is_attached(sc->sc_dev)) {
1134 callout_drain(&sc->sc_led_blink_ch);
1135 callout_drain(&sc->sc_rfswitch_ch);
1136 callout_drain(&sc->sc_task_ch);
1137 callout_drain(&sc->sc_watchdog_ch);
1138 bwn_phy_detach(mac);
1140 ieee80211_draintask(ic, &mac->mac_hwreset);
1141 ieee80211_draintask(ic, &mac->mac_txpower);
1142 ieee80211_ifdetach(ic);
1146 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
1147 taskqueue_free(sc->sc_tq);
1149 for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1150 if (mac->mac_intrhand[i] != NULL) {
1151 bus_teardown_intr(dev, mac->mac_res_irq[i],
1152 mac->mac_intrhand[i]);
1153 mac->mac_intrhand[i] = NULL;
1156 bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq);
1157 if (mac->mac_msi != 0)
1158 pci_release_msi(dev);
1160 BWN_LOCK_DESTROY(sc);
1165 bwn_attach_pre(struct bwn_softc *sc)
1171 TAILQ_INIT(&sc->sc_maclist);
1172 callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0);
1173 callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0);
1174 callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0);
1176 sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT,
1177 taskqueue_thread_enqueue, &sc->sc_tq);
1178 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
1179 "%s taskq", device_get_nameunit(sc->sc_dev));
1181 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
1183 device_printf(sc->sc_dev, "can not if_alloc()\n");
1188 /* set these up early for if_printf use */
1189 if_initname(ifp, device_get_name(sc->sc_dev),
1190 device_get_unit(sc->sc_dev));
1193 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1194 ifp->if_init = bwn_init;
1195 ifp->if_ioctl = bwn_ioctl;
1196 ifp->if_start = bwn_start;
1197 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
1198 ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
1199 IFQ_SET_READY(&ifp->if_snd);
1203 fail: BWN_LOCK_DESTROY(sc);
1208 bwn_sprom_bugfixes(device_t dev)
1210 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \
1211 ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \
1212 (siba_get_pci_device(dev) == _device) && \
1213 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \
1214 (siba_get_pci_subdevice(dev) == _subdevice))
1216 if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
1217 siba_get_pci_subdevice(dev) == 0x4e &&
1218 siba_get_pci_revid(dev) > 0x40)
1219 siba_sprom_set_bf_lo(dev,
1220 siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
1221 if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
1222 siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
1223 siba_sprom_set_bf_lo(dev,
1224 siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
1225 if (siba_get_type(dev) == SIBA_TYPE_PCI) {
1226 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1227 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1228 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1229 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1230 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1231 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1232 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1233 siba_sprom_set_bf_lo(dev,
1234 siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
1240 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1242 #define IS_RUNNING(ifp) \
1243 ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
1244 struct bwn_softc *sc = ifp->if_softc;
1245 struct ieee80211com *ic = ifp->if_l2com;
1246 struct ifreq *ifr = (struct ifreq *)data;
1247 int error = 0, startall;
1252 if (IS_RUNNING(ifp)) {
1253 bwn_update_promisc(ifp);
1254 } else if (ifp->if_flags & IFF_UP) {
1255 if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
1262 ieee80211_start_all(ic);
1265 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1268 error = ether_ioctl(ifp, cmd, data);
1278 bwn_start(struct ifnet *ifp)
1280 struct bwn_softc *sc = ifp->if_softc;
1283 bwn_start_locked(ifp);
1288 bwn_start_locked(struct ifnet *ifp)
1290 struct bwn_softc *sc = ifp->if_softc;
1291 struct bwn_mac *mac = sc->sc_curmac;
1292 struct ieee80211_frame *wh;
1293 struct ieee80211_node *ni;
1294 struct ieee80211_key *k;
1297 BWN_ASSERT_LOCKED(sc);
1299 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL ||
1300 mac->mac_status < BWN_MAC_STATUS_STARTED)
1304 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */
1308 if (bwn_tx_isfull(sc, m))
1310 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1312 device_printf(sc->sc_dev, "unexpected NULL ni\n");
1317 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
1318 wh = mtod(m, struct ieee80211_frame *);
1319 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1320 k = ieee80211_crypto_encap(ni, m);
1322 ieee80211_free_node(ni);
1328 wh = NULL; /* Catch any invalid use */
1330 if (bwn_tx_start(sc, ni, m) != 0) {
1332 ieee80211_free_node(ni);
1337 sc->sc_watchdog_timer = 5;
1342 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1344 struct bwn_dma_ring *dr;
1345 struct bwn_mac *mac = sc->sc_curmac;
1346 struct bwn_pio_txqueue *tq;
1347 struct ifnet *ifp = sc->sc_ifp;
1348 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1350 BWN_ASSERT_LOCKED(sc);
1352 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1353 dr = bwn_dma_select(mac, M_WME_GETAC(m));
1354 if (dr->dr_stop == 1 ||
1355 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1360 tq = bwn_pio_select(mac, M_WME_GETAC(m));
1361 if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1362 pktlen > (tq->tq_size - tq->tq_used)) {
1369 IFQ_DRV_PREPEND(&ifp->if_snd, m);
1370 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1375 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1377 struct bwn_mac *mac = sc->sc_curmac;
1380 BWN_ASSERT_LOCKED(sc);
1382 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1387 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1388 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1397 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1399 struct bwn_pio_txpkt *tp;
1400 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1401 struct bwn_softc *sc = mac->mac_sc;
1402 struct bwn_txhdr txhdr;
1408 BWN_ASSERT_LOCKED(sc);
1410 /* XXX TODO send packets after DTIM */
1412 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1413 tp = TAILQ_FIRST(&tq->tq_pktlist);
1417 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1419 device_printf(sc->sc_dev, "tx fail\n");
1423 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1424 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1427 if (siba_get_revid(sc->sc_dev) >= 8) {
1429 * XXX please removes m_defrag(9)
1431 m_new = m_defrag(m, M_NOWAIT);
1432 if (m_new == NULL) {
1433 device_printf(sc->sc_dev,
1434 "%s: can't defrag TX buffer\n",
1438 if (m_new->m_next != NULL)
1439 device_printf(sc->sc_dev,
1440 "TODO: fragmented packets for PIO\n");
1444 ctl32 = bwn_pio_write_multi_4(mac, tq,
1445 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1446 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1447 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1449 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1450 mtod(m_new, const void *), m_new->m_pkthdr.len);
1451 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1452 ctl32 | BWN_PIO8_TXCTL_EOF);
1454 ctl16 = bwn_pio_write_multi_2(mac, tq,
1455 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1456 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1457 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1458 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1459 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1460 ctl16 | BWN_PIO_TXCTL_EOF);
1466 static struct bwn_pio_txqueue *
1467 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1470 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1471 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1475 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1477 return (&mac->mac_method.pio.wme[WME_AC_BK]);
1479 return (&mac->mac_method.pio.wme[WME_AC_VI]);
1481 return (&mac->mac_method.pio.wme[WME_AC_VO]);
1483 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1488 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1490 #define BWN_GET_TXHDRCACHE(slot) \
1491 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)])
1492 struct bwn_dma *dma = &mac->mac_method.dma;
1493 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1494 struct bwn_dmadesc_generic *desc;
1495 struct bwn_dmadesc_meta *mt;
1496 struct bwn_softc *sc = mac->mac_sc;
1497 struct ifnet *ifp = sc->sc_ifp;
1498 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1499 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1501 BWN_ASSERT_LOCKED(sc);
1502 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1504 /* XXX send after DTIM */
1506 slot = bwn_dma_getslot(dr);
1507 dr->getdesc(dr, slot, &desc, &mt);
1508 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1509 ("%s:%d: fail", __func__, __LINE__));
1511 error = bwn_set_txhdr(dr->dr_mac, ni, m,
1512 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1513 BWN_DMA_COOKIE(dr, slot));
1516 error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap,
1517 BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr,
1518 &mt->mt_paddr, BUS_DMA_NOWAIT);
1520 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1524 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1525 BUS_DMASYNC_PREWRITE);
1526 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1527 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1528 BUS_DMASYNC_PREWRITE);
1530 slot = bwn_dma_getslot(dr);
1531 dr->getdesc(dr, slot, &desc, &mt);
1532 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1533 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1537 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1538 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1539 if (error && error != EFBIG) {
1540 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1544 if (error) { /* error == EFBIG */
1547 m_new = m_defrag(m, M_NOWAIT);
1548 if (m_new == NULL) {
1549 if_printf(ifp, "%s: can't defrag TX buffer\n",
1558 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1559 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1561 if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
1566 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1567 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1568 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1569 BUS_DMASYNC_PREWRITE);
1571 /* XXX send after DTIM */
1573 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1576 dr->dr_curslot = backup[0];
1577 dr->dr_usedslot = backup[1];
1579 #undef BWN_GET_TXHDRCACHE
1583 bwn_watchdog(void *arg)
1585 struct bwn_softc *sc = arg;
1586 struct ifnet *ifp = sc->sc_ifp;
1588 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1589 if_printf(ifp, "device timeout\n");
1592 callout_schedule(&sc->sc_watchdog_ch, hz);
1596 bwn_attach_core(struct bwn_mac *mac)
1598 struct bwn_softc *sc = mac->mac_sc;
1599 int error, have_bg = 0, have_a = 0;
1602 KASSERT(siba_get_revid(sc->sc_dev) >= 5,
1603 ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
1605 siba_powerup(sc->sc_dev, 0);
1607 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
1609 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1610 error = bwn_phy_getinfo(mac, high);
1614 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1615 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1616 if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
1617 siba_get_pci_device(sc->sc_dev) != 0x4319 &&
1618 siba_get_pci_device(sc->sc_dev) != 0x4324) {
1619 have_a = have_bg = 0;
1620 if (mac->mac_phy.type == BWN_PHYTYPE_A)
1622 else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1623 mac->mac_phy.type == BWN_PHYTYPE_N ||
1624 mac->mac_phy.type == BWN_PHYTYPE_LP)
1627 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1628 mac->mac_phy.type));
1630 /* XXX turns off PHY A because it's not supported */
1631 if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1632 mac->mac_phy.type != BWN_PHYTYPE_N) {
1637 if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1638 mac->mac_phy.attach = bwn_phy_g_attach;
1639 mac->mac_phy.detach = bwn_phy_g_detach;
1640 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1641 mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1642 mac->mac_phy.init = bwn_phy_g_init;
1643 mac->mac_phy.exit = bwn_phy_g_exit;
1644 mac->mac_phy.phy_read = bwn_phy_g_read;
1645 mac->mac_phy.phy_write = bwn_phy_g_write;
1646 mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1647 mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1648 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1649 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1650 mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1651 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1652 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1653 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1654 mac->mac_phy.set_im = bwn_phy_g_im;
1655 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1656 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1657 mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1658 mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1659 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1660 mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1661 mac->mac_phy.init = bwn_phy_lp_init;
1662 mac->mac_phy.phy_read = bwn_phy_lp_read;
1663 mac->mac_phy.phy_write = bwn_phy_lp_write;
1664 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1665 mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1666 mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1667 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1668 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1669 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1670 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1671 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1672 mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1674 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1680 mac->mac_phy.gmode = have_bg;
1681 if (mac->mac_phy.attach != NULL) {
1682 error = mac->mac_phy.attach(mac);
1684 device_printf(sc->sc_dev, "failed\n");
1689 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1691 error = bwn_chiptest(mac);
1694 error = bwn_setup_channels(mac, have_bg, have_a);
1696 device_printf(sc->sc_dev, "failed to setup channels\n");
1700 if (sc->sc_curmac == NULL)
1701 sc->sc_curmac = mac;
1703 error = bwn_dma_attach(mac);
1705 device_printf(sc->sc_dev, "failed to initialize DMA\n");
1709 mac->mac_phy.switch_analog(mac, 0);
1711 siba_dev_down(sc->sc_dev, 0);
1713 siba_powerdown(sc->sc_dev);
1718 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1720 struct bwn_softc *sc = mac->mac_sc;
1723 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1725 siba_dev_up(sc->sc_dev, flags);
1728 low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1729 ~BWN_TGSLOW_PHYRESET;
1730 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
1731 siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1733 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1734 siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1737 if (mac->mac_phy.switch_analog != NULL)
1738 mac->mac_phy.switch_analog(mac, 1);
1740 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1741 if (flags & BWN_TGSLOW_SUPPORT_G)
1742 ctl |= BWN_MACCTL_GMODE;
1743 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1747 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1749 struct bwn_phy *phy = &mac->mac_phy;
1750 struct bwn_softc *sc = mac->mac_sc;
1754 tmp = BWN_READ_2(mac, BWN_PHYVER);
1755 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1757 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1758 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1759 phy->rev = (tmp & BWN_PHYVER_VERSION);
1760 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1761 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1762 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1763 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1764 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1765 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1769 if (siba_get_chipid(sc->sc_dev) == 0x4317) {
1770 if (siba_get_chiprev(sc->sc_dev) == 0)
1772 else if (siba_get_chiprev(sc->sc_dev) == 1)
1777 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1778 tmp = BWN_READ_2(mac, BWN_RFDATALO);
1779 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1780 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1782 phy->rf_rev = (tmp & 0xf0000000) >> 28;
1783 phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1784 phy->rf_manuf = (tmp & 0x00000fff);
1785 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */
1787 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1788 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1789 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1790 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1791 (phy->type == BWN_PHYTYPE_N &&
1792 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1793 (phy->type == BWN_PHYTYPE_LP &&
1794 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1799 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1801 phy->type, phy->rev, phy->analog);
1804 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1806 phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1811 bwn_chiptest(struct bwn_mac *mac)
1813 #define TESTVAL0 0x55aaaa55
1814 #define TESTVAL1 0xaa5555aa
1815 struct bwn_softc *sc = mac->mac_sc;
1820 backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1822 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1823 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1825 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1826 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1829 bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1831 if ((siba_get_revid(sc->sc_dev) >= 3) &&
1832 (siba_get_revid(sc->sc_dev) <= 10)) {
1833 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1834 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1835 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1837 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1840 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1842 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1843 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1850 device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1854 #define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1855 #define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1858 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1860 struct bwn_softc *sc = mac->mac_sc;
1861 struct ifnet *ifp = sc->sc_ifp;
1862 struct ieee80211com *ic = ifp->if_l2com;
1864 memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1868 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1869 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1870 if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1872 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1873 &ic->ic_nchans, &bwn_chantable_n,
1874 IEEE80211_CHAN_HTA);
1877 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1878 &ic->ic_nchans, &bwn_chantable_a,
1882 mac->mac_phy.supports_2ghz = have_bg;
1883 mac->mac_phy.supports_5ghz = have_a;
1885 return (ic->ic_nchans == 0 ? ENXIO : 0);
1889 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1893 BWN_ASSERT_LOCKED(mac->mac_sc);
1895 if (way == BWN_SHARED) {
1896 KASSERT((offset & 0x0001) == 0,
1897 ("%s:%d warn", __func__, __LINE__));
1898 if (offset & 0x0003) {
1899 bwn_shm_ctlword(mac, way, offset >> 2);
1900 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1902 bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1903 ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1908 bwn_shm_ctlword(mac, way, offset);
1909 ret = BWN_READ_4(mac, BWN_SHM_DATA);
1915 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1919 BWN_ASSERT_LOCKED(mac->mac_sc);
1921 if (way == BWN_SHARED) {
1922 KASSERT((offset & 0x0001) == 0,
1923 ("%s:%d warn", __func__, __LINE__));
1924 if (offset & 0x0003) {
1925 bwn_shm_ctlword(mac, way, offset >> 2);
1926 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1931 bwn_shm_ctlword(mac, way, offset);
1932 ret = BWN_READ_2(mac, BWN_SHM_DATA);
1939 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1947 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1951 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1954 BWN_ASSERT_LOCKED(mac->mac_sc);
1956 if (way == BWN_SHARED) {
1957 KASSERT((offset & 0x0001) == 0,
1958 ("%s:%d warn", __func__, __LINE__));
1959 if (offset & 0x0003) {
1960 bwn_shm_ctlword(mac, way, offset >> 2);
1961 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1962 (value >> 16) & 0xffff);
1963 bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1964 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1969 bwn_shm_ctlword(mac, way, offset);
1970 BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1974 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1977 BWN_ASSERT_LOCKED(mac->mac_sc);
1979 if (way == BWN_SHARED) {
1980 KASSERT((offset & 0x0001) == 0,
1981 ("%s:%d warn", __func__, __LINE__));
1982 if (offset & 0x0003) {
1983 bwn_shm_ctlword(mac, way, offset >> 2);
1984 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1989 bwn_shm_ctlword(mac, way, offset);
1990 BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1994 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
1999 c->ic_flags = flags;
2002 c->ic_maxpower = 2 * txpow;
2003 c->ic_maxregpower = txpow;
2007 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
2008 const struct bwn_channelinfo *ci, int flags)
2010 struct ieee80211_channel *c;
2013 c = &chans[*nchans];
2015 for (i = 0; i < ci->nchannels; i++) {
2016 const struct bwn_channel *hc;
2018 hc = &ci->channels[i];
2019 if (*nchans >= maxchans)
2021 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
2023 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
2024 /* g channel have a separate b-only entry */
2025 if (*nchans >= maxchans)
2028 c[-1].ic_flags = IEEE80211_CHAN_B;
2031 if (flags == IEEE80211_CHAN_HTG) {
2032 /* HT g channel have a separate g-only entry */
2033 if (*nchans >= maxchans)
2035 c[-1].ic_flags = IEEE80211_CHAN_G;
2037 c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2038 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */
2041 if (flags == IEEE80211_CHAN_HTA) {
2042 /* HT a channel have a separate a-only entry */
2043 if (*nchans >= maxchans)
2045 c[-1].ic_flags = IEEE80211_CHAN_A;
2047 c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2048 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */
2055 bwn_phy_g_attach(struct bwn_mac *mac)
2057 struct bwn_softc *sc = mac->mac_sc;
2058 struct bwn_phy *phy = &mac->mac_phy;
2059 struct bwn_phy_g *pg = &phy->phy_g;
2061 int16_t pab0, pab1, pab2;
2062 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2065 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
2066 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
2067 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
2068 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
2070 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
2071 device_printf(sc->sc_dev, "not supported anymore\n");
2074 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2076 pg->pg_idletssi = 52;
2077 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2081 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2082 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
2083 if (pg->pg_tssi2dbm == NULL) {
2084 device_printf(sc->sc_dev, "failed to allocate buffer\n");
2087 for (i = 0; i < 64; i++) {
2088 int32_t m1, m2, f, q, delta;
2091 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2092 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2097 device_printf(sc->sc_dev,
2098 "failed to generate tssi2dBm\n");
2099 free(pg->pg_tssi2dbm, M_DEVBUF);
2102 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2107 } while (delta >= 2);
2109 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2113 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2118 bwn_phy_g_detach(struct bwn_mac *mac)
2120 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2122 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2123 free(pg->pg_tssi2dbm, M_DEVBUF);
2124 pg->pg_tssi2dbm = NULL;
2130 bwn_phy_g_init_pre(struct bwn_mac *mac)
2132 struct bwn_phy *phy = &mac->mac_phy;
2133 struct bwn_phy_g *pg = &phy->phy_g;
2138 tssi2dbm = pg->pg_tssi2dbm;
2139 idletssi = pg->pg_idletssi;
2141 memset(pg, 0, sizeof(*pg));
2143 pg->pg_tssi2dbm = tssi2dbm;
2144 pg->pg_idletssi = idletssi;
2146 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2148 for (i = 0; i < N(pg->pg_nrssi); i++)
2149 pg->pg_nrssi[i] = -1000;
2150 for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2151 pg->pg_nrssi_lt[i] = i;
2152 pg->pg_lofcal = 0xffff;
2153 pg->pg_initval = 0xffff;
2154 pg->pg_immode = BWN_IMMODE_NONE;
2155 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2156 pg->pg_avgtssi = 0xff;
2158 pg->pg_loctl.tx_bias = 0xff;
2159 TAILQ_INIT(&pg->pg_loctl.calib_list);
2163 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2165 struct bwn_phy *phy = &mac->mac_phy;
2166 struct bwn_phy_g *pg = &phy->phy_g;
2167 struct bwn_softc *sc = mac->mac_sc;
2168 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2169 static const struct bwn_rfatt rfatt0[] = {
2170 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
2171 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2174 static const struct bwn_rfatt rfatt1[] = {
2175 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2178 static const struct bwn_rfatt rfatt2[] = {
2179 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2182 static const struct bwn_bbatt bbatt_0[] = {
2183 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2186 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2188 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2189 pg->pg_bbatt.att = 0;
2191 pg->pg_bbatt.att = 2;
2193 /* prepare Radio Attenuation */
2194 pg->pg_rfatt.padmix = 0;
2196 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
2197 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
2198 if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
2199 pg->pg_rfatt.att = 2;
2201 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
2202 pg->pg_rfatt.att = 3;
2207 if (phy->type == BWN_PHYTYPE_A) {
2208 pg->pg_rfatt.att = 0x60;
2212 switch (phy->rf_ver) {
2214 switch (phy->rf_rev) {
2216 pg->pg_rfatt.att = 5;
2219 if (phy->type == BWN_PHYTYPE_G) {
2220 if (siba_get_pci_subvendor(sc->sc_dev) ==
2221 SIBA_BOARDVENDOR_BCM &&
2222 siba_get_pci_subdevice(sc->sc_dev) ==
2223 SIBA_BOARD_BCM4309G &&
2224 siba_get_pci_revid(sc->sc_dev) >= 30)
2225 pg->pg_rfatt.att = 3;
2226 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2227 SIBA_BOARDVENDOR_BCM &&
2228 siba_get_pci_subdevice(sc->sc_dev) ==
2230 pg->pg_rfatt.att = 3;
2232 pg->pg_rfatt.att = 1;
2234 if (siba_get_pci_subvendor(sc->sc_dev) ==
2235 SIBA_BOARDVENDOR_BCM &&
2236 siba_get_pci_subdevice(sc->sc_dev) ==
2237 SIBA_BOARD_BCM4309G &&
2238 siba_get_pci_revid(sc->sc_dev) >= 30)
2239 pg->pg_rfatt.att = 7;
2241 pg->pg_rfatt.att = 6;
2245 if (phy->type == BWN_PHYTYPE_G) {
2246 if (siba_get_pci_subvendor(sc->sc_dev) ==
2247 SIBA_BOARDVENDOR_BCM &&
2248 siba_get_pci_subdevice(sc->sc_dev) ==
2249 SIBA_BOARD_BCM4309G &&
2250 siba_get_pci_revid(sc->sc_dev) >= 30)
2251 pg->pg_rfatt.att = 3;
2252 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2253 SIBA_BOARDVENDOR_BCM &&
2254 siba_get_pci_subdevice(sc->sc_dev) ==
2256 pg->pg_rfatt.att = 5;
2257 else if (siba_get_chipid(sc->sc_dev) == 0x4320)
2258 pg->pg_rfatt.att = 4;
2260 pg->pg_rfatt.att = 3;
2262 pg->pg_rfatt.att = 6;
2265 pg->pg_rfatt.att = 5;
2269 pg->pg_rfatt.att = 1;
2273 pg->pg_rfatt.att = 5;
2276 pg->pg_rfatt.att = 0xa;
2277 pg->pg_rfatt.padmix = 1;
2281 pg->pg_rfatt.att = 5;
2286 switch (phy->rf_rev) {
2288 pg->pg_rfatt.att = 6;
2293 pg->pg_rfatt.att = 5;
2295 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2297 if (!bwn_has_hwpctl(mac)) {
2298 lo->rfatt.array = rfatt0;
2299 lo->rfatt.len = N(rfatt0);
2304 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2305 lo->rfatt.array = rfatt1;
2306 lo->rfatt.len = N(rfatt1);
2311 lo->rfatt.array = rfatt2;
2312 lo->rfatt.len = N(rfatt2);
2316 lo->bbatt.array = bbatt_0;
2317 lo->bbatt.len = N(bbatt_0);
2321 BWN_READ_4(mac, BWN_MACCTL);
2322 if (phy->rev == 1) {
2324 bwn_reset_core(mac, 0);
2325 bwn_phy_g_init_sub(mac);
2327 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2333 bwn_phy_g_txctl(struct bwn_mac *mac)
2335 struct bwn_phy *phy = &mac->mac_phy;
2337 if (phy->rf_ver != 0x2050)
2339 if (phy->rf_rev == 1)
2340 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2341 if (phy->rf_rev < 6)
2342 return (BWN_TXCTL_PA2DB);
2343 if (phy->rf_rev == 8)
2344 return (BWN_TXCTL_TXMIX);
2349 bwn_phy_g_init(struct bwn_mac *mac)
2352 bwn_phy_g_init_sub(mac);
2357 bwn_phy_g_exit(struct bwn_mac *mac)
2359 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2360 struct bwn_lo_calib *cal, *tmp;
2364 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2365 TAILQ_REMOVE(&lo->calib_list, cal, list);
2366 free(cal, M_DEVBUF);
2371 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2374 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2375 return (BWN_READ_2(mac, BWN_PHYDATA));
2379 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2382 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2383 BWN_WRITE_2(mac, BWN_PHYDATA, value);
2387 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2390 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2391 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2392 return (BWN_READ_2(mac, BWN_RFDATALO));
2396 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2399 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2400 BWN_WRITE_2(mac, BWN_RFCTL, reg);
2401 BWN_WRITE_2(mac, BWN_RFDATALO, value);
2405 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2408 return (mac->mac_phy.rev >= 6);
2412 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2414 struct bwn_phy *phy = &mac->mac_phy;
2415 struct bwn_phy_g *pg = &phy->phy_g;
2416 unsigned int channel;
2417 uint16_t rfover, rfoverval;
2423 BWN_PHY_WRITE(mac, 0x15, 0x8000);
2424 BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2425 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2426 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2427 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2428 pg->pg_radioctx_over);
2429 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2430 pg->pg_radioctx_overval);
2431 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2433 channel = phy->chan;
2434 bwn_phy_g_switch_chan(mac, 6, 1);
2435 bwn_phy_g_switch_chan(mac, channel, 0);
2439 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2440 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2441 pg->pg_radioctx_over = rfover;
2442 pg->pg_radioctx_overval = rfoverval;
2443 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2444 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2445 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2449 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2452 if ((newchan < 1) || (newchan > 14))
2454 bwn_phy_g_switch_chan(mac, newchan, 0);
2460 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2467 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2469 struct bwn_phy *phy = &mac->mac_phy;
2474 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2477 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2478 bwn_hf_write(mac, hf);
2480 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2481 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2482 ((autodiv ? BWN_ANTAUTO1 : antenna)
2483 << BWN_PHY_BBANDCFG_RXANT_SHIFT));
2486 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2487 if (antenna == BWN_ANTAUTO1)
2488 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2490 tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2491 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2493 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2495 tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2497 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2498 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2499 if (phy->rev >= 2) {
2500 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2501 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2502 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2503 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2506 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2508 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2509 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2513 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2515 hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2516 bwn_hf_write(mac, hf);
2520 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2522 struct bwn_phy *phy = &mac->mac_phy;
2523 struct bwn_phy_g *pg = &phy->phy_g;
2525 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2526 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2528 if (phy->rev == 0 || !phy->gmode)
2531 pg->pg_aci_wlan_automatic = 0;
2536 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2538 struct bwn_phy *phy = &mac->mac_phy;
2539 struct bwn_phy_g *pg = &phy->phy_g;
2540 struct bwn_softc *sc = mac->mac_sc;
2547 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2549 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2550 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2551 if (cck < 0 && ofdm < 0) {
2552 if (ignore_tssi == 0)
2553 return (BWN_TXPWR_RES_DONE);
2557 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2558 if (pg->pg_avgtssi != 0xff)
2559 tssi = (tssi + pg->pg_avgtssi) / 2;
2560 pg->pg_avgtssi = tssi;
2561 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2563 max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2564 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2567 device_printf(sc->sc_dev, "invalid max TX-power value\n");
2569 siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2572 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2573 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2574 tssi, 0x00), 0x3f)]);
2576 return (BWN_TXPWR_RES_DONE);
2578 rfatt = -((power + 7) / 8);
2579 bbatt = (-(power / 2)) - (4 * rfatt);
2580 if ((rfatt == 0) && (bbatt == 0))
2581 return (BWN_TXPWR_RES_DONE);
2582 pg->pg_bbatt_delta = bbatt;
2583 pg->pg_rfatt_delta = rfatt;
2584 return (BWN_TXPWR_RES_NEED_ADJUST);
2588 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2590 struct bwn_phy *phy = &mac->mac_phy;
2591 struct bwn_phy_g *pg = &phy->phy_g;
2592 struct bwn_softc *sc = mac->mac_sc;
2596 bwn_mac_suspend(mac);
2598 BWN_ASSERT_LOCKED(sc);
2600 bbatt = pg->pg_bbatt.att;
2601 bbatt += pg->pg_bbatt_delta;
2602 rfatt = pg->pg_rfatt.att;
2603 rfatt += pg->pg_rfatt_delta;
2605 bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2606 txctl = pg->pg_txctl;
2607 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2610 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2613 } else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2615 bbatt += 4 * (rfatt - 2);
2618 } else if (rfatt > 4 && txctl) {
2629 pg->pg_txctl = txctl;
2630 bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2631 pg->pg_rfatt.att = rfatt;
2632 pg->pg_bbatt.att = bbatt;
2634 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2638 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2641 bwn_phy_unlock(mac);
2643 bwn_mac_enable(mac);
2647 bwn_phy_g_task_15s(struct bwn_mac *mac)
2649 struct bwn_phy *phy = &mac->mac_phy;
2650 struct bwn_phy_g *pg = &phy->phy_g;
2651 struct bwn_softc *sc = mac->mac_sc;
2652 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2653 unsigned long expire, now;
2654 struct bwn_lo_calib *cal, *tmp;
2655 uint8_t expired = 0;
2657 bwn_mac_suspend(mac);
2663 if (bwn_has_hwpctl(mac)) {
2664 expire = now - BWN_LO_PWRVEC_EXPIRE;
2665 if (time_before(lo->pwr_vec_read_time, expire)) {
2666 bwn_lo_get_powervector(mac);
2667 bwn_phy_g_dc_lookup_init(mac, 0);
2672 expire = now - BWN_LO_CALIB_EXPIRE;
2673 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2674 if (!time_before(cal->calib_time, expire))
2676 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2677 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2678 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2682 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2683 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2684 cal->ctl.i, cal->ctl.q);
2686 TAILQ_REMOVE(&lo->calib_list, cal, list);
2687 free(cal, M_DEVBUF);
2689 if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2690 cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2693 device_printf(sc->sc_dev,
2694 "failed to recalibrate LO\n");
2697 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2698 bwn_lo_write(mac, &cal->ctl);
2702 bwn_mac_enable(mac);
2706 bwn_phy_g_task_60s(struct bwn_mac *mac)
2708 struct bwn_phy *phy = &mac->mac_phy;
2709 struct bwn_softc *sc = mac->mac_sc;
2710 uint8_t old = phy->chan;
2712 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2715 bwn_mac_suspend(mac);
2716 bwn_nrssi_slope_11g(mac);
2717 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2718 bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2719 bwn_switch_channel(mac, old);
2721 bwn_mac_enable(mac);
2725 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2728 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2732 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2733 const struct ieee80211_bpf_params *params)
2735 struct ieee80211com *ic = ni->ni_ic;
2736 struct ifnet *ifp = ic->ic_ifp;
2737 struct bwn_softc *sc = ifp->if_softc;
2738 struct bwn_mac *mac = sc->sc_curmac;
2740 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
2741 mac->mac_status < BWN_MAC_STATUS_STARTED) {
2742 ieee80211_free_node(ni);
2748 if (bwn_tx_isfull(sc, m)) {
2749 ieee80211_free_node(ni);
2756 if (bwn_tx_start(sc, ni, m) != 0) {
2758 ieee80211_free_node(ni);
2761 sc->sc_watchdog_timer = 5;
2767 * Callback from the 802.11 layer to update the slot time
2768 * based on the current setting. We use it to notify the
2769 * firmware of ERP changes and the f/w takes care of things
2770 * like slot time and preamble.
2773 bwn_updateslot(struct ifnet *ifp)
2775 struct bwn_softc *sc = ifp->if_softc;
2776 struct ieee80211com *ic = ifp->if_l2com;
2777 struct bwn_mac *mac;
2780 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
2781 mac = (struct bwn_mac *)sc->sc_curmac;
2782 bwn_set_slot_time(mac,
2783 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2789 * Callback from the 802.11 layer after a promiscuous mode change.
2790 * Note this interface does not check the operating mode as this
2791 * is an internal callback and we are expected to honor the current
2792 * state (e.g. this is used for setting the interface in promiscuous
2793 * mode when operating in hostap mode to do ACS).
2796 bwn_update_promisc(struct ifnet *ifp)
2798 struct bwn_softc *sc = ifp->if_softc;
2799 struct bwn_mac *mac = sc->sc_curmac;
2802 mac = sc->sc_curmac;
2803 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2804 if (ifp->if_flags & IFF_PROMISC)
2805 sc->sc_filters |= BWN_MACCTL_PROMISC;
2807 sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2808 bwn_set_opmode(mac);
2814 * Callback from the 802.11 layer to update WME parameters.
2817 bwn_wme_update(struct ieee80211com *ic)
2819 struct bwn_softc *sc = ic->ic_ifp->if_softc;
2820 struct bwn_mac *mac = sc->sc_curmac;
2821 struct wmeParams *wmep;
2825 mac = sc->sc_curmac;
2826 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2827 bwn_mac_suspend(mac);
2828 for (i = 0; i < N(sc->sc_wmeParams); i++) {
2829 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2830 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2832 bwn_mac_enable(mac);
2839 bwn_scan_start(struct ieee80211com *ic)
2841 struct ifnet *ifp = ic->ic_ifp;
2842 struct bwn_softc *sc = ifp->if_softc;
2843 struct bwn_mac *mac;
2846 mac = sc->sc_curmac;
2847 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2848 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2849 bwn_set_opmode(mac);
2850 /* disable CFP update during scan */
2851 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2857 bwn_scan_end(struct ieee80211com *ic)
2859 struct ifnet *ifp = ic->ic_ifp;
2860 struct bwn_softc *sc = ifp->if_softc;
2861 struct bwn_mac *mac;
2864 mac = sc->sc_curmac;
2865 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2866 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2867 bwn_set_opmode(mac);
2868 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2874 bwn_set_channel(struct ieee80211com *ic)
2876 struct ifnet *ifp = ic->ic_ifp;
2877 struct bwn_softc *sc = ifp->if_softc;
2878 struct bwn_mac *mac = sc->sc_curmac;
2879 struct bwn_phy *phy = &mac->mac_phy;
2884 error = bwn_switch_band(sc, ic->ic_curchan);
2887 bwn_mac_suspend(mac);
2888 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2889 chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2890 if (chan != phy->chan)
2891 bwn_switch_channel(mac, chan);
2893 /* TX power level */
2894 if (ic->ic_curchan->ic_maxpower != 0 &&
2895 ic->ic_curchan->ic_maxpower != phy->txpower) {
2896 phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2897 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2898 BWN_TXPWR_IGNORE_TSSI);
2901 bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2902 if (phy->set_antenna)
2903 phy->set_antenna(mac, BWN_ANT_DEFAULT);
2905 if (sc->sc_rf_enabled != phy->rf_on) {
2906 if (sc->sc_rf_enabled) {
2908 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2909 device_printf(sc->sc_dev,
2910 "please turn on the RF switch\n");
2912 bwn_rf_turnoff(mac);
2915 bwn_mac_enable(mac);
2919 * Setup radio tap channel freq and flags
2921 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2922 htole16(ic->ic_curchan->ic_freq);
2923 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2924 htole16(ic->ic_curchan->ic_flags & 0xffff);
2929 static struct ieee80211vap *
2930 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
2931 enum ieee80211_opmode opmode, int flags,
2932 const uint8_t bssid[IEEE80211_ADDR_LEN],
2933 const uint8_t mac0[IEEE80211_ADDR_LEN])
2935 struct ifnet *ifp = ic->ic_ifp;
2936 struct bwn_softc *sc = ifp->if_softc;
2937 struct ieee80211vap *vap;
2938 struct bwn_vap *bvp;
2939 uint8_t mac[IEEE80211_ADDR_LEN];
2941 IEEE80211_ADDR_COPY(mac, mac0);
2943 case IEEE80211_M_HOSTAP:
2944 case IEEE80211_M_MBSS:
2945 case IEEE80211_M_STA:
2946 case IEEE80211_M_WDS:
2947 case IEEE80211_M_MONITOR:
2948 case IEEE80211_M_IBSS:
2949 case IEEE80211_M_AHDEMO:
2955 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
2957 bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap),
2958 M_80211_VAP, M_NOWAIT | M_ZERO);
2960 device_printf(sc->sc_dev, "failed to allocate a buffer\n");
2964 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
2965 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
2966 /* override with driver methods */
2967 bvp->bv_newstate = vap->iv_newstate;
2968 vap->iv_newstate = bwn_newstate;
2970 /* override max aid so sta's cannot assoc when we're out of sta id's */
2971 vap->iv_max_aid = BWN_STAID_MAX;
2973 ieee80211_ratectl_init(vap);
2975 /* complete setup */
2976 ieee80211_vap_attach(vap, ieee80211_media_change,
2977 ieee80211_media_status);
2982 bwn_vap_delete(struct ieee80211vap *vap)
2984 struct bwn_vap *bvp = BWN_VAP(vap);
2986 ieee80211_ratectl_deinit(vap);
2987 ieee80211_vap_detach(vap);
2988 free(bvp, M_80211_VAP);
2994 struct bwn_softc *sc = arg;
2995 struct ifnet *ifp = sc->sc_ifp;
2996 struct ieee80211com *ic = ifp->if_l2com;
2999 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
3000 __func__, ifp->if_flags);
3003 error = bwn_init_locked(sc);
3007 ieee80211_start_all(ic); /* start all vap's */
3011 bwn_init_locked(struct bwn_softc *sc)
3013 struct bwn_mac *mac;
3014 struct ifnet *ifp = sc->sc_ifp;
3017 BWN_ASSERT_LOCKED(sc);
3019 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
3020 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
3023 sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
3024 sc->sc_rf_enabled = 1;
3026 mac = sc->sc_curmac;
3027 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
3028 error = bwn_core_init(mac);
3032 if (mac->mac_status == BWN_MAC_STATUS_INITED)
3033 bwn_core_start(mac);
3035 bwn_set_opmode(mac);
3036 bwn_set_pretbtt(mac);
3037 bwn_spu_setdelay(mac, 0);
3038 bwn_set_macaddr(mac);
3040 ifp->if_drv_flags |= IFF_DRV_RUNNING;
3041 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
3042 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
3048 bwn_stop(struct bwn_softc *sc, int statechg)
3052 bwn_stop_locked(sc, statechg);
3057 bwn_stop_locked(struct bwn_softc *sc, int statechg)
3059 struct bwn_mac *mac = sc->sc_curmac;
3060 struct ifnet *ifp = sc->sc_ifp;
3062 BWN_ASSERT_LOCKED(sc);
3064 if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
3065 /* XXX FIXME opmode not based on VAP */
3066 bwn_set_opmode(mac);
3067 bwn_set_macaddr(mac);
3070 if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
3073 callout_stop(&sc->sc_led_blink_ch);
3074 sc->sc_led_blinking = 0;
3077 sc->sc_rf_enabled = 0;
3079 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
3083 bwn_wme_clear(struct bwn_softc *sc)
3085 #define MS(_v, _f) (((_v) & _f) >> _f##_S)
3086 struct wmeParams *p;
3089 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
3090 ("%s:%d: fail", __func__, __LINE__));
3092 for (i = 0; i < N(sc->sc_wmeParams); i++) {
3093 p = &(sc->sc_wmeParams[i]);
3095 switch (bwn_wme_shm_offsets[i]) {
3097 p->wmep_txopLimit = 0;
3099 /* XXX FIXME: log2(cwmin) */
3100 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3101 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3104 p->wmep_txopLimit = 0;
3106 /* XXX FIXME: log2(cwmin) */
3107 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3108 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3110 case BWN_WME_BESTEFFORT:
3111 p->wmep_txopLimit = 0;
3113 /* XXX FIXME: log2(cwmin) */
3114 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3115 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3117 case BWN_WME_BACKGROUND:
3118 p->wmep_txopLimit = 0;
3120 /* XXX FIXME: log2(cwmin) */
3121 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3122 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3125 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3131 bwn_core_init(struct bwn_mac *mac)
3133 struct bwn_softc *sc = mac->mac_sc;
3137 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3138 ("%s:%d: fail", __func__, __LINE__));
3140 siba_powerup(sc->sc_dev, 0);
3141 if (!siba_dev_isup(sc->sc_dev))
3143 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3145 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3146 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3147 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3148 BWN_GETTIME(mac->mac_phy.nexttime);
3149 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3150 bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3151 mac->mac_stats.link_noise = -95;
3152 mac->mac_reason_intr = 0;
3153 bzero(mac->mac_reason, sizeof(mac->mac_reason));
3154 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3156 if (sc->sc_debug & BWN_DEBUG_XMIT)
3157 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3159 mac->mac_suspended = 1;
3160 mac->mac_task_state = 0;
3161 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3163 mac->mac_phy.init_pre(mac);
3165 siba_pcicore_intr(sc->sc_dev);
3167 siba_fix_imcfglobug(sc->sc_dev);
3168 bwn_bt_disable(mac);
3169 if (mac->mac_phy.prepare_hw) {
3170 error = mac->mac_phy.prepare_hw(mac);
3174 error = bwn_chip_init(mac);
3177 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3178 siba_get_revid(sc->sc_dev));
3179 hf = bwn_hf_read(mac);
3180 if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3181 hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3182 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3183 hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3184 if (mac->mac_phy.rev == 1)
3185 hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3187 if (mac->mac_phy.rf_ver == 0x2050) {
3188 if (mac->mac_phy.rf_rev < 6)
3189 hf |= BWN_HF_FORCE_VCO_RECALC;
3190 if (mac->mac_phy.rf_rev == 6)
3191 hf |= BWN_HF_4318_TSSI;
3193 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3194 hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3195 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3196 (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3197 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3198 hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3199 bwn_hf_write(mac, hf);
3201 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3202 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3203 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3204 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3207 bwn_set_phytxctl(mac);
3209 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3210 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3211 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3213 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3218 bwn_spu_setdelay(mac, 1);
3221 siba_powerup(sc->sc_dev,
3222 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3223 bwn_set_macaddr(mac);
3224 bwn_crypt_init(mac);
3226 /* XXX LED initializatin */
3228 mac->mac_status = BWN_MAC_STATUS_INITED;
3233 siba_powerdown(sc->sc_dev);
3234 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3235 ("%s:%d: fail", __func__, __LINE__));
3240 bwn_core_start(struct bwn_mac *mac)
3242 struct bwn_softc *sc = mac->mac_sc;
3245 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3246 ("%s:%d: fail", __func__, __LINE__));
3248 if (siba_get_revid(sc->sc_dev) < 5)
3252 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3253 if (!(tmp & 0x00000001))
3255 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3258 bwn_mac_enable(mac);
3259 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3260 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3262 mac->mac_status = BWN_MAC_STATUS_STARTED;
3266 bwn_core_exit(struct bwn_mac *mac)
3268 struct bwn_softc *sc = mac->mac_sc;
3271 BWN_ASSERT_LOCKED(mac->mac_sc);
3273 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3274 ("%s:%d: fail", __func__, __LINE__));
3276 if (mac->mac_status != BWN_MAC_STATUS_INITED)
3278 mac->mac_status = BWN_MAC_STATUS_UNINIT;
3280 macctl = BWN_READ_4(mac, BWN_MACCTL);
3281 macctl &= ~BWN_MACCTL_MCODE_RUN;
3282 macctl |= BWN_MACCTL_MCODE_JMP0;
3283 BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3288 mac->mac_phy.switch_analog(mac, 0);
3289 siba_dev_down(sc->sc_dev, 0);
3290 siba_powerdown(sc->sc_dev);
3294 bwn_bt_disable(struct bwn_mac *mac)
3296 struct bwn_softc *sc = mac->mac_sc;
3299 /* XXX do nothing yet */
3303 bwn_chip_init(struct bwn_mac *mac)
3305 struct bwn_softc *sc = mac->mac_sc;
3306 struct bwn_phy *phy = &mac->mac_phy;
3310 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3312 macctl |= BWN_MACCTL_GMODE;
3313 BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3315 error = bwn_fw_fillinfo(mac);
3318 error = bwn_fw_loaducode(mac);
3322 error = bwn_gpio_init(mac);
3326 error = bwn_fw_loadinitvals(mac);
3328 siba_gpio_set(sc->sc_dev, 0);
3331 phy->switch_analog(mac, 1);
3332 error = bwn_phy_init(mac);
3334 siba_gpio_set(sc->sc_dev, 0);
3338 phy->set_im(mac, BWN_IMMODE_NONE);
3339 if (phy->set_antenna)
3340 phy->set_antenna(mac, BWN_ANT_DEFAULT);
3341 bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3343 if (phy->type == BWN_PHYTYPE_B)
3344 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3345 BWN_WRITE_4(mac, 0x0100, 0x01000000);
3346 if (siba_get_revid(sc->sc_dev) < 5)
3347 BWN_WRITE_4(mac, 0x010c, 0x01000000);
3349 BWN_WRITE_4(mac, BWN_MACCTL,
3350 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3351 BWN_WRITE_4(mac, BWN_MACCTL,
3352 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3353 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3355 bwn_set_opmode(mac);
3356 if (siba_get_revid(sc->sc_dev) < 3) {
3357 BWN_WRITE_2(mac, 0x060e, 0x0000);
3358 BWN_WRITE_2(mac, 0x0610, 0x8000);
3359 BWN_WRITE_2(mac, 0x0604, 0x0000);
3360 BWN_WRITE_2(mac, 0x0606, 0x0200);
3362 BWN_WRITE_4(mac, 0x0188, 0x80000000);
3363 BWN_WRITE_4(mac, 0x018c, 0x02000000);
3365 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3366 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
3367 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3368 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3369 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3370 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3371 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3372 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3373 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3374 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3378 /* read hostflags */
3380 bwn_hf_read(struct bwn_mac *mac)
3384 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3386 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3388 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3393 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3396 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3397 (value & 0x00000000ffffull));
3398 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3399 (value & 0x0000ffff0000ull) >> 16);
3400 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3401 (value & 0xffff00000000ULL) >> 32);
3405 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3408 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3409 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3413 bwn_rate_init(struct bwn_mac *mac)
3416 switch (mac->mac_phy.type) {
3419 case BWN_PHYTYPE_LP:
3421 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3422 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3423 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3424 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3425 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3426 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3427 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3428 if (mac->mac_phy.type == BWN_PHYTYPE_A)
3432 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3433 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3434 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3435 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3438 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3443 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3449 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3452 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3454 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3455 bwn_shm_read_2(mac, BWN_SHARED, offset));
3459 bwn_plcp_getcck(const uint8_t bitrate)
3463 case BWN_CCK_RATE_1MB:
3465 case BWN_CCK_RATE_2MB:
3467 case BWN_CCK_RATE_5MB:
3469 case BWN_CCK_RATE_11MB:
3472 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3477 bwn_plcp_getofdm(const uint8_t bitrate)
3481 case BWN_OFDM_RATE_6MB:
3483 case BWN_OFDM_RATE_9MB:
3485 case BWN_OFDM_RATE_12MB:
3487 case BWN_OFDM_RATE_18MB:
3489 case BWN_OFDM_RATE_24MB:
3491 case BWN_OFDM_RATE_36MB:
3493 case BWN_OFDM_RATE_48MB:
3495 case BWN_OFDM_RATE_54MB:
3498 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3503 bwn_set_phytxctl(struct bwn_mac *mac)
3507 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3509 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3510 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3511 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3515 bwn_pio_init(struct bwn_mac *mac)
3517 struct bwn_pio *pio = &mac->mac_method.pio;
3519 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3520 & ~BWN_MACCTL_BIGENDIAN);
3521 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3523 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3524 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3525 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3526 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3527 bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3528 bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3532 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3535 struct bwn_pio_txpkt *tp;
3536 struct bwn_softc *sc = mac->mac_sc;
3539 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3540 tq->tq_index = index;
3542 tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3543 if (siba_get_revid(sc->sc_dev) >= 8)
3546 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3550 TAILQ_INIT(&tq->tq_pktlist);
3551 for (i = 0; i < N(tq->tq_pkts); i++) {
3552 tp = &(tq->tq_pkts[i]);
3555 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3560 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3562 struct bwn_softc *sc = mac->mac_sc;
3563 static const uint16_t bases[] = {
3573 static const uint16_t bases_rev11[] = {
3582 if (siba_get_revid(sc->sc_dev) >= 11) {
3583 if (index >= N(bases_rev11))
3584 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3585 return (bases_rev11[index]);
3587 if (index >= N(bases))
3588 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3589 return (bases[index]);
3593 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3596 struct bwn_softc *sc = mac->mac_sc;
3599 prq->prq_rev = siba_get_revid(sc->sc_dev);
3600 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3601 bwn_dma_rxdirectfifo(mac, index, 1);
3605 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3609 bwn_pio_cancel_tx_packets(tq);
3613 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3616 bwn_destroy_pioqueue_tx(pio);
3620 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3624 return (BWN_READ_2(mac, tq->tq_base + offset));
3628 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3634 type = bwn_dma_mask2type(bwn_dma_mask(mac));
3635 base = bwn_dma_base(type, idx);
3636 if (type == BWN_DMA_64BIT) {
3637 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3638 ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3640 ctl |= BWN_DMA64_RXDIRECTFIFO;
3641 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3643 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3644 ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3646 ctl |= BWN_DMA32_RXDIRECTFIFO;
3647 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3652 bwn_dma_mask(struct bwn_mac *mac)
3657 tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3658 if (tmp & SIBA_TGSHIGH_DMA64)
3659 return (BWN_DMA_BIT_MASK(64));
3660 base = bwn_dma_base(0, 0);
3661 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3662 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3663 if (tmp & BWN_DMA32_TXADDREXT_MASK)
3664 return (BWN_DMA_BIT_MASK(32));
3666 return (BWN_DMA_BIT_MASK(30));
3670 bwn_dma_mask2type(uint64_t dmamask)
3673 if (dmamask == BWN_DMA_BIT_MASK(30))
3674 return (BWN_DMA_30BIT);
3675 if (dmamask == BWN_DMA_BIT_MASK(32))
3676 return (BWN_DMA_32BIT);
3677 if (dmamask == BWN_DMA_BIT_MASK(64))
3678 return (BWN_DMA_64BIT);
3679 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3680 return (BWN_DMA_30BIT);
3684 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3686 struct bwn_pio_txpkt *tp;
3689 for (i = 0; i < N(tq->tq_pkts); i++) {
3690 tp = &(tq->tq_pkts[i]);
3699 bwn_dma_base(int type, int controller_idx)
3701 static const uint16_t map64[] = {
3709 static const uint16_t map32[] = {
3718 if (type == BWN_DMA_64BIT) {
3719 KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3720 ("%s:%d: fail", __func__, __LINE__));
3721 return (map64[controller_idx]);
3723 KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3724 ("%s:%d: fail", __func__, __LINE__));
3725 return (map32[controller_idx]);
3729 bwn_dma_init(struct bwn_mac *mac)
3731 struct bwn_dma *dma = &mac->mac_method.dma;
3733 /* setup TX DMA channels. */
3734 bwn_dma_setup(dma->wme[WME_AC_BK]);
3735 bwn_dma_setup(dma->wme[WME_AC_BE]);
3736 bwn_dma_setup(dma->wme[WME_AC_VI]);
3737 bwn_dma_setup(dma->wme[WME_AC_VO]);
3738 bwn_dma_setup(dma->mcast);
3739 /* setup RX DMA channel. */
3740 bwn_dma_setup(dma->rx);
3743 static struct bwn_dma_ring *
3744 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3745 int for_tx, int type)
3747 struct bwn_dma *dma = &mac->mac_method.dma;
3748 struct bwn_dma_ring *dr;
3749 struct bwn_dmadesc_generic *desc;
3750 struct bwn_dmadesc_meta *mt;
3751 struct bwn_softc *sc = mac->mac_sc;
3754 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO);
3757 dr->dr_numslots = BWN_RXRING_SLOTS;
3759 dr->dr_numslots = BWN_TXRING_SLOTS;
3761 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3762 M_DEVBUF, M_NOWAIT | M_ZERO);
3763 if (dr->dr_meta == NULL)
3768 dr->dr_base = bwn_dma_base(type, controller_index);
3769 dr->dr_index = controller_index;
3770 if (type == BWN_DMA_64BIT) {
3771 dr->getdesc = bwn_dma_64_getdesc;
3772 dr->setdesc = bwn_dma_64_setdesc;
3773 dr->start_transfer = bwn_dma_64_start_transfer;
3774 dr->suspend = bwn_dma_64_suspend;
3775 dr->resume = bwn_dma_64_resume;
3776 dr->get_curslot = bwn_dma_64_get_curslot;
3777 dr->set_curslot = bwn_dma_64_set_curslot;
3779 dr->getdesc = bwn_dma_32_getdesc;
3780 dr->setdesc = bwn_dma_32_setdesc;
3781 dr->start_transfer = bwn_dma_32_start_transfer;
3782 dr->suspend = bwn_dma_32_suspend;
3783 dr->resume = bwn_dma_32_resume;
3784 dr->get_curslot = bwn_dma_32_get_curslot;
3785 dr->set_curslot = bwn_dma_32_set_curslot;
3789 dr->dr_curslot = -1;
3791 if (dr->dr_index == 0) {
3792 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3793 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3795 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3798 error = bwn_dma_allocringmemory(dr);
3804 * Assumption: BWN_TXRING_SLOTS can be divided by
3805 * BWN_TX_SLOTS_PER_FRAME
3807 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3808 ("%s:%d: fail", __func__, __LINE__));
3810 dr->dr_txhdr_cache =
3811 malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3812 BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO);
3813 KASSERT(dr->dr_txhdr_cache != NULL,
3814 ("%s:%d: fail", __func__, __LINE__));
3817 * Create TX ring DMA stuffs
3819 error = bus_dma_tag_create(dma->parent_dtag,
3826 BUS_SPACE_MAXSIZE_32BIT,
3829 &dr->dr_txring_dtag);
3831 device_printf(sc->sc_dev,
3832 "can't create TX ring DMA tag: TODO frees\n");
3836 for (i = 0; i < dr->dr_numslots; i += 2) {
3837 dr->getdesc(dr, i, &desc, &mt);
3839 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3843 error = bus_dmamap_create(dr->dr_txring_dtag, 0,
3846 device_printf(sc->sc_dev,
3847 "can't create RX buf DMA map\n");
3851 dr->getdesc(dr, i + 1, &desc, &mt);
3853 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3857 error = bus_dmamap_create(dma->txbuf_dtag, 0,
3860 device_printf(sc->sc_dev,
3861 "can't create RX buf DMA map\n");
3866 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3867 &dr->dr_spare_dmap);
3869 device_printf(sc->sc_dev,
3870 "can't create RX buf DMA map\n");
3871 goto out; /* XXX wrong! */
3874 for (i = 0; i < dr->dr_numslots; i++) {
3875 dr->getdesc(dr, i, &desc, &mt);
3877 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3880 device_printf(sc->sc_dev,
3881 "can't create RX buf DMA map\n");
3882 goto out; /* XXX wrong! */
3884 error = bwn_dma_newbuf(dr, desc, mt, 1);
3886 device_printf(sc->sc_dev,
3887 "failed to allocate RX buf\n");
3888 goto out; /* XXX wrong! */
3892 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3893 BUS_DMASYNC_PREWRITE);
3895 dr->dr_usedslot = dr->dr_numslots;
3902 free(dr->dr_txhdr_cache, M_DEVBUF);
3904 free(dr->dr_meta, M_DEVBUF);
3911 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3917 bwn_dma_free_descbufs(*dr);
3918 bwn_dma_free_ringmemory(*dr);
3920 free((*dr)->dr_txhdr_cache, M_DEVBUF);
3921 free((*dr)->dr_meta, M_DEVBUF);
3922 free(*dr, M_DEVBUF);
3928 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3929 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3931 struct bwn_dmadesc32 *desc;
3933 *meta = &(dr->dr_meta[slot]);
3934 desc = dr->dr_ring_descbase;
3935 desc = &(desc[slot]);
3937 *gdesc = (struct bwn_dmadesc_generic *)desc;
3941 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3942 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3943 int start, int end, int irq)
3945 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3946 struct bwn_softc *sc = dr->dr_mac->mac_sc;
3947 uint32_t addr, addrext, ctl;
3950 slot = (int)(&(desc->dma.dma32) - descbase);
3951 KASSERT(slot >= 0 && slot < dr->dr_numslots,
3952 ("%s:%d: fail", __func__, __LINE__));
3954 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
3955 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
3956 addr |= siba_dma_translation(sc->sc_dev);
3957 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3958 if (slot == dr->dr_numslots - 1)
3959 ctl |= BWN_DMA32_DCTL_DTABLEEND;
3961 ctl |= BWN_DMA32_DCTL_FRAMESTART;
3963 ctl |= BWN_DMA32_DCTL_FRAMEEND;
3965 ctl |= BWN_DMA32_DCTL_IRQ;
3966 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3967 & BWN_DMA32_DCTL_ADDREXT_MASK;
3969 desc->dma.dma32.control = htole32(ctl);
3970 desc->dma.dma32.address = htole32(addr);
3974 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3977 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3978 (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3982 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3985 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3986 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3990 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3993 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3994 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
3998 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
4002 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
4003 val &= BWN_DMA32_RXDPTR;
4005 return (val / sizeof(struct bwn_dmadesc32));
4009 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
4012 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
4013 (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
4017 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
4018 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
4020 struct bwn_dmadesc64 *desc;
4022 *meta = &(dr->dr_meta[slot]);
4023 desc = dr->dr_ring_descbase;
4024 desc = &(desc[slot]);
4026 *gdesc = (struct bwn_dmadesc_generic *)desc;
4030 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
4031 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
4032 int start, int end, int irq)
4034 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
4035 struct bwn_softc *sc = dr->dr_mac->mac_sc;
4037 uint32_t ctl0 = 0, ctl1 = 0;
4038 uint32_t addrlo, addrhi;
4041 slot = (int)(&(desc->dma.dma64) - descbase);
4042 KASSERT(slot >= 0 && slot < dr->dr_numslots,
4043 ("%s:%d: fail", __func__, __LINE__));
4045 addrlo = (uint32_t) (dmaaddr & 0xffffffff);
4046 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
4047 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
4049 addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
4050 if (slot == dr->dr_numslots - 1)
4051 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
4053 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
4055 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
4057 ctl0 |= BWN_DMA64_DCTL0_IRQ;
4058 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
4059 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
4060 & BWN_DMA64_DCTL1_ADDREXT_MASK;
4062 desc->dma.dma64.control0 = htole32(ctl0);
4063 desc->dma.dma64.control1 = htole32(ctl1);
4064 desc->dma.dma64.address_low = htole32(addrlo);
4065 desc->dma.dma64.address_high = htole32(addrhi);
4069 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
4072 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
4073 (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4077 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
4080 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4081 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
4085 bwn_dma_64_resume(struct bwn_dma_ring *dr)
4088 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4089 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
4093 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
4097 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
4098 val &= BWN_DMA64_RXSTATDPTR;
4100 return (val / sizeof(struct bwn_dmadesc64));
4104 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4107 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4108 (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4112 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4114 struct bwn_mac *mac = dr->dr_mac;
4115 struct bwn_dma *dma = &mac->mac_method.dma;
4116 struct bwn_softc *sc = mac->mac_sc;
4119 error = bus_dma_tag_create(dma->parent_dtag,
4124 BWN_DMA_RINGMEMSIZE,
4126 BUS_SPACE_MAXSIZE_32BIT,
4131 device_printf(sc->sc_dev,
4132 "can't create TX ring DMA tag: TODO frees\n");
4136 error = bus_dmamem_alloc(dr->dr_ring_dtag,
4137 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4140 device_printf(sc->sc_dev,
4141 "can't allocate DMA mem: TODO frees\n");
4144 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4145 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4146 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
4148 device_printf(sc->sc_dev,
4149 "can't load DMA mem: TODO free\n");
4157 bwn_dma_setup(struct bwn_dma_ring *dr)
4159 struct bwn_softc *sc = dr->dr_mac->mac_sc;
4161 uint32_t addrext, ring32, value;
4162 uint32_t trans = siba_dma_translation(sc->sc_dev);
4165 dr->dr_curslot = -1;
4167 if (dr->dr_type == BWN_DMA_64BIT) {
4168 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4169 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4171 value = BWN_DMA64_TXENABLE;
4172 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4173 & BWN_DMA64_TXADDREXT_MASK;
4174 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4175 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4176 (ring64 & 0xffffffff));
4177 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4179 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4181 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4182 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4183 value = BWN_DMA32_TXENABLE;
4184 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4185 & BWN_DMA32_TXADDREXT_MASK;
4186 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4187 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4188 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4196 dr->dr_usedslot = dr->dr_numslots;
4198 if (dr->dr_type == BWN_DMA_64BIT) {
4199 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4200 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4201 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4202 value |= BWN_DMA64_RXENABLE;
4203 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4204 & BWN_DMA64_RXADDREXT_MASK;
4205 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4206 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4207 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4208 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4210 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4211 sizeof(struct bwn_dmadesc64));
4213 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4214 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4215 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4216 value |= BWN_DMA32_RXENABLE;
4217 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4218 & BWN_DMA32_RXADDREXT_MASK;
4219 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4220 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4221 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4222 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4223 sizeof(struct bwn_dmadesc32));
4228 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4231 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4232 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4237 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4241 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4242 if (dr->dr_type == BWN_DMA_64BIT) {
4243 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4244 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4246 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4248 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4249 if (dr->dr_type == BWN_DMA_64BIT) {
4250 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4251 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4253 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4258 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4260 struct bwn_dmadesc_generic *desc;
4261 struct bwn_dmadesc_meta *meta;
4262 struct bwn_mac *mac = dr->dr_mac;
4263 struct bwn_dma *dma = &mac->mac_method.dma;
4264 struct bwn_softc *sc = mac->mac_sc;
4267 if (!dr->dr_usedslot)
4269 for (i = 0; i < dr->dr_numslots; i++) {
4270 dr->getdesc(dr, i, &desc, &meta);
4272 if (meta->mt_m == NULL) {
4274 device_printf(sc->sc_dev, "%s: not TX?\n",
4279 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
4280 bus_dmamap_unload(dr->dr_txring_dtag,
4282 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
4283 bus_dmamap_unload(dma->txbuf_dtag,
4286 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4287 bwn_dma_free_descbuf(dr, meta);
4292 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4295 struct bwn_softc *sc = mac->mac_sc;
4300 for (i = 0; i < 10; i++) {
4301 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4303 value = BWN_READ_4(mac, base + offset);
4304 if (type == BWN_DMA_64BIT) {
4305 value &= BWN_DMA64_TXSTAT;
4306 if (value == BWN_DMA64_TXSTAT_DISABLED ||
4307 value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4308 value == BWN_DMA64_TXSTAT_STOPPED)
4311 value &= BWN_DMA32_TXSTATE;
4312 if (value == BWN_DMA32_TXSTAT_DISABLED ||
4313 value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4314 value == BWN_DMA32_TXSTAT_STOPPED)
4319 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4320 BWN_WRITE_4(mac, base + offset, 0);
4321 for (i = 0; i < 10; i++) {
4322 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4324 value = BWN_READ_4(mac, base + offset);
4325 if (type == BWN_DMA_64BIT) {
4326 value &= BWN_DMA64_TXSTAT;
4327 if (value == BWN_DMA64_TXSTAT_DISABLED) {
4332 value &= BWN_DMA32_TXSTATE;
4333 if (value == BWN_DMA32_TXSTAT_DISABLED) {
4341 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4350 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4353 struct bwn_softc *sc = mac->mac_sc;
4358 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4359 BWN_WRITE_4(mac, base + offset, 0);
4360 for (i = 0; i < 10; i++) {
4361 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4363 value = BWN_READ_4(mac, base + offset);
4364 if (type == BWN_DMA_64BIT) {
4365 value &= BWN_DMA64_RXSTAT;
4366 if (value == BWN_DMA64_RXSTAT_DISABLED) {
4371 value &= BWN_DMA32_RXSTATE;
4372 if (value == BWN_DMA32_RXSTAT_DISABLED) {
4380 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4388 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4389 struct bwn_dmadesc_meta *meta)
4392 if (meta->mt_m != NULL) {
4393 m_freem(meta->mt_m);
4396 if (meta->mt_ni != NULL) {
4397 ieee80211_free_node(meta->mt_ni);
4403 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4405 struct bwn_rxhdr4 *rxhdr;
4406 unsigned char *frame;
4408 rxhdr = mtod(m, struct bwn_rxhdr4 *);
4409 rxhdr->frame_len = 0;
4411 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4412 sizeof(struct bwn_plcp6) + 2,
4413 ("%s:%d: fail", __func__, __LINE__));
4414 frame = mtod(m, char *) + dr->dr_frameoffset;
4415 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4419 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4421 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4423 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4428 bwn_wme_init(struct bwn_mac *mac)
4433 /* enable WME support. */
4434 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4435 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4436 BWN_IFSCTL_USE_EDCF);
4440 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4442 struct bwn_softc *sc = mac->mac_sc;
4443 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
4444 uint16_t delay; /* microsec */
4446 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4447 if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4449 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4450 delay = max(delay, (uint16_t)2400);
4452 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4456 bwn_bt_enable(struct bwn_mac *mac)
4458 struct bwn_softc *sc = mac->mac_sc;
4461 if (bwn_bluetooth == 0)
4463 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4465 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4468 hf = bwn_hf_read(mac);
4469 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4470 hf |= BWN_HF_BT_COEXISTALT;
4472 hf |= BWN_HF_BT_COEXIST;
4473 bwn_hf_write(mac, hf);
4477 bwn_set_macaddr(struct bwn_mac *mac)
4480 bwn_mac_write_bssid(mac);
4481 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
4485 bwn_clear_keys(struct bwn_mac *mac)
4489 for (i = 0; i < mac->mac_max_nr_keys; i++) {
4490 KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4491 ("%s:%d: fail", __func__, __LINE__));
4493 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4494 NULL, BWN_SEC_KEYSIZE, NULL);
4495 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4496 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4497 NULL, BWN_SEC_KEYSIZE, NULL);
4499 mac->mac_key[i].keyconf = NULL;
4504 bwn_crypt_init(struct bwn_mac *mac)
4506 struct bwn_softc *sc = mac->mac_sc;
4508 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4509 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4510 ("%s:%d: fail", __func__, __LINE__));
4511 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4513 if (siba_get_revid(sc->sc_dev) >= 5)
4514 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4515 bwn_clear_keys(mac);
4519 bwn_chip_exit(struct bwn_mac *mac)
4521 struct bwn_softc *sc = mac->mac_sc;
4524 siba_gpio_set(sc->sc_dev, 0);
4528 bwn_fw_fillinfo(struct bwn_mac *mac)
4532 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4535 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4542 bwn_gpio_init(struct bwn_mac *mac)
4544 struct bwn_softc *sc = mac->mac_sc;
4545 uint32_t mask = 0x1f, set = 0xf, value;
4547 BWN_WRITE_4(mac, BWN_MACCTL,
4548 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4549 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4550 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4552 if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4556 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4557 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4558 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4562 if (siba_get_revid(sc->sc_dev) >= 2)
4565 value = siba_gpio_get(sc->sc_dev);
4568 siba_gpio_set(sc->sc_dev, (value & mask) | set);
4574 bwn_fw_loadinitvals(struct bwn_mac *mac)
4576 #define GETFWOFFSET(fwp, offset) \
4577 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4578 const size_t hdr_len = sizeof(struct bwn_fwhdr);
4579 const struct bwn_fwhdr *hdr;
4580 struct bwn_fw *fw = &mac->mac_fw;
4583 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4584 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4585 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4588 if (fw->initvals_band.fw) {
4589 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4590 error = bwn_fwinitvals_write(mac,
4591 GETFWOFFSET(fw->initvals_band, hdr_len),
4593 fw->initvals_band.fw->datasize - hdr_len);
4600 bwn_phy_init(struct bwn_mac *mac)
4602 struct bwn_softc *sc = mac->mac_sc;
4605 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4606 mac->mac_phy.rf_onoff(mac, 1);
4607 error = mac->mac_phy.init(mac);
4609 device_printf(sc->sc_dev, "PHY init failed\n");
4612 error = bwn_switch_channel(mac,
4613 mac->mac_phy.get_default_chan(mac));
4615 device_printf(sc->sc_dev,
4616 "failed to switch default channel\n");
4621 if (mac->mac_phy.exit)
4622 mac->mac_phy.exit(mac);
4624 mac->mac_phy.rf_onoff(mac, 0);
4630 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4635 ant = bwn_ant2phy(antenna);
4638 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4639 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4640 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4641 /* For Probe Resposes */
4642 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4643 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4644 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4648 bwn_set_opmode(struct bwn_mac *mac)
4650 struct bwn_softc *sc = mac->mac_sc;
4651 struct ifnet *ifp = sc->sc_ifp;
4652 struct ieee80211com *ic = ifp->if_l2com;
4654 uint16_t cfp_pretbtt;
4656 ctl = BWN_READ_4(mac, BWN_MACCTL);
4657 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4658 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4659 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4660 ctl |= BWN_MACCTL_STA;
4662 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4663 ic->ic_opmode == IEEE80211_M_MBSS)
4664 ctl |= BWN_MACCTL_HOSTAP;
4665 else if (ic->ic_opmode == IEEE80211_M_IBSS)
4666 ctl &= ~BWN_MACCTL_STA;
4667 ctl |= sc->sc_filters;
4669 if (siba_get_revid(sc->sc_dev) <= 4)
4670 ctl |= BWN_MACCTL_PROMISC;
4672 BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4675 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4676 if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4677 siba_get_chiprev(sc->sc_dev) == 3)
4682 BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4686 bwn_dma_gettype(struct bwn_mac *mac)
4691 tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4692 if (tmp & SIBA_TGSHIGH_DMA64)
4693 return (BWN_DMA_64BIT);
4694 base = bwn_dma_base(0, 0);
4695 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4696 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4697 if (tmp & BWN_DMA32_TXADDREXT_MASK)
4698 return (BWN_DMA_32BIT);
4700 return (BWN_DMA_30BIT);
4704 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4707 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4708 *((bus_addr_t *)arg) = seg->ds_addr;
4713 bwn_phy_g_init_sub(struct bwn_mac *mac)
4715 struct bwn_phy *phy = &mac->mac_phy;
4716 struct bwn_phy_g *pg = &phy->phy_g;
4717 struct bwn_softc *sc = mac->mac_sc;
4721 bwn_phy_init_b5(mac);
4723 bwn_phy_init_b6(mac);
4725 if (phy->rev >= 2 || phy->gmode)
4726 bwn_phy_init_a(mac);
4728 if (phy->rev >= 2) {
4729 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4730 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4732 if (phy->rev == 2) {
4733 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4734 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4737 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4738 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4740 if (phy->gmode || phy->rev >= 2) {
4741 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4742 tmp &= BWN_PHYVER_VERSION;
4743 if (tmp == 3 || tmp == 5) {
4744 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4745 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4748 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4752 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4753 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4754 if (phy->rf_rev == 8) {
4755 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4756 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4758 if (BWN_HAS_LOOPBACK(phy))
4759 bwn_loopback_calcgain(mac);
4761 if (phy->rf_rev != 8) {
4762 if (pg->pg_initval == 0xffff)
4763 pg->pg_initval = bwn_rf_init_bcm2050(mac);
4765 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4768 if (BWN_HAS_TXMAG(phy)) {
4769 BWN_RF_WRITE(mac, 0x52,
4770 (BWN_RF_READ(mac, 0x52) & 0xff00)
4771 | pg->pg_loctl.tx_bias |
4772 pg->pg_loctl.tx_magn);
4774 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4776 if (phy->rev >= 6) {
4777 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4778 (pg->pg_loctl.tx_bias << 12));
4780 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4781 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4783 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4785 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4787 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4788 if (phy->gmode || phy->rev >= 2) {
4789 bwn_lo_g_adjust(mac);
4790 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4793 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4794 for (i = 0; i < 64; i++) {
4795 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4796 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4797 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4800 bwn_nrssi_threshold(mac);
4801 } else if (phy->gmode || phy->rev >= 2) {
4802 if (pg->pg_nrssi[0] == -1000) {
4803 KASSERT(pg->pg_nrssi[1] == -1000,
4804 ("%s:%d: fail", __func__, __LINE__));
4805 bwn_nrssi_slope_11g(mac);
4807 bwn_nrssi_threshold(mac);
4809 if (phy->rf_rev == 8)
4810 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4811 bwn_phy_hwpctl_init(mac);
4812 if ((siba_get_chipid(sc->sc_dev) == 0x4306
4813 && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4814 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4815 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4820 bwn_has_hwpctl(struct bwn_mac *mac)
4823 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4825 return (mac->mac_phy.use_hwpctl(mac));
4829 bwn_phy_init_b5(struct bwn_mac *mac)
4831 struct bwn_phy *phy = &mac->mac_phy;
4832 struct bwn_phy_g *pg = &phy->phy_g;
4833 struct bwn_softc *sc = mac->mac_sc;
4834 uint16_t offset, value;
4835 uint8_t old_channel;
4837 if (phy->analog == 1)
4838 BWN_RF_SET(mac, 0x007a, 0x0050);
4839 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4840 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4842 for (offset = 0x00a8; offset < 0x00c7; offset++) {
4843 BWN_PHY_WRITE(mac, offset, value);
4847 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4848 if (phy->rf_ver == 0x2050)
4849 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4851 if (phy->gmode || phy->rev >= 2) {
4852 if (phy->rf_ver == 0x2050) {
4853 BWN_RF_SET(mac, 0x007a, 0x0020);
4854 BWN_RF_SET(mac, 0x0051, 0x0004);
4856 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4858 BWN_PHY_SET(mac, 0x0802, 0x0100);
4859 BWN_PHY_SET(mac, 0x042b, 0x2000);
4861 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4863 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4864 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4865 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4868 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4869 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4871 if (phy->analog == 1) {
4872 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4873 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4874 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4875 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4876 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4878 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4879 BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4880 BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4882 if (phy->analog == 1)
4883 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4885 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4887 if (phy->analog == 0)
4888 BWN_WRITE_2(mac, 0x03e4, 0x3000);
4890 old_channel = phy->chan;
4891 bwn_phy_g_switch_chan(mac, 7, 0);
4893 if (phy->rf_ver != 0x2050) {
4894 BWN_RF_WRITE(mac, 0x0075, 0x0080);
4895 BWN_RF_WRITE(mac, 0x0079, 0x0081);
4898 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4899 BWN_RF_WRITE(mac, 0x0050, 0x0023);
4901 if (phy->rf_ver == 0x2050) {
4902 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4903 BWN_RF_WRITE(mac, 0x005a, 0x0070);
4906 BWN_RF_WRITE(mac, 0x005b, 0x007b);
4907 BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4908 BWN_RF_SET(mac, 0x007a, 0x0007);
4910 bwn_phy_g_switch_chan(mac, old_channel, 0);
4911 BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4912 BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4913 BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4915 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4918 if (phy->rf_ver == 0x2050)
4919 BWN_RF_WRITE(mac, 0x005d, 0x000d);
4921 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4925 bwn_loopback_calcgain(struct bwn_mac *mac)
4927 struct bwn_phy *phy = &mac->mac_phy;
4928 struct bwn_phy_g *pg = &phy->phy_g;
4929 struct bwn_softc *sc = mac->mac_sc;
4930 uint16_t backup_phy[16] = { 0 };
4931 uint16_t backup_radio[3];
4932 uint16_t backup_bband;
4933 uint16_t i, j, loop_i_max;
4935 uint16_t loop1_outer_done, loop1_inner_done;
4937 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4938 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4939 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4940 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4941 if (phy->rev != 1) {
4942 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4943 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4945 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4946 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4947 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4948 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4949 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4950 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4951 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4952 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4953 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4954 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4955 backup_bband = pg->pg_bbatt.att;
4956 backup_radio[0] = BWN_RF_READ(mac, 0x52);
4957 backup_radio[1] = BWN_RF_READ(mac, 0x43);
4958 backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4960 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4961 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4962 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4963 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4964 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4965 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4966 if (phy->rev != 1) {
4967 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4968 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4969 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4970 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4972 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4973 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4974 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4975 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4977 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4978 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4979 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4981 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4982 if (phy->rev != 1) {
4983 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4984 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4986 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4988 if (phy->rf_rev == 8)
4989 BWN_RF_WRITE(mac, 0x43, 0x000f);
4991 BWN_RF_WRITE(mac, 0x52, 0);
4992 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4994 bwn_phy_g_set_bbatt(mac, 11);
4997 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
4999 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5000 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5002 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
5003 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
5005 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
5006 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
5008 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
5009 if (phy->rev >= 7) {
5010 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
5011 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
5014 BWN_RF_MASK(mac, 0x7a, 0x00f7);
5017 loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
5018 for (i = 0; i < loop_i_max; i++) {
5019 for (j = 0; j < 16; j++) {
5020 BWN_RF_WRITE(mac, 0x43, i);
5021 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
5023 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5024 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5026 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5031 loop1_outer_done = i;
5032 loop1_inner_done = j;
5034 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
5036 for (j = j - 8; j < 16; j++) {
5037 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
5038 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5039 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5042 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5049 if (phy->rev != 1) {
5050 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
5051 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
5053 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
5054 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
5055 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
5056 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
5057 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
5058 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
5059 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
5060 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
5061 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
5063 bwn_phy_g_set_bbatt(mac, backup_bband);
5065 BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
5066 BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
5067 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
5069 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
5071 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
5072 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
5073 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
5074 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
5076 pg->pg_max_lb_gain =
5077 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
5078 pg->pg_trsw_rx_gain = trsw_rx * 2;
5082 bwn_rf_init_bcm2050(struct bwn_mac *mac)
5084 struct bwn_phy *phy = &mac->mac_phy;
5085 uint32_t tmp1 = 0, tmp2 = 0;
5086 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
5087 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
5088 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
5089 static const uint8_t rcc_table[] = {
5090 0x02, 0x03, 0x01, 0x0f,
5091 0x06, 0x07, 0x05, 0x0f,
5092 0x0a, 0x0b, 0x09, 0x0f,
5093 0x0e, 0x0f, 0x0d, 0x0f,
5096 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
5097 rfoverval = rfover = cck3 = 0;
5098 radio0 = BWN_RF_READ(mac, 0x43);
5099 radio1 = BWN_RF_READ(mac, 0x51);
5100 radio2 = BWN_RF_READ(mac, 0x52);
5101 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5102 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5103 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5104 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5106 if (phy->type == BWN_PHYTYPE_B) {
5107 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5108 reg0 = BWN_READ_2(mac, 0x3ec);
5110 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5111 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5112 } else if (phy->gmode || phy->rev >= 2) {
5113 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5114 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5115 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5116 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5117 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5118 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5120 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5121 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5122 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5123 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5124 if (BWN_HAS_LOOPBACK(phy)) {
5125 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5126 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5128 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5130 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5131 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5134 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5135 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5137 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5138 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5140 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5142 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5143 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5144 reg1 = BWN_READ_2(mac, 0x3e6);
5145 reg2 = BWN_READ_2(mac, 0x3f4);
5147 if (phy->analog == 0)
5148 BWN_WRITE_2(mac, 0x03e6, 0x0122);
5150 if (phy->analog >= 2)
5151 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5152 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5153 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5156 reg = BWN_RF_READ(mac, 0x60);
5157 index = (reg & 0x001e) >> 1;
5158 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5160 if (phy->type == BWN_PHYTYPE_B)
5161 BWN_RF_WRITE(mac, 0x78, 0x26);
5162 if (phy->gmode || phy->rev >= 2) {
5163 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5164 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5167 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5168 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5169 if (phy->gmode || phy->rev >= 2) {
5170 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5171 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5174 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5175 BWN_RF_SET(mac, 0x51, 0x0004);
5176 if (phy->rf_rev == 8)
5177 BWN_RF_WRITE(mac, 0x43, 0x1f);
5179 BWN_RF_WRITE(mac, 0x52, 0);
5180 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5182 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5184 for (i = 0; i < 16; i++) {
5185 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5186 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5187 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5188 if (phy->gmode || phy->rev >= 2) {
5189 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5190 bwn_rf_2050_rfoverval(mac,
5191 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5193 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5195 if (phy->gmode || phy->rev >= 2) {
5196 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5197 bwn_rf_2050_rfoverval(mac,
5198 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5200 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5202 if (phy->gmode || phy->rev >= 2) {
5203 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5204 bwn_rf_2050_rfoverval(mac,
5205 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5207 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5209 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5210 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5211 if (phy->gmode || phy->rev >= 2) {
5212 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5213 bwn_rf_2050_rfoverval(mac,
5214 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5216 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5220 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5224 for (i = 0; i < 16; i++) {
5225 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5226 BWN_RF_WRITE(mac, 0x78, radio78);
5228 for (j = 0; j < 16; j++) {
5229 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5230 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5231 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5232 if (phy->gmode || phy->rev >= 2) {
5233 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5234 bwn_rf_2050_rfoverval(mac,
5235 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5237 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5239 if (phy->gmode || phy->rev >= 2) {
5240 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5241 bwn_rf_2050_rfoverval(mac,
5242 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5244 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5246 if (phy->gmode || phy->rev >= 2) {
5247 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5248 bwn_rf_2050_rfoverval(mac,
5249 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5251 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5253 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5254 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5255 if (phy->gmode || phy->rev >= 2) {
5256 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5257 bwn_rf_2050_rfoverval(mac,
5258 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5260 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5268 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5269 BWN_RF_WRITE(mac, 0x51, radio1);
5270 BWN_RF_WRITE(mac, 0x52, radio2);
5271 BWN_RF_WRITE(mac, 0x43, radio0);
5272 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5273 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5274 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5275 BWN_WRITE_2(mac, 0x3e6, reg1);
5276 if (phy->analog != 0)
5277 BWN_WRITE_2(mac, 0x3f4, reg2);
5278 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5279 bwn_spu_workaround(mac, phy->chan);
5280 if (phy->type == BWN_PHYTYPE_B) {
5281 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5282 BWN_WRITE_2(mac, 0x3ec, reg0);
5283 } else if (phy->gmode) {
5284 BWN_WRITE_2(mac, BWN_PHY_RADIO,
5285 BWN_READ_2(mac, BWN_PHY_RADIO)
5287 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5288 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5289 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5290 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5292 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5293 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5294 if (BWN_HAS_LOOPBACK(phy)) {
5295 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5296 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5300 return ((i > 15) ? radio78 : rcc);
5304 bwn_phy_init_b6(struct bwn_mac *mac)
5306 struct bwn_phy *phy = &mac->mac_phy;
5307 struct bwn_phy_g *pg = &phy->phy_g;
5308 struct bwn_softc *sc = mac->mac_sc;
5309 uint16_t offset, val;
5310 uint8_t old_channel;
5312 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5313 ("%s:%d: fail", __func__, __LINE__));
5315 BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5316 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5317 if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5318 BWN_RF_WRITE(mac, 0x51, 0x37);
5319 BWN_RF_WRITE(mac, 0x52, 0x70);
5320 BWN_RF_WRITE(mac, 0x53, 0xb3);
5321 BWN_RF_WRITE(mac, 0x54, 0x9b);
5322 BWN_RF_WRITE(mac, 0x5a, 0x88);
5323 BWN_RF_WRITE(mac, 0x5b, 0x88);
5324 BWN_RF_WRITE(mac, 0x5d, 0x88);
5325 BWN_RF_WRITE(mac, 0x5e, 0x88);
5326 BWN_RF_WRITE(mac, 0x7d, 0x88);
5328 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5330 if (phy->rf_rev == 8) {
5331 BWN_RF_WRITE(mac, 0x51, 0);
5332 BWN_RF_WRITE(mac, 0x52, 0x40);
5333 BWN_RF_WRITE(mac, 0x53, 0xb7);
5334 BWN_RF_WRITE(mac, 0x54, 0x98);
5335 BWN_RF_WRITE(mac, 0x5a, 0x88);
5336 BWN_RF_WRITE(mac, 0x5b, 0x6b);
5337 BWN_RF_WRITE(mac, 0x5c, 0x0f);
5338 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5339 BWN_RF_WRITE(mac, 0x5d, 0xfa);
5340 BWN_RF_WRITE(mac, 0x5e, 0xd8);
5342 BWN_RF_WRITE(mac, 0x5d, 0xf5);
5343 BWN_RF_WRITE(mac, 0x5e, 0xb8);
5345 BWN_RF_WRITE(mac, 0x0073, 0x0003);
5346 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5347 BWN_RF_WRITE(mac, 0x007c, 0x0001);
5348 BWN_RF_WRITE(mac, 0x007e, 0x0008);
5350 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5351 BWN_PHY_WRITE(mac, offset, val);
5354 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5355 BWN_PHY_WRITE(mac, offset, val);
5358 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5359 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5362 if (phy->type == BWN_PHYTYPE_G) {
5363 BWN_RF_SET(mac, 0x007a, 0x0020);
5364 BWN_RF_SET(mac, 0x0051, 0x0004);
5365 BWN_PHY_SET(mac, 0x0802, 0x0100);
5366 BWN_PHY_SET(mac, 0x042b, 0x2000);
5367 BWN_PHY_WRITE(mac, 0x5b, 0);
5368 BWN_PHY_WRITE(mac, 0x5c, 0);
5371 old_channel = phy->chan;
5372 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5374 BWN_RF_WRITE(mac, 0x0050, 0x0020);
5375 BWN_RF_WRITE(mac, 0x0050, 0x0023);
5377 if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5378 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5379 BWN_RF_WRITE(mac, 0x50, 0x20);
5381 if (phy->rf_rev <= 2) {
5382 BWN_RF_WRITE(mac, 0x7c, 0x20);
5383 BWN_RF_WRITE(mac, 0x5a, 0x70);
5384 BWN_RF_WRITE(mac, 0x5b, 0x7b);
5385 BWN_RF_WRITE(mac, 0x5c, 0xb0);
5387 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5389 bwn_phy_g_switch_chan(mac, old_channel, 0);
5391 BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5392 if (phy->rf_rev >= 6)
5393 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5395 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5396 BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5397 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5399 if (phy->rf_rev <= 5)
5400 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5401 if (phy->rf_rev <= 2)
5402 BWN_RF_WRITE(mac, 0x005d, 0x000d);
5404 if (phy->analog == 4) {
5405 BWN_WRITE_2(mac, 0x3e4, 9);
5406 BWN_PHY_MASK(mac, 0x61, 0x0fff);
5408 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5409 if (phy->type == BWN_PHYTYPE_B)
5410 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5411 else if (phy->type == BWN_PHYTYPE_G)
5412 BWN_WRITE_2(mac, 0x03e6, 0x0);
5416 bwn_phy_init_a(struct bwn_mac *mac)
5418 struct bwn_phy *phy = &mac->mac_phy;
5419 struct bwn_softc *sc = mac->mac_sc;
5421 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5422 ("%s:%d: fail", __func__, __LINE__));
5424 if (phy->rev >= 6) {
5425 if (phy->type == BWN_PHYTYPE_A)
5426 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5427 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5428 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5430 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5435 if (phy->type == BWN_PHYTYPE_G &&
5436 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5437 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5441 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5445 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5446 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5450 bwn_wa_agc(struct bwn_mac *mac)
5452 struct bwn_phy *phy = &mac->mac_phy;
5454 if (phy->rev == 1) {
5455 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5456 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5457 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5458 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5459 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5460 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5461 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5462 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5463 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5465 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5466 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5467 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5468 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5471 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5473 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5474 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5475 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5476 BWN_RF_SET(mac, 0x7a, 0x0008);
5477 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5478 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5479 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5480 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5482 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5483 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5484 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5485 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5486 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5487 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5488 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5489 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5490 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5491 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5492 if (phy->rev == 1) {
5493 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5494 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5496 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5497 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5498 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5499 if (phy->rev >= 6) {
5500 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5501 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5502 (uint16_t)~0xf000, 0x3000);
5505 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5506 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5507 if (phy->rev == 1) {
5508 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5509 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5510 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5511 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5512 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5513 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5514 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5515 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5517 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5518 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5519 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5520 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5522 if (phy->rev >= 6) {
5523 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5524 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5526 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5530 bwn_wa_grev1(struct bwn_mac *mac)
5532 struct bwn_phy *phy = &mac->mac_phy;
5534 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5535 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5536 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5538 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5540 /* init CRSTHRES and ANTDWELL */
5541 if (phy->rev == 1) {
5542 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5543 } else if (phy->rev == 2) {
5544 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5545 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5546 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5548 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5549 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5550 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5551 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5553 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5554 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5555 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5557 /* XXX support PHY-A??? */
5558 for (i = 0; i < N(bwn_tab_finefreqg); i++)
5559 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5560 bwn_tab_finefreqg[i]);
5562 /* XXX support PHY-A??? */
5564 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5565 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5566 bwn_tab_noise_g1[i]);
5568 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5569 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5570 bwn_tab_noise_g2[i]);
5573 for (i = 0; i < N(bwn_tab_rotor); i++)
5574 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5577 /* XXX support PHY-A??? */
5578 if (phy->rev >= 6) {
5579 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5581 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5583 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5585 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5587 for (i = 0; i < N(bwn_tab_retard); i++)
5588 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5591 if (phy->rev == 1) {
5592 for (i = 0; i < 16; i++)
5593 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5596 for (i = 0; i < 32; i++)
5597 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5604 bwn_wa_grev26789(struct bwn_mac *mac)
5606 struct bwn_phy *phy = &mac->mac_phy;
5608 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5611 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5613 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5615 /* init CRSTHRES and ANTDWELL */
5617 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5618 else if (phy->rev == 2) {
5619 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5620 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5621 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5623 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5624 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5625 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5626 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5629 for (i = 0; i < 64; i++)
5630 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5632 /* XXX support PHY-A??? */
5634 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5635 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5636 bwn_tab_noise_g1[i]);
5638 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5639 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5640 bwn_tab_noise_g2[i]);
5642 /* XXX support PHY-A??? */
5643 if (phy->rev >= 6) {
5644 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5646 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5648 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5650 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5652 for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5653 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5654 bwn_tab_sigmasqr2[i]);
5656 if (phy->rev == 1) {
5657 for (i = 0; i < 16; i++)
5658 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5661 for (i = 0; i < 32; i++)
5662 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5667 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5669 if (phy->type == BWN_PHYTYPE_A)
5670 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5672 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5674 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5675 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5676 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5679 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5680 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5684 bwn_wa_init(struct bwn_mac *mac)
5686 struct bwn_phy *phy = &mac->mac_phy;
5687 struct bwn_softc *sc = mac->mac_sc;
5689 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5700 bwn_wa_grev26789(mac);
5703 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5706 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5707 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5708 siba_get_pci_revid(sc->sc_dev) != 0x17) {
5710 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5712 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5715 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5716 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5717 if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5720 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5721 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
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,
5736 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5737 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5738 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5741 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5742 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5746 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5749 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5752 addr = table + offset;
5753 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5754 (addr - 1 != pg->pg_ofdmtab_addr)) {
5755 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5756 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5758 pg->pg_ofdmtab_addr = addr;
5759 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5763 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5766 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5769 addr = table + offset;
5770 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5771 (addr - 1 != pg->pg_ofdmtab_addr)) {
5772 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5773 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5775 pg->pg_ofdmtab_addr = addr;
5777 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5778 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5782 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5786 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5787 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5791 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5793 struct bwn_phy *phy = &mac->mac_phy;
5794 struct bwn_softc *sc = mac->mac_sc;
5795 unsigned int i, max_loop;
5797 uint32_t buffer[5] = {
5798 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5803 buffer[0] = 0x000201cc;
5806 buffer[0] = 0x000b846e;
5809 BWN_ASSERT_LOCKED(mac->mac_sc);
5811 for (i = 0; i < 5; i++)
5812 bwn_ram_write(mac, i * 4, buffer[i]);
5814 BWN_WRITE_2(mac, 0x0568, 0x0000);
5815 BWN_WRITE_2(mac, 0x07c0,
5816 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5817 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5818 BWN_WRITE_2(mac, 0x050c, value);
5819 if (phy->type == BWN_PHYTYPE_LP)
5820 BWN_WRITE_2(mac, 0x0514, 0x1a02);
5821 BWN_WRITE_2(mac, 0x0508, 0x0000);
5822 BWN_WRITE_2(mac, 0x050a, 0x0000);
5823 BWN_WRITE_2(mac, 0x054c, 0x0000);
5824 BWN_WRITE_2(mac, 0x056a, 0x0014);
5825 BWN_WRITE_2(mac, 0x0568, 0x0826);
5826 BWN_WRITE_2(mac, 0x0500, 0x0000);
5827 if (phy->type == BWN_PHYTYPE_LP)
5828 BWN_WRITE_2(mac, 0x0502, 0x0050);
5830 BWN_WRITE_2(mac, 0x0502, 0x0030);
5832 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5833 BWN_RF_WRITE(mac, 0x0051, 0x0017);
5834 for (i = 0x00; i < max_loop; i++) {
5835 value = BWN_READ_2(mac, 0x050e);
5840 for (i = 0x00; i < 0x0a; i++) {
5841 value = BWN_READ_2(mac, 0x050e);
5846 for (i = 0x00; i < 0x19; i++) {
5847 value = BWN_READ_2(mac, 0x0690);
5848 if (!(value & 0x0100))
5852 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5853 BWN_RF_WRITE(mac, 0x0051, 0x0037);
5857 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5861 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5863 macctl = BWN_READ_4(mac, BWN_MACCTL);
5864 if (macctl & BWN_MACCTL_BIGENDIAN)
5865 printf("TODO: need swap\n");
5867 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5868 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5869 BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5873 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5877 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5878 ("%s:%d: fail", __func__, __LINE__));
5880 value = (uint8_t) (ctl->q);
5881 value |= ((uint8_t) (ctl->i)) << 8;
5882 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5886 bwn_lo_calcfeed(struct bwn_mac *mac,
5887 uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5889 struct bwn_phy *phy = &mac->mac_phy;
5890 struct bwn_softc *sc = mac->mac_sc;
5892 uint16_t feedthrough;
5895 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5896 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5898 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5899 ("%s:%d: fail", __func__, __LINE__));
5900 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5901 ("%s:%d: fail", __func__, __LINE__));
5903 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5905 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5906 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5908 rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5910 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5911 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5913 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5914 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5916 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5917 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5919 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5921 pga |= BWN_PHY_PGACTL_UNKNOWN;
5922 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5924 pga |= BWN_PHY_PGACTL_LOWBANDW;
5925 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5927 pga |= BWN_PHY_PGACTL_LPF;
5928 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5931 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5933 return (feedthrough);
5937 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5938 uint16_t *value, uint16_t *pad_mix_gain)
5940 struct bwn_phy *phy = &mac->mac_phy;
5941 uint16_t reg, v, padmix;
5943 if (phy->type == BWN_PHYTYPE_B) {
5945 if (phy->rf_rev <= 5) {
5953 if (phy->rev >= 2 && phy->rf_rev == 8) {
5966 *pad_mix_gain = padmix;
5972 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5974 struct bwn_phy *phy = &mac->mac_phy;
5975 struct bwn_phy_g *pg = &phy->phy_g;
5976 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5978 uint16_t trsw_rx, pga;
5979 uint16_t rf_pctl_reg;
5981 static const uint8_t tx_bias_values[] = {
5982 0x09, 0x08, 0x0a, 0x01, 0x00,
5983 0x02, 0x05, 0x04, 0x06,
5985 static const uint8_t tx_magn_values[] = {
5989 if (!BWN_HAS_LOOPBACK(phy)) {
5997 lb_gain = pg->pg_max_lb_gain / 2;
6000 pga = abs(10 - lb_gain) / 6;
6001 pga = MIN(MAX(pga, 0), 15);
6008 if ((phy->rev >= 2) &&
6009 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
6012 if ((10 - lb_gain) < cmp_val)
6013 tmp = (10 - lb_gain);
6021 rf_pctl_reg = cmp_val;
6026 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
6027 bwn_phy_g_set_bbatt(mac, 2);
6029 reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
6031 BWN_RF_MASK(mac, reg, mask);
6033 if (BWN_HAS_TXMAG(phy)) {
6036 int min_feedth = 0xffff;
6037 uint8_t tx_magn, tx_bias;
6039 for (i = 0; i < N(tx_magn_values); i++) {
6040 tx_magn = tx_magn_values[i];
6041 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
6042 for (j = 0; j < N(tx_bias_values); j++) {
6043 tx_bias = tx_bias_values[j];
6044 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
6045 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
6047 if (feedthrough < min_feedth) {
6048 lo->tx_bias = tx_bias;
6049 lo->tx_magn = tx_magn;
6050 min_feedth = feedthrough;
6052 if (lo->tx_bias == 0)
6055 BWN_RF_WRITE(mac, 0x52,
6056 (BWN_RF_READ(mac, 0x52)
6057 & 0xff00) | lo->tx_bias | lo->
6063 BWN_RF_MASK(mac, 0x52, 0xfff0);
6066 BWN_GETTIME(lo->txctl_measured_time);
6070 bwn_lo_get_powervector(struct bwn_mac *mac)
6072 struct bwn_phy *phy = &mac->mac_phy;
6073 struct bwn_phy_g *pg = &phy->phy_g;
6074 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6077 uint64_t power_vector = 0;
6079 for (i = 0; i < 8; i += 2) {
6080 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
6081 power_vector |= (tmp << (i * 8));
6082 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
6085 lo->power_vector = power_vector;
6087 BWN_GETTIME(lo->pwr_vec_read_time);
6091 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
6094 struct bwn_phy *phy = &mac->mac_phy;
6095 struct bwn_phy_g *pg = &phy->phy_g;
6098 if (max_rx_gain < 0)
6101 if (BWN_HAS_LOOPBACK(phy)) {
6106 trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6107 if (max_rx_gain >= trsw_rx_gain) {
6108 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6112 trsw_rx_gain = max_rx_gain;
6113 if (trsw_rx_gain < 9) {
6114 pg->pg_lna_lod_gain = 0;
6116 pg->pg_lna_lod_gain = 1;
6119 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6120 pg->pg_pga_gain = trsw_rx_gain / 3;
6121 if (pg->pg_pga_gain >= 5) {
6122 pg->pg_pga_gain -= 5;
6123 pg->pg_lna_gain = 2;
6125 pg->pg_lna_gain = 0;
6127 pg->pg_lna_gain = 0;
6128 pg->pg_trsw_rx_gain = 0x20;
6129 if (max_rx_gain >= 0x14) {
6130 pg->pg_lna_lod_gain = 1;
6131 pg->pg_pga_gain = 2;
6132 } else if (max_rx_gain >= 0x12) {
6133 pg->pg_lna_lod_gain = 1;
6134 pg->pg_pga_gain = 1;
6135 } else if (max_rx_gain >= 0xf) {
6136 pg->pg_lna_lod_gain = 1;
6137 pg->pg_pga_gain = 0;
6139 pg->pg_lna_lod_gain = 0;
6140 pg->pg_pga_gain = 0;
6144 tmp = BWN_RF_READ(mac, 0x7a);
6145 if (pg->pg_lna_lod_gain == 0)
6149 BWN_RF_WRITE(mac, 0x7a, tmp);
6153 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6155 struct bwn_phy *phy = &mac->mac_phy;
6156 struct bwn_phy_g *pg = &phy->phy_g;
6157 struct bwn_softc *sc = mac->mac_sc;
6158 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6162 if (bwn_has_hwpctl(mac)) {
6163 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6164 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6165 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6166 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6167 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6169 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6170 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6171 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6172 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6174 if (phy->type == BWN_PHYTYPE_B &&
6175 phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6176 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6177 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6179 if (phy->rev >= 2) {
6180 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6181 sav->phy_analogoverval =
6182 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6183 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6184 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6185 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6186 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6187 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6189 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6190 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6191 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6192 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6193 if (phy->type == BWN_PHYTYPE_G) {
6194 if ((phy->rev >= 7) &&
6195 (siba_sprom_get_bf_lo(sc->sc_dev) &
6197 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6199 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6202 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6204 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6206 sav->reg0 = BWN_READ_2(mac, 0x3f4);
6207 sav->reg1 = BWN_READ_2(mac, 0x3e2);
6208 sav->rf0 = BWN_RF_READ(mac, 0x43);
6209 sav->rf1 = BWN_RF_READ(mac, 0x7a);
6210 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6211 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6212 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6213 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6215 if (!BWN_HAS_TXMAG(phy)) {
6216 sav->rf2 = BWN_RF_READ(mac, 0x52);
6219 if (phy->type == BWN_PHYTYPE_B) {
6220 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6221 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6222 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6223 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6225 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6228 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6232 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6233 BWN_PHY_WRITE(mac, tmp, 0x007f);
6235 tmp = sav->phy_syncctl;
6236 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6238 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6240 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6241 if (phy->type == BWN_PHYTYPE_G ||
6242 (phy->type == BWN_PHYTYPE_B &&
6243 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6244 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6246 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6248 bwn_dummy_transmission(mac, 0, 1);
6249 bwn_phy_g_switch_chan(mac, 6, 0);
6250 BWN_RF_READ(mac, 0x51);
6251 if (phy->type == BWN_PHYTYPE_G)
6252 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6255 if (time_before(lo->txctl_measured_time,
6256 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6257 bwn_lo_measure_txctl_values(mac);
6259 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6260 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6262 if (phy->type == BWN_PHYTYPE_B)
6263 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6265 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6270 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6272 struct bwn_phy *phy = &mac->mac_phy;
6273 struct bwn_phy_g *pg = &phy->phy_g;
6276 if (phy->rev >= 2) {
6277 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6278 tmp = (pg->pg_pga_gain << 8);
6279 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6281 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6283 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6285 tmp = (pg->pg_pga_gain | 0xefa0);
6286 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6288 if (phy->type == BWN_PHYTYPE_G) {
6290 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6292 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6294 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6296 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6298 BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6299 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6300 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6301 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6302 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6303 BWN_RF_WRITE(mac, 0x43, sav->rf0);
6304 BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6305 if (!BWN_HAS_TXMAG(phy)) {
6307 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6309 BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6310 if (phy->type == BWN_PHYTYPE_B &&
6311 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6312 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6313 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6315 if (phy->rev >= 2) {
6316 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6317 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6318 sav->phy_analogoverval);
6319 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6320 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6321 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6322 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6323 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6325 if (bwn_has_hwpctl(mac)) {
6326 tmp = (sav->phy_lomask & 0xbfff);
6327 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6328 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6329 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6330 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6331 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6333 bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6337 bwn_lo_probe_loctl(struct bwn_mac *mac,
6338 struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6340 struct bwn_phy *phy = &mac->mac_phy;
6341 struct bwn_phy_g *pg = &phy->phy_g;
6342 struct bwn_loctl orig, test;
6343 struct bwn_loctl prev = { -100, -100 };
6344 static const struct bwn_loctl modifiers[] = {
6345 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,},
6346 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,}
6348 int begin, end, lower = 0, i;
6351 if (d->curstate == 0) {
6354 } else if (d->curstate % 2 == 0) {
6355 begin = d->curstate - 1;
6356 end = d->curstate + 1;
6358 begin = d->curstate - 2;
6359 end = d->curstate + 2;
6366 memcpy(&orig, probe, sizeof(struct bwn_loctl));
6370 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6371 memcpy(&test, &orig, sizeof(struct bwn_loctl));
6372 test.i += modifiers[i - 1].i * d->multipler;
6373 test.q += modifiers[i - 1].q * d->multipler;
6374 if ((test.i != prev.i || test.q != prev.q) &&
6375 (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6376 bwn_lo_write(mac, &test);
6377 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6378 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6379 if (feedth < d->feedth) {
6380 memcpy(probe, &test,
6381 sizeof(struct bwn_loctl));
6384 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6388 memcpy(&prev, &test, sizeof(prev));
6402 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6404 struct bwn_phy *phy = &mac->mac_phy;
6405 struct bwn_phy_g *pg = &phy->phy_g;
6406 struct bwn_lo_g_sm d;
6407 struct bwn_loctl probe;
6408 int lower, repeat, cnt = 0;
6413 if (BWN_HAS_LOOPBACK(phy))
6416 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6417 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6420 bwn_lo_write(mac, &d.loctl);
6421 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6422 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6423 if (feedth < 0x258) {
6424 if (feedth >= 0x12c)
6428 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6429 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6434 KASSERT(d.curstate >= 0 && d.curstate <= 8,
6435 ("%s:%d: fail", __func__, __LINE__));
6436 memcpy(&probe, &d.loctl,
6437 sizeof(struct bwn_loctl));
6438 lower = bwn_lo_probe_loctl(mac, &probe, &d);
6441 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6443 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6445 } while (d.nmeasure < 24);
6446 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6448 if (BWN_HAS_LOOPBACK(phy)) {
6449 if (d.feedth > 0x1194)
6451 else if (d.feedth < 0x5dc)
6454 if (d.feedth <= 0x5dc) {
6459 } else if (cnt == 2)
6462 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6463 } while (++cnt < repeat);
6466 static struct bwn_lo_calib *
6467 bwn_lo_calibset(struct bwn_mac *mac,
6468 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6470 struct bwn_phy *phy = &mac->mac_phy;
6471 struct bwn_phy_g *pg = &phy->phy_g;
6472 struct bwn_loctl loctl = { 0, 0 };
6473 struct bwn_lo_calib *cal;
6474 struct bwn_lo_g_value sval = { 0 };
6476 uint16_t pad, reg, value;
6478 sval.old_channel = phy->chan;
6479 bwn_mac_suspend(mac);
6480 bwn_lo_save(mac, &sval);
6482 reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6483 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6484 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6486 rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6489 if (BWN_HAS_LOOPBACK(phy))
6490 rxgain += pg->pg_max_lb_gain;
6491 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6492 bwn_phy_g_set_bbatt(mac, bbatt->att);
6493 bwn_lo_probe_sm(mac, &loctl, &rxgain);
6495 bwn_lo_restore(mac, &sval);
6496 bwn_mac_enable(mac);
6498 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
6500 device_printf(mac->mac_sc->sc_dev, "out of memory\n");
6503 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6504 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6505 memcpy(&cal->ctl, &loctl, sizeof(loctl));
6507 BWN_GETTIME(cal->calib_time);
6512 static struct bwn_lo_calib *
6513 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6514 const struct bwn_rfatt *rfatt)
6516 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6517 struct bwn_lo_calib *c;
6519 TAILQ_FOREACH(c, &lo->calib_list, list) {
6520 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6522 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6527 c = bwn_lo_calibset(mac, bbatt, rfatt);
6530 TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6536 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6538 struct bwn_phy *phy = &mac->mac_phy;
6539 struct bwn_phy_g *pg = &phy->phy_g;
6540 struct bwn_softc *sc = mac->mac_sc;
6541 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6542 const struct bwn_rfatt *rfatt;
6543 const struct bwn_bbatt *bbatt;
6546 int rf_offset, bb_offset;
6547 uint8_t changed = 0;
6549 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6550 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6551 ("%s:%d: fail", __func__, __LINE__));
6553 pvector = lo->power_vector;
6554 if (!update && !pvector)
6557 bwn_mac_suspend(mac);
6559 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6560 struct bwn_lo_calib *cal;
6564 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6566 bb_offset = i / lo->rfatt.len;
6567 rf_offset = i % lo->rfatt.len;
6568 bbatt = &(lo->bbatt.array[bb_offset]);
6569 rfatt = &(lo->rfatt.array[rf_offset]);
6571 cal = bwn_lo_calibset(mac, bbatt, rfatt);
6573 device_printf(sc->sc_dev, "LO: Could not "
6574 "calibrate DC table entry\n");
6577 val = (uint8_t)(cal->ctl.q);
6578 val |= ((uint8_t)(cal->ctl.i)) << 4;
6579 free(cal, M_DEVBUF);
6583 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6584 | ((val & 0x00ff) << 8);
6586 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6591 for (i = 0; i < BWN_DC_LT_SIZE; i++)
6592 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6594 bwn_mac_enable(mac);
6598 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6603 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6608 bwn_lo_g_adjust(struct bwn_mac *mac)
6610 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6611 struct bwn_lo_calib *cal;
6612 struct bwn_rfatt rf;
6614 memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6615 bwn_lo_fixup_rfatt(&rf);
6617 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6620 bwn_lo_write(mac, &cal->ctl);
6624 bwn_lo_g_init(struct bwn_mac *mac)
6627 if (!bwn_has_hwpctl(mac))
6630 bwn_lo_get_powervector(mac);
6631 bwn_phy_g_dc_lookup_init(mac, 1);
6635 bwn_mac_suspend(struct bwn_mac *mac)
6637 struct bwn_softc *sc = mac->mac_sc;
6641 KASSERT(mac->mac_suspended >= 0,
6642 ("%s:%d: fail", __func__, __LINE__));
6644 if (mac->mac_suspended == 0) {
6645 bwn_psctl(mac, BWN_PS_AWAKE);
6646 BWN_WRITE_4(mac, BWN_MACCTL,
6647 BWN_READ_4(mac, BWN_MACCTL)
6649 BWN_READ_4(mac, BWN_MACCTL);
6650 for (i = 35; i; i--) {
6651 tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6652 if (tmp & BWN_INTR_MAC_SUSPENDED)
6656 for (i = 40; i; i--) {
6657 tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6658 if (tmp & BWN_INTR_MAC_SUSPENDED)
6662 device_printf(sc->sc_dev, "MAC suspend failed\n");
6665 mac->mac_suspended++;
6669 bwn_mac_enable(struct bwn_mac *mac)
6671 struct bwn_softc *sc = mac->mac_sc;
6674 state = bwn_shm_read_2(mac, BWN_SHARED,
6675 BWN_SHARED_UCODESTAT);
6676 if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6677 state != BWN_SHARED_UCODESTAT_SLEEP)
6678 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6680 mac->mac_suspended--;
6681 KASSERT(mac->mac_suspended >= 0,
6682 ("%s:%d: fail", __func__, __LINE__));
6683 if (mac->mac_suspended == 0) {
6684 BWN_WRITE_4(mac, BWN_MACCTL,
6685 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6686 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6687 BWN_READ_4(mac, BWN_MACCTL);
6688 BWN_READ_4(mac, BWN_INTR_REASON);
6694 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6696 struct bwn_softc *sc = mac->mac_sc;
6700 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6701 ("%s:%d: fail", __func__, __LINE__));
6702 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6703 ("%s:%d: fail", __func__, __LINE__));
6705 /* XXX forcibly awake and hwps-off */
6707 BWN_WRITE_4(mac, BWN_MACCTL,
6708 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6710 BWN_READ_4(mac, BWN_MACCTL);
6711 if (siba_get_revid(sc->sc_dev) >= 5) {
6712 for (i = 0; i < 100; i++) {
6713 ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6714 BWN_SHARED_UCODESTAT);
6715 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6723 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6726 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6727 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6731 bwn_nrssi_threshold(struct bwn_mac *mac)
6733 struct bwn_phy *phy = &mac->mac_phy;
6734 struct bwn_phy_g *pg = &phy->phy_g;
6735 struct bwn_softc *sc = mac->mac_sc;
6740 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6742 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6743 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6751 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6752 a += (pg->pg_nrssi[0] << 6);
6753 a += (a < 32) ? 31 : 32;
6755 a = MIN(MAX(a, -31), 31);
6757 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6758 b += (pg->pg_nrssi[0] << 6);
6764 b = MIN(MAX(b, -31), 31);
6766 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6767 tmpu16 |= ((uint32_t)b & 0x0000003f);
6768 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6769 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6773 tmp16 = bwn_nrssi_read(mac, 0x20);
6776 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6780 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6782 #define SAVE_RF_MAX 3
6783 #define SAVE_PHY_COMM_MAX 4
6784 #define SAVE_PHY3_MAX 8
6785 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6786 { 0x7a, 0x52, 0x43 };
6787 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6788 { 0x15, 0x5a, 0x59, 0x58 };
6789 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6790 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6791 0x0801, 0x0060, 0x0014, 0x0478
6793 struct bwn_phy *phy = &mac->mac_phy;
6794 struct bwn_phy_g *pg = &phy->phy_g;
6795 int32_t i, tmp32, phy3_idx = 0;
6796 uint16_t delta, tmp;
6797 uint16_t save_rf[SAVE_RF_MAX];
6798 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6799 uint16_t save_phy3[SAVE_PHY3_MAX];
6800 uint16_t ant_div, phy0, chan_ex;
6801 int16_t nrssi0, nrssi1;
6803 KASSERT(phy->type == BWN_PHYTYPE_G,
6804 ("%s:%d: fail", __func__, __LINE__));
6806 if (phy->rf_rev >= 9)
6808 if (phy->rf_rev == 8)
6809 bwn_nrssi_offset(mac);
6811 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6812 BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6815 * Save RF/PHY registers for later restoration
6817 ant_div = BWN_READ_2(mac, 0x03e2);
6818 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6819 for (i = 0; i < SAVE_RF_MAX; ++i)
6820 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6821 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6822 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6824 phy0 = BWN_READ_2(mac, BWN_PHY0);
6825 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6826 if (phy->rev >= 3) {
6827 for (i = 0; i < SAVE_PHY3_MAX; ++i)
6828 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6829 BWN_PHY_WRITE(mac, 0x002e, 0);
6830 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6835 BWN_PHY_SET(mac, 0x0478, 0x0100);
6836 BWN_PHY_SET(mac, 0x0801, 0x0040);
6840 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6843 BWN_PHY_SET(mac, 0x0060, 0x0040);
6844 BWN_PHY_SET(mac, 0x0014, 0x0200);
6849 BWN_RF_SET(mac, 0x007a, 0x0070);
6850 bwn_set_all_gains(mac, 0, 8, 0);
6851 BWN_RF_MASK(mac, 0x007a, 0x00f7);
6852 if (phy->rev >= 2) {
6853 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6854 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6856 BWN_RF_SET(mac, 0x007a, 0x0080);
6859 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6860 if (nrssi0 >= 0x0020)
6866 BWN_RF_MASK(mac, 0x007a, 0x007f);
6868 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6870 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6871 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6872 BWN_RF_SET(mac, 0x007a, 0x000f);
6873 BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6874 if (phy->rev >= 2) {
6875 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6876 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6879 bwn_set_all_gains(mac, 3, 0, 1);
6880 if (phy->rf_rev == 8) {
6881 BWN_RF_WRITE(mac, 0x0043, 0x001f);
6883 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6884 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6885 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6886 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6888 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6889 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6890 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6892 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6895 * Install calculated narrow RSSI values
6897 if (nrssi1 >= 0x0020)
6899 if (nrssi0 == nrssi1)
6900 pg->pg_nrssi_slope = 0x00010000;
6902 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6904 pg->pg_nrssi[0] = nrssi1;
6905 pg->pg_nrssi[1] = nrssi0;
6909 * Restore saved RF/PHY registers
6911 if (phy->rev >= 3) {
6912 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6913 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6914 save_phy3[phy3_idx]);
6917 if (phy->rev >= 2) {
6918 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6919 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6922 for (i = 0; i < SAVE_RF_MAX; ++i)
6923 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6925 BWN_WRITE_2(mac, 0x03e2, ant_div);
6926 BWN_WRITE_2(mac, 0x03e6, phy0);
6927 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6929 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6930 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6932 bwn_spu_workaround(mac, phy->chan);
6933 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6934 bwn_set_original_gains(mac);
6935 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6936 if (phy->rev >= 3) {
6937 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6938 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6939 save_phy3[phy3_idx]);
6943 delta = 0x1f - pg->pg_nrssi[0];
6944 for (i = 0; i < 64; i++) {
6945 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6946 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6947 pg->pg_nrssi_lt[i] = tmp32;
6950 bwn_nrssi_threshold(mac);
6952 #undef SAVE_PHY_COMM_MAX
6953 #undef SAVE_PHY3_MAX
6957 bwn_nrssi_offset(struct bwn_mac *mac)
6959 #define SAVE_RF_MAX 2
6960 #define SAVE_PHY_COMM_MAX 10
6961 #define SAVE_PHY6_MAX 8
6962 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6964 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6965 0x0001, 0x0811, 0x0812, 0x0814,
6966 0x0815, 0x005a, 0x0059, 0x0058,
6969 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6970 0x002e, 0x002f, 0x080f, 0x0810,
6971 0x0801, 0x0060, 0x0014, 0x0478
6973 struct bwn_phy *phy = &mac->mac_phy;
6974 int i, phy6_idx = 0;
6975 uint16_t save_rf[SAVE_RF_MAX];
6976 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6977 uint16_t save_phy6[SAVE_PHY6_MAX];
6979 uint16_t saved = 0xffff;
6981 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6982 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6983 for (i = 0; i < SAVE_RF_MAX; ++i)
6984 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6986 BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6987 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6988 BWN_PHY_SET(mac, 0x0811, 0x000c);
6989 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6990 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6991 if (phy->rev >= 6) {
6992 for (i = 0; i < SAVE_PHY6_MAX; ++i)
6993 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6995 BWN_PHY_WRITE(mac, 0x002e, 0);
6996 BWN_PHY_WRITE(mac, 0x002f, 0);
6997 BWN_PHY_WRITE(mac, 0x080f, 0);
6998 BWN_PHY_WRITE(mac, 0x0810, 0);
6999 BWN_PHY_SET(mac, 0x0478, 0x0100);
7000 BWN_PHY_SET(mac, 0x0801, 0x0040);
7001 BWN_PHY_SET(mac, 0x0060, 0x0040);
7002 BWN_PHY_SET(mac, 0x0014, 0x0200);
7004 BWN_RF_SET(mac, 0x007a, 0x0070);
7005 BWN_RF_SET(mac, 0x007a, 0x0080);
7008 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7012 for (i = 7; i >= 4; i--) {
7013 BWN_RF_WRITE(mac, 0x007b, i);
7015 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
7019 if (nrssi < 31 && saved == 0xffff)
7022 if (saved == 0xffff)
7025 BWN_RF_MASK(mac, 0x007a, 0x007f);
7026 if (phy->rev != 1) {
7027 BWN_PHY_SET(mac, 0x0814, 0x0001);
7028 BWN_PHY_MASK(mac, 0x0815, 0xfffe);
7030 BWN_PHY_SET(mac, 0x0811, 0x000c);
7031 BWN_PHY_SET(mac, 0x0812, 0x000c);
7032 BWN_PHY_SET(mac, 0x0811, 0x0030);
7033 BWN_PHY_SET(mac, 0x0812, 0x0030);
7034 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
7035 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
7036 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
7038 BWN_PHY_WRITE(mac, 0x0003, 0x0122);
7040 BWN_PHY_SET(mac, 0x000a, 0x2000);
7041 if (phy->rev != 1) {
7042 BWN_PHY_SET(mac, 0x0814, 0x0004);
7043 BWN_PHY_MASK(mac, 0x0815, 0xfffb);
7045 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
7046 BWN_RF_SET(mac, 0x007a, 0x000f);
7047 bwn_set_all_gains(mac, 3, 0, 1);
7048 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
7050 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7054 for (i = 0; i < 4; i++) {
7055 BWN_RF_WRITE(mac, 0x007b, i);
7057 nrssi = (int16_t)((BWN_PHY_READ(mac,
7058 0x047f) >> 8) & 0x003f);
7061 if (nrssi > -31 && saved == 0xffff)
7064 if (saved == 0xffff)
7069 BWN_RF_WRITE(mac, 0x007b, saved);
7072 * Restore saved RF/PHY registers
7074 if (phy->rev >= 6) {
7075 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
7076 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7077 save_phy6[phy6_idx]);
7080 if (phy->rev != 1) {
7081 for (i = 3; i < 5; i++)
7082 BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
7085 for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
7086 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
7088 for (i = SAVE_RF_MAX - 1; i >= 0; --i)
7089 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
7091 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
7092 BWN_PHY_SET(mac, 0x0429, 0x8000);
7093 bwn_set_original_gains(mac);
7094 if (phy->rev >= 6) {
7095 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
7096 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7097 save_phy6[phy6_idx]);
7101 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7102 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7103 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7107 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7110 struct bwn_phy *phy = &mac->mac_phy;
7112 uint16_t start = 0x08, end = 0x18;
7116 if (phy->rev <= 1) {
7121 table = BWN_OFDMTAB_GAINX;
7123 table = BWN_OFDMTAB_GAINX_R1;
7124 for (i = 0; i < 4; i++)
7125 bwn_ofdmtab_write_2(mac, table, i, first);
7127 for (i = start; i < end; i++)
7128 bwn_ofdmtab_write_2(mac, table, i, second);
7131 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7132 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7133 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7134 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7136 bwn_dummy_transmission(mac, 0, 1);
7140 bwn_set_original_gains(struct bwn_mac *mac)
7142 struct bwn_phy *phy = &mac->mac_phy;
7145 uint16_t start = 0x0008, end = 0x0018;
7147 if (phy->rev <= 1) {
7152 table = BWN_OFDMTAB_GAINX;
7154 table = BWN_OFDMTAB_GAINX_R1;
7155 for (i = 0; i < 4; i++) {
7157 tmp |= (i & 0x0001) << 1;
7158 tmp |= (i & 0x0002) >> 1;
7160 bwn_ofdmtab_write_2(mac, table, i, tmp);
7163 for (i = start; i < end; i++)
7164 bwn_ofdmtab_write_2(mac, table, i, i - start);
7166 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7167 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7168 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7169 bwn_dummy_transmission(mac, 0, 1);
7173 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7175 struct bwn_phy *phy = &mac->mac_phy;
7176 struct bwn_phy_g *pg = &phy->phy_g;
7177 struct bwn_rfatt old_rfatt, rfatt;
7178 struct bwn_bbatt old_bbatt, bbatt;
7179 struct bwn_softc *sc = mac->mac_sc;
7180 uint8_t old_txctl = 0;
7182 KASSERT(phy->type == BWN_PHYTYPE_G,
7183 ("%s:%d: fail", __func__, __LINE__));
7185 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7186 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7189 BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7191 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7195 bwn_hwpctl_early_init(mac);
7196 if (pg->pg_curtssi == 0) {
7197 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7198 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7200 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7201 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7202 old_txctl = pg->pg_txctl;
7205 if (phy->rf_rev == 8) {
7212 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7214 bwn_dummy_transmission(mac, 0, 1);
7215 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7216 if (phy->rf_ver == 0x2050 && phy->analog == 0)
7217 BWN_RF_MASK(mac, 0x0076, 0xff7b);
7219 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7220 &old_rfatt, old_txctl);
7222 bwn_hwpctl_init_gphy(mac);
7225 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7226 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7227 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7228 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7232 bwn_hwpctl_early_init(struct bwn_mac *mac)
7234 struct bwn_phy *phy = &mac->mac_phy;
7236 if (!bwn_has_hwpctl(mac)) {
7237 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7241 BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7242 BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7243 BWN_PHY_SET(mac, 0x047c, 0x0002);
7244 BWN_PHY_SET(mac, 0x047a, 0xf000);
7245 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7246 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7247 BWN_PHY_SET(mac, 0x005d, 0x8000);
7248 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7249 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7250 BWN_PHY_SET(mac, 0x0036, 0x0400);
7252 BWN_PHY_SET(mac, 0x0036, 0x0200);
7253 BWN_PHY_SET(mac, 0x0036, 0x0400);
7254 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7255 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7256 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7257 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7258 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7263 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7265 struct bwn_phy *phy = &mac->mac_phy;
7266 struct bwn_phy_g *pg = &phy->phy_g;
7267 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7269 uint16_t nr_written = 0, tmp, value;
7272 if (!bwn_has_hwpctl(mac)) {
7273 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7277 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7278 (pg->pg_idletssi - pg->pg_curtssi));
7279 BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7280 (pg->pg_idletssi - pg->pg_curtssi));
7282 for (i = 0; i < 32; i++)
7283 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7284 for (i = 32; i < 64; i++)
7285 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7286 for (i = 0; i < 64; i += 2) {
7287 value = (uint16_t) pg->pg_tssi2dbm[i];
7288 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7289 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7292 for (rf = 0; rf < lo->rfatt.len; rf++) {
7293 for (bb = 0; bb < lo->bbatt.len; bb++) {
7294 if (nr_written >= 0x40)
7296 tmp = lo->bbatt.array[bb].att;
7298 if (phy->rf_rev == 8)
7302 tmp |= lo->rfatt.array[rf].att;
7303 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7308 BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7309 BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7311 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7312 BWN_PHY_SET(mac, 0x0478, 0x0800);
7313 BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7314 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7316 bwn_phy_g_dc_lookup_init(mac, 1);
7317 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7321 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7323 struct bwn_softc *sc = mac->mac_sc;
7326 bwn_spu_workaround(mac, channel);
7328 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7330 if (channel == 14) {
7331 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7333 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7336 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7337 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7338 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7342 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7343 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7347 bwn_phy_g_chan2freq(uint8_t channel)
7349 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7351 KASSERT(channel >= 1 && channel <= 14,
7352 ("%s:%d: fail", __func__, __LINE__));
7354 return (bwn_phy_g_rf_channels[channel - 1]);
7358 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7359 const struct bwn_rfatt *rfatt, uint8_t txctl)
7361 struct bwn_phy *phy = &mac->mac_phy;
7362 struct bwn_phy_g *pg = &phy->phy_g;
7363 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7365 uint16_t tx_bias, tx_magn;
7369 tx_bias = lo->tx_bias;
7370 tx_magn = lo->tx_magn;
7371 if (tx_bias == 0xff)
7374 pg->pg_txctl = txctl;
7375 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7376 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7377 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7378 bwn_phy_g_set_bbatt(mac, bb);
7379 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7380 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7381 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7383 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7384 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7386 if (BWN_HAS_TXMAG(phy))
7387 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7389 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7390 bwn_lo_g_adjust(mac);
7394 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7397 struct bwn_phy *phy = &mac->mac_phy;
7399 if (phy->analog == 0) {
7400 BWN_WRITE_2(mac, BWN_PHY0,
7401 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7404 if (phy->analog > 1) {
7405 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7408 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7412 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7414 struct bwn_phy *phy = &mac->mac_phy;
7415 struct bwn_phy_g *pg = &phy->phy_g;
7416 struct bwn_softc *sc = mac->mac_sc;
7421 if (phy->gmode == 0)
7424 if (BWN_HAS_LOOPBACK(phy)) {
7425 max_lb_gain = pg->pg_max_lb_gain;
7426 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7427 if (max_lb_gain >= 0x46) {
7429 max_lb_gain -= 0x46;
7430 } else if (max_lb_gain >= 0x3a) {
7432 max_lb_gain -= 0x3a;
7433 } else if (max_lb_gain >= 0x2e) {
7435 max_lb_gain -= 0x2e;
7438 max_lb_gain -= 0x10;
7441 for (i = 0; i < 16; i++) {
7442 max_lb_gain -= (i * 6);
7443 if (max_lb_gain < 6)
7447 if ((phy->rev < 7) ||
7448 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7449 if (reg == BWN_PHY_RFOVER) {
7451 } else if (reg == BWN_PHY_RFOVERVAL) {
7454 case BWN_LPD(0, 1, 1):
7456 case BWN_LPD(0, 0, 1):
7457 case BWN_LPD(1, 0, 1):
7458 return (0x0092 | extlna);
7459 case BWN_LPD(1, 0, 0):
7460 return (0x0093 | extlna);
7463 ("%s:%d: fail", __func__, __LINE__));
7465 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7467 if (reg == BWN_PHY_RFOVER)
7469 if (reg == BWN_PHY_RFOVERVAL) {
7474 case BWN_LPD(0, 1, 1):
7476 case BWN_LPD(0, 0, 1):
7477 return (0x8092 | extlna);
7478 case BWN_LPD(1, 0, 1):
7479 return (0x2092 | extlna);
7480 case BWN_LPD(1, 0, 0):
7481 return (0x2093 | extlna);
7484 ("%s:%d: fail", __func__, __LINE__));
7486 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7491 if ((phy->rev < 7) ||
7492 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7493 if (reg == BWN_PHY_RFOVER) {
7495 } else if (reg == BWN_PHY_RFOVERVAL) {
7497 case BWN_LPD(0, 1, 1):
7499 case BWN_LPD(0, 0, 1):
7501 case BWN_LPD(1, 0, 1):
7503 case BWN_LPD(1, 0, 0):
7507 ("%s:%d: fail", __func__, __LINE__));
7509 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7511 if (reg == BWN_PHY_RFOVER) {
7513 } else if (reg == BWN_PHY_RFOVERVAL) {
7515 case BWN_LPD(0, 1, 1):
7517 case BWN_LPD(0, 0, 1):
7519 case BWN_LPD(1, 0, 1):
7521 case BWN_LPD(1, 0, 0):
7525 ("%s:%d: fail", __func__, __LINE__));
7527 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7533 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7536 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7538 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7539 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7541 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7545 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7547 struct bwn_softc *sc = mac->mac_sc;
7548 struct bwn_fw *fw = &mac->mac_fw;
7549 const uint8_t rev = siba_get_revid(sc->sc_dev);
7550 const char *filename;
7555 if (rev >= 5 && rev <= 10)
7556 filename = "ucode5";
7557 else if (rev >= 11 && rev <= 12)
7558 filename = "ucode11";
7560 filename = "ucode13";
7562 filename = "ucode14";
7564 filename = "ucode15";
7566 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7567 bwn_release_firmware(mac);
7568 return (EOPNOTSUPP);
7570 error = bwn_fw_get(mac, type, filename, &fw->ucode);
7572 bwn_release_firmware(mac);
7577 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7578 if (rev >= 5 && rev <= 10) {
7579 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7580 if (error == ENOENT)
7583 bwn_release_firmware(mac);
7586 } else if (rev < 11) {
7587 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7588 return (EOPNOTSUPP);
7592 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7593 switch (mac->mac_phy.type) {
7595 if (rev < 5 || rev > 10)
7597 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7598 filename = "a0g1initvals5";
7600 filename = "a0g0initvals5";
7603 if (rev >= 5 && rev <= 10)
7604 filename = "b0g0initvals5";
7606 filename = "b0g0initvals13";
7610 case BWN_PHYTYPE_LP:
7612 filename = "lp0initvals13";
7614 filename = "lp0initvals14";
7616 filename = "lp0initvals15";
7621 if (rev >= 11 && rev <= 12)
7622 filename = "n0initvals11";
7629 error = bwn_fw_get(mac, type, filename, &fw->initvals);
7631 bwn_release_firmware(mac);
7635 /* bandswitch initvals */
7636 switch (mac->mac_phy.type) {
7638 if (rev >= 5 && rev <= 10) {
7639 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7640 filename = "a0g1bsinitvals5";
7642 filename = "a0g0bsinitvals5";
7643 } else if (rev >= 11)
7649 if (rev >= 5 && rev <= 10)
7650 filename = "b0g0bsinitvals5";
7656 case BWN_PHYTYPE_LP:
7658 filename = "lp0bsinitvals13";
7660 filename = "lp0bsinitvals14";
7662 filename = "lp0bsinitvals15";
7667 if (rev >= 11 && rev <= 12)
7668 filename = "n0bsinitvals11";
7675 error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7677 bwn_release_firmware(mac);
7682 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7683 bwn_release_firmware(mac);
7684 return (EOPNOTSUPP);
7688 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7689 const char *name, struct bwn_fwfile *bfw)
7691 const struct bwn_fwhdr *hdr;
7692 struct bwn_softc *sc = mac->mac_sc;
7693 const struct firmware *fw;
7697 bwn_do_release_fw(bfw);
7700 if (bfw->filename != NULL) {
7701 if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7703 bwn_do_release_fw(bfw);
7706 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7707 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7708 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7709 /* XXX Sleeping on "fwload" with the non-sleepable locks held */
7710 fw = firmware_get(namebuf);
7712 device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7716 if (fw->datasize < sizeof(struct bwn_fwhdr))
7718 hdr = (const struct bwn_fwhdr *)(fw->data);
7719 switch (hdr->type) {
7720 case BWN_FWTYPE_UCODE:
7721 case BWN_FWTYPE_PCM:
7722 if (be32toh(hdr->size) !=
7723 (fw->datasize - sizeof(struct bwn_fwhdr)))
7733 bfw->filename = name;
7738 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7740 firmware_put(fw, FIRMWARE_UNLOAD);
7745 bwn_release_firmware(struct bwn_mac *mac)
7748 bwn_do_release_fw(&mac->mac_fw.ucode);
7749 bwn_do_release_fw(&mac->mac_fw.pcm);
7750 bwn_do_release_fw(&mac->mac_fw.initvals);
7751 bwn_do_release_fw(&mac->mac_fw.initvals_band);
7755 bwn_do_release_fw(struct bwn_fwfile *bfw)
7758 if (bfw->fw != NULL)
7759 firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7761 bfw->filename = NULL;
7765 bwn_fw_loaducode(struct bwn_mac *mac)
7767 #define GETFWOFFSET(fwp, offset) \
7768 ((const uint32_t *)((const char *)fwp.fw->data + offset))
7769 #define GETFWSIZE(fwp, offset) \
7770 ((fwp.fw->datasize - offset) / sizeof(uint32_t))
7771 struct bwn_softc *sc = mac->mac_sc;
7772 const uint32_t *data;
7775 uint16_t date, fwcaps, time;
7778 ctl = BWN_READ_4(mac, BWN_MACCTL);
7779 ctl |= BWN_MACCTL_MCODE_JMP0;
7780 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7782 BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7783 for (i = 0; i < 64; i++)
7784 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7785 for (i = 0; i < 4096; i += 2)
7786 bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7788 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7789 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7790 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7792 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7796 if (mac->mac_fw.pcm.fw) {
7797 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7798 bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7799 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7800 bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7801 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7802 sizeof(struct bwn_fwhdr)); i++) {
7803 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7808 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7809 BWN_WRITE_4(mac, BWN_MACCTL,
7810 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7811 BWN_MACCTL_MCODE_RUN);
7813 for (i = 0; i < 21; i++) {
7814 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7817 device_printf(sc->sc_dev, "ucode timeout\n");
7823 BWN_READ_4(mac, BWN_INTR_REASON);
7825 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7826 if (mac->mac_fw.rev <= 0x128) {
7827 device_printf(sc->sc_dev, "the firmware is too old\n");
7831 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7832 BWN_SHARED_UCODE_PATCH);
7833 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7834 mac->mac_fw.opensource = (date == 0xffff);
7836 mac->mac_flags |= BWN_MAC_FLAG_WME;
7837 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7839 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7840 if (mac->mac_fw.opensource == 0) {
7841 device_printf(sc->sc_dev,
7842 "firmware version (rev %u patch %u date %#x time %#x)\n",
7843 mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7844 if (mac->mac_fw.no_pcmfile)
7845 device_printf(sc->sc_dev,
7846 "no HW crypto acceleration due to pcm5\n");
7848 mac->mac_fw.patch = time;
7849 fwcaps = bwn_fwcaps_read(mac);
7850 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7851 device_printf(sc->sc_dev,
7852 "disabling HW crypto acceleration\n");
7853 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7855 if (!(fwcaps & BWN_FWCAPS_WME)) {
7856 device_printf(sc->sc_dev, "disabling WME support\n");
7857 mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7861 if (BWN_ISOLDFMT(mac))
7862 device_printf(sc->sc_dev, "using old firmware image\n");
7867 BWN_WRITE_4(mac, BWN_MACCTL,
7868 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7869 BWN_MACCTL_MCODE_JMP0);
7876 /* OpenFirmware only */
7878 bwn_fwcaps_read(struct bwn_mac *mac)
7881 KASSERT(mac->mac_fw.opensource == 1,
7882 ("%s:%d: fail", __func__, __LINE__));
7883 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7887 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7888 size_t count, size_t array_size)
7890 #define GET_NEXTIV16(iv) \
7891 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \
7892 sizeof(uint16_t) + sizeof(uint16_t)))
7893 #define GET_NEXTIV32(iv) \
7894 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \
7895 sizeof(uint16_t) + sizeof(uint32_t)))
7896 struct bwn_softc *sc = mac->mac_sc;
7897 const struct bwn_fwinitvals *iv;
7902 KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7903 ("%s:%d: fail", __func__, __LINE__));
7905 for (i = 0; i < count; i++) {
7906 if (array_size < sizeof(iv->offset_size))
7908 array_size -= sizeof(iv->offset_size);
7909 offset = be16toh(iv->offset_size);
7910 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7911 offset &= BWN_FWINITVALS_OFFSET_MASK;
7912 if (offset >= 0x1000)
7915 if (array_size < sizeof(iv->data.d32))
7917 array_size -= sizeof(iv->data.d32);
7918 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7919 iv = GET_NEXTIV32(iv);
7922 if (array_size < sizeof(iv->data.d16))
7924 array_size -= sizeof(iv->data.d16);
7925 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7927 iv = GET_NEXTIV16(iv);
7930 if (array_size != 0)
7934 device_printf(sc->sc_dev, "initvals: invalid format\n");
7941 bwn_switch_channel(struct bwn_mac *mac, int chan)
7943 struct bwn_phy *phy = &(mac->mac_phy);
7944 struct bwn_softc *sc = mac->mac_sc;
7945 struct ifnet *ifp = sc->sc_ifp;
7946 struct ieee80211com *ic = ifp->if_l2com;
7947 uint16_t channelcookie, savedcookie;
7951 chan = phy->get_default_chan(mac);
7953 channelcookie = chan;
7954 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
7955 channelcookie |= 0x100;
7956 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
7957 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
7958 error = phy->switch_channel(mac, chan);
7962 mac->mac_phy.chan = chan;
7966 device_printf(sc->sc_dev, "failed to switch channel\n");
7967 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
7972 bwn_ant2phy(int antenna)
7977 return (BWN_TX_PHY_ANT0);
7979 return (BWN_TX_PHY_ANT1);
7981 return (BWN_TX_PHY_ANT2);
7983 return (BWN_TX_PHY_ANT3);
7985 return (BWN_TX_PHY_ANT01AUTO);
7987 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7992 bwn_wme_load(struct bwn_mac *mac)
7994 struct bwn_softc *sc = mac->mac_sc;
7997 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
7998 ("%s:%d: fail", __func__, __LINE__));
8000 bwn_mac_suspend(mac);
8001 for (i = 0; i < N(sc->sc_wmeParams); i++)
8002 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
8003 bwn_wme_shm_offsets[i]);
8004 bwn_mac_enable(mac);
8008 bwn_wme_loadparams(struct bwn_mac *mac,
8009 const struct wmeParams *p, uint16_t shm_offset)
8011 #define SM(_v, _f) (((_v) << _f##_S) & _f)
8012 struct bwn_softc *sc = mac->mac_sc;
8013 uint16_t params[BWN_NR_WMEPARAMS];
8017 slot = BWN_READ_2(mac, BWN_RNG) &
8018 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8020 memset(¶ms, 0, sizeof(params));
8022 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
8023 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
8024 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
8026 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
8027 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8028 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
8029 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8030 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
8031 params[BWN_WMEPARAM_BSLOTS] = slot;
8032 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
8034 for (i = 0; i < N(params); i++) {
8035 if (i == BWN_WMEPARAM_STATUS) {
8036 tmp = bwn_shm_read_2(mac, BWN_SHARED,
8037 shm_offset + (i * 2));
8039 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8042 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8049 bwn_mac_write_bssid(struct bwn_mac *mac)
8051 struct bwn_softc *sc = mac->mac_sc;
8054 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
8056 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
8057 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
8058 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
8059 IEEE80211_ADDR_LEN);
8061 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
8062 tmp = (uint32_t) (mac_bssid[i + 0]);
8063 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
8064 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
8065 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
8066 bwn_ram_write(mac, 0x20 + i, tmp);
8071 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
8072 const uint8_t *macaddr)
8074 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
8081 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
8084 data |= macaddr[1] << 8;
8085 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8087 data |= macaddr[3] << 8;
8088 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8090 data |= macaddr[5] << 8;
8091 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8095 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8096 const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
8098 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
8099 uint8_t per_sta_keys_start = 8;
8101 if (BWN_SEC_NEWAPI(mac))
8102 per_sta_keys_start = 4;
8104 KASSERT(index < mac->mac_max_nr_keys,
8105 ("%s:%d: fail", __func__, __LINE__));
8106 KASSERT(key_len <= BWN_SEC_KEYSIZE,
8107 ("%s:%d: fail", __func__, __LINE__));
8109 if (index >= per_sta_keys_start)
8110 bwn_key_macwrite(mac, index, NULL);
8112 memcpy(buf, key, key_len);
8113 bwn_key_write(mac, index, algorithm, buf);
8114 if (index >= per_sta_keys_start)
8115 bwn_key_macwrite(mac, index, mac_addr);
8117 mac->mac_key[index].algorithm = algorithm;
8121 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8123 struct bwn_softc *sc = mac->mac_sc;
8124 uint32_t addrtmp[2] = { 0, 0 };
8127 if (BWN_SEC_NEWAPI(mac))
8130 KASSERT(index >= start,
8131 ("%s:%d: fail", __func__, __LINE__));
8135 addrtmp[0] = addr[0];
8136 addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8137 addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8138 addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8139 addrtmp[1] = addr[4];
8140 addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8143 if (siba_get_revid(sc->sc_dev) >= 5) {
8144 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8145 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8148 bwn_shm_write_4(mac, BWN_SHARED,
8149 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8150 bwn_shm_write_2(mac, BWN_SHARED,
8151 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8157 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8162 uint16_t kidx, value;
8164 kidx = BWN_SEC_KEY2FW(mac, index);
8165 bwn_shm_write_2(mac, BWN_SHARED,
8166 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8168 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8169 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8171 value |= (uint16_t)(key[i + 1]) << 8;
8172 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8177 bwn_phy_exit(struct bwn_mac *mac)
8180 mac->mac_phy.rf_onoff(mac, 0);
8181 if (mac->mac_phy.exit != NULL)
8182 mac->mac_phy.exit(mac);
8186 bwn_dma_free(struct bwn_mac *mac)
8188 struct bwn_dma *dma;
8190 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8192 dma = &mac->mac_method.dma;
8194 bwn_dma_ringfree(&dma->rx);
8195 bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8196 bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8197 bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8198 bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8199 bwn_dma_ringfree(&dma->mcast);
8203 bwn_core_stop(struct bwn_mac *mac)
8205 struct bwn_softc *sc = mac->mac_sc;
8207 BWN_ASSERT_LOCKED(sc);
8209 if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8212 callout_stop(&sc->sc_rfswitch_ch);
8213 callout_stop(&sc->sc_task_ch);
8214 callout_stop(&sc->sc_watchdog_ch);
8215 sc->sc_watchdog_timer = 0;
8216 BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8217 BWN_READ_4(mac, BWN_INTR_MASK);
8218 bwn_mac_suspend(mac);
8220 mac->mac_status = BWN_MAC_STATUS_INITED;
8224 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8226 struct bwn_mac *up_dev = NULL;
8227 struct bwn_mac *down_dev;
8228 struct bwn_mac *mac;
8232 BWN_ASSERT_LOCKED(sc);
8234 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8235 if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8236 mac->mac_phy.supports_2ghz) {
8239 } else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8240 mac->mac_phy.supports_5ghz) {
8244 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8250 if (up_dev == NULL) {
8251 device_printf(sc->sc_dev, "Could not find a device\n");
8254 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8257 device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8258 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8260 down_dev = sc->sc_curmac;
8261 status = down_dev->mac_status;
8262 if (status >= BWN_MAC_STATUS_STARTED)
8263 bwn_core_stop(down_dev);
8264 if (status >= BWN_MAC_STATUS_INITED)
8265 bwn_core_exit(down_dev);
8267 if (down_dev != up_dev)
8268 bwn_phy_reset(down_dev);
8270 up_dev->mac_phy.gmode = gmode;
8271 if (status >= BWN_MAC_STATUS_INITED) {
8272 err = bwn_core_init(up_dev);
8274 device_printf(sc->sc_dev,
8275 "fatal: failed to initialize for %s-GHz\n",
8276 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8280 if (status >= BWN_MAC_STATUS_STARTED)
8281 bwn_core_start(up_dev);
8282 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8283 sc->sc_curmac = up_dev;
8287 sc->sc_curmac = NULL;
8292 bwn_rf_turnon(struct bwn_mac *mac)
8295 bwn_mac_suspend(mac);
8296 mac->mac_phy.rf_onoff(mac, 1);
8297 mac->mac_phy.rf_on = 1;
8298 bwn_mac_enable(mac);
8302 bwn_rf_turnoff(struct bwn_mac *mac)
8305 bwn_mac_suspend(mac);
8306 mac->mac_phy.rf_onoff(mac, 0);
8307 mac->mac_phy.rf_on = 0;
8308 bwn_mac_enable(mac);
8312 bwn_phy_reset(struct bwn_mac *mac)
8314 struct bwn_softc *sc = mac->mac_sc;
8316 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8317 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8318 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8320 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8321 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8322 BWN_TGSLOW_PHYRESET);
8327 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8329 struct bwn_vap *bvp = BWN_VAP(vap);
8330 struct ieee80211com *ic= vap->iv_ic;
8331 struct ifnet *ifp = ic->ic_ifp;
8332 enum ieee80211_state ostate = vap->iv_state;
8333 struct bwn_softc *sc = ifp->if_softc;
8334 struct bwn_mac *mac = sc->sc_curmac;
8337 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8338 ieee80211_state_name[vap->iv_state],
8339 ieee80211_state_name[nstate]);
8341 error = bvp->bv_newstate(vap, nstate, arg);
8347 bwn_led_newstate(mac, nstate);
8350 * Clear the BSSID when we stop a STA
8352 if (vap->iv_opmode == IEEE80211_M_STA) {
8353 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8355 * Clear out the BSSID. If we reassociate to
8356 * the same AP, this will reinialize things
8359 if (ic->ic_opmode == IEEE80211_M_STA &&
8360 (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8361 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8362 bwn_set_macaddr(mac);
8367 if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8368 vap->iv_opmode == IEEE80211_M_AHDEMO) {
8369 /* XXX nothing to do? */
8370 } else if (nstate == IEEE80211_S_RUN) {
8371 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8372 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
8373 bwn_set_opmode(mac);
8374 bwn_set_pretbtt(mac);
8375 bwn_spu_setdelay(mac, 0);
8376 bwn_set_macaddr(mac);
8385 bwn_set_pretbtt(struct bwn_mac *mac)
8387 struct bwn_softc *sc = mac->mac_sc;
8388 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8391 if (ic->ic_opmode == IEEE80211_M_IBSS)
8394 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8395 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8396 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8402 struct bwn_mac *mac = arg;
8403 struct bwn_softc *sc = mac->mac_sc;
8406 if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8407 (sc->sc_flags & BWN_FLAG_INVALID))
8408 return (FILTER_STRAY);
8410 reason = BWN_READ_4(mac, BWN_INTR_REASON);
8411 if (reason == 0xffffffff) /* shared IRQ */
8412 return (FILTER_STRAY);
8413 reason &= mac->mac_intr_mask;
8415 return (FILTER_HANDLED);
8417 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
8418 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8419 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8420 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8421 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8422 BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8423 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8424 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8425 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8426 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8427 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8429 /* Disable interrupts. */
8430 BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8432 mac->mac_reason_intr = reason;
8434 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8435 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8437 taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask);
8438 return (FILTER_HANDLED);
8442 bwn_intrtask(void *arg, int npending)
8444 struct bwn_mac *mac = arg;
8445 struct bwn_softc *sc = mac->mac_sc;
8446 struct ifnet *ifp = sc->sc_ifp;
8447 uint32_t merged = 0;
8448 int i, tx = 0, rx = 0;
8451 if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8452 (sc->sc_flags & BWN_FLAG_INVALID)) {
8457 for (i = 0; i < N(mac->mac_reason); i++)
8458 merged |= mac->mac_reason[i];
8460 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8461 device_printf(sc->sc_dev, "MAC trans error\n");
8463 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8464 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8465 mac->mac_phy.txerrors--;
8466 if (mac->mac_phy.txerrors == 0) {
8467 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8468 bwn_restart(mac, "PHY TX errors");
8472 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
8473 if (merged & BWN_DMAINTR_FATALMASK) {
8474 device_printf(sc->sc_dev,
8475 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8476 mac->mac_reason[0], mac->mac_reason[1],
8477 mac->mac_reason[2], mac->mac_reason[3],
8478 mac->mac_reason[4], mac->mac_reason[5]);
8479 bwn_restart(mac, "DMA error");
8483 if (merged & BWN_DMAINTR_NONFATALMASK) {
8484 device_printf(sc->sc_dev,
8485 "DMA error: %#x %#x %#x %#x %#x %#x\n",
8486 mac->mac_reason[0], mac->mac_reason[1],
8487 mac->mac_reason[2], mac->mac_reason[3],
8488 mac->mac_reason[4], mac->mac_reason[5]);
8492 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8493 bwn_intr_ucode_debug(mac);
8494 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8495 bwn_intr_tbtt_indication(mac);
8496 if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8497 bwn_intr_atim_end(mac);
8498 if (mac->mac_reason_intr & BWN_INTR_BEACON)
8499 bwn_intr_beacon(mac);
8500 if (mac->mac_reason_intr & BWN_INTR_PMQ)
8502 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8503 bwn_intr_noise(mac);
8505 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8506 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8507 bwn_dma_rx(mac->mac_method.dma.rx);
8511 rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8513 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8514 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8515 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8516 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8517 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8519 if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8520 bwn_intr_txeof(mac);
8524 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8526 if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8527 int evt = BWN_LED_EVENT_NONE;
8530 if (sc->sc_rx_rate > sc->sc_tx_rate)
8531 evt = BWN_LED_EVENT_RX;
8533 evt = BWN_LED_EVENT_TX;
8535 evt = BWN_LED_EVENT_TX;
8537 evt = BWN_LED_EVENT_RX;
8538 } else if (rx == 0) {
8539 evt = BWN_LED_EVENT_POLL;
8542 if (evt != BWN_LED_EVENT_NONE)
8543 bwn_led_event(mac, evt);
8546 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
8547 if (!IFQ_IS_EMPTY(&ifp->if_snd))
8548 bwn_start_locked(ifp);
8551 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8552 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8558 bwn_restart(struct bwn_mac *mac, const char *msg)
8560 struct bwn_softc *sc = mac->mac_sc;
8561 struct ifnet *ifp = sc->sc_ifp;
8562 struct ieee80211com *ic = ifp->if_l2com;
8564 if (mac->mac_status < BWN_MAC_STATUS_INITED)
8567 device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8568 ieee80211_runtask(ic, &mac->mac_hwreset);
8572 bwn_intr_ucode_debug(struct bwn_mac *mac)
8574 struct bwn_softc *sc = mac->mac_sc;
8577 if (mac->mac_fw.opensource == 0)
8580 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8582 case BWN_DEBUGINTR_PANIC:
8583 bwn_handle_fwpanic(mac);
8585 case BWN_DEBUGINTR_DUMP_SHM:
8586 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8588 case BWN_DEBUGINTR_DUMP_REGS:
8589 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8591 case BWN_DEBUGINTR_MARKER:
8592 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8595 device_printf(sc->sc_dev,
8596 "ucode debug unknown reason: %#x\n", reason);
8599 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8604 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8606 struct bwn_softc *sc = mac->mac_sc;
8607 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8609 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8611 if (ic->ic_opmode == IEEE80211_M_IBSS)
8612 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8616 bwn_intr_atim_end(struct bwn_mac *mac)
8619 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8620 BWN_WRITE_4(mac, BWN_MACCMD,
8621 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8622 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8627 bwn_intr_beacon(struct bwn_mac *mac)
8629 struct bwn_softc *sc = mac->mac_sc;
8630 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8631 uint32_t cmd, beacon0, beacon1;
8633 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8634 ic->ic_opmode == IEEE80211_M_MBSS)
8637 mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8639 cmd = BWN_READ_4(mac, BWN_MACCMD);
8640 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8641 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8643 if (beacon0 && beacon1) {
8644 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8645 mac->mac_intr_mask |= BWN_INTR_BEACON;
8649 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8650 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8651 bwn_load_beacon0(mac);
8652 bwn_load_beacon1(mac);
8653 cmd = BWN_READ_4(mac, BWN_MACCMD);
8654 cmd |= BWN_MACCMD_BEACON0_VALID;
8655 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8658 bwn_load_beacon0(mac);
8659 cmd = BWN_READ_4(mac, BWN_MACCMD);
8660 cmd |= BWN_MACCMD_BEACON0_VALID;
8661 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8662 } else if (!beacon1) {
8663 bwn_load_beacon1(mac);
8664 cmd = BWN_READ_4(mac, BWN_MACCMD);
8665 cmd |= BWN_MACCMD_BEACON1_VALID;
8666 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8672 bwn_intr_pmq(struct bwn_mac *mac)
8677 tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8678 if (!(tmp & 0x00000008))
8681 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8685 bwn_intr_noise(struct bwn_mac *mac)
8687 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8693 if (mac->mac_phy.type != BWN_PHYTYPE_G)
8696 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8697 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8698 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8702 KASSERT(mac->mac_noise.noi_nsamples < 8,
8703 ("%s:%d: fail", __func__, __LINE__));
8704 i = mac->mac_noise.noi_nsamples;
8705 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8706 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8707 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8708 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8709 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8710 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8711 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8712 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8713 mac->mac_noise.noi_nsamples++;
8714 if (mac->mac_noise.noi_nsamples == 8) {
8716 for (i = 0; i < 8; i++) {
8717 for (j = 0; j < 4; j++)
8718 average += mac->mac_noise.noi_samples[i][j];
8720 average = (((average / 32) * 125) + 64) / 128;
8721 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8726 average -= (tmp == 8) ? 72 : 48;
8728 mac->mac_stats.link_noise = average;
8729 mac->mac_noise.noi_running = 0;
8733 bwn_noise_gensample(mac);
8737 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8739 struct bwn_mac *mac = prq->prq_mac;
8740 struct bwn_softc *sc = mac->mac_sc;
8743 BWN_ASSERT_LOCKED(sc);
8745 if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8748 for (i = 0; i < 5000; i++) {
8749 if (bwn_pio_rxeof(prq) == 0)
8753 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8754 return ((i > 0) ? 1 : 0);
8758 bwn_dma_rx(struct bwn_dma_ring *dr)
8762 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8763 curslot = dr->get_curslot(dr);
8764 KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8765 ("%s:%d: fail", __func__, __LINE__));
8767 slot = dr->dr_curslot;
8768 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8769 bwn_dma_rxeof(dr, &slot);
8771 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8772 BUS_DMASYNC_PREWRITE);
8774 dr->set_curslot(dr, slot);
8775 dr->dr_curslot = slot;
8779 bwn_intr_txeof(struct bwn_mac *mac)
8781 struct bwn_txstatus stat;
8782 uint32_t stat0, stat1;
8785 BWN_ASSERT_LOCKED(mac->mac_sc);
8788 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8789 if (!(stat0 & 0x00000001))
8791 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8793 stat.cookie = (stat0 >> 16);
8794 stat.seq = (stat1 & 0x0000ffff);
8795 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8796 tmp = (stat0 & 0x0000ffff);
8797 stat.framecnt = ((tmp & 0xf000) >> 12);
8798 stat.rtscnt = ((tmp & 0x0f00) >> 8);
8799 stat.sreason = ((tmp & 0x001c) >> 2);
8800 stat.pm = (tmp & 0x0080) ? 1 : 0;
8801 stat.im = (tmp & 0x0040) ? 1 : 0;
8802 stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8803 stat.ack = (tmp & 0x0002) ? 1 : 0;
8805 bwn_handle_txeof(mac, &stat);
8810 bwn_hwreset(void *arg, int npending)
8812 struct bwn_mac *mac = arg;
8813 struct bwn_softc *sc = mac->mac_sc;
8819 prev_status = mac->mac_status;
8820 if (prev_status >= BWN_MAC_STATUS_STARTED)
8822 if (prev_status >= BWN_MAC_STATUS_INITED)
8825 if (prev_status >= BWN_MAC_STATUS_INITED) {
8826 error = bwn_core_init(mac);
8830 if (prev_status >= BWN_MAC_STATUS_STARTED)
8831 bwn_core_start(mac);
8834 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8835 sc->sc_curmac = NULL;
8841 bwn_handle_fwpanic(struct bwn_mac *mac)
8843 struct bwn_softc *sc = mac->mac_sc;
8846 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8847 device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8849 if (reason == BWN_FWPANIC_RESTART)
8850 bwn_restart(mac, "ucode panic");
8854 bwn_load_beacon0(struct bwn_mac *mac)
8857 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8861 bwn_load_beacon1(struct bwn_mac *mac)
8864 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8868 bwn_jssi_read(struct bwn_mac *mac)
8872 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8874 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8880 bwn_noise_gensample(struct bwn_mac *mac)
8882 uint32_t jssi = 0x7f7f7f7f;
8884 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8885 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8886 BWN_WRITE_4(mac, BWN_MACCMD,
8887 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8891 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8893 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8895 return (dr->dr_numslots - dr->dr_usedslot);
8899 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8901 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8903 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8904 ("%s:%d: fail", __func__, __LINE__));
8905 if (slot == dr->dr_numslots - 1)
8911 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8913 struct bwn_mac *mac = dr->dr_mac;
8914 struct bwn_softc *sc = mac->mac_sc;
8915 struct bwn_dma *dma = &mac->mac_method.dma;
8916 struct bwn_dmadesc_generic *desc;
8917 struct bwn_dmadesc_meta *meta;
8918 struct bwn_rxhdr4 *rxhdr;
8919 struct ifnet *ifp = sc->sc_ifp;
8926 dr->getdesc(dr, *slot, &desc, &meta);
8928 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8931 if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8936 rxhdr = mtod(m, struct bwn_rxhdr4 *);
8937 len = le16toh(rxhdr->frame_len);
8942 if (bwn_dma_check_redzone(dr, m)) {
8943 device_printf(sc->sc_dev, "redzone error.\n");
8944 bwn_dma_set_redzone(dr, m);
8945 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8946 BUS_DMASYNC_PREWRITE);
8949 if (len > dr->dr_rx_bufsize) {
8952 dr->getdesc(dr, *slot, &desc, &meta);
8953 bwn_dma_set_redzone(dr, meta->mt_m);
8954 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8955 BUS_DMASYNC_PREWRITE);
8956 *slot = bwn_dma_nextslot(dr, *slot);
8958 tmp -= dr->dr_rx_bufsize;
8962 device_printf(sc->sc_dev, "too small buffer "
8963 "(len %u buffer %u dropped %d)\n",
8964 len, dr->dr_rx_bufsize, cnt);
8967 macstat = le32toh(rxhdr->mac_status);
8968 if (macstat & BWN_RX_MAC_FCSERR) {
8969 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8970 device_printf(sc->sc_dev, "RX drop\n");
8975 m->m_pkthdr.rcvif = ifp;
8976 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8977 m_adj(m, dr->dr_frameoffset);
8979 bwn_rxeof(dr->dr_mac, m, rxhdr);
8983 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8985 struct bwn_dma_ring *dr;
8986 struct bwn_dmadesc_generic *desc;
8987 struct bwn_dmadesc_meta *meta;
8988 struct bwn_pio_txqueue *tq;
8989 struct bwn_pio_txpkt *tp = NULL;
8990 struct bwn_softc *sc = mac->mac_sc;
8991 struct bwn_stats *stats = &mac->mac_stats;
8992 struct ieee80211_node *ni;
8993 struct ieee80211vap *vap;
8994 int retrycnt = 0, slot;
8996 BWN_ASSERT_LOCKED(mac->mac_sc);
8999 device_printf(sc->sc_dev, "TODO: STATUS IM\n");
9001 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
9002 if (status->rtscnt) {
9003 if (status->rtscnt == 0xf)
9009 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
9011 dr = bwn_dma_parse_cookie(mac, status,
9012 status->cookie, &slot);
9014 device_printf(sc->sc_dev,
9015 "failed to parse cookie\n");
9019 dr->getdesc(dr, slot, &desc, &meta);
9020 if (meta->mt_islast) {
9023 ieee80211_ratectl_tx_complete(vap, ni,
9025 IEEE80211_RATECTL_TX_SUCCESS :
9026 IEEE80211_RATECTL_TX_FAILURE,
9030 slot = bwn_dma_nextslot(dr, slot);
9033 bwn_dma_handle_txeof(mac, status);
9036 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9038 device_printf(sc->sc_dev,
9039 "failed to parse cookie\n");
9044 ieee80211_ratectl_tx_complete(vap, ni,
9046 IEEE80211_RATECTL_TX_SUCCESS :
9047 IEEE80211_RATECTL_TX_FAILURE,
9050 bwn_pio_handle_txeof(mac, status);
9053 bwn_phy_txpower_check(mac, 0);
9057 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
9059 struct bwn_mac *mac = prq->prq_mac;
9060 struct bwn_softc *sc = mac->mac_sc;
9061 struct bwn_rxhdr4 rxhdr;
9062 struct ifnet *ifp = sc->sc_ifp;
9064 uint32_t ctl32, macstat, v32;
9065 unsigned int i, padding;
9066 uint16_t ctl16, len, totlen, v16;
9070 memset(&rxhdr, 0, sizeof(rxhdr));
9072 if (prq->prq_rev >= 8) {
9073 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9074 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
9076 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9077 BWN_PIO8_RXCTL_FRAMEREADY);
9078 for (i = 0; i < 10; i++) {
9079 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9080 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
9085 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9086 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
9088 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
9089 BWN_PIO_RXCTL_FRAMEREADY);
9090 for (i = 0; i < 10; i++) {
9091 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9092 if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
9097 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
9100 if (prq->prq_rev >= 8)
9101 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9102 prq->prq_base + BWN_PIO8_RXDATA);
9104 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9105 prq->prq_base + BWN_PIO_RXDATA);
9106 len = le16toh(rxhdr.frame_len);
9108 device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9112 device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9116 macstat = le32toh(rxhdr.mac_status);
9117 if (macstat & BWN_RX_MAC_FCSERR) {
9118 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9119 device_printf(sc->sc_dev, "%s: FCS error", __func__);
9124 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9125 totlen = len + padding;
9126 KASSERT(totlen <= MCLBYTES, ("too big..\n"));
9127 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9129 device_printf(sc->sc_dev, "%s: out of memory", __func__);
9132 mp = mtod(m, unsigned char *);
9133 if (prq->prq_rev >= 8) {
9134 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3),
9135 prq->prq_base + BWN_PIO8_RXDATA);
9137 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9138 data = &(mp[totlen - 1]);
9139 switch (totlen & 3) {
9141 *data = (v32 >> 16);
9151 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1),
9152 prq->prq_base + BWN_PIO_RXDATA);
9154 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9155 mp[totlen - 1] = v16;
9159 m->m_pkthdr.rcvif = ifp;
9160 m->m_len = m->m_pkthdr.len = totlen;
9162 bwn_rxeof(prq->prq_mac, m, &rxhdr);
9166 if (prq->prq_rev >= 8)
9167 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9168 BWN_PIO8_RXCTL_DATAREADY);
9170 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9175 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9176 struct bwn_dmadesc_meta *meta, int init)
9178 struct bwn_mac *mac = dr->dr_mac;
9179 struct bwn_dma *dma = &mac->mac_method.dma;
9180 struct bwn_rxhdr4 *hdr;
9186 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9191 * If the NIC is up and running, we need to:
9192 * - Clear RX buffer's header.
9193 * - Restore RX descriptor settings.
9200 m->m_len = m->m_pkthdr.len = MCLBYTES;
9202 bwn_dma_set_redzone(dr, m);
9205 * Try to load RX buf into temporary DMA map
9207 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9208 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9213 * See the comment above
9222 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9224 meta->mt_paddr = paddr;
9227 * Swap RX buf's DMA map with the loaded temporary one
9229 map = meta->mt_dmap;
9230 meta->mt_dmap = dr->dr_spare_dmap;
9231 dr->dr_spare_dmap = map;
9235 * Clear RX buf header
9237 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9238 bzero(hdr, sizeof(*hdr));
9239 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9240 BUS_DMASYNC_PREWRITE);
9243 * Setup RX buf descriptor
9245 dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len -
9246 sizeof(*hdr), 0, 0, 0);
9251 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9252 bus_size_t mapsz __unused, int error)
9256 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9257 *((bus_addr_t *)arg) = seg->ds_addr;
9262 bwn_hwrate2ieeerate(int rate)
9266 case BWN_CCK_RATE_1MB:
9268 case BWN_CCK_RATE_2MB:
9270 case BWN_CCK_RATE_5MB:
9272 case BWN_CCK_RATE_11MB:
9274 case BWN_OFDM_RATE_6MB:
9276 case BWN_OFDM_RATE_9MB:
9278 case BWN_OFDM_RATE_12MB:
9280 case BWN_OFDM_RATE_18MB:
9282 case BWN_OFDM_RATE_24MB:
9284 case BWN_OFDM_RATE_36MB:
9286 case BWN_OFDM_RATE_48MB:
9288 case BWN_OFDM_RATE_54MB:
9297 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9299 const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9300 struct bwn_plcp6 *plcp;
9301 struct bwn_softc *sc = mac->mac_sc;
9302 struct ieee80211_frame_min *wh;
9303 struct ieee80211_node *ni;
9304 struct ifnet *ifp = sc->sc_ifp;
9305 struct ieee80211com *ic = ifp->if_l2com;
9307 int padding, rate, rssi = 0, noise = 0, type;
9308 uint16_t phytype, phystat0, phystat3, chanstat;
9309 unsigned char *mp = mtod(m, unsigned char *);
9310 static int rx_mac_dec_rpt = 0;
9312 BWN_ASSERT_LOCKED(sc);
9314 phystat0 = le16toh(rxhdr->phy_status0);
9315 phystat3 = le16toh(rxhdr->phy_status3);
9316 macstat = le32toh(rxhdr->mac_status);
9317 chanstat = le16toh(rxhdr->channel);
9318 phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9320 if (macstat & BWN_RX_MAC_FCSERR)
9321 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9322 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9323 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9324 if (macstat & BWN_RX_MAC_DECERR)
9327 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9328 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9329 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9333 plcp = (struct bwn_plcp6 *)(mp + padding);
9334 m_adj(m, sizeof(struct bwn_plcp6) + padding);
9335 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9336 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9340 wh = mtod(m, struct ieee80211_frame_min *);
9342 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9343 device_printf(sc->sc_dev,
9344 "RX decryption attempted (old %d keyidx %#x)\n",
9346 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9348 /* XXX calculating RSSI & noise & antenna */
9350 if (phystat0 & BWN_RX_PHYST0_OFDM)
9351 rate = bwn_plcp_get_ofdmrate(mac, plcp,
9352 phytype == BWN_PHYTYPE_A);
9354 rate = bwn_plcp_get_cckrate(mac, plcp);
9356 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9359 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9362 if (ieee80211_radiotap_active(ic))
9363 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9364 m_adj(m, -IEEE80211_CRC_LEN);
9366 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */
9367 noise = mac->mac_stats.link_noise;
9373 ni = ieee80211_find_rxnode(ic, wh);
9375 type = ieee80211_input(ni, m, rssi, noise);
9376 ieee80211_free_node(ni);
9378 type = ieee80211_input_all(ic, m, rssi, noise);
9383 device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9387 bwn_dma_handle_txeof(struct bwn_mac *mac,
9388 const struct bwn_txstatus *status)
9390 struct bwn_dma *dma = &mac->mac_method.dma;
9391 struct bwn_dma_ring *dr;
9392 struct bwn_dmadesc_generic *desc;
9393 struct bwn_dmadesc_meta *meta;
9394 struct bwn_softc *sc = mac->mac_sc;
9395 struct ieee80211_node *ni;
9396 struct ifnet *ifp = sc->sc_ifp;
9400 BWN_ASSERT_LOCKED(sc);
9402 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9404 device_printf(sc->sc_dev, "failed to parse cookie\n");
9407 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9410 KASSERT(slot >= 0 && slot < dr->dr_numslots,
9411 ("%s:%d: fail", __func__, __LINE__));
9412 dr->getdesc(dr, slot, &desc, &meta);
9414 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
9415 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
9416 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
9417 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9419 if (meta->mt_islast) {
9420 KASSERT(meta->mt_m != NULL,
9421 ("%s:%d: fail", __func__, __LINE__));
9427 * Do any tx complete callback. Note this must
9428 * be done before releasing the node reference.
9430 if (m->m_flags & M_TXCB)
9431 ieee80211_process_callback(ni, m, 0);
9432 ieee80211_free_node(ni);
9438 KASSERT(meta->mt_m == NULL,
9439 ("%s:%d: fail", __func__, __LINE__));
9443 if (meta->mt_islast) {
9447 slot = bwn_dma_nextslot(dr, slot);
9449 sc->sc_watchdog_timer = 0;
9451 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9452 ("%s:%d: fail", __func__, __LINE__));
9453 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9459 bwn_pio_handle_txeof(struct bwn_mac *mac,
9460 const struct bwn_txstatus *status)
9462 struct bwn_pio_txqueue *tq;
9463 struct bwn_pio_txpkt *tp = NULL;
9464 struct bwn_softc *sc = mac->mac_sc;
9465 struct ifnet *ifp = sc->sc_ifp;
9467 BWN_ASSERT_LOCKED(sc);
9469 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9473 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9476 ieee80211_tx_complete(tp->tp_ni, tp->tp_m, 0);
9479 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9483 sc->sc_watchdog_timer = 0;
9485 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9491 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9493 struct bwn_softc *sc = mac->mac_sc;
9494 struct bwn_phy *phy = &mac->mac_phy;
9495 struct ifnet *ifp = sc->sc_ifp;
9496 struct ieee80211com *ic = ifp->if_l2com;
9502 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9504 phy->nexttime = now + 2 * 1000;
9506 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9507 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9510 if (phy->recalc_txpwr != NULL) {
9511 result = phy->recalc_txpwr(mac,
9512 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9513 if (result == BWN_TXPWR_RES_DONE)
9515 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9516 ("%s: fail", __func__));
9517 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9519 ieee80211_runtask(ic, &mac->mac_txpower);
9524 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9527 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9531 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9534 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9538 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9541 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9545 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9548 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9552 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9556 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9558 return (BWN_OFDM_RATE_6MB);
9560 return (BWN_OFDM_RATE_9MB);
9562 return (BWN_OFDM_RATE_12MB);
9564 return (BWN_OFDM_RATE_18MB);
9566 return (BWN_OFDM_RATE_24MB);
9568 return (BWN_OFDM_RATE_36MB);
9570 return (BWN_OFDM_RATE_48MB);
9572 return (BWN_OFDM_RATE_54MB);
9573 /* CCK rates (NB: not IEEE std, device-specific) */
9575 return (BWN_CCK_RATE_1MB);
9577 return (BWN_CCK_RATE_2MB);
9579 return (BWN_CCK_RATE_5MB);
9581 return (BWN_CCK_RATE_11MB);
9584 device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9585 return (BWN_CCK_RATE_1MB);
9589 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9590 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9592 const struct bwn_phy *phy = &mac->mac_phy;
9593 struct bwn_softc *sc = mac->mac_sc;
9594 struct ieee80211_frame *wh;
9595 struct ieee80211_frame *protwh;
9596 struct ieee80211_frame_cts *cts;
9597 struct ieee80211_frame_rts *rts;
9598 const struct ieee80211_txparam *tp;
9599 struct ieee80211vap *vap = ni->ni_vap;
9600 struct ifnet *ifp = sc->sc_ifp;
9601 struct ieee80211com *ic = ifp->if_l2com;
9604 uint32_t macctl = 0;
9605 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9606 uint16_t phyctl = 0;
9607 uint8_t rate, rate_fb;
9609 wh = mtod(m, struct ieee80211_frame *);
9610 memset(txhdr, 0, sizeof(*txhdr));
9612 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9613 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9614 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9619 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9620 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9621 rate = rate_fb = tp->mgmtrate;
9623 rate = rate_fb = tp->mcastrate;
9624 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9625 rate = rate_fb = tp->ucastrate;
9627 rix = ieee80211_ratectl_rate(ni, NULL, 0);
9628 rate = ni->ni_txrate;
9631 rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9637 sc->sc_tx_rate = rate;
9639 rate = bwn_ieeerate2hwrate(sc, rate);
9640 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9642 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9643 bwn_plcp_getcck(rate);
9644 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9645 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9647 if ((rate_fb == rate) ||
9648 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9649 (*(u_int16_t *)wh->i_dur == htole16(0)))
9650 txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9652 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9653 m->m_pkthdr.len, rate, isshort);
9655 /* XXX TX encryption */
9656 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9657 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9658 (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9659 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9660 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9661 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9663 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9665 txhdr->chan = phy->chan;
9666 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9668 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9669 rate == BWN_CCK_RATE_11MB))
9670 phyctl |= BWN_TX_PHY_SHORTPRMBL;
9672 /* XXX TX antenna selection */
9674 switch (bwn_antenna_sanitize(mac, 0)) {
9676 phyctl |= BWN_TX_PHY_ANT01AUTO;
9679 phyctl |= BWN_TX_PHY_ANT0;
9682 phyctl |= BWN_TX_PHY_ANT1;
9685 phyctl |= BWN_TX_PHY_ANT2;
9688 phyctl |= BWN_TX_PHY_ANT3;
9691 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9695 macctl |= BWN_TX_MAC_ACK;
9697 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9698 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9699 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9700 macctl |= BWN_TX_MAC_LONGFRAME;
9702 if (ic->ic_flags & IEEE80211_F_USEPROT) {
9703 /* XXX RTS rate is always 1MB??? */
9704 rts_rate = BWN_CCK_RATE_1MB;
9705 rts_rate_fb = bwn_get_fbrate(rts_rate);
9707 protdur = ieee80211_compute_duration(ic->ic_rt,
9708 m->m_pkthdr.len, rate, isshort) +
9709 + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9711 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9712 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9713 (txhdr->body.old.rts_frame) :
9714 (txhdr->body.new.rts_frame));
9715 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9717 KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9718 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9719 mprot->m_pkthdr.len);
9721 macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9722 len = sizeof(struct ieee80211_frame_cts);
9724 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9725 (txhdr->body.old.rts_frame) :
9726 (txhdr->body.new.rts_frame));
9727 protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9729 mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9730 wh->i_addr2, protdur);
9731 KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9732 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9733 mprot->m_pkthdr.len);
9735 macctl |= BWN_TX_MAC_SEND_RTSCTS;
9736 len = sizeof(struct ieee80211_frame_rts);
9738 len += IEEE80211_CRC_LEN;
9739 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9740 &txhdr->body.old.rts_plcp :
9741 &txhdr->body.new.rts_plcp), len, rts_rate);
9742 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9745 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9746 (&txhdr->body.old.rts_frame) :
9747 (&txhdr->body.new.rts_frame));
9748 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9750 if (BWN_ISOFDMRATE(rts_rate)) {
9751 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9752 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9754 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9755 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9757 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9758 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9761 if (BWN_ISOLDFMT(mac))
9762 txhdr->body.old.cookie = htole16(cookie);
9764 txhdr->body.new.cookie = htole16(cookie);
9766 txhdr->macctl = htole32(macctl);
9767 txhdr->phyctl = htole16(phyctl);
9772 if (ieee80211_radiotap_active_vap(vap)) {
9773 sc->sc_tx_th.wt_flags = 0;
9774 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
9775 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9777 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9778 rate == BWN_CCK_RATE_11MB))
9779 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9780 sc->sc_tx_th.wt_rate = rate;
9782 ieee80211_radiotap_tx(vap, m);
9789 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9793 uint8_t *raw = plcp->o.raw;
9795 if (BWN_ISOFDMRATE(rate)) {
9796 d = bwn_plcp_getofdm(rate);
9797 KASSERT(!(octets & 0xf000),
9798 ("%s:%d: fail", __func__, __LINE__));
9800 plcp->o.data = htole32(d);
9802 plen = octets * 16 / rate;
9803 if ((octets * 16 % rate) > 0) {
9805 if ((rate == BWN_CCK_RATE_11MB)
9806 && ((octets * 8 % 11) < 4)) {
9812 plcp->o.data |= htole32(plen << 16);
9813 raw[0] = bwn_plcp_getcck(rate);
9818 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9820 struct bwn_softc *sc = mac->mac_sc;
9825 if (mac->mac_phy.gmode)
9826 mask = siba_sprom_get_ant_bg(sc->sc_dev);
9828 mask = siba_sprom_get_ant_a(sc->sc_dev);
9829 if (!(mask & (1 << (n - 1))))
9835 bwn_get_fbrate(uint8_t bitrate)
9838 case BWN_CCK_RATE_1MB:
9839 return (BWN_CCK_RATE_1MB);
9840 case BWN_CCK_RATE_2MB:
9841 return (BWN_CCK_RATE_1MB);
9842 case BWN_CCK_RATE_5MB:
9843 return (BWN_CCK_RATE_2MB);
9844 case BWN_CCK_RATE_11MB:
9845 return (BWN_CCK_RATE_5MB);
9846 case BWN_OFDM_RATE_6MB:
9847 return (BWN_CCK_RATE_5MB);
9848 case BWN_OFDM_RATE_9MB:
9849 return (BWN_OFDM_RATE_6MB);
9850 case BWN_OFDM_RATE_12MB:
9851 return (BWN_OFDM_RATE_9MB);
9852 case BWN_OFDM_RATE_18MB:
9853 return (BWN_OFDM_RATE_12MB);
9854 case BWN_OFDM_RATE_24MB:
9855 return (BWN_OFDM_RATE_18MB);
9856 case BWN_OFDM_RATE_36MB:
9857 return (BWN_OFDM_RATE_24MB);
9858 case BWN_OFDM_RATE_48MB:
9859 return (BWN_OFDM_RATE_36MB);
9860 case BWN_OFDM_RATE_54MB:
9861 return (BWN_OFDM_RATE_48MB);
9863 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9868 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9869 uint32_t ctl, const void *_data, int len)
9871 struct bwn_softc *sc = mac->mac_sc;
9873 const uint8_t *data = _data;
9875 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9876 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9877 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9879 siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9880 tq->tq_base + BWN_PIO8_TXDATA);
9882 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9883 BWN_PIO8_TXCTL_24_31);
9884 data = &(data[len - 1]);
9887 ctl |= BWN_PIO8_TXCTL_16_23;
9888 value |= (uint32_t)(*data) << 16;
9891 ctl |= BWN_PIO8_TXCTL_8_15;
9892 value |= (uint32_t)(*data) << 8;
9895 value |= (uint32_t)(*data);
9897 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9898 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9905 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9906 uint16_t offset, uint32_t value)
9909 BWN_WRITE_4(mac, tq->tq_base + offset, value);
9913 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9914 uint16_t ctl, const void *_data, int len)
9916 struct bwn_softc *sc = mac->mac_sc;
9917 const uint8_t *data = _data;
9919 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9920 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9922 siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9923 tq->tq_base + BWN_PIO_TXDATA);
9925 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9926 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9927 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9934 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9935 uint16_t ctl, struct mbuf *m0)
9940 struct mbuf *m = m0;
9942 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9943 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9945 for (; m != NULL; m = m->m_next) {
9946 buf = mtod(m, const uint8_t *);
9947 for (i = 0; i < m->m_len; i++) {
9951 data |= (buf[i] << 8);
9952 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9957 if (m0->m_pkthdr.len % 2) {
9958 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9959 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9960 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9967 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9970 if (mac->mac_phy.type != BWN_PHYTYPE_G)
9972 BWN_WRITE_2(mac, 0x684, 510 + time);
9973 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9976 static struct bwn_dma_ring *
9977 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9980 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9981 return (mac->mac_method.dma.wme[WME_AC_BE]);
9985 return (mac->mac_method.dma.wme[WME_AC_VO]);
9987 return (mac->mac_method.dma.wme[WME_AC_VI]);
9989 return (mac->mac_method.dma.wme[WME_AC_BE]);
9991 return (mac->mac_method.dma.wme[WME_AC_BK]);
9993 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9998 bwn_dma_getslot(struct bwn_dma_ring *dr)
10002 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
10004 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
10005 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
10006 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
10008 slot = bwn_dma_nextslot(dr, dr->dr_curslot);
10009 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
10010 dr->dr_curslot = slot;
10017 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
10019 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
10020 unsigned int a, b, c, d;
10024 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
10026 b = (tmp >> 8) & 0xff;
10027 c = (tmp >> 16) & 0xff;
10028 d = (tmp >> 24) & 0xff;
10029 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
10030 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
10032 bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
10033 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
10034 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
10037 a = (a + 32) & 0x3f;
10038 b = (b + 32) & 0x3f;
10039 c = (c + 32) & 0x3f;
10040 d = (d + 32) & 0x3f;
10043 avg = (a + b + c + d + 2) / 4;
10045 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
10046 & BWN_HF_4DB_CCK_POWERBOOST)
10047 avg = (avg >= 13) ? (avg - 13) : 0;
10053 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
10055 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
10056 int rfatt = *rfattp;
10057 int bbatt = *bbattp;
10060 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
10062 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
10064 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
10066 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
10068 if (bbatt > lo->bbatt.max) {
10073 if (bbatt < lo->bbatt.min) {
10078 if (rfatt > lo->rfatt.max) {
10083 if (rfatt < lo->rfatt.min) {
10091 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
10092 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
10096 bwn_phy_lock(struct bwn_mac *mac)
10098 struct bwn_softc *sc = mac->mac_sc;
10099 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10101 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10102 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10104 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10105 bwn_psctl(mac, BWN_PS_AWAKE);
10109 bwn_phy_unlock(struct bwn_mac *mac)
10111 struct bwn_softc *sc = mac->mac_sc;
10112 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10114 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10115 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10117 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10122 bwn_rf_lock(struct bwn_mac *mac)
10125 BWN_WRITE_4(mac, BWN_MACCTL,
10126 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
10127 BWN_READ_4(mac, BWN_MACCTL);
10132 bwn_rf_unlock(struct bwn_mac *mac)
10135 BWN_READ_2(mac, BWN_PHYVER);
10136 BWN_WRITE_4(mac, BWN_MACCTL,
10137 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10140 static struct bwn_pio_txqueue *
10141 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10142 struct bwn_pio_txpkt **pack)
10144 struct bwn_pio *pio = &mac->mac_method.pio;
10145 struct bwn_pio_txqueue *tq = NULL;
10146 unsigned int index;
10148 switch (cookie & 0xf000) {
10150 tq = &pio->wme[WME_AC_BK];
10153 tq = &pio->wme[WME_AC_BE];
10156 tq = &pio->wme[WME_AC_VI];
10159 tq = &pio->wme[WME_AC_VO];
10165 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10168 index = (cookie & 0x0fff);
10169 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10170 if (index >= N(tq->tq_pkts))
10172 *pack = &tq->tq_pkts[index];
10173 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10178 bwn_txpwr(void *arg, int npending)
10180 struct bwn_mac *mac = arg;
10181 struct bwn_softc *sc = mac->mac_sc;
10184 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10185 mac->mac_phy.set_txpwr != NULL)
10186 mac->mac_phy.set_txpwr(mac);
10191 bwn_task_15s(struct bwn_mac *mac)
10195 if (mac->mac_fw.opensource) {
10196 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10198 bwn_restart(mac, "fw watchdog");
10201 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10203 if (mac->mac_phy.task_15s)
10204 mac->mac_phy.task_15s(mac);
10206 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10210 bwn_task_30s(struct bwn_mac *mac)
10213 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10215 mac->mac_noise.noi_running = 1;
10216 mac->mac_noise.noi_nsamples = 0;
10218 bwn_noise_gensample(mac);
10222 bwn_task_60s(struct bwn_mac *mac)
10225 if (mac->mac_phy.task_60s)
10226 mac->mac_phy.task_60s(mac);
10227 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10231 bwn_tasks(void *arg)
10233 struct bwn_mac *mac = arg;
10234 struct bwn_softc *sc = mac->mac_sc;
10236 BWN_ASSERT_LOCKED(sc);
10237 if (mac->mac_status != BWN_MAC_STATUS_STARTED)
10240 if (mac->mac_task_state % 4 == 0)
10242 if (mac->mac_task_state % 2 == 0)
10246 mac->mac_task_state++;
10247 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10251 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10253 struct bwn_softc *sc = mac->mac_sc;
10255 KASSERT(a == 0, ("not support APHY\n"));
10257 switch (plcp->o.raw[0] & 0xf) {
10259 return (BWN_OFDM_RATE_6MB);
10261 return (BWN_OFDM_RATE_9MB);
10263 return (BWN_OFDM_RATE_12MB);
10265 return (BWN_OFDM_RATE_18MB);
10267 return (BWN_OFDM_RATE_24MB);
10269 return (BWN_OFDM_RATE_36MB);
10271 return (BWN_OFDM_RATE_48MB);
10273 return (BWN_OFDM_RATE_54MB);
10275 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10276 plcp->o.raw[0] & 0xf);
10281 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10283 struct bwn_softc *sc = mac->mac_sc;
10285 switch (plcp->o.raw[0]) {
10287 return (BWN_CCK_RATE_1MB);
10289 return (BWN_CCK_RATE_2MB);
10291 return (BWN_CCK_RATE_5MB);
10293 return (BWN_CCK_RATE_11MB);
10295 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10300 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10301 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10302 int rssi, int noise)
10304 struct bwn_softc *sc = mac->mac_sc;
10305 const struct ieee80211_frame_min *wh;
10307 uint16_t low_mactime_now;
10309 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10310 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10312 wh = mtod(m, const struct ieee80211_frame_min *);
10313 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
10314 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10316 bwn_tsf_read(mac, &tsf);
10317 low_mactime_now = tsf;
10318 tsf = tsf & ~0xffffULL;
10319 tsf += le16toh(rxhdr->mac_time);
10320 if (low_mactime_now < le16toh(rxhdr->mac_time))
10323 sc->sc_rx_th.wr_tsf = tsf;
10324 sc->sc_rx_th.wr_rate = rate;
10325 sc->sc_rx_th.wr_antsignal = rssi;
10326 sc->sc_rx_th.wr_antnoise = noise;
10330 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10332 uint32_t low, high;
10334 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10335 ("%s:%d: fail", __func__, __LINE__));
10337 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10338 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10345 bwn_dma_attach(struct bwn_mac *mac)
10347 struct bwn_dma *dma = &mac->mac_method.dma;
10348 struct bwn_softc *sc = mac->mac_sc;
10349 bus_addr_t lowaddr = 0;
10352 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10355 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10357 mac->mac_flags |= BWN_MAC_FLAG_DMA;
10359 dma->dmatype = bwn_dma_gettype(mac);
10360 if (dma->dmatype == BWN_DMA_30BIT)
10361 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10362 else if (dma->dmatype == BWN_DMA_32BIT)
10363 lowaddr = BUS_SPACE_MAXADDR_32BIT;
10365 lowaddr = BUS_SPACE_MAXADDR;
10368 * Create top level DMA tag
10370 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
10371 BWN_ALIGN, 0, /* alignment, bounds */
10372 lowaddr, /* lowaddr */
10373 BUS_SPACE_MAXADDR, /* highaddr */
10374 NULL, NULL, /* filter, filterarg */
10375 BUS_SPACE_MAXSIZE, /* maxsize */
10376 BUS_SPACE_UNRESTRICTED, /* nsegments */
10377 BUS_SPACE_MAXSIZE, /* maxsegsize */
10379 NULL, NULL, /* lockfunc, lockarg */
10380 &dma->parent_dtag);
10382 device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10387 * Create TX/RX mbuf DMA tag
10389 error = bus_dma_tag_create(dma->parent_dtag,
10397 BUS_SPACE_MAXSIZE_32BIT,
10402 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10405 error = bus_dma_tag_create(dma->parent_dtag,
10413 BUS_SPACE_MAXSIZE_32BIT,
10418 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10422 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10423 if (!dma->wme[WME_AC_BK])
10426 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10427 if (!dma->wme[WME_AC_BE])
10430 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10431 if (!dma->wme[WME_AC_VI])
10434 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10435 if (!dma->wme[WME_AC_VO])
10438 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10441 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10447 fail7: bwn_dma_ringfree(&dma->mcast);
10448 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10449 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10450 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10451 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10452 fail2: bus_dma_tag_destroy(dma->txbuf_dtag);
10453 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag);
10454 fail0: bus_dma_tag_destroy(dma->parent_dtag);
10458 static struct bwn_dma_ring *
10459 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10460 uint16_t cookie, int *slot)
10462 struct bwn_dma *dma = &mac->mac_method.dma;
10463 struct bwn_dma_ring *dr;
10464 struct bwn_softc *sc = mac->mac_sc;
10466 BWN_ASSERT_LOCKED(mac->mac_sc);
10468 switch (cookie & 0xf000) {
10470 dr = dma->wme[WME_AC_BK];
10473 dr = dma->wme[WME_AC_BE];
10476 dr = dma->wme[WME_AC_VI];
10479 dr = dma->wme[WME_AC_VO];
10487 ("invalid cookie value %d", cookie & 0xf000));
10489 *slot = (cookie & 0x0fff);
10490 if (*slot < 0 || *slot >= dr->dr_numslots) {
10492 * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10493 * that it occurs events which have same H/W sequence numbers.
10494 * When it's occurred just prints a WARNING msgs and ignores.
10496 KASSERT(status->seq == dma->lastseq,
10497 ("%s:%d: fail", __func__, __LINE__));
10498 device_printf(sc->sc_dev,
10499 "out of slot ranges (0 < %d < %d)\n", *slot,
10503 dma->lastseq = status->seq;
10508 bwn_dma_stop(struct bwn_mac *mac)
10510 struct bwn_dma *dma;
10512 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10514 dma = &mac->mac_method.dma;
10516 bwn_dma_ringstop(&dma->rx);
10517 bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10518 bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10519 bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10520 bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10521 bwn_dma_ringstop(&dma->mcast);
10525 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10531 bwn_dma_cleanup(*dr);
10535 bwn_pio_stop(struct bwn_mac *mac)
10537 struct bwn_pio *pio;
10539 if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10541 pio = &mac->mac_method.pio;
10543 bwn_destroy_queue_tx(&pio->mcast);
10544 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10545 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10546 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10547 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10551 bwn_led_attach(struct bwn_mac *mac)
10553 struct bwn_softc *sc = mac->mac_sc;
10554 const uint8_t *led_act = NULL;
10555 uint16_t val[BWN_LED_MAX];
10558 sc->sc_led_idle = (2350 * hz) / 1000;
10559 sc->sc_led_blink = 1;
10561 for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10562 if (siba_get_pci_subvendor(sc->sc_dev) ==
10563 bwn_vendor_led_act[i].vid) {
10564 led_act = bwn_vendor_led_act[i].led_act;
10568 if (led_act == NULL)
10569 led_act = bwn_default_led_act;
10571 val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10572 val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10573 val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10574 val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10576 for (i = 0; i < BWN_LED_MAX; ++i) {
10577 struct bwn_led *led = &sc->sc_leds[i];
10579 if (val[i] == 0xff) {
10580 led->led_act = led_act[i];
10582 if (val[i] & BWN_LED_ACT_LOW)
10583 led->led_flags |= BWN_LED_F_ACTLOW;
10584 led->led_act = val[i] & BWN_LED_ACT_MASK;
10586 led->led_mask = (1 << i);
10588 if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10589 led->led_act == BWN_LED_ACT_BLINK_POLL ||
10590 led->led_act == BWN_LED_ACT_BLINK) {
10591 led->led_flags |= BWN_LED_F_BLINK;
10592 if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10593 led->led_flags |= BWN_LED_F_POLLABLE;
10594 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10595 led->led_flags |= BWN_LED_F_SLOW;
10597 if (sc->sc_blink_led == NULL) {
10598 sc->sc_blink_led = led;
10599 if (led->led_flags & BWN_LED_F_SLOW)
10600 BWN_LED_SLOWDOWN(sc->sc_led_idle);
10604 DPRINTF(sc, BWN_DEBUG_LED,
10605 "%dth led, act %d, lowact %d\n", i,
10606 led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10608 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
10611 static __inline uint16_t
10612 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10615 if (led->led_flags & BWN_LED_F_ACTLOW)
10618 val |= led->led_mask;
10620 val &= ~led->led_mask;
10625 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10627 struct bwn_softc *sc = mac->mac_sc;
10628 struct ifnet *ifp = sc->sc_ifp;
10629 struct ieee80211com *ic = ifp->if_l2com;
10633 if (nstate == IEEE80211_S_INIT) {
10634 callout_stop(&sc->sc_led_blink_ch);
10635 sc->sc_led_blinking = 0;
10638 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
10641 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10642 for (i = 0; i < BWN_LED_MAX; ++i) {
10643 struct bwn_led *led = &sc->sc_leds[i];
10646 if (led->led_act == BWN_LED_ACT_UNKN ||
10647 led->led_act == BWN_LED_ACT_NULL)
10650 if ((led->led_flags & BWN_LED_F_BLINK) &&
10651 nstate != IEEE80211_S_INIT)
10654 switch (led->led_act) {
10655 case BWN_LED_ACT_ON: /* Always on */
10658 case BWN_LED_ACT_OFF: /* Always off */
10659 case BWN_LED_ACT_5GHZ: /* TODO: 11A */
10665 case IEEE80211_S_INIT:
10668 case IEEE80211_S_RUN:
10669 if (led->led_act == BWN_LED_ACT_11G &&
10670 ic->ic_curmode != IEEE80211_MODE_11G)
10674 if (led->led_act == BWN_LED_ACT_ASSOC)
10681 val = bwn_led_onoff(led, val, on);
10683 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10687 bwn_led_event(struct bwn_mac *mac, int event)
10689 struct bwn_softc *sc = mac->mac_sc;
10690 struct bwn_led *led = sc->sc_blink_led;
10693 if (event == BWN_LED_EVENT_POLL) {
10694 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10696 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10700 sc->sc_led_ticks = ticks;
10701 if (sc->sc_led_blinking)
10705 case BWN_LED_EVENT_RX:
10706 rate = sc->sc_rx_rate;
10708 case BWN_LED_EVENT_TX:
10709 rate = sc->sc_tx_rate;
10711 case BWN_LED_EVENT_POLL:
10715 panic("unknown LED event %d\n", event);
10718 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10719 bwn_led_duration[rate].off_dur);
10723 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10725 struct bwn_softc *sc = mac->mac_sc;
10726 struct bwn_led *led = sc->sc_blink_led;
10729 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10730 val = bwn_led_onoff(led, val, 1);
10731 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10733 if (led->led_flags & BWN_LED_F_SLOW) {
10734 BWN_LED_SLOWDOWN(on_dur);
10735 BWN_LED_SLOWDOWN(off_dur);
10738 sc->sc_led_blinking = 1;
10739 sc->sc_led_blink_offdur = off_dur;
10741 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10745 bwn_led_blink_next(void *arg)
10747 struct bwn_mac *mac = arg;
10748 struct bwn_softc *sc = mac->mac_sc;
10751 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10752 val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10753 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10755 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10756 bwn_led_blink_end, mac);
10760 bwn_led_blink_end(void *arg)
10762 struct bwn_mac *mac = arg;
10763 struct bwn_softc *sc = mac->mac_sc;
10765 sc->sc_led_blinking = 0;
10769 bwn_suspend(device_t dev)
10771 struct bwn_softc *sc = device_get_softc(dev);
10778 bwn_resume(device_t dev)
10780 struct bwn_softc *sc = device_get_softc(dev);
10781 struct ifnet *ifp = sc->sc_ifp;
10783 if (ifp->if_flags & IFF_UP)
10789 bwn_rfswitch(void *arg)
10791 struct bwn_softc *sc = arg;
10792 struct bwn_mac *mac = sc->sc_curmac;
10793 int cur = 0, prev = 0;
10795 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10796 ("%s: invalid MAC status %d", __func__, mac->mac_status));
10798 if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10799 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10800 & BWN_RF_HWENABLED_HI_MASK))
10803 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10804 & BWN_RF_HWENABLED_LO_MASK)
10808 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10813 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10815 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10817 device_printf(sc->sc_dev,
10818 "status of RF switch is changed to %s\n",
10819 cur ? "ON" : "OFF");
10820 if (cur != mac->mac_phy.rf_on) {
10822 bwn_rf_turnon(mac);
10824 bwn_rf_turnoff(mac);
10828 callout_schedule(&sc->sc_rfswitch_ch, hz);
10832 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10834 struct bwn_phy *phy = &mac->mac_phy;
10835 struct bwn_phy_lp *plp = &phy->phy_lp;
10837 plp->plp_antenna = BWN_ANT_DEFAULT;
10841 bwn_phy_lp_init(struct bwn_mac *mac)
10843 static const struct bwn_stxtable tables[] = {
10844 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10845 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff },
10846 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff },
10847 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10848 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f },
10849 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10850 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 },
10851 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f },
10852 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10853 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 },
10854 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10855 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 },
10856 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f },
10857 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f },
10858 { 2, 11, 0x40, 0, 0x0f }
10860 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10861 struct bwn_softc *sc = mac->mac_sc;
10862 const struct bwn_stxtable *st;
10863 struct ifnet *ifp = sc->sc_ifp;
10864 struct ieee80211com *ic = ifp->if_l2com;
10868 bwn_phy_lp_readsprom(mac); /* XXX bad place */
10869 bwn_phy_lp_bbinit(mac);
10871 /* initialize RF */
10872 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10874 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10877 if (mac->mac_phy.rf_ver == 0x2062)
10878 bwn_phy_lp_b2062_init(mac);
10880 bwn_phy_lp_b2063_init(mac);
10882 /* synchronize stx table. */
10883 for (i = 0; i < N(tables); i++) {
10885 tmp = BWN_RF_READ(mac, st->st_rfaddr);
10886 tmp >>= st->st_rfshift;
10887 tmp <<= st->st_physhift;
10888 BWN_PHY_SETMASK(mac,
10889 BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10890 ~(st->st_mask << st->st_physhift), tmp);
10893 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10894 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10898 if (mac->mac_phy.rev >= 2)
10899 bwn_phy_lp_rxcal_r2(mac);
10900 else if (!plp->plp_rccap) {
10901 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10902 bwn_phy_lp_rccal_r12(mac);
10904 bwn_phy_lp_set_rccap(mac);
10906 error = bwn_phy_lp_switch_channel(mac, 7);
10908 device_printf(sc->sc_dev,
10909 "failed to change channel 7 (%d)\n", error);
10910 bwn_phy_lp_txpctl_init(mac);
10911 bwn_phy_lp_calib(mac);
10916 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10919 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10920 return (BWN_READ_2(mac, BWN_PHYDATA));
10924 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10927 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10928 BWN_WRITE_2(mac, BWN_PHYDATA, value);
10932 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10936 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10937 BWN_WRITE_2(mac, BWN_PHYDATA,
10938 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10942 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10945 KASSERT(reg != 1, ("unaccessible register %d", reg));
10946 if (mac->mac_phy.rev < 2 && reg != 0x4001)
10948 if (mac->mac_phy.rev >= 2)
10950 BWN_WRITE_2(mac, BWN_RFCTL, reg);
10951 return BWN_READ_2(mac, BWN_RFDATALO);
10955 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10958 KASSERT(reg != 1, ("unaccessible register %d", reg));
10959 BWN_WRITE_2(mac, BWN_RFCTL, reg);
10960 BWN_WRITE_2(mac, BWN_RFDATALO, value);
10964 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10968 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10969 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10970 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10974 if (mac->mac_phy.rev >= 2) {
10975 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10976 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10977 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10978 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10979 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
10983 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
10984 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10985 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
10986 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
10990 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
10992 struct bwn_phy *phy = &mac->mac_phy;
10993 struct bwn_phy_lp *plp = &phy->phy_lp;
10996 if (phy->rf_ver == 0x2063) {
10997 error = bwn_phy_lp_b2063_switch_channel(mac, chan);
11001 error = bwn_phy_lp_b2062_switch_channel(mac, chan);
11004 bwn_phy_lp_set_anafilter(mac, chan);
11005 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
11008 plp->plp_chan = chan;
11009 BWN_WRITE_2(mac, BWN_CHANNEL, chan);
11014 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
11016 struct bwn_softc *sc = mac->mac_sc;
11017 struct ifnet *ifp = sc->sc_ifp;
11018 struct ieee80211com *ic = ifp->if_l2com;
11020 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
11024 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
11026 struct bwn_phy *phy = &mac->mac_phy;
11027 struct bwn_phy_lp *plp = &phy->phy_lp;
11029 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
11032 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
11033 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
11034 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
11035 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
11036 plp->plp_antenna = antenna;
11040 bwn_phy_lp_task_60s(struct bwn_mac *mac)
11043 bwn_phy_lp_calib(mac);
11047 bwn_phy_lp_readsprom(struct bwn_mac *mac)
11049 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11050 struct bwn_softc *sc = mac->mac_sc;
11051 struct ifnet *ifp = sc->sc_ifp;
11052 struct ieee80211com *ic = ifp->if_l2com;
11054 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11055 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
11056 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
11057 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
11058 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
11059 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
11060 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
11064 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
11065 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
11066 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
11067 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
11068 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
11069 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
11070 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
11071 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
11075 bwn_phy_lp_bbinit(struct bwn_mac *mac)
11078 bwn_phy_lp_tblinit(mac);
11079 if (mac->mac_phy.rev >= 2)
11080 bwn_phy_lp_bbinit_r2(mac);
11082 bwn_phy_lp_bbinit_r01(mac);
11086 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
11088 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
11089 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
11090 struct bwn_softc *sc = mac->mac_sc;
11091 struct ifnet *ifp = sc->sc_ifp;
11092 struct ieee80211com *ic = ifp->if_l2com;
11094 bwn_phy_lp_set_txgain(mac,
11095 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
11096 bwn_phy_lp_set_bbmult(mac, 150);
11100 bwn_phy_lp_calib(struct bwn_mac *mac)
11102 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11103 struct bwn_softc *sc = mac->mac_sc;
11104 struct ifnet *ifp = sc->sc_ifp;
11105 struct ieee80211com *ic = ifp->if_l2com;
11106 const struct bwn_rxcompco *rc = NULL;
11107 struct bwn_txgain ogain;
11108 int i, omode, oafeovr, orf, obbmult;
11109 uint8_t mode, fc = 0;
11111 if (plp->plp_chanfullcal != plp->plp_chan) {
11112 plp->plp_chanfullcal = plp->plp_chan;
11116 bwn_mac_suspend(mac);
11118 /* BlueTooth Coexistance Override */
11119 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
11120 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
11122 if (mac->mac_phy.rev >= 2)
11123 bwn_phy_lp_digflt_save(mac);
11124 bwn_phy_lp_get_txpctlmode(mac);
11125 mode = plp->plp_txpctlmode;
11126 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11127 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
11128 bwn_phy_lp_bugfix(mac);
11129 if (mac->mac_phy.rev >= 2 && fc == 1) {
11130 bwn_phy_lp_get_txpctlmode(mac);
11131 omode = plp->plp_txpctlmode;
11132 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11134 ogain = bwn_phy_lp_get_txgain(mac);
11135 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11136 obbmult = bwn_phy_lp_get_bbmult(mac);
11137 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11139 bwn_phy_lp_set_txgain(mac, &ogain);
11140 bwn_phy_lp_set_bbmult(mac, obbmult);
11141 bwn_phy_lp_set_txpctlmode(mac, omode);
11142 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11144 bwn_phy_lp_set_txpctlmode(mac, mode);
11145 if (mac->mac_phy.rev >= 2)
11146 bwn_phy_lp_digflt_restore(mac);
11148 /* do RX IQ Calculation; assumes that noise is true. */
11149 if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11150 for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11151 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11152 rc = &bwn_rxcompco_5354[i];
11154 } else if (mac->mac_phy.rev >= 2)
11155 rc = &bwn_rxcompco_r2;
11157 for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11158 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11159 rc = &bwn_rxcompco_r12[i];
11165 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11166 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11168 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11170 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11171 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11172 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11174 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11175 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11178 bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11179 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11180 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11181 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11182 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11183 bwn_phy_lp_set_deaf(mac, 0);
11184 /* XXX no checking return value? */
11185 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11186 bwn_phy_lp_clear_deaf(mac, 0);
11187 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11188 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11189 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11191 /* disable RX GAIN override. */
11192 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11193 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11194 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11195 if (mac->mac_phy.rev >= 2) {
11196 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11197 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11198 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11199 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11202 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11205 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11206 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11208 bwn_mac_enable(mac);
11212 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11216 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11220 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11221 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11225 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11227 static const struct bwn_b206x_chan *bc = NULL;
11228 struct bwn_softc *sc = mac->mac_sc;
11229 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11231 uint16_t old, scale, tmp16;
11234 for (i = 0; i < N(bwn_b2063_chantable); i++) {
11235 if (bwn_b2063_chantable[i].bc_chan == chan) {
11236 bc = &bwn_b2063_chantable[i];
11243 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11244 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11245 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11246 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11247 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11248 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11249 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11250 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11251 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11252 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11253 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11254 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11256 old = BWN_RF_READ(mac, BWN_B2063_COM15);
11257 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11259 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11260 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11261 freqref = freqxtal * 3;
11262 div = (freqxtal <= 26000000 ? 1 : 2);
11263 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11264 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11265 999999) / 1000000) + 1;
11267 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11268 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11269 0xfff8, timeout >> 2);
11270 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11271 0xff9f,timeout << 5);
11272 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11274 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11275 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11276 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11278 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11279 (timeoutref + 1)) - 1;
11280 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11282 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11284 tmp[0] = ((val[2] * 62500) / freqref) << 4;
11285 tmp[1] = ((val[2] * 62500) % freqref) << 4;
11286 while (tmp[1] >= freqref) {
11290 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11291 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11292 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11293 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11294 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11296 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11297 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11298 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11299 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11301 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11302 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11304 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11306 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11309 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11311 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11312 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11314 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11319 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11320 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11322 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11323 if (freqxtal > 26000000)
11324 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11326 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11329 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11331 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11333 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11335 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11337 /* VCO Calibration */
11338 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11339 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11340 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11342 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11344 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11346 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11348 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11350 BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11355 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11357 struct bwn_softc *sc = mac->mac_sc;
11358 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11359 const struct bwn_b206x_chan *bc = NULL;
11360 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11364 for (i = 0; i < N(bwn_b2062_chantable); i++) {
11365 if (bwn_b2062_chantable[i].bc_chan == chan) {
11366 bc = &bwn_b2062_chantable[i];
11374 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11375 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11376 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11377 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11378 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11379 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11380 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11381 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11382 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11383 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11385 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11386 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11387 bwn_phy_lp_b2062_reset_pllbias(mac);
11388 tmp[0] = freqxtal / 1000;
11389 tmp[1] = plp->plp_div * 1000;
11390 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11391 if (ieee80211_ieee2mhz(chan, 0) < 4000)
11393 tmp[3] = 48 * tmp[0];
11394 tmp[5] = tmp[2] / tmp[3];
11395 tmp[6] = tmp[2] % tmp[3];
11396 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11397 tmp[4] = tmp[6] * 0x100;
11398 tmp[5] = tmp[4] / tmp[3];
11399 tmp[6] = tmp[4] % tmp[3];
11400 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11401 tmp[4] = tmp[6] * 0x100;
11402 tmp[5] = tmp[4] / tmp[3];
11403 tmp[6] = tmp[4] % tmp[3];
11404 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11405 tmp[4] = tmp[6] * 0x100;
11406 tmp[5] = tmp[4] / tmp[3];
11407 tmp[6] = tmp[4] % tmp[3];
11408 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11409 tmp[5] + ((2 * tmp[6]) / tmp[3]));
11410 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11411 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11412 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11413 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11415 bwn_phy_lp_b2062_vco_calib(mac);
11416 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11417 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11418 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11419 bwn_phy_lp_b2062_reset_pllbias(mac);
11420 bwn_phy_lp_b2062_vco_calib(mac);
11421 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11422 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11426 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11431 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11433 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11434 uint16_t tmp = (channel == 14);
11436 if (mac->mac_phy.rev < 2) {
11437 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11438 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11439 bwn_phy_lp_set_rccap(mac);
11443 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11447 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11449 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11450 struct bwn_softc *sc = mac->mac_sc;
11451 struct ifnet *ifp = sc->sc_ifp;
11452 struct ieee80211com *ic = ifp->if_l2com;
11453 uint16_t iso, tmp[3];
11455 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11457 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11458 iso = plp->plp_txisoband_m;
11459 else if (freq <= 5320)
11460 iso = plp->plp_txisoband_l;
11461 else if (freq <= 5700)
11462 iso = plp->plp_txisoband_m;
11464 iso = plp->plp_txisoband_h;
11466 tmp[0] = ((iso - 26) / 12) << 12;
11467 tmp[1] = tmp[0] + 0x1000;
11468 tmp[2] = tmp[0] + 0x2000;
11470 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11471 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11475 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11477 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11479 static const uint16_t addr[] = {
11480 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11481 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11482 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11483 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11484 BWN_PHY_OFDM(0xcf),
11486 static const uint16_t val[] = {
11487 0xde5e, 0xe832, 0xe331, 0x4d26,
11488 0x0026, 0x1420, 0x0020, 0xfe08,
11492 for (i = 0; i < N(addr); i++) {
11493 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11494 BWN_PHY_WRITE(mac, addr[i], val[i]);
11499 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11501 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11502 struct bwn_softc *sc = mac->mac_sc;
11505 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11506 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11507 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11508 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11510 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11511 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11513 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11514 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11517 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11518 device_printf(sc->sc_dev, "unknown command mode\n");
11524 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11526 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11530 bwn_phy_lp_get_txpctlmode(mac);
11531 old = plp->plp_txpctlmode;
11534 plp->plp_txpctlmode = mode;
11536 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11537 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11539 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11540 0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11542 /* disable TX GAIN override */
11543 if (mac->mac_phy.rev < 2)
11544 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11546 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11547 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11549 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11551 plp->plp_txpwridx = -1;
11553 if (mac->mac_phy.rev >= 2) {
11554 if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11555 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11557 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11560 /* writes TX Power Control mode */
11561 switch (plp->plp_txpctlmode) {
11562 case BWN_PHYLP_TXPCTL_OFF:
11563 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11565 case BWN_PHYLP_TXPCTL_ON_HW:
11566 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11568 case BWN_PHYLP_TXPCTL_ON_SW:
11569 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11573 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11575 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11576 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11580 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11582 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11583 struct bwn_softc *sc = mac->mac_sc;
11584 const unsigned int size = 256;
11585 struct bwn_txgain tg;
11586 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11587 uint16_t tssinpt, tssiidx, value[2];
11591 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
11592 M_NOWAIT | M_ZERO);
11593 if (tabs == NULL) {
11594 device_printf(sc->sc_dev, "failed to allocate buffer.\n");
11598 bwn_phy_lp_get_txpctlmode(mac);
11599 mode = plp->plp_txpctlmode;
11600 txpwridx = plp->plp_txpwridx;
11601 tssinpt = plp->plp_tssinpt;
11602 tssiidx = plp->plp_tssiidx;
11604 bwn_tab_read_multi(mac,
11605 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11606 BWN_TAB_4(7, 0x140), size, tabs);
11608 bwn_phy_lp_tblinit(mac);
11609 bwn_phy_lp_bbinit(mac);
11610 bwn_phy_lp_txpctl_init(mac);
11611 bwn_phy_lp_rf_onoff(mac, 1);
11612 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11614 bwn_tab_write_multi(mac,
11615 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11616 BWN_TAB_4(7, 0x140), size, tabs);
11618 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11619 plp->plp_tssinpt = tssinpt;
11620 plp->plp_tssiidx = tssiidx;
11621 bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11622 if (txpwridx != -1) {
11623 /* set TX power by index */
11624 plp->plp_txpwridx = txpwridx;
11625 bwn_phy_lp_get_txpctlmode(mac);
11626 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11627 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11628 if (mac->mac_phy.rev >= 2) {
11629 rxcomp = bwn_tab_read(mac,
11630 BWN_TAB_4(7, txpwridx + 320));
11631 txgain = bwn_tab_read(mac,
11632 BWN_TAB_4(7, txpwridx + 192));
11633 tg.tg_pad = (txgain >> 16) & 0xff;
11634 tg.tg_gm = txgain & 0xff;
11635 tg.tg_pga = (txgain >> 8) & 0xff;
11636 tg.tg_dac = (rxcomp >> 28) & 0xff;
11637 bwn_phy_lp_set_txgain(mac, &tg);
11639 rxcomp = bwn_tab_read(mac,
11640 BWN_TAB_4(10, txpwridx + 320));
11641 txgain = bwn_tab_read(mac,
11642 BWN_TAB_4(10, txpwridx + 192));
11643 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11644 0xf800, (txgain >> 4) & 0x7fff);
11645 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11646 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11648 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11651 value[0] = (rxcomp >> 10) & 0x3ff;
11652 value[1] = rxcomp & 0x3ff;
11653 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11655 coeff = bwn_tab_read(mac,
11656 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11657 BWN_TAB_4(10, txpwridx + 448));
11658 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11659 if (mac->mac_phy.rev >= 2) {
11660 rfpwr = bwn_tab_read(mac,
11661 BWN_TAB_4(7, txpwridx + 576));
11662 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11665 bwn_phy_lp_set_txgain_override(mac);
11667 if (plp->plp_rccap)
11668 bwn_phy_lp_set_rccap(mac);
11669 bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11670 bwn_phy_lp_set_txpctlmode(mac, mode);
11671 free(tabs, M_DEVBUF);
11675 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11677 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11679 static const uint16_t addr[] = {
11680 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11681 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11682 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11683 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11684 BWN_PHY_OFDM(0xcf),
11687 for (i = 0; i < N(addr); i++)
11688 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11692 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11694 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11696 if (mac->mac_phy.rev < 2) {
11697 bwn_phy_lp_tblinit_r01(mac);
11698 bwn_phy_lp_tblinit_txgain(mac);
11699 bwn_phy_lp_set_gaintbl(mac, freq);
11703 bwn_phy_lp_tblinit_r2(mac);
11704 bwn_phy_lp_tblinit_txgain(mac);
11712 struct bwn_smpair {
11719 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11721 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11722 struct bwn_softc *sc = mac->mac_sc;
11723 struct ifnet *ifp = sc->sc_ifp;
11724 struct ieee80211com *ic = ifp->if_l2com;
11725 static const struct bwn_wpair v1[] = {
11726 { BWN_PHY_AFE_DAC_CTL, 0x50 },
11727 { BWN_PHY_AFE_CTL, 0x8800 },
11728 { BWN_PHY_AFE_CTL_OVR, 0 },
11729 { BWN_PHY_AFE_CTL_OVRVAL, 0 },
11730 { BWN_PHY_RF_OVERRIDE_0, 0 },
11731 { BWN_PHY_RF_OVERRIDE_2, 0 },
11732 { BWN_PHY_OFDM(0xf9), 0 },
11733 { BWN_PHY_TR_LOOKUP_1, 0 }
11735 static const struct bwn_smpair v2[] = {
11736 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11737 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11738 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11739 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11740 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11742 static const struct bwn_smpair v3[] = {
11743 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11744 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11745 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11746 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11747 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11748 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11749 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11750 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11751 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11752 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11757 for (i = 0; i < N(v1); i++)
11758 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11759 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11760 for (i = 0; i < N(v2); i++)
11761 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11763 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11764 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11765 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11766 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11767 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11768 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11770 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11772 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11773 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11774 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11775 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11776 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11777 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11778 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11779 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11780 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11781 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11782 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11783 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11784 (siba_get_chiprev(sc->sc_dev) == 0)) {
11785 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11786 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11788 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11789 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11791 for (i = 0; i < N(v3); i++)
11792 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11793 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11794 (siba_get_chiprev(sc->sc_dev) == 0)) {
11795 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11796 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11799 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11800 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11801 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11802 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11803 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11804 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11805 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11807 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11809 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11810 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11811 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11812 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11813 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11814 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11815 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11816 0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11817 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11819 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11820 (siba_get_chiprev(sc->sc_dev) == 0)) {
11821 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11822 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11823 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11826 bwn_phy_lp_digflt_save(mac);
11830 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11832 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11833 struct bwn_softc *sc = mac->mac_sc;
11834 struct ifnet *ifp = sc->sc_ifp;
11835 struct ieee80211com *ic = ifp->if_l2com;
11836 static const struct bwn_smpair v1[] = {
11837 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11838 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11839 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11840 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11841 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11842 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11843 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11845 static const struct bwn_smpair v2[] = {
11846 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11847 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11848 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11849 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11850 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11851 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11852 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11853 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11854 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11855 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11856 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11857 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11858 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11859 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11860 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11861 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11863 static const struct bwn_smpair v3[] = {
11864 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11865 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11866 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11867 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11868 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11869 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11870 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11871 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11873 static const struct bwn_smpair v4[] = {
11874 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11875 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11876 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11877 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11878 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11879 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11880 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11881 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11883 static const struct bwn_smpair v5[] = {
11884 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11885 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11886 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11887 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11888 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11889 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11890 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11891 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11894 uint16_t tmp, tmp2;
11896 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11897 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11898 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11899 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11900 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11901 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11902 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11903 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11904 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11905 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11906 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11907 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11908 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11909 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11910 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11911 for (i = 0; i < N(v1); i++)
11912 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11913 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11914 0xff00, plp->plp_rxpwroffset);
11915 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11916 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11917 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11918 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11919 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11920 if (mac->mac_phy.rev == 0)
11921 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11923 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11925 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11926 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11927 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11929 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11930 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11931 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11932 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11934 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11935 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11936 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11937 0xfff9, (plp->plp_bxarch << 1));
11938 if (mac->mac_phy.rev == 1 &&
11939 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11940 for (i = 0; i < N(v2); i++)
11941 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11943 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11944 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11945 ((mac->mac_phy.rev == 0) &&
11946 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11947 for (i = 0; i < N(v3); i++)
11948 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11950 } else if (mac->mac_phy.rev == 1 ||
11951 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11952 for (i = 0; i < N(v4); i++)
11953 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11956 for (i = 0; i < N(v5); i++)
11957 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11960 if (mac->mac_phy.rev == 1 &&
11961 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11962 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11963 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11964 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11965 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11967 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11968 (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11969 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11970 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11971 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11972 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11973 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11975 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11976 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11977 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11978 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11979 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11980 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11981 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
11982 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
11983 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11985 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
11986 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
11988 if (mac->mac_phy.rev == 1) {
11989 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
11990 tmp2 = (tmp & 0x03e0) >> 5;
11992 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
11993 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
11994 tmp2 = (tmp & 0x1f00) >> 8;
11996 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
11997 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
11998 tmp2 = tmp & 0x00ff;
12000 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
12004 struct bwn_b2062_freq {
12010 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
12012 #define CALC_CTL7(freq, div) \
12013 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
12014 #define CALC_CTL18(freq, div) \
12015 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
12016 #define CALC_CTL19(freq, div) \
12017 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
12018 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12019 struct bwn_softc *sc = mac->mac_sc;
12020 struct ifnet *ifp = sc->sc_ifp;
12021 struct ieee80211com *ic = ifp->if_l2com;
12022 static const struct bwn_b2062_freq freqdata_tab[] = {
12023 { 12000, { 6, 6, 6, 6, 10, 6 } },
12024 { 13000, { 4, 4, 4, 4, 11, 7 } },
12025 { 14400, { 3, 3, 3, 3, 12, 7 } },
12026 { 16200, { 3, 3, 3, 3, 13, 8 } },
12027 { 18000, { 2, 2, 2, 2, 14, 8 } },
12028 { 19200, { 1, 1, 1, 1, 14, 9 } }
12030 static const struct bwn_wpair v1[] = {
12031 { BWN_B2062_N_TXCTL3, 0 },
12032 { BWN_B2062_N_TXCTL4, 0 },
12033 { BWN_B2062_N_TXCTL5, 0 },
12034 { BWN_B2062_N_TXCTL6, 0 },
12035 { BWN_B2062_N_PDNCTL0, 0x40 },
12036 { BWN_B2062_N_PDNCTL0, 0 },
12037 { BWN_B2062_N_CALIB_TS, 0x10 },
12038 { BWN_B2062_N_CALIB_TS, 0 }
12040 const struct bwn_b2062_freq *f = NULL;
12041 uint32_t xtalfreq, ref;
12044 bwn_phy_lp_b2062_tblinit(mac);
12046 for (i = 0; i < N(v1); i++)
12047 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12048 if (mac->mac_phy.rev > 0)
12049 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
12050 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
12051 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12052 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
12054 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
12056 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
12057 ("%s:%d: fail", __func__, __LINE__));
12058 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12059 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
12061 if (xtalfreq <= 30000000) {
12063 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
12066 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
12069 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
12070 CALC_CTL7(xtalfreq, plp->plp_div));
12071 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
12072 CALC_CTL18(xtalfreq, plp->plp_div));
12073 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
12074 CALC_CTL19(xtalfreq, plp->plp_div));
12076 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
12078 for (i = 0; i < N(freqdata_tab); i++) {
12079 if (ref < freqdata_tab[i].freq) {
12080 f = &freqdata_tab[i];
12085 f = &freqdata_tab[N(freqdata_tab) - 1];
12086 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
12087 ((uint16_t)(f->value[1]) << 4) | f->value[0]);
12088 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
12089 ((uint16_t)(f->value[3]) << 4) | f->value[2]);
12090 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
12091 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
12098 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
12101 bwn_phy_lp_b2063_tblinit(mac);
12102 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
12103 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
12104 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
12105 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
12106 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
12107 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
12108 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
12109 if (mac->mac_phy.rev == 2) {
12110 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
12111 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
12112 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
12114 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
12115 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
12120 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
12122 struct bwn_softc *sc = mac->mac_sc;
12123 static const struct bwn_wpair v1[] = {
12124 { BWN_B2063_RX_BB_SP8, 0x0 },
12125 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12126 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12127 { BWN_B2063_RC_CALIB_CTL2, 0x15 },
12128 { BWN_B2063_RC_CALIB_CTL3, 0x70 },
12129 { BWN_B2063_RC_CALIB_CTL4, 0x52 },
12130 { BWN_B2063_RC_CALIB_CTL5, 0x1 },
12131 { BWN_B2063_RC_CALIB_CTL1, 0x7d }
12133 static const struct bwn_wpair v2[] = {
12134 { BWN_B2063_TX_BB_SP3, 0x0 },
12135 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12136 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12137 { BWN_B2063_RC_CALIB_CTL2, 0x55 },
12138 { BWN_B2063_RC_CALIB_CTL3, 0x76 }
12140 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12144 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12146 for (i = 0; i < 2; i++)
12147 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12148 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12149 for (i = 2; i < N(v1); i++)
12150 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12151 for (i = 0; i < 10000; i++) {
12152 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12157 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12158 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12160 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12162 for (i = 0; i < N(v2); i++)
12163 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12164 if (freqxtal == 24000000) {
12165 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12166 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12168 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12169 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12171 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12172 for (i = 0; i < 10000; i++) {
12173 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12177 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12178 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12179 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12183 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12185 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12186 struct bwn_softc *sc = mac->mac_sc;
12187 struct bwn_phy_lp_iq_est ie;
12188 struct bwn_txgain tx_gains;
12189 static const uint32_t pwrtbl[21] = {
12190 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12191 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12192 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12193 0x0004c, 0x0002c, 0x0001a,
12195 uint32_t npwr, ipwr, sqpwr, tmp;
12196 int loopback, i, j, sum, error;
12198 uint8_t txo, bbmult, txpctlmode;
12200 error = bwn_phy_lp_switch_channel(mac, 7);
12202 device_printf(sc->sc_dev,
12203 "failed to change channel to 7 (%d)\n", error);
12204 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12205 bbmult = bwn_phy_lp_get_bbmult(mac);
12207 tx_gains = bwn_phy_lp_get_txgain(mac);
12209 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12210 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12211 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12212 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12213 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12214 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12215 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12217 bwn_phy_lp_get_txpctlmode(mac);
12218 txpctlmode = plp->plp_txpctlmode;
12219 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12222 bwn_phy_lp_set_deaf(mac, 1);
12223 bwn_phy_lp_set_trsw_over(mac, 0, 1);
12224 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12225 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12226 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12227 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12228 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12229 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12230 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12231 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12232 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12233 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12234 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12235 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12236 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12237 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12238 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12239 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12240 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12241 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12242 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12243 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12244 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12245 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12246 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12248 loopback = bwn_phy_lp_loopback(mac);
12249 if (loopback == -1)
12251 bwn_phy_lp_set_rxgain_idx(mac, loopback);
12252 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12253 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12254 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12255 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12258 memset(&ie, 0, sizeof(ie));
12259 for (i = 128; i <= 159; i++) {
12260 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12262 for (j = 5; j <= 25; j++) {
12263 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12264 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12266 sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12267 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12268 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12270 sum += ((ipwr - npwr) * (ipwr - npwr));
12271 if ((i == 128) || (sum < tmp)) {
12272 plp->plp_rccap = i;
12277 bwn_phy_lp_ddfs_turnoff(mac);
12280 bwn_phy_lp_clear_deaf(mac, 1);
12281 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12282 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12284 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12285 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12286 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12287 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12288 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12289 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12290 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12292 bwn_phy_lp_set_bbmult(mac, bbmult);
12294 bwn_phy_lp_set_txgain(mac, &tx_gains);
12295 bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12296 if (plp->plp_rccap)
12297 bwn_phy_lp_set_rccap(mac);
12301 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12303 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12304 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12306 if (mac->mac_phy.rev == 1)
12307 rc_cap = MIN(rc_cap + 5, 15);
12309 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12310 MAX(plp->plp_rccap - 4, 0x80));
12311 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12312 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12313 ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12317 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12324 for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12326 if (r << 1 >= div) {
12328 r = (r << 1) - div;
12337 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12339 struct bwn_softc *sc = mac->mac_sc;
12341 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12343 if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12344 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12345 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12347 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12353 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12356 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12357 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12362 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12364 #define FLAG_A 0x01
12365 #define FLAG_G 0x02
12366 struct bwn_softc *sc = mac->mac_sc;
12367 struct ifnet *ifp = sc->sc_ifp;
12368 struct ieee80211com *ic = ifp->if_l2com;
12369 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12370 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12371 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12372 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12373 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12374 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12375 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12376 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12377 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12378 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12379 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12380 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12381 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12382 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12383 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12384 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12385 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12386 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12387 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12388 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12389 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12390 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12391 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12392 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12393 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12394 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12395 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12396 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12397 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12398 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12399 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12400 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12401 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12402 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12403 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12404 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12405 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12406 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12407 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12408 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12409 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12410 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12411 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12412 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12413 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12414 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12415 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12416 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12418 const struct bwn_b206x_rfinit_entry *br;
12421 for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12422 br = &bwn_b2062_init_tab[i];
12423 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12424 if (br->br_flags & FLAG_G)
12425 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12427 if (br->br_flags & FLAG_A)
12428 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12436 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12438 #define FLAG_A 0x01
12439 #define FLAG_G 0x02
12440 struct bwn_softc *sc = mac->mac_sc;
12441 struct ifnet *ifp = sc->sc_ifp;
12442 struct ieee80211com *ic = ifp->if_l2com;
12443 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12444 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12445 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12446 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12447 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12448 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12449 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12450 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12451 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12452 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12453 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12454 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12455 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12456 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12457 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12458 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12459 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12460 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12461 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12462 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12463 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12464 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12465 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12466 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12467 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12468 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12469 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12470 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12471 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12472 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12473 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12474 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12475 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12476 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12477 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12478 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12479 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12480 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12481 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12482 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12483 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12484 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12485 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12487 const struct bwn_b206x_rfinit_entry *br;
12490 for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12491 br = &bwn_b2063_init_tab[i];
12492 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12493 if (br->br_flags & FLAG_G)
12494 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12496 if (br->br_flags & FLAG_A)
12497 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12505 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12506 int count, void *_data)
12509 uint32_t offset, type;
12510 uint8_t *data = _data;
12512 type = BWN_TAB_GETTYPE(typenoffset);
12513 offset = BWN_TAB_GETOFFSET(typenoffset);
12514 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12516 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12518 for (i = 0; i < count; i++) {
12521 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12524 case BWN_TAB_16BIT:
12525 *((uint16_t *)data) = BWN_PHY_READ(mac,
12526 BWN_PHY_TABLEDATALO);
12529 case BWN_TAB_32BIT:
12530 *((uint32_t *)data) = BWN_PHY_READ(mac,
12531 BWN_PHY_TABLEDATAHI);
12532 *((uint32_t *)data) <<= 16;
12533 *((uint32_t *)data) |= BWN_PHY_READ(mac,
12534 BWN_PHY_TABLEDATALO);
12538 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12544 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12545 int count, const void *_data)
12547 uint32_t offset, type, value;
12548 const uint8_t *data = _data;
12551 type = BWN_TAB_GETTYPE(typenoffset);
12552 offset = BWN_TAB_GETOFFSET(typenoffset);
12553 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12555 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12557 for (i = 0; i < count; i++) {
12562 KASSERT(!(value & ~0xff),
12563 ("%s:%d: fail", __func__, __LINE__));
12564 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12566 case BWN_TAB_16BIT:
12567 value = *((const uint16_t *)data);
12569 KASSERT(!(value & ~0xffff),
12570 ("%s:%d: fail", __func__, __LINE__));
12571 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12573 case BWN_TAB_32BIT:
12574 value = *((const uint32_t *)data);
12576 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12577 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12580 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12585 static struct bwn_txgain
12586 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12588 struct bwn_txgain tg;
12591 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12592 if (mac->mac_phy.rev < 2) {
12593 tmp = BWN_PHY_READ(mac,
12594 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12595 tg.tg_gm = tmp & 0x0007;
12596 tg.tg_pga = (tmp & 0x0078) >> 3;
12597 tg.tg_pad = (tmp & 0x780) >> 7;
12601 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12602 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12603 tg.tg_gm = tmp & 0xff;
12604 tg.tg_pga = (tmp >> 8) & 0xff;
12609 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12612 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12616 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12620 if (mac->mac_phy.rev < 2) {
12621 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12622 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12623 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12624 bwn_phy_lp_set_txgain_override(mac);
12628 pa = bwn_phy_lp_get_pa_gain(mac);
12629 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12630 (tg->tg_pga << 8) | tg->tg_gm);
12631 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12632 tg->tg_pad | (pa << 6));
12633 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12634 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12635 tg->tg_pad | (pa << 8));
12636 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12637 bwn_phy_lp_set_txgain_override(mac);
12641 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12644 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12648 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12650 uint16_t trsw = (tx << 1) | rx;
12652 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12653 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12657 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12659 struct bwn_softc *sc = mac->mac_sc;
12660 struct ifnet *ifp = sc->sc_ifp;
12661 struct ieee80211com *ic = ifp->if_l2com;
12662 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12664 if (mac->mac_phy.rev < 2) {
12666 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12667 ext_lna = (gain & 2) >> 1;
12669 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12670 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12671 0xfbff, ext_lna << 10);
12672 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12673 0xf7ff, ext_lna << 11);
12674 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12676 low_gain = gain & 0xffff;
12677 high_gain = (gain >> 16) & 0xf;
12678 ext_lna = (gain >> 21) & 0x1;
12679 trsw = ~(gain >> 20) & 0x1;
12681 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12682 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12683 0xfdff, ext_lna << 9);
12684 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12685 0xfbff, ext_lna << 10);
12686 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12687 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12688 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12689 tmp = (gain >> 2) & 0x3;
12690 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12692 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12697 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12698 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12699 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12700 if (mac->mac_phy.rev >= 2) {
12701 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12702 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12703 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12704 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12708 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12712 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12714 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12717 plp->plp_crsusr_off = 1;
12719 plp->plp_crssys_off = 1;
12721 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12725 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12727 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12728 struct bwn_softc *sc = mac->mac_sc;
12729 struct ifnet *ifp = sc->sc_ifp;
12730 struct ieee80211com *ic = ifp->if_l2com;
12733 plp->plp_crsusr_off = 0;
12735 plp->plp_crssys_off = 0;
12737 if (plp->plp_crsusr_off || plp->plp_crssys_off)
12740 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12741 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12743 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12746 static unsigned int
12747 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12749 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12750 static uint8_t sqrt_table[256] = {
12751 10, 14, 17, 20, 22, 24, 26, 28,
12752 30, 31, 33, 34, 36, 37, 38, 40,
12753 41, 42, 43, 44, 45, 46, 47, 48,
12754 50, 50, 51, 52, 53, 54, 55, 56,
12755 57, 58, 59, 60, 60, 61, 62, 63,
12756 64, 64, 65, 66, 67, 67, 68, 69,
12757 70, 70, 71, 72, 72, 73, 74, 74,
12758 75, 76, 76, 77, 78, 78, 79, 80,
12759 80, 81, 81, 82, 83, 83, 84, 84,
12760 85, 86, 86, 87, 87, 88, 88, 89,
12761 90, 90, 91, 91, 92, 92, 93, 93,
12762 94, 94, 95, 95, 96, 96, 97, 97,
12763 98, 98, 99, 100, 100, 100, 101, 101,
12764 102, 102, 103, 103, 104, 104, 105, 105,
12765 106, 106, 107, 107, 108, 108, 109, 109,
12766 110, 110, 110, 111, 111, 112, 112, 113,
12767 113, 114, 114, 114, 115, 115, 116, 116,
12768 117, 117, 117, 118, 118, 119, 119, 120,
12769 120, 120, 121, 121, 122, 122, 122, 123,
12770 123, 124, 124, 124, 125, 125, 126, 126,
12771 126, 127, 127, 128, 128, 128, 129, 129,
12772 130, 130, 130, 131, 131, 131, 132, 132,
12773 133, 133, 133, 134, 134, 134, 135, 135,
12774 136, 136, 136, 137, 137, 137, 138, 138,
12775 138, 139, 139, 140, 140, 140, 141, 141,
12776 141, 142, 142, 142, 143, 143, 143, 144,
12777 144, 144, 145, 145, 145, 146, 146, 146,
12778 147, 147, 147, 148, 148, 148, 149, 149,
12779 150, 150, 150, 150, 151, 151, 151, 152,
12780 152, 152, 153, 153, 153, 154, 154, 154,
12781 155, 155, 155, 156, 156, 156, 157, 157,
12782 157, 158, 158, 158, 159, 159, 159, 160
12790 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12794 return (sqrt_table[x - 1] / 10);
12798 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12800 #define CALC_COEFF(_v, _x, _y, _z) do { \
12804 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12806 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12809 #define CALC_COEFF2(_v, _x, _y, _z) do { \
12813 _v = (_y << (31 - _x)) / (_z >> _t); \
12815 _v = (_y << (31 - _x)) / (_z << -_t); \
12817 struct bwn_phy_lp_iq_est ie;
12821 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12825 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12826 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12828 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12832 if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12837 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12838 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12840 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12844 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12845 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12852 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12854 static const uint16_t noisescale[] = {
12855 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12856 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12857 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12858 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12859 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12861 static const uint16_t crsgainnft[] = {
12862 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12863 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12864 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12865 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12868 static const uint16_t filterctl[] = {
12869 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12872 static const uint32_t psctl[] = {
12873 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12874 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12875 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12876 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12877 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12878 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12879 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12880 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12882 static const uint16_t ofdmcckgain_r0[] = {
12883 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12884 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12885 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12886 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12889 static const uint16_t ofdmcckgain_r1[] = {
12890 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12891 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12892 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12893 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12896 static const uint16_t gaindelta[] = {
12897 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12900 static const uint32_t txpwrctl[] = {
12901 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12902 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12903 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12904 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12905 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12906 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12907 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12908 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12909 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12910 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12911 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12912 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12913 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
12914 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12915 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12916 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12917 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12918 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12919 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12920 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12921 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12922 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12923 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12924 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12925 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12926 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12927 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12928 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12929 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12930 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12931 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12932 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12933 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12934 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12935 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12936 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12937 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12938 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12939 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12940 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12941 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12942 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12943 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12944 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12945 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12946 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12947 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12948 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12949 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12950 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12951 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12952 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12953 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12954 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12955 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12956 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12957 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12958 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12959 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12960 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12961 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12962 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12963 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12964 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12965 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12966 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12967 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12968 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12969 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12970 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12971 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12972 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12973 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12974 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12975 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12976 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12977 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12978 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12979 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12980 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12981 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12982 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12983 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12984 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12985 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12986 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12987 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12988 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12989 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12990 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
12991 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
12992 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
12993 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
12994 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
12995 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
12996 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
12997 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
12998 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
12999 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
13000 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
13001 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
13002 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
13003 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
13004 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
13005 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
13006 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
13007 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
13008 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
13009 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
13010 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
13011 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
13012 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
13013 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
13014 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
13015 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
13019 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13021 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13022 bwn_tab_sigsq_tbl);
13023 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13024 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
13025 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
13026 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
13027 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13028 bwn_tab_pllfrac_tbl);
13029 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13030 bwn_tabl_iqlocal_tbl);
13031 if (mac->mac_phy.rev == 0) {
13032 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
13034 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
13037 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
13039 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
13042 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
13043 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
13047 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
13049 struct bwn_softc *sc = mac->mac_sc;
13051 static const uint16_t noisescale[] = {
13052 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13053 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13054 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13055 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13056 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13057 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13058 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
13060 static const uint32_t filterctl[] = {
13061 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
13062 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
13064 static const uint32_t psctl[] = {
13065 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
13066 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
13067 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
13068 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
13070 static const uint32_t gainidx[] = {
13071 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13072 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13073 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13074 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
13075 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
13076 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
13077 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
13078 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
13079 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
13080 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
13081 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
13082 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
13083 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
13084 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
13085 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
13086 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13087 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13088 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13089 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
13090 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
13091 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
13092 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
13093 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
13094 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
13095 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
13096 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
13097 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
13098 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
13099 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
13100 0x0000001a, 0x64ca55ad, 0x0000001a
13102 static const uint16_t auxgainidx[] = {
13103 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13104 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
13105 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
13108 static const uint16_t swctl[] = {
13109 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13110 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13111 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13112 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
13113 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13114 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13115 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13116 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
13118 static const uint8_t hf[] = {
13119 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
13120 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
13122 static const uint32_t gainval[] = {
13123 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13124 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13125 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13126 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13127 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13128 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13129 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13130 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13131 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13132 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13133 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13134 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13135 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
13136 0x000000f1, 0x00000000, 0x00000000
13138 static const uint16_t gain[] = {
13139 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13140 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13141 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13142 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13143 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13144 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
13145 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13146 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13147 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13148 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13149 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13150 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13152 static const uint32_t papdeps[] = {
13153 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13154 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13155 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13156 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13157 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13158 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13159 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13160 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13161 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13162 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13163 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13164 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13165 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13167 static const uint32_t papdmult[] = {
13168 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13169 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13170 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13171 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13172 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13173 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13174 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13175 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13176 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13177 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13178 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13179 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13180 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13182 static const uint32_t gainidx_a0[] = {
13183 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13184 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13185 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13186 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13187 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13188 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13189 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13190 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13191 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13192 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13193 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13194 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13195 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13197 static const uint16_t auxgainidx_a0[] = {
13198 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13199 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13200 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13203 static const uint32_t gainval_a0[] = {
13204 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13205 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13206 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13207 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13208 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13209 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13210 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13211 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13212 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13213 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13214 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13215 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13216 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13217 0x000000f7, 0x00000000, 0x00000000
13219 static const uint16_t gain_a0[] = {
13220 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13221 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13222 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13223 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13224 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13225 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
13226 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13227 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13228 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13229 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13230 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13231 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13234 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13236 for (i = 0; i < 704; i++)
13237 bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13239 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13240 bwn_tab_sigsq_tbl);
13241 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13242 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13243 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13244 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13245 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13246 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13247 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13248 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13249 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13250 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13251 bwn_tab_pllfrac_tbl);
13252 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13253 bwn_tabl_iqlocal_tbl);
13254 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13255 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13257 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13258 (siba_get_chiprev(sc->sc_dev) == 0)) {
13259 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13261 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13263 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13265 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13270 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13272 struct bwn_softc *sc = mac->mac_sc;
13273 struct ifnet *ifp = sc->sc_ifp;
13274 struct ieee80211com *ic = ifp->if_l2com;
13275 static struct bwn_txgain_entry txgain_r2[] = {
13276 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13277 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13278 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13279 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13280 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13281 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13282 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13283 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13284 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13285 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13286 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13287 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13288 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13289 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13290 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13291 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13292 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13293 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13294 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13295 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13296 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13297 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13298 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13299 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13300 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13301 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13302 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13303 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13304 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13305 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13306 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13307 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13308 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13309 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13310 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13311 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13312 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13313 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13314 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13315 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13316 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13317 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13318 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13319 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13320 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13321 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13322 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13323 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13324 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13325 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13326 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13327 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13328 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13329 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13330 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13331 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13332 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13333 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13334 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13335 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13336 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13337 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13338 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13339 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13341 static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13342 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13343 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13344 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13345 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13346 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13347 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13348 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13349 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13350 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13351 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13352 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13353 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13354 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13355 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13356 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13357 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13358 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13359 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13360 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13361 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13362 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13363 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13364 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13365 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13366 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13367 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13368 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13369 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13370 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13371 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13372 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13373 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13374 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13375 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13376 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13377 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13378 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13379 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13380 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13381 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13382 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13383 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13384 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13385 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13386 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13387 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13388 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13389 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13390 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13391 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13392 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13393 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13394 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13395 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13396 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13397 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13398 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13399 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13400 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13401 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13402 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13403 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13404 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13405 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13407 static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13408 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13409 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13410 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13411 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13412 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13413 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13414 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13415 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13416 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13417 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13418 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13419 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13420 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13421 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13422 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13423 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13424 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13425 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13426 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13427 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13428 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13429 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13430 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13431 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13432 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13433 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13434 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13435 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13436 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13437 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13438 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13439 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13440 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13441 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13442 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13443 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13444 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13445 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13446 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13447 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13448 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13449 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13450 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13451 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13452 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13453 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13454 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13455 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13456 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13457 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13458 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13459 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13460 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13461 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13462 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13463 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13464 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13465 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13466 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13467 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13468 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13469 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13470 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13471 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13473 static struct bwn_txgain_entry txgain_r0[] = {
13474 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13475 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13476 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13477 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13478 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13479 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13480 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13481 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13482 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13483 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13484 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13485 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13486 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13487 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13488 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13489 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13490 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13491 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13492 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13493 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13494 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13495 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13496 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13497 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13498 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13499 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13500 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13501 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13502 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13503 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13504 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13505 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13506 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13507 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13508 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13509 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13510 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13511 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13512 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13513 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13514 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13515 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13516 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13517 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13518 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13519 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13520 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13521 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13522 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13523 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13524 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13525 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13526 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13527 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13528 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13529 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13530 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13531 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13532 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13533 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13534 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13535 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13536 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13537 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13539 static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13540 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13541 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13542 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13543 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13544 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13545 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13546 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13547 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13548 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13549 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13550 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13551 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13552 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13553 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13554 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13555 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13556 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13557 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13558 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13559 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13560 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13561 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13562 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13563 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13564 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13565 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13566 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13567 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13568 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13569 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13570 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13571 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13572 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13573 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13574 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13575 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13576 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13577 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13578 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13579 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13580 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13581 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13582 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13583 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13584 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13585 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13586 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13587 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13588 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13589 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13590 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13591 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13592 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13593 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13594 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13595 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13596 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13597 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13598 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13599 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13600 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13601 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13602 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13603 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13605 static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13606 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13607 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13608 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13609 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13610 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13611 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13612 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13613 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13614 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13615 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13616 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13617 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13618 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13619 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13620 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13621 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13622 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13623 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13624 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13625 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13626 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13627 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13628 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13629 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13630 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13631 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13632 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13633 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13634 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13635 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13636 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13637 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13638 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13639 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13640 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13641 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13642 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13643 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13644 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13645 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13646 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13647 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13648 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13649 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13650 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13651 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13652 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13653 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13654 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13655 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13656 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13657 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13658 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13659 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13660 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13661 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13662 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13663 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13664 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13665 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13666 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13667 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13668 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13669 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13671 static struct bwn_txgain_entry txgain_r1[] = {
13672 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13673 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13674 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13675 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13676 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13677 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13678 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13679 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13680 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13681 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13682 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13683 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13684 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13685 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13686 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13687 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13688 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13689 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13690 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13691 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13692 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13693 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13694 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13695 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13696 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13697 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13698 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13699 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13700 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13701 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13702 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13703 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13704 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13705 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13706 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13707 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13708 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13709 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13710 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13711 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13712 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13713 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13714 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13715 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13716 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13717 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13718 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13719 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13720 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13721 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13722 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13723 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13724 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13725 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13726 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13727 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13728 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13729 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13730 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13731 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13732 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13733 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13734 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13735 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13736 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13737 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13738 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13739 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13740 { 7, 11, 6, 0, 71 }
13742 static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13743 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13744 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13745 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13746 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13747 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13748 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13749 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13750 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13751 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13752 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13753 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13754 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13755 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13756 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13757 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13758 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13759 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13760 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13761 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13762 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13763 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13764 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13765 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13766 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13767 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13768 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13769 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13770 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13771 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13772 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13773 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13774 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13775 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13776 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13777 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13778 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13779 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13780 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13781 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13782 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13783 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13784 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13785 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13786 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13787 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13788 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13789 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13790 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13791 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13792 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13793 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13794 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13795 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13796 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13797 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13798 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13799 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13800 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13801 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13802 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13803 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13804 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13805 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13806 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13808 static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13809 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13810 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13811 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13812 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13813 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13814 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13815 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13816 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13817 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13818 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13819 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13820 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13821 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13822 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13823 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13824 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13825 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13826 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13827 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13828 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13829 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13830 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13831 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13832 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13833 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13834 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13835 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13836 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13837 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13838 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13839 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13840 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13841 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13842 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13843 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13844 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13845 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13846 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13847 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13848 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13849 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13850 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13851 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13852 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13853 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13854 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13855 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13856 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13857 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13858 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13859 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13860 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13861 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13862 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13863 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13864 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13865 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13866 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13867 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13868 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13869 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13870 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13871 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13872 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13875 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13876 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13877 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13878 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13879 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13882 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13887 if (mac->mac_phy.rev == 0) {
13888 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13889 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13890 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13891 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13892 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13895 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13900 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13901 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13902 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13903 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13904 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13906 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13910 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13912 uint32_t offset, type;
13914 type = BWN_TAB_GETTYPE(typeoffset);
13915 offset = BWN_TAB_GETOFFSET(typeoffset);
13916 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13920 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13921 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13922 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13924 case BWN_TAB_16BIT:
13925 KASSERT(!(value & ~0xffff),
13926 ("%s:%d: fail", __func__, __LINE__));
13927 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13928 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13930 case BWN_TAB_32BIT:
13931 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13932 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13933 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13936 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13941 bwn_phy_lp_loopback(struct bwn_mac *mac)
13943 struct bwn_phy_lp_iq_est ie;
13947 memset(&ie, 0, sizeof(ie));
13949 bwn_phy_lp_set_trsw_over(mac, 1, 1);
13950 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13951 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13952 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13953 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13954 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13955 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13956 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13957 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13958 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13959 for (i = 0; i < 32; i++) {
13960 bwn_phy_lp_set_rxgain_idx(mac, i);
13961 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13962 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13964 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13965 if ((tmp > 4000) && (tmp < 10000)) {
13970 bwn_phy_lp_ddfs_turnoff(mac);
13975 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13978 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
13982 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
13983 int incr1, int incr2, int scale_idx)
13986 bwn_phy_lp_ddfs_turnoff(mac);
13987 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
13988 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
13989 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
13990 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
13991 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
13992 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
13993 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
13994 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
13995 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
13996 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
14000 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
14001 struct bwn_phy_lp_iq_est *ie)
14005 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
14006 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
14007 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
14008 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
14009 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
14011 for (i = 0; i < 500; i++) {
14012 if (!(BWN_PHY_READ(mac,
14013 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
14017 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
14018 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14022 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
14023 ie->ie_iqprod <<= 16;
14024 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
14025 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
14026 ie->ie_ipwr <<= 16;
14027 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
14028 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
14029 ie->ie_qpwr <<= 16;
14030 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
14032 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14037 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
14039 uint32_t offset, type, value;
14041 type = BWN_TAB_GETTYPE(typeoffset);
14042 offset = BWN_TAB_GETOFFSET(typeoffset);
14043 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
14047 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14048 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
14050 case BWN_TAB_16BIT:
14051 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14052 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14054 case BWN_TAB_32BIT:
14055 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14056 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
14058 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14061 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
14069 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
14072 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
14073 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
14077 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
14081 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
14083 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
14087 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
14090 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
14091 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
14095 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
14098 if (mac->mac_phy.rev < 2)
14099 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
14101 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
14102 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
14104 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
14108 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
14111 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
14115 bwn_nbits(int32_t val)
14120 for (tmp = abs(val); tmp != 0; tmp >>= 1)
14126 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
14127 struct bwn_txgain_entry *table)
14131 for (i = offset; i < count; i++)
14132 bwn_phy_lp_gaintbl_write(mac, i, table[i]);
14136 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
14137 struct bwn_txgain_entry data)
14140 if (mac->mac_phy.rev >= 2)
14141 bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14143 bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14147 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14148 struct bwn_txgain_entry te)
14150 struct bwn_softc *sc = mac->mac_sc;
14151 struct ifnet *ifp = sc->sc_ifp;
14152 struct ieee80211com *ic = ifp->if_l2com;
14155 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14157 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14158 if (mac->mac_phy.rev >= 3) {
14159 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14160 (0x10 << 24) : (0x70 << 24));
14162 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14163 (0x14 << 24) : (0x7f << 24));
14165 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14166 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14167 te.te_bbmult << 20 | te.te_dac << 28);
14171 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14172 struct bwn_txgain_entry te)
14175 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14177 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14178 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) |
14180 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14184 bwn_sysctl_node(struct bwn_softc *sc)
14186 device_t dev = sc->sc_dev;
14187 struct bwn_mac *mac;
14188 struct bwn_stats *stats;
14190 /* XXX assume that count of MAC is only 1. */
14192 if ((mac = sc->sc_curmac) == NULL)
14194 stats = &mac->mac_stats;
14196 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14197 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14198 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14199 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14200 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14201 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14202 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14203 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14204 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14207 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14208 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14209 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14213 static device_method_t bwn_methods[] = {
14214 /* Device interface */
14215 DEVMETHOD(device_probe, bwn_probe),
14216 DEVMETHOD(device_attach, bwn_attach),
14217 DEVMETHOD(device_detach, bwn_detach),
14218 DEVMETHOD(device_suspend, bwn_suspend),
14219 DEVMETHOD(device_resume, bwn_resume),
14222 static driver_t bwn_driver = {
14225 sizeof(struct bwn_softc)
14227 static devclass_t bwn_devclass;
14228 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
14229 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14230 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */
14231 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */
14232 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);