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: head/sys/dev/bwn/if_bwn.c 260444 2014-01-08 08:06:56Z kevlo $");
34 * The Broadcom Wireless LAN controller driver.
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/module.h>
43 #include <sys/kernel.h>
44 #include <sys/endian.h>
45 #include <sys/errno.h>
46 #include <sys/firmware.h>
47 #include <sys/bus_resource.h>
50 #include <sys/socket.h>
51 #include <sys/sockio.h>
53 #include <net/ethernet.h>
55 #include <net/if_var.h>
56 #include <net/if_arp.h>
57 #include <net/if_dl.h>
58 #include <net/if_llc.h>
59 #include <net/if_media.h>
60 #include <net/if_types.h>
61 #include <net/ifq_var.h>
63 #include <bus/pci/pcivar.h>
64 #include <bus/pci/pcireg.h>
65 #include <dev/netif/bwn/siba/siba_ids.h>
66 #include <dev/netif/bwn/siba/sibareg.h>
67 #include <dev/netif/bwn/siba/sibavar.h>
69 #include <netproto/802_11/ieee80211_var.h>
70 #include <netproto/802_11/ieee80211_radiotap.h>
71 #include <netproto/802_11/ieee80211_regdomain.h>
72 #include <netproto/802_11/ieee80211_phy.h>
73 #include <netproto/802_11/ieee80211_ratectl.h>
75 #include "if_bwnreg.h"
76 #include "if_bwnvar.h"
78 static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0,
79 "Broadcom driver parameters");
82 * Tunable & sysctl variables.
86 static int bwn_debug = 0;
87 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RW, &bwn_debug, 0,
88 "Broadcom debugging printfs");
89 TUNABLE_INT("hw.bwn.debug", &bwn_debug);
91 BWN_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
92 BWN_DEBUG_RECV = 0x00000002, /* basic recv operation */
93 BWN_DEBUG_STATE = 0x00000004, /* 802.11 state transitions */
94 BWN_DEBUG_TXPOW = 0x00000008, /* tx power processing */
95 BWN_DEBUG_RESET = 0x00000010, /* reset processing */
96 BWN_DEBUG_OPS = 0x00000020, /* bwn_ops processing */
97 BWN_DEBUG_BEACON = 0x00000040, /* beacon handling */
98 BWN_DEBUG_WATCHDOG = 0x00000080, /* watchdog timeout */
99 BWN_DEBUG_INTR = 0x00000100, /* ISR */
100 BWN_DEBUG_CALIBRATE = 0x00000200, /* periodic calibration */
101 BWN_DEBUG_NODE = 0x00000400, /* node management */
102 BWN_DEBUG_LED = 0x00000800, /* led management */
103 BWN_DEBUG_CMD = 0x00001000, /* cmd submission */
104 BWN_DEBUG_LO = 0x00002000, /* LO */
105 BWN_DEBUG_FW = 0x00004000, /* firmware */
106 BWN_DEBUG_WME = 0x00008000, /* WME */
107 BWN_DEBUG_RF = 0x00010000, /* RF */
108 BWN_DEBUG_FATAL = 0x80000000, /* fatal errors */
109 BWN_DEBUG_ANY = 0xffffffff
111 #define DPRINTF(sc, m, fmt, ...) do { \
112 if (sc->sc_debug & (m)) \
113 kprintf(fmt, __VA_ARGS__); \
116 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
119 static int bwn_bfp = 0; /* use "Bad Frames Preemption" */
120 SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0,
121 "uses Bad Frames Preemption");
122 static int bwn_bluetooth = 1;
123 SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0,
124 "turns on Bluetooth Coexistence");
125 static int bwn_hwpctl = 0;
126 SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0,
127 "uses H/W power control");
128 static int bwn_msi_enable = 1;
129 TUNABLE_INT("hw.bwn.msi.enable", &bwn_msi_enable);
130 static int bwn_usedma = 1;
131 SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0,
133 TUNABLE_INT("hw.bwn.usedma", &bwn_usedma);
134 static int bwn_wme = 1;
135 SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0,
138 static int bwn_attach_pre(struct bwn_softc *);
139 static int bwn_attach_post(struct bwn_softc *);
140 static void bwn_sprom_bugfixes(device_t);
141 static void bwn_init(void *);
142 static int bwn_init_locked(struct bwn_softc *);
143 static int bwn_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *);
144 static void bwn_start(struct ifnet *, struct ifaltq_subque *);
145 static int bwn_attach_core(struct bwn_mac *);
146 static void bwn_reset_core(struct bwn_mac *, uint32_t);
147 static int bwn_phy_getinfo(struct bwn_mac *, int);
148 static int bwn_chiptest(struct bwn_mac *);
149 static int bwn_setup_channels(struct bwn_mac *, int, int);
150 static int bwn_phy_g_attach(struct bwn_mac *);
151 static void bwn_phy_g_detach(struct bwn_mac *);
152 static void bwn_phy_g_init_pre(struct bwn_mac *);
153 static int bwn_phy_g_prepare_hw(struct bwn_mac *);
154 static int bwn_phy_g_init(struct bwn_mac *);
155 static void bwn_phy_g_exit(struct bwn_mac *);
156 static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t);
157 static void bwn_phy_g_write(struct bwn_mac *, uint16_t,
159 static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t);
160 static void bwn_phy_g_rf_write(struct bwn_mac *, uint16_t,
162 static int bwn_phy_g_hwpctl(struct bwn_mac *);
163 static void bwn_phy_g_rf_onoff(struct bwn_mac *, int);
164 static int bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t);
165 static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *);
166 static void bwn_phy_g_set_antenna(struct bwn_mac *, int);
167 static int bwn_phy_g_im(struct bwn_mac *, int);
168 static int bwn_phy_g_recalc_txpwr(struct bwn_mac *, int);
169 static void bwn_phy_g_set_txpwr(struct bwn_mac *);
170 static void bwn_phy_g_task_15s(struct bwn_mac *);
171 static void bwn_phy_g_task_60s(struct bwn_mac *);
172 static uint16_t bwn_phy_g_txctl(struct bwn_mac *);
173 static void bwn_phy_switch_analog(struct bwn_mac *, int);
174 static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t);
175 static void bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t,
177 static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t);
178 static void bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t,
180 static void bwn_shm_ctlword(struct bwn_mac *, uint16_t,
182 static void bwn_addchannels(struct ieee80211_channel [], int, int *,
183 const struct bwn_channelinfo *, int);
184 static int bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
185 const struct ieee80211_bpf_params *);
186 static void bwn_updateslot(struct ifnet *);
187 static void bwn_update_promisc(struct ifnet *);
188 static void bwn_wme_init(struct bwn_mac *);
189 static int bwn_wme_update(struct ieee80211com *);
190 static void bwn_wme_clear(struct bwn_softc *);
191 static void bwn_wme_load(struct bwn_mac *);
192 static void bwn_wme_loadparams(struct bwn_mac *,
193 const struct wmeParams *, uint16_t);
194 static void bwn_scan_start(struct ieee80211com *);
195 static void bwn_scan_end(struct ieee80211com *);
196 static void bwn_set_channel(struct ieee80211com *);
197 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *,
198 const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
199 const uint8_t [IEEE80211_ADDR_LEN],
200 const uint8_t [IEEE80211_ADDR_LEN]);
201 static void bwn_vap_delete(struct ieee80211vap *);
202 static void bwn_stop(struct bwn_softc *, int);
203 static void bwn_stop_locked(struct bwn_softc *, int);
204 static int bwn_core_init(struct bwn_mac *);
205 static void bwn_core_start(struct bwn_mac *);
206 static void bwn_core_exit(struct bwn_mac *);
207 static void bwn_bt_disable(struct bwn_mac *);
208 static int bwn_chip_init(struct bwn_mac *);
209 static uint64_t bwn_hf_read(struct bwn_mac *);
210 static void bwn_hf_write(struct bwn_mac *, uint64_t);
211 static void bwn_set_txretry(struct bwn_mac *, int, int);
212 static void bwn_rate_init(struct bwn_mac *);
213 static void bwn_set_phytxctl(struct bwn_mac *);
214 static void bwn_spu_setdelay(struct bwn_mac *, int);
215 static void bwn_bt_enable(struct bwn_mac *);
216 static void bwn_set_macaddr(struct bwn_mac *);
217 static void bwn_crypt_init(struct bwn_mac *);
218 static void bwn_chip_exit(struct bwn_mac *);
219 static int bwn_fw_fillinfo(struct bwn_mac *);
220 static int bwn_fw_loaducode(struct bwn_mac *);
221 static int bwn_gpio_init(struct bwn_mac *);
222 static int bwn_fw_loadinitvals(struct bwn_mac *);
223 static int bwn_phy_init(struct bwn_mac *);
224 static void bwn_set_txantenna(struct bwn_mac *, int);
225 static void bwn_set_opmode(struct bwn_mac *);
226 static void bwn_rate_write(struct bwn_mac *, uint16_t, int);
227 static uint8_t bwn_plcp_getcck(const uint8_t);
228 static uint8_t bwn_plcp_getofdm(const uint8_t);
229 static void bwn_pio_init(struct bwn_mac *);
230 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int);
231 static void bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *,
233 static void bwn_pio_setupqueue_rx(struct bwn_mac *,
234 struct bwn_pio_rxqueue *, int);
235 static void bwn_destroy_queue_tx(struct bwn_pio_txqueue *);
236 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *,
238 static void bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *);
239 static int bwn_pio_rx(struct bwn_pio_rxqueue *);
240 static uint8_t bwn_pio_rxeof(struct bwn_pio_rxqueue *);
241 static void bwn_pio_handle_txeof(struct bwn_mac *,
242 const struct bwn_txstatus *);
243 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t);
244 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t);
245 static void bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t,
247 static void bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t,
249 static int bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *,
251 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t);
252 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *,
253 struct bwn_pio_txqueue *, uint32_t, const void *, int);
254 static void bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *,
256 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *,
257 struct bwn_pio_txqueue *, uint16_t, const void *, int);
258 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *,
259 struct bwn_pio_txqueue *, uint16_t, struct mbuf *);
260 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *,
261 uint16_t, struct bwn_pio_txpkt **);
262 static void bwn_dma_init(struct bwn_mac *);
263 static void bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t);
264 static int bwn_dma_mask2type(uint64_t);
265 static uint64_t bwn_dma_mask(struct bwn_mac *);
266 static uint16_t bwn_dma_base(int, int);
267 static void bwn_dma_ringfree(struct bwn_dma_ring **);
268 static void bwn_dma_32_getdesc(struct bwn_dma_ring *,
269 int, struct bwn_dmadesc_generic **,
270 struct bwn_dmadesc_meta **);
271 static void bwn_dma_32_setdesc(struct bwn_dma_ring *,
272 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
274 static void bwn_dma_32_start_transfer(struct bwn_dma_ring *, int);
275 static void bwn_dma_32_suspend(struct bwn_dma_ring *);
276 static void bwn_dma_32_resume(struct bwn_dma_ring *);
277 static int bwn_dma_32_get_curslot(struct bwn_dma_ring *);
278 static void bwn_dma_32_set_curslot(struct bwn_dma_ring *, int);
279 static void bwn_dma_64_getdesc(struct bwn_dma_ring *,
280 int, struct bwn_dmadesc_generic **,
281 struct bwn_dmadesc_meta **);
282 static void bwn_dma_64_setdesc(struct bwn_dma_ring *,
283 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
285 static void bwn_dma_64_start_transfer(struct bwn_dma_ring *, int);
286 static void bwn_dma_64_suspend(struct bwn_dma_ring *);
287 static void bwn_dma_64_resume(struct bwn_dma_ring *);
288 static int bwn_dma_64_get_curslot(struct bwn_dma_ring *);
289 static void bwn_dma_64_set_curslot(struct bwn_dma_ring *, int);
290 static int bwn_dma_allocringmemory(struct bwn_dma_ring *);
291 static void bwn_dma_setup(struct bwn_dma_ring *);
292 static void bwn_dma_free_ringmemory(struct bwn_dma_ring *);
293 static void bwn_dma_cleanup(struct bwn_dma_ring *);
294 static void bwn_dma_free_descbufs(struct bwn_dma_ring *);
295 static int bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int);
296 static void bwn_dma_rx_handle_overflow(struct bwn_dma_ring *);
297 static void bwn_dma_rx(struct bwn_dma_ring *);
298 static int bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int);
299 static void bwn_dma_free_descbuf(struct bwn_dma_ring *,
300 struct bwn_dmadesc_meta *);
301 static void bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *);
302 static int bwn_dma_gettype(struct bwn_mac *);
303 static void bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int);
304 static int bwn_dma_freeslot(struct bwn_dma_ring *);
305 static int bwn_dma_nextslot(struct bwn_dma_ring *, int);
306 static void bwn_dma_rxeof(struct bwn_dma_ring *, int *);
307 static int bwn_dma_newbuf(struct bwn_dma_ring *,
308 struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *,
310 static void bwn_dma_buf_addr(void *, bus_dma_segment_t *, int,
312 static uint8_t bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *);
313 static void bwn_dma_handle_txeof(struct bwn_mac *,
314 const struct bwn_txstatus *);
315 static int bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *,
317 static int bwn_dma_getslot(struct bwn_dma_ring *);
318 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *,
320 static int bwn_dma_attach(struct bwn_mac *);
321 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *,
323 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *,
324 const struct bwn_txstatus *, uint16_t, int *);
325 static void bwn_dma_free(struct bwn_mac *);
326 static void bwn_phy_g_init_sub(struct bwn_mac *);
327 static uint8_t bwn_has_hwpctl(struct bwn_mac *);
328 static void bwn_phy_init_b5(struct bwn_mac *);
329 static void bwn_phy_init_b6(struct bwn_mac *);
330 static void bwn_phy_init_a(struct bwn_mac *);
331 static void bwn_loopback_calcgain(struct bwn_mac *);
332 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *);
333 static void bwn_lo_g_init(struct bwn_mac *);
334 static void bwn_lo_g_adjust(struct bwn_mac *);
335 static void bwn_lo_get_powervector(struct bwn_mac *);
336 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *,
337 const struct bwn_bbatt *, const struct bwn_rfatt *);
338 static void bwn_lo_write(struct bwn_mac *, struct bwn_loctl *);
339 static void bwn_phy_hwpctl_init(struct bwn_mac *);
340 static void bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t);
341 static void bwn_phy_g_set_txpwr_sub(struct bwn_mac *,
342 const struct bwn_bbatt *, const struct bwn_rfatt *,
344 static void bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t);
345 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t);
346 static void bwn_spu_workaround(struct bwn_mac *, uint8_t);
347 static void bwn_wa_init(struct bwn_mac *);
348 static void bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t,
350 static void bwn_dummy_transmission(struct bwn_mac *, int, int);
351 static void bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t,
353 static void bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t,
355 static void bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t);
356 static void bwn_mac_suspend(struct bwn_mac *);
357 static void bwn_mac_enable(struct bwn_mac *);
358 static void bwn_psctl(struct bwn_mac *, uint32_t);
359 static int16_t bwn_nrssi_read(struct bwn_mac *, uint16_t);
360 static void bwn_nrssi_offset(struct bwn_mac *);
361 static void bwn_nrssi_threshold(struct bwn_mac *);
362 static void bwn_nrssi_slope_11g(struct bwn_mac *);
363 static void bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t,
365 static void bwn_set_original_gains(struct bwn_mac *);
366 static void bwn_hwpctl_early_init(struct bwn_mac *);
367 static void bwn_hwpctl_init_gphy(struct bwn_mac *);
368 static uint16_t bwn_phy_g_chan2freq(uint8_t);
369 static int bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype);
370 static int bwn_fw_get(struct bwn_mac *, enum bwn_fwtype,
371 const char *, struct bwn_fwfile *);
372 static void bwn_release_firmware(struct bwn_mac *);
373 static void bwn_do_release_fw(struct bwn_fwfile *);
374 static uint16_t bwn_fwcaps_read(struct bwn_mac *);
375 static int bwn_fwinitvals_write(struct bwn_mac *,
376 const struct bwn_fwinitvals *, size_t, size_t);
377 static int bwn_switch_channel(struct bwn_mac *, int);
378 static uint16_t bwn_ant2phy(int);
379 static void bwn_mac_write_bssid(struct bwn_mac *);
380 static void bwn_mac_setfilter(struct bwn_mac *, uint16_t,
382 static void bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t,
383 const uint8_t *, size_t, const uint8_t *);
384 static void bwn_key_macwrite(struct bwn_mac *, uint8_t,
386 static void bwn_key_write(struct bwn_mac *, uint8_t, uint8_t,
388 static void bwn_phy_exit(struct bwn_mac *);
389 static void bwn_core_stop(struct bwn_mac *);
390 static int bwn_switch_band(struct bwn_softc *,
391 struct ieee80211_channel *);
392 static void bwn_phy_reset(struct bwn_mac *);
393 static int bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
394 static void bwn_set_pretbtt(struct bwn_mac *);
395 static void bwn_intr(void *);
396 static void bwn_intrtask(void *, int);
397 static void bwn_restart(struct bwn_mac *, const char *);
398 static void bwn_intr_ucode_debug(struct bwn_mac *);
399 static void bwn_intr_tbtt_indication(struct bwn_mac *);
400 static void bwn_intr_atim_end(struct bwn_mac *);
401 static void bwn_intr_beacon(struct bwn_mac *);
402 static void bwn_intr_pmq(struct bwn_mac *);
403 static void bwn_intr_noise(struct bwn_mac *);
404 static void bwn_intr_txeof(struct bwn_mac *);
405 static void bwn_hwreset(void *, int);
406 static void bwn_handle_fwpanic(struct bwn_mac *);
407 static void bwn_load_beacon0(struct bwn_mac *);
408 static void bwn_load_beacon1(struct bwn_mac *);
409 static uint32_t bwn_jssi_read(struct bwn_mac *);
410 static void bwn_noise_gensample(struct bwn_mac *);
411 static void bwn_handle_txeof(struct bwn_mac *,
412 const struct bwn_txstatus *);
413 static void bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *);
414 static void bwn_phy_txpower_check(struct bwn_mac *, uint32_t);
415 static void bwn_start_locked(struct ifnet *);
416 static int bwn_tx_start(struct bwn_softc *, struct ieee80211_node *,
418 static int bwn_tx_isfull(struct bwn_softc *, struct mbuf *);
419 static int bwn_set_txhdr(struct bwn_mac *,
420 struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *,
422 static void bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t,
424 static uint8_t bwn_antenna_sanitize(struct bwn_mac *, uint8_t);
425 static uint8_t bwn_get_fbrate(uint8_t);
426 static int bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t);
427 static void bwn_phy_g_setatt(struct bwn_mac *, int *, int *);
428 static void bwn_phy_lock(struct bwn_mac *);
429 static void bwn_phy_unlock(struct bwn_mac *);
430 static void bwn_rf_lock(struct bwn_mac *);
431 static void bwn_rf_unlock(struct bwn_mac *);
432 static void bwn_txpwr(void *, int);
433 static void bwn_tasks(void *);
434 static void bwn_task_15s(struct bwn_mac *);
435 static void bwn_task_30s(struct bwn_mac *);
436 static void bwn_task_60s(struct bwn_mac *);
437 static int bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *,
439 static int bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *);
440 static void bwn_rx_radiotap(struct bwn_mac *, struct mbuf *,
441 const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int,
443 static void bwn_tsf_read(struct bwn_mac *, uint64_t *);
444 static void bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t);
445 static void bwn_set_slot_time(struct bwn_mac *, uint16_t);
446 static void bwn_watchdog(void *);
447 static void bwn_dma_stop(struct bwn_mac *);
448 static void bwn_pio_stop(struct bwn_mac *);
449 static void bwn_dma_ringstop(struct bwn_dma_ring **);
450 static void bwn_led_attach(struct bwn_mac *);
451 static void bwn_led_newstate(struct bwn_mac *, enum ieee80211_state);
452 static void bwn_led_event(struct bwn_mac *, int);
453 static void bwn_led_blink_start(struct bwn_mac *, int, int);
454 static void bwn_led_blink_next(void *);
455 static void bwn_led_blink_end(void *);
456 static void bwn_rfswitch(void *);
457 static void bwn_rf_turnon(struct bwn_mac *);
458 static void bwn_rf_turnoff(struct bwn_mac *);
459 static void bwn_phy_lp_init_pre(struct bwn_mac *);
460 static int bwn_phy_lp_init(struct bwn_mac *);
461 static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t);
462 static void bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t);
463 static void bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t,
465 static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t);
466 static void bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t);
467 static void bwn_phy_lp_rf_onoff(struct bwn_mac *, int);
468 static int bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t);
469 static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *);
470 static void bwn_phy_lp_set_antenna(struct bwn_mac *, int);
471 static void bwn_phy_lp_task_60s(struct bwn_mac *);
472 static void bwn_phy_lp_readsprom(struct bwn_mac *);
473 static void bwn_phy_lp_bbinit(struct bwn_mac *);
474 static void bwn_phy_lp_txpctl_init(struct bwn_mac *);
475 static void bwn_phy_lp_calib(struct bwn_mac *);
476 static void bwn_phy_lp_switch_analog(struct bwn_mac *, int);
477 static int bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t);
478 static int bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t);
479 static void bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t);
480 static void bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t);
481 static void bwn_phy_lp_digflt_save(struct bwn_mac *);
482 static void bwn_phy_lp_get_txpctlmode(struct bwn_mac *);
483 static void bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t);
484 static void bwn_phy_lp_bugfix(struct bwn_mac *);
485 static void bwn_phy_lp_digflt_restore(struct bwn_mac *);
486 static void bwn_phy_lp_tblinit(struct bwn_mac *);
487 static void bwn_phy_lp_bbinit_r2(struct bwn_mac *);
488 static void bwn_phy_lp_bbinit_r01(struct bwn_mac *);
489 static void bwn_phy_lp_b2062_init(struct bwn_mac *);
490 static void bwn_phy_lp_b2063_init(struct bwn_mac *);
491 static void bwn_phy_lp_rxcal_r2(struct bwn_mac *);
492 static void bwn_phy_lp_rccal_r12(struct bwn_mac *);
493 static void bwn_phy_lp_set_rccap(struct bwn_mac *);
494 static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t);
495 static void bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *);
496 static void bwn_phy_lp_b2062_vco_calib(struct bwn_mac *);
497 static void bwn_tab_write_multi(struct bwn_mac *, uint32_t, int,
499 static void bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *);
500 static struct bwn_txgain
501 bwn_phy_lp_get_txgain(struct bwn_mac *);
502 static uint8_t bwn_phy_lp_get_bbmult(struct bwn_mac *);
503 static void bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *);
504 static void bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t);
505 static void bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t);
506 static void bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t);
507 static void bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t);
508 static int bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t);
509 static void bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t);
510 static void bwn_phy_lp_tblinit_r01(struct bwn_mac *);
511 static void bwn_phy_lp_tblinit_r2(struct bwn_mac *);
512 static void bwn_phy_lp_tblinit_txgain(struct bwn_mac *);
513 static void bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t);
514 static void bwn_phy_lp_b2062_tblinit(struct bwn_mac *);
515 static void bwn_phy_lp_b2063_tblinit(struct bwn_mac *);
516 static int bwn_phy_lp_loopback(struct bwn_mac *);
517 static void bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t);
518 static void bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int,
520 static uint8_t bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t,
521 struct bwn_phy_lp_iq_est *);
522 static void bwn_phy_lp_ddfs_turnoff(struct bwn_mac *);
523 static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t);
524 static void bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t);
525 static void bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t);
526 static void bwn_phy_lp_set_txgain_override(struct bwn_mac *);
527 static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *);
528 static uint8_t bwn_nbits(int32_t);
529 static void bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int,
530 struct bwn_txgain_entry *);
531 static void bwn_phy_lp_gaintbl_write(struct bwn_mac *, int,
532 struct bwn_txgain_entry);
533 static void bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int,
534 struct bwn_txgain_entry);
535 static void bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int,
536 struct bwn_txgain_entry);
537 static void bwn_sysctl_node(struct bwn_softc *);
539 static const struct bwn_channelinfo bwn_chantable_bg = {
541 { 2412, 1, 30 }, { 2417, 2, 30 }, { 2422, 3, 30 },
542 { 2427, 4, 30 }, { 2432, 5, 30 }, { 2437, 6, 30 },
543 { 2442, 7, 30 }, { 2447, 8, 30 }, { 2452, 9, 30 },
544 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 },
545 { 2472, 13, 30 }, { 2484, 14, 30 } },
549 static const struct bwn_channelinfo bwn_chantable_a = {
551 { 5170, 34, 30 }, { 5180, 36, 30 }, { 5190, 38, 30 },
552 { 5200, 40, 30 }, { 5210, 42, 30 }, { 5220, 44, 30 },
553 { 5230, 46, 30 }, { 5240, 48, 30 }, { 5260, 52, 30 },
554 { 5280, 56, 30 }, { 5300, 60, 30 }, { 5320, 64, 30 },
555 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 },
556 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 },
557 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 },
558 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 },
559 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 },
560 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 },
561 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 },
562 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 },
567 static const struct bwn_channelinfo bwn_chantable_n = {
569 { 5160, 32, 30 }, { 5170, 34, 30 }, { 5180, 36, 30 },
570 { 5190, 38, 30 }, { 5200, 40, 30 }, { 5210, 42, 30 },
571 { 5220, 44, 30 }, { 5230, 46, 30 }, { 5240, 48, 30 },
572 { 5250, 50, 30 }, { 5260, 52, 30 }, { 5270, 54, 30 },
573 { 5280, 56, 30 }, { 5290, 58, 30 }, { 5300, 60, 30 },
574 { 5310, 62, 30 }, { 5320, 64, 30 }, { 5330, 66, 30 },
575 { 5340, 68, 30 }, { 5350, 70, 30 }, { 5360, 72, 30 },
576 { 5370, 74, 30 }, { 5380, 76, 30 }, { 5390, 78, 30 },
577 { 5400, 80, 30 }, { 5410, 82, 30 }, { 5420, 84, 30 },
578 { 5430, 86, 30 }, { 5440, 88, 30 }, { 5450, 90, 30 },
579 { 5460, 92, 30 }, { 5470, 94, 30 }, { 5480, 96, 30 },
580 { 5490, 98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 },
581 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 },
582 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 },
583 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 },
584 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 },
585 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 },
586 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 },
587 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 },
588 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 },
589 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 },
590 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 },
591 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 },
592 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 },
593 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 },
594 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 },
595 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 },
596 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 },
597 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 },
598 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 },
599 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 },
600 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 },
601 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
602 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
603 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
604 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
605 { 6130, 226, 30 }, { 6140, 228, 30 } },
609 static const uint8_t bwn_b2063_chantable_data[33][12] = {
610 { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
611 { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
612 { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
613 { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
614 { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
615 { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 },
616 { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 },
617 { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 },
618 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 },
619 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 },
620 { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 },
621 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 },
622 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 },
623 { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 },
624 { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
625 { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
626 { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 },
627 { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 },
628 { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 },
629 { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
630 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
631 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
632 { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
633 { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
634 { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 },
635 { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
636 { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
637 { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
638 { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
639 { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
640 { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
641 { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
642 { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }
645 static const struct bwn_b206x_chan bwn_b2063_chantable[] = {
646 { 1, 2412, bwn_b2063_chantable_data[0] },
647 { 2, 2417, bwn_b2063_chantable_data[0] },
648 { 3, 2422, bwn_b2063_chantable_data[0] },
649 { 4, 2427, bwn_b2063_chantable_data[1] },
650 { 5, 2432, bwn_b2063_chantable_data[1] },
651 { 6, 2437, bwn_b2063_chantable_data[1] },
652 { 7, 2442, bwn_b2063_chantable_data[1] },
653 { 8, 2447, bwn_b2063_chantable_data[1] },
654 { 9, 2452, bwn_b2063_chantable_data[2] },
655 { 10, 2457, bwn_b2063_chantable_data[2] },
656 { 11, 2462, bwn_b2063_chantable_data[3] },
657 { 12, 2467, bwn_b2063_chantable_data[3] },
658 { 13, 2472, bwn_b2063_chantable_data[3] },
659 { 14, 2484, bwn_b2063_chantable_data[4] },
660 { 34, 5170, bwn_b2063_chantable_data[5] },
661 { 36, 5180, bwn_b2063_chantable_data[6] },
662 { 38, 5190, bwn_b2063_chantable_data[7] },
663 { 40, 5200, bwn_b2063_chantable_data[8] },
664 { 42, 5210, bwn_b2063_chantable_data[9] },
665 { 44, 5220, bwn_b2063_chantable_data[10] },
666 { 46, 5230, bwn_b2063_chantable_data[11] },
667 { 48, 5240, bwn_b2063_chantable_data[12] },
668 { 52, 5260, bwn_b2063_chantable_data[13] },
669 { 56, 5280, bwn_b2063_chantable_data[14] },
670 { 60, 5300, bwn_b2063_chantable_data[14] },
671 { 64, 5320, bwn_b2063_chantable_data[15] },
672 { 100, 5500, bwn_b2063_chantable_data[16] },
673 { 104, 5520, bwn_b2063_chantable_data[17] },
674 { 108, 5540, bwn_b2063_chantable_data[18] },
675 { 112, 5560, bwn_b2063_chantable_data[19] },
676 { 116, 5580, bwn_b2063_chantable_data[20] },
677 { 120, 5600, bwn_b2063_chantable_data[21] },
678 { 124, 5620, bwn_b2063_chantable_data[21] },
679 { 128, 5640, bwn_b2063_chantable_data[22] },
680 { 132, 5660, bwn_b2063_chantable_data[22] },
681 { 136, 5680, bwn_b2063_chantable_data[22] },
682 { 140, 5700, bwn_b2063_chantable_data[23] },
683 { 149, 5745, bwn_b2063_chantable_data[23] },
684 { 153, 5765, bwn_b2063_chantable_data[23] },
685 { 157, 5785, bwn_b2063_chantable_data[23] },
686 { 161, 5805, bwn_b2063_chantable_data[23] },
687 { 165, 5825, bwn_b2063_chantable_data[23] },
688 { 184, 4920, bwn_b2063_chantable_data[24] },
689 { 188, 4940, bwn_b2063_chantable_data[25] },
690 { 192, 4960, bwn_b2063_chantable_data[26] },
691 { 196, 4980, bwn_b2063_chantable_data[27] },
692 { 200, 5000, bwn_b2063_chantable_data[28] },
693 { 204, 5020, bwn_b2063_chantable_data[29] },
694 { 208, 5040, bwn_b2063_chantable_data[30] },
695 { 212, 5060, bwn_b2063_chantable_data[31] },
696 { 216, 5080, bwn_b2063_chantable_data[32] }
699 static const uint8_t bwn_b2062_chantable_data[22][12] = {
700 { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 },
701 { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
702 { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
703 { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
704 { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
705 { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
706 { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
707 { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
708 { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
709 { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
710 { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
711 { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
712 { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
713 { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
714 { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
715 { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
716 { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
717 { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
718 { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
719 { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
720 { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
721 { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }
724 static const struct bwn_b206x_chan bwn_b2062_chantable[] = {
725 { 1, 2412, bwn_b2062_chantable_data[0] },
726 { 2, 2417, bwn_b2062_chantable_data[0] },
727 { 3, 2422, bwn_b2062_chantable_data[0] },
728 { 4, 2427, bwn_b2062_chantable_data[0] },
729 { 5, 2432, bwn_b2062_chantable_data[0] },
730 { 6, 2437, bwn_b2062_chantable_data[0] },
731 { 7, 2442, bwn_b2062_chantable_data[0] },
732 { 8, 2447, bwn_b2062_chantable_data[0] },
733 { 9, 2452, bwn_b2062_chantable_data[0] },
734 { 10, 2457, bwn_b2062_chantable_data[0] },
735 { 11, 2462, bwn_b2062_chantable_data[0] },
736 { 12, 2467, bwn_b2062_chantable_data[0] },
737 { 13, 2472, bwn_b2062_chantable_data[0] },
738 { 14, 2484, bwn_b2062_chantable_data[0] },
739 { 34, 5170, bwn_b2062_chantable_data[1] },
740 { 38, 5190, bwn_b2062_chantable_data[2] },
741 { 42, 5210, bwn_b2062_chantable_data[2] },
742 { 46, 5230, bwn_b2062_chantable_data[3] },
743 { 36, 5180, bwn_b2062_chantable_data[4] },
744 { 40, 5200, bwn_b2062_chantable_data[5] },
745 { 44, 5220, bwn_b2062_chantable_data[6] },
746 { 48, 5240, bwn_b2062_chantable_data[3] },
747 { 52, 5260, bwn_b2062_chantable_data[3] },
748 { 56, 5280, bwn_b2062_chantable_data[3] },
749 { 60, 5300, bwn_b2062_chantable_data[7] },
750 { 64, 5320, bwn_b2062_chantable_data[8] },
751 { 100, 5500, bwn_b2062_chantable_data[9] },
752 { 104, 5520, bwn_b2062_chantable_data[10] },
753 { 108, 5540, bwn_b2062_chantable_data[10] },
754 { 112, 5560, bwn_b2062_chantable_data[10] },
755 { 116, 5580, bwn_b2062_chantable_data[11] },
756 { 120, 5600, bwn_b2062_chantable_data[12] },
757 { 124, 5620, bwn_b2062_chantable_data[12] },
758 { 128, 5640, bwn_b2062_chantable_data[12] },
759 { 132, 5660, bwn_b2062_chantable_data[12] },
760 { 136, 5680, bwn_b2062_chantable_data[12] },
761 { 140, 5700, bwn_b2062_chantable_data[12] },
762 { 149, 5745, bwn_b2062_chantable_data[12] },
763 { 153, 5765, bwn_b2062_chantable_data[12] },
764 { 157, 5785, bwn_b2062_chantable_data[12] },
765 { 161, 5805, bwn_b2062_chantable_data[12] },
766 { 165, 5825, bwn_b2062_chantable_data[12] },
767 { 184, 4920, bwn_b2062_chantable_data[13] },
768 { 188, 4940, bwn_b2062_chantable_data[14] },
769 { 192, 4960, bwn_b2062_chantable_data[15] },
770 { 196, 4980, bwn_b2062_chantable_data[16] },
771 { 200, 5000, bwn_b2062_chantable_data[17] },
772 { 204, 5020, bwn_b2062_chantable_data[18] },
773 { 208, 5040, bwn_b2062_chantable_data[19] },
774 { 212, 5060, bwn_b2062_chantable_data[20] },
775 { 216, 5080, bwn_b2062_chantable_data[21] }
779 static const struct bwn_rxcompco bwn_rxcompco_5354[] = {
780 { 1, -66, 15 }, { 2, -66, 15 }, { 3, -66, 15 }, { 4, -66, 15 },
781 { 5, -66, 15 }, { 6, -66, 15 }, { 7, -66, 14 }, { 8, -66, 14 },
782 { 9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 },
783 { 13, -66, 13 }, { 14, -66, 13 },
787 static const struct bwn_rxcompco bwn_rxcompco_r12[] = {
788 { 1, -64, 13 }, { 2, -64, 13 }, { 3, -64, 13 }, { 4, -64, 13 },
789 { 5, -64, 12 }, { 6, -64, 12 }, { 7, -64, 12 }, { 8, -64, 12 },
790 { 9, -64, 12 }, { 10, -64, 11 }, { 11, -64, 11 }, { 12, -64, 11 },
791 { 13, -64, 11 }, { 14, -64, 10 }, { 34, -62, 24 }, { 38, -62, 24 },
792 { 42, -62, 24 }, { 46, -62, 23 }, { 36, -62, 24 }, { 40, -62, 24 },
793 { 44, -62, 23 }, { 48, -62, 23 }, { 52, -62, 23 }, { 56, -62, 22 },
794 { 60, -62, 22 }, { 64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 },
795 { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 },
796 { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 },
797 { 140, -62, 10 }, { 149, -61, 9 }, { 153, -61, 9 }, { 157, -61, 9 },
798 { 161, -61, 8 }, { 165, -61, 8 }, { 184, -62, 25 }, { 188, -62, 25 },
799 { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 },
800 { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 },
803 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 };
805 static const uint8_t bwn_tab_sigsq_tbl[] = {
806 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd,
807 0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
808 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00,
809 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
810 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
811 0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
814 static const uint8_t bwn_tab_pllfrac_tbl[] = {
815 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80,
816 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
819 static const uint16_t bwn_tabl_iqlocal_tbl[] = {
820 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002,
821 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
822 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
823 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
824 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006,
825 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
826 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
827 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
828 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
829 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
830 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
831 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
834 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
835 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
836 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
837 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
838 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
839 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
841 #define VENDOR_LED_ACT(vendor) \
843 .vid = PCI_VENDOR_##vendor, \
844 .led_act = { BWN_VENDOR_LED_ACT_##vendor } \
847 static const struct {
849 uint8_t led_act[BWN_LED_MAX];
850 } bwn_vendor_led_act[] = {
851 VENDOR_LED_ACT(COMPAQ),
852 VENDOR_LED_ACT(ASUSTEK)
855 static const uint8_t bwn_default_led_act[BWN_LED_MAX] =
856 { BWN_VENDOR_LED_ACT_DEFAULT };
858 #undef VENDOR_LED_ACT
860 static const struct {
863 } bwn_led_duration[109] = {
879 static const uint16_t bwn_wme_shm_offsets[] = {
880 [0] = BWN_WME_BESTEFFORT,
881 [1] = BWN_WME_BACKGROUND,
886 static const struct siba_devid bwn_devs[] = {
887 SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"),
888 SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"),
889 SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"),
890 SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"),
891 SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"),
892 SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"),
893 SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"),
894 SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"),
895 SIBA_DEV(BROADCOM, 80211, 16, "Revision 16")
899 bwn_probe(device_t dev)
903 wlan_serialize_enter();
905 for (i = 0; i < NELEM(bwn_devs); i++) {
906 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor &&
907 siba_get_device(dev) == bwn_devs[i].sd_device &&
908 siba_get_revid(dev) == bwn_devs[i].sd_rev) {
909 wlan_serialize_exit();
910 return (BUS_PROBE_DEFAULT);
913 wlan_serialize_exit();
918 bwn_attach(device_t dev)
921 struct bwn_softc *sc = device_get_softc(dev);
925 wlan_serialize_enter();
929 sc->sc_debug = bwn_debug;
932 if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
933 error = bwn_attach_pre(sc);
935 wlan_serialize_exit();
938 bwn_sprom_bugfixes(dev);
939 sc->sc_flags |= BWN_FLAG_ATTACHED;
942 if (!TAILQ_EMPTY(&sc->sc_maclist)) {
943 if (siba_get_pci_device(dev) != 0x4313 &&
944 siba_get_pci_device(dev) != 0x431a &&
945 siba_get_pci_device(dev) != 0x4321) {
946 device_printf(sc->sc_dev,
947 "skip 802.11 cores\n");
948 wlan_serialize_exit();
953 mac = (struct bwn_mac *)kmalloc(sizeof(*mac), M_DEVBUF,
956 mac->mac_status = BWN_MAC_STATUS_UNINIT;
958 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
960 TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac);
961 TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac);
962 TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac);
964 error = bwn_attach_core(mac);
969 device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) "
970 "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
971 siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev),
972 mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev,
973 mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver,
974 mac->mac_phy.rf_rev);
975 if (mac->mac_flags & BWN_MAC_FLAG_DMA)
976 device_printf(sc->sc_dev, "DMA (%d bits)\n",
977 mac->mac_method.dma.dmatype);
979 device_printf(sc->sc_dev, "PIO\n");
981 /* Allocate IRQ resource. */
983 sc->bwn_irq_type = pci_alloc_1intr(sc->sc_dev, bwn_msi_enable,
984 &sc->bwn_irq_rid, &irq_flags);
985 if ((sc->bwn_irq = bus_alloc_resource_any(sc->sc_dev, SYS_RES_IRQ,
986 &sc->bwn_irq_rid, irq_flags)) == NULL) {
987 device_printf(sc->sc_dev, "Cannot allocate interrupt\n");
991 if ((error = bus_setup_intr(sc->sc_dev, sc->bwn_irq, INTR_MPSAFE,
992 bwn_intr, mac, &sc->bwn_intr, &wlan_global_serializer)) != 0) {
993 device_printf(sc->sc_dev, "Cannot set up interrupt\n");
997 TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list);
1000 * calls attach-post routine
1002 if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0)
1003 bwn_attach_post(sc);
1005 wlan_serialize_exit();
1008 if (sc->bwn_irq_type == PCI_INTR_TYPE_MSI)
1009 pci_release_msi(dev);
1011 kfree(mac, M_DEVBUF);
1012 wlan_serialize_exit();
1017 bwn_is_valid_ether_addr(uint8_t *addr)
1019 char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
1021 if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN)))
1028 bwn_attach_post(struct bwn_softc *sc)
1030 struct ieee80211com *ic;
1031 struct ifnet *ifp = sc->sc_ifp;
1035 /* XXX not right but it's not used anywhere important */
1036 ic->ic_phytype = IEEE80211_T_OFDM;
1037 ic->ic_opmode = IEEE80211_M_STA;
1039 IEEE80211_C_STA /* station mode supported */
1040 | IEEE80211_C_MONITOR /* monitor mode */
1041 | IEEE80211_C_AHDEMO /* adhoc demo mode */
1042 | IEEE80211_C_SHPREAMBLE /* short preamble supported */
1043 | IEEE80211_C_SHSLOT /* short slot time supported */
1044 | IEEE80211_C_WME /* WME/WMM supported */
1045 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */
1046 | IEEE80211_C_BGSCAN /* capable of bg scanning */
1047 | IEEE80211_C_TXPMGT /* capable of txpow mgt */
1050 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */
1052 /* call MI attach routine. */
1053 ieee80211_ifattach(ic,
1054 bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
1055 siba_sprom_get_mac_80211a(sc->sc_dev) :
1056 siba_sprom_get_mac_80211bg(sc->sc_dev));
1058 ic->ic_headroom = sizeof(struct bwn_txhdr);
1060 /* override default methods */
1061 ic->ic_raw_xmit = bwn_raw_xmit;
1062 ic->ic_updateslot = bwn_updateslot;
1063 ic->ic_update_promisc = bwn_update_promisc;
1064 ic->ic_wme.wme_update = bwn_wme_update;
1066 ic->ic_scan_start = bwn_scan_start;
1067 ic->ic_scan_end = bwn_scan_end;
1068 ic->ic_set_channel = bwn_set_channel;
1070 ic->ic_vap_create = bwn_vap_create;
1071 ic->ic_vap_delete = bwn_vap_delete;
1073 ieee80211_radiotap_attach(ic,
1074 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
1075 BWN_TX_RADIOTAP_PRESENT,
1076 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
1077 BWN_RX_RADIOTAP_PRESENT);
1079 bwn_sysctl_node(sc);
1082 ieee80211_announce(ic);
1087 bwn_phy_detach(struct bwn_mac *mac)
1090 if (mac->mac_phy.detach != NULL)
1091 mac->mac_phy.detach(mac);
1095 bwn_detach(device_t dev)
1097 struct bwn_softc *sc = device_get_softc(dev);
1098 struct bwn_mac *mac = sc->sc_curmac;
1099 struct ifnet *ifp = sc->sc_ifp;
1100 struct ieee80211com *ic = ifp->if_l2com;
1102 wlan_serialize_enter();
1104 sc->sc_flags |= BWN_FLAG_INVALID;
1106 if (device_is_attached(sc->sc_dev)) {
1109 callout_stop_sync(&sc->sc_led_blink_ch);
1110 callout_stop_sync(&sc->sc_rfswitch_ch);
1111 callout_stop_sync(&sc->sc_task_ch);
1112 callout_stop_sync(&sc->sc_watchdog_ch);
1113 bwn_phy_detach(mac);
1115 wlan_serialize_exit();
1116 ieee80211_draintask(ic, &mac->mac_hwreset);
1117 ieee80211_draintask(ic, &mac->mac_txpower);
1118 wlan_serialize_enter();
1119 ieee80211_ifdetach(ic);
1123 wlan_serialize_exit();
1124 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
1125 taskqueue_free(sc->sc_tq);
1126 wlan_serialize_enter();
1129 bus_teardown_intr(dev, sc->bwn_irq, sc->bwn_intr);
1130 if (sc->bwn_irq != NULL)
1131 bus_release_resource(dev, SYS_RES_IRQ, sc->bwn_irq_rid,
1134 if (sc->bwn_irq_type == PCI_INTR_TYPE_MSI)
1135 pci_release_msi(dev);
1137 wlan_serialize_exit();
1142 bwn_attach_pre(struct bwn_softc *sc)
1147 TAILQ_INIT(&sc->sc_maclist);
1148 callout_init(&sc->sc_rfswitch_ch);
1149 callout_init(&sc->sc_task_ch);
1150 callout_init(&sc->sc_watchdog_ch);
1152 sc->sc_tq = taskqueue_create("bwn_taskq", M_WAITOK,
1153 taskqueue_thread_enqueue, &sc->sc_tq);
1154 taskqueue_start_threads(&sc->sc_tq, 1, TDPRI_KERN_DAEMON, -1,
1155 "%s taskq", device_get_nameunit(sc->sc_dev));
1157 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
1159 device_printf(sc->sc_dev, "can not if_alloc()\n");
1164 /* set these up early for if_printf use */
1165 if_initname(ifp, device_get_name(sc->sc_dev),
1166 device_get_unit(sc->sc_dev));
1169 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1170 ifp->if_init = bwn_init;
1171 ifp->if_ioctl = bwn_ioctl;
1172 ifp->if_start = bwn_start;
1173 ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
1182 bwn_sprom_bugfixes(device_t dev)
1184 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \
1185 ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \
1186 (siba_get_pci_device(dev) == _device) && \
1187 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \
1188 (siba_get_pci_subdevice(dev) == _subdevice))
1190 if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
1191 siba_get_pci_subdevice(dev) == 0x4e &&
1192 siba_get_pci_revid(dev) > 0x40)
1193 siba_sprom_set_bf_lo(dev,
1194 siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
1195 if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
1196 siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
1197 siba_sprom_set_bf_lo(dev,
1198 siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
1199 if (siba_get_type(dev) == SIBA_TYPE_PCI) {
1200 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1201 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1202 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1203 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1204 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1205 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1206 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1207 siba_sprom_set_bf_lo(dev,
1208 siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
1214 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data,
1215 struct ucred *cr __unused)
1217 #define IS_RUNNING(ifp) \
1218 ((ifp->if_flags & IFF_UP) && (ifp->if_flags & IFF_RUNNING))
1219 struct bwn_softc *sc = ifp->if_softc;
1220 struct ieee80211com *ic = ifp->if_l2com;
1221 struct ifreq *ifr = (struct ifreq *)data;
1226 if (IS_RUNNING(ifp)) {
1227 bwn_update_promisc(ifp);
1228 } else if (ifp->if_flags & IFF_UP) {
1229 if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
1236 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1239 error = ether_ioctl(ifp, cmd, data);
1249 bwn_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
1251 wlan_assert_serialized();
1252 bwn_start_locked(ifp);
1256 bwn_start_locked(struct ifnet *ifp)
1258 struct bwn_softc *sc = ifp->if_softc;
1259 struct bwn_mac *mac = sc->sc_curmac;
1260 struct ieee80211_frame *wh;
1261 struct ieee80211_node *ni;
1262 struct ieee80211_key *k;
1265 wlan_assert_serialized();
1267 if ((ifp->if_flags & IFF_RUNNING) == 0 || mac == NULL ||
1268 mac->mac_status < BWN_MAC_STATUS_STARTED)
1272 m = ifq_dequeue(&ifp->if_snd); /* XXX: LOCK */
1276 if (bwn_tx_isfull(sc, m))
1278 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1280 device_printf(sc->sc_dev, "unexpected NULL ni\n");
1285 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
1286 wh = mtod(m, struct ieee80211_frame *);
1287 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1288 k = ieee80211_crypto_encap(ni, m);
1290 ieee80211_free_node(ni);
1296 wh = NULL; /* Catch any invalid use */
1298 if (bwn_tx_start(sc, ni, m) != 0) {
1300 ieee80211_free_node(ni);
1305 sc->sc_watchdog_timer = 5;
1310 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1312 struct bwn_dma_ring *dr;
1313 struct bwn_mac *mac = sc->sc_curmac;
1314 struct bwn_pio_txqueue *tq;
1315 struct ifnet *ifp = sc->sc_ifp;
1316 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1318 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1319 dr = bwn_dma_select(mac, M_WME_GETAC(m));
1320 if (dr->dr_stop == 1 ||
1321 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1326 tq = bwn_pio_select(mac, M_WME_GETAC(m));
1327 if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1328 pktlen > (tq->tq_size - tq->tq_used)) {
1335 ifq_prepend(&ifp->if_snd, m);
1336 ifq_set_oactive(&ifp->if_snd);
1341 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1343 struct bwn_mac *mac = sc->sc_curmac;
1346 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1351 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1352 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1361 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1363 struct bwn_pio_txpkt *tp;
1364 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1365 struct bwn_softc *sc = mac->mac_sc;
1366 struct bwn_txhdr txhdr;
1372 /* XXX TODO send packets after DTIM */
1374 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1375 tp = TAILQ_FIRST(&tq->tq_pktlist);
1379 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1381 device_printf(sc->sc_dev, "tx fail\n");
1385 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1386 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1389 if (siba_get_revid(sc->sc_dev) >= 8) {
1391 * XXX please removes m_defrag(9)
1393 m_new = m_defrag(m, M_INTWAIT);
1394 if (m_new == NULL) {
1395 device_printf(sc->sc_dev,
1396 "%s: can't defrag TX buffer\n",
1400 if (m_new->m_next != NULL)
1401 device_printf(sc->sc_dev,
1402 "TODO: fragmented packets for PIO\n");
1406 ctl32 = bwn_pio_write_multi_4(mac, tq,
1407 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1408 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1409 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1411 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1412 mtod(m_new, const void *), m_new->m_pkthdr.len);
1413 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1414 ctl32 | BWN_PIO8_TXCTL_EOF);
1416 ctl16 = bwn_pio_write_multi_2(mac, tq,
1417 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1418 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1419 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1420 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1421 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1422 ctl16 | BWN_PIO_TXCTL_EOF);
1428 static struct bwn_pio_txqueue *
1429 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1432 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1433 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1437 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1439 return (&mac->mac_method.pio.wme[WME_AC_BK]);
1441 return (&mac->mac_method.pio.wme[WME_AC_VI]);
1443 return (&mac->mac_method.pio.wme[WME_AC_VO]);
1445 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1450 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1452 #define BWN_GET_TXHDRCACHE(slot) \
1453 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_MAX_HDRSIZE(mac)])
1454 struct bwn_dma *dma = &mac->mac_method.dma;
1455 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1456 struct bwn_dmadesc_generic *desc;
1457 struct bwn_dmadesc_meta *mt;
1458 struct bwn_softc *sc = mac->mac_sc;
1459 struct ifnet *ifp = sc->sc_ifp;
1460 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1461 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1463 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1465 /* XXX send after DTIM */
1467 slot = bwn_dma_getslot(dr);
1468 dr->getdesc(dr, slot, &desc, &mt);
1469 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1470 ("%s:%d: fail", __func__, __LINE__));
1472 error = bwn_set_txhdr(dr->dr_mac, ni, m,
1473 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1474 BWN_DMA_COOKIE(dr, slot));
1477 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1478 BUS_DMASYNC_PREWRITE);
1479 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1480 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1481 BUS_DMASYNC_PREWRITE);
1483 slot = bwn_dma_getslot(dr);
1484 dr->getdesc(dr, slot, &desc, &mt);
1485 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1486 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1490 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1491 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1492 if (error && error != EFBIG) {
1493 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1497 if (error) { /* error == EFBIG */
1500 m_new = m_defrag(m, M_INTWAIT);
1501 if (m_new == NULL) {
1502 if_printf(ifp, "%s: can't defrag TX buffer\n",
1511 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1512 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1514 if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
1519 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1520 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1521 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1522 BUS_DMASYNC_PREWRITE);
1524 /* XXX send after DTIM */
1526 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1529 dr->dr_curslot = backup[0];
1530 dr->dr_usedslot = backup[1];
1532 #undef BWN_GET_TXHDRCACHE
1536 bwn_watchdog(void *arg)
1538 struct bwn_softc *sc = arg;
1539 struct ifnet *ifp = sc->sc_ifp;
1541 wlan_serialize_enter();
1543 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1544 if_printf(ifp, "device timeout\n");
1547 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
1548 wlan_serialize_exit();
1552 bwn_attach_core(struct bwn_mac *mac)
1554 struct bwn_softc *sc = mac->mac_sc;
1555 int error, have_bg = 0, have_a = 0;
1558 KASSERT(siba_get_revid(sc->sc_dev) >= 5,
1559 ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
1561 siba_powerup(sc->sc_dev, 0);
1563 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
1565 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1566 error = bwn_phy_getinfo(mac, high);
1570 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1571 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1572 if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
1573 siba_get_pci_device(sc->sc_dev) != 0x4319 &&
1574 siba_get_pci_device(sc->sc_dev) != 0x4324) {
1575 have_a = have_bg = 0;
1576 if (mac->mac_phy.type == BWN_PHYTYPE_A)
1578 else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1579 mac->mac_phy.type == BWN_PHYTYPE_N ||
1580 mac->mac_phy.type == BWN_PHYTYPE_LP)
1583 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1584 mac->mac_phy.type));
1586 /* XXX turns off PHY A because it's not supported */
1587 if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1588 mac->mac_phy.type != BWN_PHYTYPE_N) {
1593 if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1594 mac->mac_phy.attach = bwn_phy_g_attach;
1595 mac->mac_phy.detach = bwn_phy_g_detach;
1596 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1597 mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1598 mac->mac_phy.init = bwn_phy_g_init;
1599 mac->mac_phy.exit = bwn_phy_g_exit;
1600 mac->mac_phy.phy_read = bwn_phy_g_read;
1601 mac->mac_phy.phy_write = bwn_phy_g_write;
1602 mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1603 mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1604 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1605 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1606 mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1607 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1608 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1609 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1610 mac->mac_phy.set_im = bwn_phy_g_im;
1611 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1612 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1613 mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1614 mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1615 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1616 mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1617 mac->mac_phy.init = bwn_phy_lp_init;
1618 mac->mac_phy.phy_read = bwn_phy_lp_read;
1619 mac->mac_phy.phy_write = bwn_phy_lp_write;
1620 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1621 mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1622 mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1623 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1624 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1625 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1626 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1627 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1628 mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1630 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1636 mac->mac_phy.gmode = have_bg;
1637 if (mac->mac_phy.attach != NULL) {
1638 error = mac->mac_phy.attach(mac);
1640 device_printf(sc->sc_dev, "failed\n");
1645 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1647 error = bwn_chiptest(mac);
1650 error = bwn_setup_channels(mac, have_bg, have_a);
1652 device_printf(sc->sc_dev, "failed to setup channels\n");
1656 if (sc->sc_curmac == NULL)
1657 sc->sc_curmac = mac;
1659 wlan_assert_serialized();
1660 wlan_serialize_exit();
1661 error = bwn_dma_attach(mac);
1662 wlan_serialize_enter();
1664 device_printf(sc->sc_dev, "failed to initialize DMA\n");
1668 mac->mac_phy.switch_analog(mac, 0);
1670 siba_dev_down(sc->sc_dev, 0);
1672 siba_powerdown(sc->sc_dev);
1677 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1679 struct bwn_softc *sc = mac->mac_sc;
1682 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1684 siba_dev_up(sc->sc_dev, flags);
1687 low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1688 ~BWN_TGSLOW_PHYRESET;
1689 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
1690 siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1692 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1693 siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1696 if (mac->mac_phy.switch_analog != NULL)
1697 mac->mac_phy.switch_analog(mac, 1);
1699 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1700 if (flags & BWN_TGSLOW_SUPPORT_G)
1701 ctl |= BWN_MACCTL_GMODE;
1702 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1706 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1708 struct bwn_phy *phy = &mac->mac_phy;
1709 struct bwn_softc *sc = mac->mac_sc;
1713 tmp = BWN_READ_2(mac, BWN_PHYVER);
1714 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1716 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1717 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1718 phy->rev = (tmp & BWN_PHYVER_VERSION);
1719 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1720 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1721 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1722 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1723 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1724 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1728 if (siba_get_chipid(sc->sc_dev) == 0x4317) {
1729 if (siba_get_chiprev(sc->sc_dev) == 0)
1731 else if (siba_get_chiprev(sc->sc_dev) == 1)
1736 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1737 tmp = BWN_READ_2(mac, BWN_RFDATALO);
1738 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1739 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1741 phy->rf_rev = (tmp & 0xf0000000) >> 28;
1742 phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1743 phy->rf_manuf = (tmp & 0x00000fff);
1744 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */
1746 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1747 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1748 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1749 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1750 (phy->type == BWN_PHYTYPE_N &&
1751 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1752 (phy->type == BWN_PHYTYPE_LP &&
1753 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1758 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1760 phy->type, phy->rev, phy->analog);
1763 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1765 phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1770 bwn_chiptest(struct bwn_mac *mac)
1772 #define TESTVAL0 0x55aaaa55
1773 #define TESTVAL1 0xaa5555aa
1774 struct bwn_softc *sc = mac->mac_sc;
1777 backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1779 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1780 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1782 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1783 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1786 bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1788 if ((siba_get_revid(sc->sc_dev) >= 3) &&
1789 (siba_get_revid(sc->sc_dev) <= 10)) {
1790 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1791 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1792 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1794 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1797 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1799 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1800 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1805 device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1809 #define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1810 #define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1813 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1815 struct bwn_softc *sc = mac->mac_sc;
1816 struct ifnet *ifp = sc->sc_ifp;
1817 struct ieee80211com *ic = ifp->if_l2com;
1819 memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1823 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1824 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1825 if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1827 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1828 &ic->ic_nchans, &bwn_chantable_n,
1829 IEEE80211_CHAN_HTA);
1832 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1833 &ic->ic_nchans, &bwn_chantable_a,
1837 mac->mac_phy.supports_2ghz = have_bg;
1838 mac->mac_phy.supports_5ghz = have_a;
1840 return (ic->ic_nchans == 0 ? ENXIO : 0);
1844 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1848 if (way == BWN_SHARED) {
1849 KASSERT((offset & 0x0001) == 0,
1850 ("%s:%d warn", __func__, __LINE__));
1851 if (offset & 0x0003) {
1852 bwn_shm_ctlword(mac, way, offset >> 2);
1853 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1855 bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1856 ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1861 bwn_shm_ctlword(mac, way, offset);
1862 ret = BWN_READ_4(mac, BWN_SHM_DATA);
1868 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1872 if (way == BWN_SHARED) {
1873 KASSERT((offset & 0x0001) == 0,
1874 ("%s:%d warn", __func__, __LINE__));
1875 if (offset & 0x0003) {
1876 bwn_shm_ctlword(mac, way, offset >> 2);
1877 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1882 bwn_shm_ctlword(mac, way, offset);
1883 ret = BWN_READ_2(mac, BWN_SHM_DATA);
1890 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1898 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1902 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1905 if (way == BWN_SHARED) {
1906 KASSERT((offset & 0x0001) == 0,
1907 ("%s:%d warn", __func__, __LINE__));
1908 if (offset & 0x0003) {
1909 bwn_shm_ctlword(mac, way, offset >> 2);
1910 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1911 (value >> 16) & 0xffff);
1912 bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1913 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1918 bwn_shm_ctlword(mac, way, offset);
1919 BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1923 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1926 if (way == BWN_SHARED) {
1927 KASSERT((offset & 0x0001) == 0,
1928 ("%s:%d warn", __func__, __LINE__));
1929 if (offset & 0x0003) {
1930 bwn_shm_ctlword(mac, way, offset >> 2);
1931 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1936 bwn_shm_ctlword(mac, way, offset);
1937 BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1941 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
1946 c->ic_flags = flags;
1949 c->ic_maxpower = 2 * txpow;
1950 c->ic_maxregpower = txpow;
1954 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
1955 const struct bwn_channelinfo *ci, int flags)
1957 struct ieee80211_channel *c;
1960 c = &chans[*nchans];
1962 for (i = 0; i < ci->nchannels; i++) {
1963 const struct bwn_channel *hc;
1965 hc = &ci->channels[i];
1966 if (*nchans >= maxchans)
1968 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
1970 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
1971 /* g channel have a separate b-only entry */
1972 if (*nchans >= maxchans)
1975 c[-1].ic_flags = IEEE80211_CHAN_B;
1978 if (flags == IEEE80211_CHAN_HTG) {
1979 /* HT g channel have a separate g-only entry */
1980 if (*nchans >= maxchans)
1982 c[-1].ic_flags = IEEE80211_CHAN_G;
1984 c[0].ic_flags &= ~IEEE80211_CHAN_HT;
1985 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */
1988 if (flags == IEEE80211_CHAN_HTA) {
1989 /* HT a channel have a separate a-only entry */
1990 if (*nchans >= maxchans)
1992 c[-1].ic_flags = IEEE80211_CHAN_A;
1994 c[0].ic_flags &= ~IEEE80211_CHAN_HT;
1995 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */
2002 bwn_phy_g_attach(struct bwn_mac *mac)
2004 struct bwn_softc *sc = mac->mac_sc;
2005 struct bwn_phy *phy = &mac->mac_phy;
2006 struct bwn_phy_g *pg = &phy->phy_g;
2008 int16_t pab0, pab1, pab2;
2009 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2012 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
2013 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
2014 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
2015 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
2017 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
2018 device_printf(sc->sc_dev, "not supported anymore\n");
2021 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2023 pg->pg_idletssi = 52;
2024 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2028 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2029 pg->pg_tssi2dbm = (uint8_t *)kmalloc(64, M_DEVBUF, M_INTWAIT | M_ZERO);
2030 for (i = 0; i < 64; i++) {
2031 int32_t m1, m2, f, q, delta;
2034 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2035 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2040 device_printf(sc->sc_dev,
2041 "failed to generate tssi2dBm\n");
2042 kfree(pg->pg_tssi2dbm, M_DEVBUF);
2045 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2050 } while (delta >= 2);
2052 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2056 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2061 bwn_phy_g_detach(struct bwn_mac *mac)
2063 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2065 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2066 kfree(pg->pg_tssi2dbm, M_DEVBUF);
2067 pg->pg_tssi2dbm = NULL;
2073 bwn_phy_g_init_pre(struct bwn_mac *mac)
2075 struct bwn_phy *phy = &mac->mac_phy;
2076 struct bwn_phy_g *pg = &phy->phy_g;
2081 tssi2dbm = pg->pg_tssi2dbm;
2082 idletssi = pg->pg_idletssi;
2084 memset(pg, 0, sizeof(*pg));
2086 pg->pg_tssi2dbm = tssi2dbm;
2087 pg->pg_idletssi = idletssi;
2089 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2091 for (i = 0; i < N(pg->pg_nrssi); i++)
2092 pg->pg_nrssi[i] = -1000;
2093 for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2094 pg->pg_nrssi_lt[i] = i;
2095 pg->pg_lofcal = 0xffff;
2096 pg->pg_initval = 0xffff;
2097 pg->pg_immode = BWN_IMMODE_NONE;
2098 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2099 pg->pg_avgtssi = 0xff;
2101 pg->pg_loctl.tx_bias = 0xff;
2102 TAILQ_INIT(&pg->pg_loctl.calib_list);
2106 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2108 struct bwn_phy *phy = &mac->mac_phy;
2109 struct bwn_phy_g *pg = &phy->phy_g;
2110 struct bwn_softc *sc = mac->mac_sc;
2111 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2112 static const struct bwn_rfatt rfatt0[] = {
2113 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
2114 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2117 static const struct bwn_rfatt rfatt1[] = {
2118 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2121 static const struct bwn_rfatt rfatt2[] = {
2122 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2125 static const struct bwn_bbatt bbatt_0[] = {
2126 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2129 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2131 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2132 pg->pg_bbatt.att = 0;
2134 pg->pg_bbatt.att = 2;
2136 /* prepare Radio Attenuation */
2137 pg->pg_rfatt.padmix = 0;
2139 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
2140 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
2141 if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
2142 pg->pg_rfatt.att = 2;
2144 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
2145 pg->pg_rfatt.att = 3;
2150 if (phy->type == BWN_PHYTYPE_A) {
2151 pg->pg_rfatt.att = 0x60;
2155 switch (phy->rf_ver) {
2157 switch (phy->rf_rev) {
2159 pg->pg_rfatt.att = 5;
2162 if (phy->type == BWN_PHYTYPE_G) {
2163 if (siba_get_pci_subvendor(sc->sc_dev) ==
2164 SIBA_BOARDVENDOR_BCM &&
2165 siba_get_pci_subdevice(sc->sc_dev) ==
2166 SIBA_BOARD_BCM4309G &&
2167 siba_get_pci_revid(sc->sc_dev) >= 30)
2168 pg->pg_rfatt.att = 3;
2169 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2170 SIBA_BOARDVENDOR_BCM &&
2171 siba_get_pci_subdevice(sc->sc_dev) ==
2173 pg->pg_rfatt.att = 3;
2175 pg->pg_rfatt.att = 1;
2177 if (siba_get_pci_subvendor(sc->sc_dev) ==
2178 SIBA_BOARDVENDOR_BCM &&
2179 siba_get_pci_subdevice(sc->sc_dev) ==
2180 SIBA_BOARD_BCM4309G &&
2181 siba_get_pci_revid(sc->sc_dev) >= 30)
2182 pg->pg_rfatt.att = 7;
2184 pg->pg_rfatt.att = 6;
2188 if (phy->type == BWN_PHYTYPE_G) {
2189 if (siba_get_pci_subvendor(sc->sc_dev) ==
2190 SIBA_BOARDVENDOR_BCM &&
2191 siba_get_pci_subdevice(sc->sc_dev) ==
2192 SIBA_BOARD_BCM4309G &&
2193 siba_get_pci_revid(sc->sc_dev) >= 30)
2194 pg->pg_rfatt.att = 3;
2195 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2196 SIBA_BOARDVENDOR_BCM &&
2197 siba_get_pci_subdevice(sc->sc_dev) ==
2199 pg->pg_rfatt.att = 5;
2200 else if (siba_get_chipid(sc->sc_dev) == 0x4320)
2201 pg->pg_rfatt.att = 4;
2203 pg->pg_rfatt.att = 3;
2205 pg->pg_rfatt.att = 6;
2208 pg->pg_rfatt.att = 5;
2212 pg->pg_rfatt.att = 1;
2216 pg->pg_rfatt.att = 5;
2219 pg->pg_rfatt.att = 0xa;
2220 pg->pg_rfatt.padmix = 1;
2224 pg->pg_rfatt.att = 5;
2229 switch (phy->rf_rev) {
2231 pg->pg_rfatt.att = 6;
2236 pg->pg_rfatt.att = 5;
2238 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2240 if (!bwn_has_hwpctl(mac)) {
2241 lo->rfatt.array = rfatt0;
2242 lo->rfatt.len = N(rfatt0);
2247 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2248 lo->rfatt.array = rfatt1;
2249 lo->rfatt.len = N(rfatt1);
2254 lo->rfatt.array = rfatt2;
2255 lo->rfatt.len = N(rfatt2);
2259 lo->bbatt.array = bbatt_0;
2260 lo->bbatt.len = N(bbatt_0);
2264 BWN_READ_4(mac, BWN_MACCTL);
2265 if (phy->rev == 1) {
2267 bwn_reset_core(mac, 0);
2268 bwn_phy_g_init_sub(mac);
2270 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2276 bwn_phy_g_txctl(struct bwn_mac *mac)
2278 struct bwn_phy *phy = &mac->mac_phy;
2280 if (phy->rf_ver != 0x2050)
2282 if (phy->rf_rev == 1)
2283 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2284 if (phy->rf_rev < 6)
2285 return (BWN_TXCTL_PA2DB);
2286 if (phy->rf_rev == 8)
2287 return (BWN_TXCTL_TXMIX);
2292 bwn_phy_g_init(struct bwn_mac *mac)
2295 bwn_phy_g_init_sub(mac);
2300 bwn_phy_g_exit(struct bwn_mac *mac)
2302 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2303 struct bwn_lo_calib *cal, *tmp;
2307 TAILQ_FOREACH_MUTABLE(cal, &lo->calib_list, list, tmp) {
2308 TAILQ_REMOVE(&lo->calib_list, cal, list);
2309 kfree(cal, M_DEVBUF);
2314 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2317 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2318 return (BWN_READ_2(mac, BWN_PHYDATA));
2322 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2325 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2326 BWN_WRITE_2(mac, BWN_PHYDATA, value);
2330 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2333 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2334 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2335 return (BWN_READ_2(mac, BWN_RFDATALO));
2339 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2342 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2343 BWN_WRITE_2(mac, BWN_RFCTL, reg);
2344 BWN_WRITE_2(mac, BWN_RFDATALO, value);
2348 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2351 return (mac->mac_phy.rev >= 6);
2355 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2357 struct bwn_phy *phy = &mac->mac_phy;
2358 struct bwn_phy_g *pg = &phy->phy_g;
2359 unsigned int channel;
2360 uint16_t rfover, rfoverval;
2366 BWN_PHY_WRITE(mac, 0x15, 0x8000);
2367 BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2368 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2369 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2370 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2371 pg->pg_radioctx_over);
2372 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2373 pg->pg_radioctx_overval);
2374 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2376 channel = phy->chan;
2377 bwn_phy_g_switch_chan(mac, 6, 1);
2378 bwn_phy_g_switch_chan(mac, channel, 0);
2382 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2383 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2384 pg->pg_radioctx_over = rfover;
2385 pg->pg_radioctx_overval = rfoverval;
2386 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2387 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2388 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2392 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2395 if ((newchan < 1) || (newchan > 14))
2397 bwn_phy_g_switch_chan(mac, newchan, 0);
2403 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2410 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2412 struct bwn_phy *phy = &mac->mac_phy;
2417 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2420 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2421 bwn_hf_write(mac, hf);
2423 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2424 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2425 ((autodiv ? BWN_ANTAUTO1 : antenna)
2426 << BWN_PHY_BBANDCFG_RXANT_SHIFT));
2429 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2430 if (antenna == BWN_ANTAUTO1)
2431 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2433 tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2434 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2436 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2438 tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2440 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2441 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2442 if (phy->rev >= 2) {
2443 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2444 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2445 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2446 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2449 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2451 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2452 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2456 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2458 hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2459 bwn_hf_write(mac, hf);
2463 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2465 struct bwn_phy *phy = &mac->mac_phy;
2466 struct bwn_phy_g *pg = &phy->phy_g;
2468 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2469 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2471 if (phy->rev == 0 || !phy->gmode)
2474 pg->pg_aci_wlan_automatic = 0;
2479 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2481 struct bwn_phy *phy = &mac->mac_phy;
2482 struct bwn_phy_g *pg = &phy->phy_g;
2483 struct bwn_softc *sc = mac->mac_sc;
2490 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2492 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2493 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2494 if (cck < 0 && ofdm < 0) {
2495 if (ignore_tssi == 0)
2496 return (BWN_TXPWR_RES_DONE);
2500 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2501 if (pg->pg_avgtssi != 0xff)
2502 tssi = (tssi + pg->pg_avgtssi) / 2;
2503 pg->pg_avgtssi = tssi;
2504 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2506 max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2507 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2510 device_printf(sc->sc_dev, "invalid max TX-power value\n");
2512 siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2515 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2516 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2517 tssi, 0x00), 0x3f)]);
2519 return (BWN_TXPWR_RES_DONE);
2521 rfatt = -((power + 7) / 8);
2522 bbatt = (-(power / 2)) - (4 * rfatt);
2523 if ((rfatt == 0) && (bbatt == 0))
2524 return (BWN_TXPWR_RES_DONE);
2525 pg->pg_bbatt_delta = bbatt;
2526 pg->pg_rfatt_delta = rfatt;
2527 return (BWN_TXPWR_RES_NEED_ADJUST);
2531 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2533 struct bwn_phy *phy = &mac->mac_phy;
2534 struct bwn_phy_g *pg = &phy->phy_g;
2535 struct bwn_softc *sc = mac->mac_sc;
2539 bwn_mac_suspend(mac);
2541 bbatt = pg->pg_bbatt.att;
2542 bbatt += pg->pg_bbatt_delta;
2543 rfatt = pg->pg_rfatt.att;
2544 rfatt += pg->pg_rfatt_delta;
2546 bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2547 txctl = pg->pg_txctl;
2548 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2551 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2554 } else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2556 bbatt += 4 * (rfatt - 2);
2559 } else if (rfatt > 4 && txctl) {
2570 pg->pg_txctl = txctl;
2571 bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2572 pg->pg_rfatt.att = rfatt;
2573 pg->pg_bbatt.att = bbatt;
2575 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2579 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2582 bwn_phy_unlock(mac);
2584 bwn_mac_enable(mac);
2588 bwn_phy_g_task_15s(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;
2593 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2594 unsigned long expire, now;
2595 struct bwn_lo_calib *cal, *tmp;
2596 uint8_t expired = 0;
2598 bwn_mac_suspend(mac);
2604 if (bwn_has_hwpctl(mac)) {
2605 expire = now - BWN_LO_PWRVEC_EXPIRE;
2606 if (time_before(lo->pwr_vec_read_time, expire)) {
2607 bwn_lo_get_powervector(mac);
2608 bwn_phy_g_dc_lookup_init(mac, 0);
2613 expire = now - BWN_LO_CALIB_EXPIRE;
2614 TAILQ_FOREACH_MUTABLE(cal, &lo->calib_list, list, tmp) {
2615 if (!time_before(cal->calib_time, expire))
2617 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2618 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2619 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2623 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2624 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2625 cal->ctl.i, cal->ctl.q);
2627 TAILQ_REMOVE(&lo->calib_list, cal, list);
2628 kfree(cal, M_DEVBUF);
2630 if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2631 cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2633 if (cal == NULL) { /* XXX ivadasz: can't happen */
2634 device_printf(sc->sc_dev,
2635 "failed to recalibrate LO\n");
2638 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2639 bwn_lo_write(mac, &cal->ctl);
2643 bwn_mac_enable(mac);
2647 bwn_phy_g_task_60s(struct bwn_mac *mac)
2649 struct bwn_phy *phy = &mac->mac_phy;
2650 struct bwn_softc *sc = mac->mac_sc;
2651 uint8_t old = phy->chan;
2653 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2656 bwn_mac_suspend(mac);
2657 bwn_nrssi_slope_11g(mac);
2658 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2659 bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2660 bwn_switch_channel(mac, old);
2662 bwn_mac_enable(mac);
2666 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2669 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2673 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2674 const struct ieee80211_bpf_params *params)
2676 struct ieee80211com *ic = ni->ni_ic;
2677 struct ifnet *ifp = ic->ic_ifp;
2678 struct bwn_softc *sc = ifp->if_softc;
2679 struct bwn_mac *mac = sc->sc_curmac;
2681 if ((ifp->if_flags & IFF_RUNNING) == 0 ||
2682 mac->mac_status < BWN_MAC_STATUS_STARTED) {
2683 ieee80211_free_node(ni);
2688 if (bwn_tx_isfull(sc, m)) {
2689 ieee80211_free_node(ni);
2695 if (bwn_tx_start(sc, ni, m) != 0) {
2697 ieee80211_free_node(ni);
2700 sc->sc_watchdog_timer = 5;
2705 * Callback from the 802.11 layer to update the slot time
2706 * based on the current setting. We use it to notify the
2707 * firmware of ERP changes and the f/w takes care of things
2708 * like slot time and preamble.
2711 bwn_updateslot(struct ifnet *ifp)
2713 struct bwn_softc *sc = ifp->if_softc;
2714 struct ieee80211com *ic = ifp->if_l2com;
2715 struct bwn_mac *mac;
2717 if (ifp->if_flags & IFF_RUNNING) {
2718 mac = (struct bwn_mac *)sc->sc_curmac;
2719 bwn_set_slot_time(mac,
2720 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2725 * Callback from the 802.11 layer after a promiscuous mode change.
2726 * Note this interface does not check the operating mode as this
2727 * is an internal callback and we are expected to honor the current
2728 * state (e.g. this is used for setting the interface in promiscuous
2729 * mode when operating in hostap mode to do ACS).
2732 bwn_update_promisc(struct ifnet *ifp)
2734 struct bwn_softc *sc = ifp->if_softc;
2735 struct bwn_mac *mac = sc->sc_curmac;
2737 mac = sc->sc_curmac;
2738 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2739 if (ifp->if_flags & IFF_PROMISC)
2740 sc->sc_filters |= BWN_MACCTL_PROMISC;
2742 sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2743 bwn_set_opmode(mac);
2748 * Callback from the 802.11 layer to update WME parameters.
2751 bwn_wme_update(struct ieee80211com *ic)
2753 struct bwn_softc *sc = ic->ic_ifp->if_softc;
2754 struct bwn_mac *mac = sc->sc_curmac;
2755 struct wmeParams *wmep;
2758 mac = sc->sc_curmac;
2759 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2760 bwn_mac_suspend(mac);
2761 for (i = 0; i < N(sc->sc_wmeParams); i++) {
2762 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2763 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2765 bwn_mac_enable(mac);
2771 bwn_scan_start(struct ieee80211com *ic)
2773 struct ifnet *ifp = ic->ic_ifp;
2774 struct bwn_softc *sc = ifp->if_softc;
2775 struct bwn_mac *mac;
2777 mac = sc->sc_curmac;
2778 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2779 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2780 bwn_set_opmode(mac);
2781 /* disable CFP update during scan */
2782 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2787 bwn_scan_end(struct ieee80211com *ic)
2789 struct ifnet *ifp = ic->ic_ifp;
2790 struct bwn_softc *sc = ifp->if_softc;
2791 struct bwn_mac *mac;
2793 mac = sc->sc_curmac;
2794 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2795 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2796 bwn_set_opmode(mac);
2797 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2802 bwn_set_channel(struct ieee80211com *ic)
2804 struct ifnet *ifp = ic->ic_ifp;
2805 struct bwn_softc *sc = ifp->if_softc;
2806 struct bwn_mac *mac = sc->sc_curmac;
2807 struct bwn_phy *phy = &mac->mac_phy;
2810 error = bwn_switch_band(sc, ic->ic_curchan);
2813 bwn_mac_suspend(mac);
2814 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2815 chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2816 if (chan != phy->chan)
2817 bwn_switch_channel(mac, chan);
2819 /* TX power level */
2820 if (ic->ic_curchan->ic_maxpower != 0 &&
2821 ic->ic_curchan->ic_maxpower != phy->txpower) {
2822 phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2823 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2824 BWN_TXPWR_IGNORE_TSSI);
2827 bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2828 if (phy->set_antenna)
2829 phy->set_antenna(mac, BWN_ANT_DEFAULT);
2831 if (sc->sc_rf_enabled != phy->rf_on) {
2832 if (sc->sc_rf_enabled) {
2834 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2835 device_printf(sc->sc_dev,
2836 "please turn on the RF switch\n");
2838 bwn_rf_turnoff(mac);
2841 bwn_mac_enable(mac);
2845 * Setup radio tap channel freq and flags
2847 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2848 htole16(ic->ic_curchan->ic_freq);
2849 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2850 htole16(ic->ic_curchan->ic_flags & 0xffff);
2853 static struct ieee80211vap *
2854 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
2855 enum ieee80211_opmode opmode, int flags,
2856 const uint8_t bssid[IEEE80211_ADDR_LEN],
2857 const uint8_t mac0[IEEE80211_ADDR_LEN])
2859 struct ifnet *ifp = ic->ic_ifp;
2860 struct bwn_softc *sc = ifp->if_softc;
2861 struct ieee80211vap *vap;
2862 struct bwn_vap *bvp;
2863 uint8_t mac[IEEE80211_ADDR_LEN];
2865 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
2868 IEEE80211_ADDR_COPY(mac, mac0);
2870 case IEEE80211_M_HOSTAP:
2871 case IEEE80211_M_MBSS:
2872 case IEEE80211_M_STA:
2873 case IEEE80211_M_WDS:
2874 case IEEE80211_M_MONITOR:
2875 case IEEE80211_M_IBSS:
2876 case IEEE80211_M_AHDEMO:
2882 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
2884 bvp = (struct bwn_vap *) kmalloc(sizeof(struct bwn_vap),
2885 M_80211_VAP, M_INTWAIT | M_ZERO);
2887 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
2888 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
2889 /* override with driver methods */
2890 bvp->bv_newstate = vap->iv_newstate;
2891 vap->iv_newstate = bwn_newstate;
2893 /* override max aid so sta's cannot assoc when we're out of sta id's */
2894 vap->iv_max_aid = BWN_STAID_MAX;
2896 ieee80211_ratectl_init(vap);
2898 /* complete setup */
2899 ieee80211_vap_attach(vap, ieee80211_media_change,
2900 ieee80211_media_status);
2901 ic->ic_opmode = opmode;
2906 bwn_vap_delete(struct ieee80211vap *vap)
2908 struct bwn_vap *bvp = BWN_VAP(vap);
2910 ieee80211_ratectl_deinit(vap);
2911 ieee80211_vap_detach(vap);
2912 kfree(bvp, M_80211_VAP);
2918 struct bwn_softc *sc = arg;
2919 struct ifnet *ifp = sc->sc_ifp;
2920 struct ieee80211com *ic = ifp->if_l2com;
2923 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
2924 __func__, ifp->if_flags);
2926 wlan_assert_serialized();
2927 error = bwn_init_locked(sc);
2930 ieee80211_start_all(ic); /* start all vap's */
2934 bwn_init_locked(struct bwn_softc *sc)
2936 struct bwn_mac *mac;
2937 struct ifnet *ifp = sc->sc_ifp;
2940 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
2941 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
2944 sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
2945 sc->sc_rf_enabled = 1;
2947 mac = sc->sc_curmac;
2948 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
2949 error = bwn_core_init(mac);
2953 if (mac->mac_status == BWN_MAC_STATUS_INITED)
2954 bwn_core_start(mac);
2956 bwn_set_opmode(mac);
2957 bwn_set_pretbtt(mac);
2958 bwn_spu_setdelay(mac, 0);
2959 bwn_set_macaddr(mac);
2961 ifp->if_flags |= IFF_RUNNING;
2962 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
2963 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
2969 bwn_stop(struct bwn_softc *sc, int statechg)
2972 wlan_assert_serialized();
2973 bwn_stop_locked(sc, statechg);
2977 bwn_stop_locked(struct bwn_softc *sc, int statechg)
2979 struct bwn_mac *mac = sc->sc_curmac;
2980 struct ifnet *ifp = sc->sc_ifp;
2982 if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
2983 /* XXX FIXME opmode not based on VAP */
2984 bwn_set_opmode(mac);
2985 bwn_set_macaddr(mac);
2988 if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
2991 callout_stop(&sc->sc_led_blink_ch);
2992 sc->sc_led_blinking = 0;
2995 sc->sc_rf_enabled = 0;
2997 ifp->if_flags &= ~IFF_RUNNING;
2998 ifq_clr_oactive(&ifp->if_snd);
3002 bwn_wme_clear(struct bwn_softc *sc)
3004 #define MS(_v, _f) (((_v) & _f) >> _f##_S)
3005 struct wmeParams *p;
3008 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
3009 ("%s:%d: fail", __func__, __LINE__));
3011 for (i = 0; i < N(sc->sc_wmeParams); i++) {
3012 p = &(sc->sc_wmeParams[i]);
3014 switch (bwn_wme_shm_offsets[i]) {
3016 p->wmep_txopLimit = 0;
3018 /* XXX FIXME: log2(cwmin) */
3019 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3020 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3023 p->wmep_txopLimit = 0;
3025 /* XXX FIXME: log2(cwmin) */
3026 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3027 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3029 case BWN_WME_BESTEFFORT:
3030 p->wmep_txopLimit = 0;
3032 /* XXX FIXME: log2(cwmin) */
3033 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3034 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3036 case BWN_WME_BACKGROUND:
3037 p->wmep_txopLimit = 0;
3039 /* XXX FIXME: log2(cwmin) */
3040 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3041 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3044 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3050 bwn_core_init(struct bwn_mac *mac)
3052 struct bwn_softc *sc = mac->mac_sc;
3056 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3057 ("%s:%d: fail", __func__, __LINE__));
3059 siba_powerup(sc->sc_dev, 0);
3060 if (!siba_dev_isup(sc->sc_dev))
3062 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3064 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3065 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3066 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3067 BWN_GETTIME(mac->mac_phy.nexttime);
3068 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3069 bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3070 mac->mac_stats.link_noise = -95;
3071 mac->mac_reason_intr = 0;
3072 bzero(mac->mac_reason, sizeof(mac->mac_reason));
3073 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3075 if (sc->sc_debug & BWN_DEBUG_XMIT)
3076 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3078 mac->mac_suspended = 1;
3079 mac->mac_task_state = 0;
3080 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3082 mac->mac_phy.init_pre(mac);
3084 siba_pcicore_intr(sc->sc_dev);
3086 siba_fix_imcfglobug(sc->sc_dev);
3087 bwn_bt_disable(mac);
3088 if (mac->mac_phy.prepare_hw) {
3089 error = mac->mac_phy.prepare_hw(mac);
3093 error = bwn_chip_init(mac);
3096 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3097 siba_get_revid(sc->sc_dev));
3098 hf = bwn_hf_read(mac);
3099 if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3100 hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3101 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3102 hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3103 if (mac->mac_phy.rev == 1)
3104 hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3106 if (mac->mac_phy.rf_ver == 0x2050) {
3107 if (mac->mac_phy.rf_rev < 6)
3108 hf |= BWN_HF_FORCE_VCO_RECALC;
3109 if (mac->mac_phy.rf_rev == 6)
3110 hf |= BWN_HF_4318_TSSI;
3112 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3113 hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3114 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3115 (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3116 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3117 hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3118 bwn_hf_write(mac, hf);
3120 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3121 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3122 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3123 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3126 bwn_set_phytxctl(mac);
3128 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3129 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3130 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3132 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3137 bwn_spu_setdelay(mac, 1);
3140 siba_powerup(sc->sc_dev,
3141 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3142 bwn_set_macaddr(mac);
3143 bwn_crypt_init(mac);
3145 /* XXX LED initializatin */
3147 mac->mac_status = BWN_MAC_STATUS_INITED;
3152 siba_powerdown(sc->sc_dev);
3153 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3154 ("%s:%d: fail", __func__, __LINE__));
3159 bwn_core_start(struct bwn_mac *mac)
3161 struct bwn_softc *sc = mac->mac_sc;
3164 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3165 ("%s:%d: fail", __func__, __LINE__));
3167 if (siba_get_revid(sc->sc_dev) < 5)
3171 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3172 if (!(tmp & 0x00000001))
3174 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3177 bwn_mac_enable(mac);
3178 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3179 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3181 mac->mac_status = BWN_MAC_STATUS_STARTED;
3185 bwn_core_exit(struct bwn_mac *mac)
3187 struct bwn_softc *sc = mac->mac_sc;
3190 wlan_assert_serialized();
3192 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3193 ("%s:%d: fail", __func__, __LINE__));
3195 if (mac->mac_status != BWN_MAC_STATUS_INITED)
3197 mac->mac_status = BWN_MAC_STATUS_UNINIT;
3199 macctl = BWN_READ_4(mac, BWN_MACCTL);
3200 macctl &= ~BWN_MACCTL_MCODE_RUN;
3201 macctl |= BWN_MACCTL_MCODE_JMP0;
3202 BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3207 mac->mac_phy.switch_analog(mac, 0);
3208 siba_dev_down(sc->sc_dev, 0);
3209 siba_powerdown(sc->sc_dev);
3213 bwn_bt_disable(struct bwn_mac *mac)
3215 struct bwn_softc *sc = mac->mac_sc;
3218 /* XXX do nothing yet */
3222 bwn_chip_init(struct bwn_mac *mac)
3224 struct bwn_softc *sc = mac->mac_sc;
3225 struct bwn_phy *phy = &mac->mac_phy;
3229 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3231 macctl |= BWN_MACCTL_GMODE;
3232 BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3234 error = bwn_fw_fillinfo(mac);
3237 error = bwn_fw_loaducode(mac);
3241 error = bwn_gpio_init(mac);
3245 error = bwn_fw_loadinitvals(mac);
3247 siba_gpio_set(sc->sc_dev, 0);
3250 phy->switch_analog(mac, 1);
3251 error = bwn_phy_init(mac);
3253 siba_gpio_set(sc->sc_dev, 0);
3257 phy->set_im(mac, BWN_IMMODE_NONE);
3258 if (phy->set_antenna)
3259 phy->set_antenna(mac, BWN_ANT_DEFAULT);
3260 bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3262 if (phy->type == BWN_PHYTYPE_B)
3263 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3264 BWN_WRITE_4(mac, 0x0100, 0x01000000);
3265 if (siba_get_revid(sc->sc_dev) < 5)
3266 BWN_WRITE_4(mac, 0x010c, 0x01000000);
3268 BWN_WRITE_4(mac, BWN_MACCTL,
3269 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3270 BWN_WRITE_4(mac, BWN_MACCTL,
3271 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3272 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3274 bwn_set_opmode(mac);
3275 if (siba_get_revid(sc->sc_dev) < 3) {
3276 BWN_WRITE_2(mac, 0x060e, 0x0000);
3277 BWN_WRITE_2(mac, 0x0610, 0x8000);
3278 BWN_WRITE_2(mac, 0x0604, 0x0000);
3279 BWN_WRITE_2(mac, 0x0606, 0x0200);
3281 BWN_WRITE_4(mac, 0x0188, 0x80000000);
3282 BWN_WRITE_4(mac, 0x018c, 0x02000000);
3284 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3285 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001fc00);
3286 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3287 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3288 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3289 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3290 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3291 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3292 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3293 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3297 /* read hostflags */
3299 bwn_hf_read(struct bwn_mac *mac)
3303 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3305 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3307 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3312 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3315 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3316 (value & 0x00000000ffffull));
3317 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3318 (value & 0x0000ffff0000ull) >> 16);
3319 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3320 (value & 0xffff00000000ULL) >> 32);
3324 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3327 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3328 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3332 bwn_rate_init(struct bwn_mac *mac)
3335 switch (mac->mac_phy.type) {
3338 case BWN_PHYTYPE_LP:
3340 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3341 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3342 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3343 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3344 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3345 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3346 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3347 if (mac->mac_phy.type == BWN_PHYTYPE_A)
3351 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3352 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3353 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3354 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3357 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3362 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3368 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3371 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3373 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3374 bwn_shm_read_2(mac, BWN_SHARED, offset));
3378 bwn_plcp_getcck(const uint8_t bitrate)
3382 case BWN_CCK_RATE_1MB:
3384 case BWN_CCK_RATE_2MB:
3386 case BWN_CCK_RATE_5MB:
3388 case BWN_CCK_RATE_11MB:
3391 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3396 bwn_plcp_getofdm(const uint8_t bitrate)
3400 case BWN_OFDM_RATE_6MB:
3402 case BWN_OFDM_RATE_9MB:
3404 case BWN_OFDM_RATE_12MB:
3406 case BWN_OFDM_RATE_18MB:
3408 case BWN_OFDM_RATE_24MB:
3410 case BWN_OFDM_RATE_36MB:
3412 case BWN_OFDM_RATE_48MB:
3414 case BWN_OFDM_RATE_54MB:
3417 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3422 bwn_set_phytxctl(struct bwn_mac *mac)
3426 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3428 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3429 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3430 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3434 bwn_pio_init(struct bwn_mac *mac)
3436 struct bwn_pio *pio = &mac->mac_method.pio;
3438 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3439 & ~BWN_MACCTL_BIGENDIAN);
3440 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3442 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3443 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3444 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3445 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3446 bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3447 bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3451 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3454 struct bwn_pio_txpkt *tp;
3455 struct bwn_softc *sc = mac->mac_sc;
3458 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3459 tq->tq_index = index;
3461 tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3462 if (siba_get_revid(sc->sc_dev) >= 8)
3465 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3469 TAILQ_INIT(&tq->tq_pktlist);
3470 for (i = 0; i < N(tq->tq_pkts); i++) {
3471 tp = &(tq->tq_pkts[i]);
3474 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3479 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3481 struct bwn_softc *sc = mac->mac_sc;
3482 static const uint16_t bases[] = {
3492 static const uint16_t bases_rev11[] = {
3501 if (siba_get_revid(sc->sc_dev) >= 11) {
3502 if (index >= N(bases_rev11))
3503 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3504 return (bases_rev11[index]);
3506 if (index >= N(bases))
3507 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3508 return (bases[index]);
3512 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3515 struct bwn_softc *sc = mac->mac_sc;
3518 prq->prq_rev = siba_get_revid(sc->sc_dev);
3519 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3520 bwn_dma_rxdirectfifo(mac, index, 1);
3524 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3528 bwn_pio_cancel_tx_packets(tq);
3532 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3535 bwn_destroy_pioqueue_tx(pio);
3539 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3543 return (BWN_READ_2(mac, tq->tq_base + offset));
3547 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3553 type = bwn_dma_mask2type(bwn_dma_mask(mac));
3554 base = bwn_dma_base(type, idx);
3555 if (type == BWN_DMA_64BIT) {
3556 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3557 ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3559 ctl |= BWN_DMA64_RXDIRECTFIFO;
3560 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3562 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3563 ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3565 ctl |= BWN_DMA32_RXDIRECTFIFO;
3566 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3571 bwn_dma_mask(struct bwn_mac *mac)
3576 tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3577 if (tmp & SIBA_TGSHIGH_DMA64)
3578 return (BWN_DMA_BIT_MASK(64));
3579 base = bwn_dma_base(0, 0);
3580 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3581 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3582 if (tmp & BWN_DMA32_TXADDREXT_MASK)
3583 return (BWN_DMA_BIT_MASK(32));
3585 return (BWN_DMA_BIT_MASK(30));
3589 bwn_dma_mask2type(uint64_t dmamask)
3592 if (dmamask == BWN_DMA_BIT_MASK(30))
3593 return (BWN_DMA_30BIT);
3594 if (dmamask == BWN_DMA_BIT_MASK(32))
3595 return (BWN_DMA_32BIT);
3596 if (dmamask == BWN_DMA_BIT_MASK(64))
3597 return (BWN_DMA_64BIT);
3598 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3599 return (BWN_DMA_30BIT);
3603 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3605 struct bwn_pio_txpkt *tp;
3608 for (i = 0; i < N(tq->tq_pkts); i++) {
3609 tp = &(tq->tq_pkts[i]);
3618 bwn_dma_base(int type, int controller_idx)
3620 static const uint16_t map64[] = {
3628 static const uint16_t map32[] = {
3637 if (type == BWN_DMA_64BIT) {
3638 KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3639 ("%s:%d: fail", __func__, __LINE__));
3640 return (map64[controller_idx]);
3642 KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3643 ("%s:%d: fail", __func__, __LINE__));
3644 return (map32[controller_idx]);
3648 bwn_dma_init(struct bwn_mac *mac)
3650 struct bwn_dma *dma = &mac->mac_method.dma;
3652 /* setup TX DMA channels. */
3653 bwn_dma_setup(dma->wme[WME_AC_BK]);
3654 bwn_dma_setup(dma->wme[WME_AC_BE]);
3655 bwn_dma_setup(dma->wme[WME_AC_VI]);
3656 bwn_dma_setup(dma->wme[WME_AC_VO]);
3657 bwn_dma_setup(dma->mcast);
3658 /* setup RX DMA channel. */
3659 bwn_dma_setup(dma->rx);
3662 static struct bwn_dma_ring *
3663 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3664 int for_tx, int type)
3666 struct bwn_dma *dma = &mac->mac_method.dma;
3667 struct bwn_dma_ring *dr;
3668 struct bwn_dmadesc_generic *desc;
3669 struct bwn_dmadesc_meta *mt;
3670 struct bwn_softc *sc = mac->mac_sc;
3673 dr = kmalloc(sizeof(*dr), M_DEVBUF, M_INTWAIT | M_ZERO);
3674 dr->dr_numslots = BWN_RXRING_SLOTS;
3676 dr->dr_numslots = BWN_TXRING_SLOTS;
3678 dr->dr_meta = kmalloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3679 M_DEVBUF, M_INTWAIT | M_ZERO);
3683 dr->dr_base = bwn_dma_base(type, controller_index);
3684 dr->dr_index = controller_index;
3685 if (type == BWN_DMA_64BIT) {
3686 dr->getdesc = bwn_dma_64_getdesc;
3687 dr->setdesc = bwn_dma_64_setdesc;
3688 dr->start_transfer = bwn_dma_64_start_transfer;
3689 dr->suspend = bwn_dma_64_suspend;
3690 dr->resume = bwn_dma_64_resume;
3691 dr->get_curslot = bwn_dma_64_get_curslot;
3692 dr->set_curslot = bwn_dma_64_set_curslot;
3694 dr->getdesc = bwn_dma_32_getdesc;
3695 dr->setdesc = bwn_dma_32_setdesc;
3696 dr->start_transfer = bwn_dma_32_start_transfer;
3697 dr->suspend = bwn_dma_32_suspend;
3698 dr->resume = bwn_dma_32_resume;
3699 dr->get_curslot = bwn_dma_32_get_curslot;
3700 dr->set_curslot = bwn_dma_32_set_curslot;
3704 dr->dr_curslot = -1;
3706 if (dr->dr_index == 0) {
3707 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3708 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3710 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3713 error = bwn_dma_allocringmemory(dr);
3719 * Assumption: BWN_TXRING_SLOTS can be divided by
3720 * BWN_TX_SLOTS_PER_FRAME
3722 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3723 ("%s:%d: fail", __func__, __LINE__));
3726 * Create TX ring DMA stuffs
3728 dr->dr_txhdr_cache = bus_dmamem_coherent_any(dma->parent_dtag,
3729 4, (dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3730 BWN_MAX_HDRSIZE(mac),
3731 BUS_DMA_WAITOK | BUS_DMA_ZERO,
3732 &dr->dr_txring_dtag, &dr->dr_txring_dmap,
3733 &dr->dr_txring_paddr);
3734 if (dr->dr_txhdr_cache == NULL) {
3735 device_printf(sc->sc_dev,
3736 "can't create TX ring DMA memory\n");
3740 for (i = 0; i < dr->dr_numslots; i += 2) {
3741 dr->getdesc(dr, i, &desc, &mt);
3743 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3747 mt->mt_dmap = dr->dr_txring_dmap;
3748 mt->mt_paddr = dr->dr_txring_paddr +
3749 (i / BWN_TX_SLOTS_PER_FRAME) *
3750 BWN_MAX_HDRSIZE(mac);
3752 dr->getdesc(dr, i + 1, &desc, &mt);
3754 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3758 error = bus_dmamap_create(dma->txbuf_dtag, 0,
3761 device_printf(sc->sc_dev,
3762 "can't create RX buf DMA map\n");
3767 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3768 &dr->dr_spare_dmap);
3770 device_printf(sc->sc_dev,
3771 "can't create RX buf DMA map\n");
3772 goto out; /* XXX wrong! */
3775 for (i = 0; i < dr->dr_numslots; i++) {
3776 dr->getdesc(dr, i, &desc, &mt);
3778 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3781 device_printf(sc->sc_dev,
3782 "can't create RX buf DMA map\n");
3783 goto out; /* XXX wrong! */
3785 error = bwn_dma_newbuf(dr, desc, mt, 1);
3787 device_printf(sc->sc_dev,
3788 "failed to allocate RX buf\n");
3789 goto out; /* XXX wrong! */
3793 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3794 BUS_DMASYNC_PREWRITE);
3796 dr->dr_usedslot = dr->dr_numslots;
3803 /* XXX free up dma allocations */
3805 kfree(dr->dr_meta, M_DEVBUF);
3806 kfree(dr, M_DEVBUF);
3811 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3817 bwn_dma_free_descbufs(*dr);
3818 bwn_dma_free_ringmemory(*dr);
3820 if ((*dr)->dr_meta != NULL)
3821 kfree((*dr)->dr_meta, M_DEVBUF);
3822 kfree(*dr, M_DEVBUF);
3828 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3829 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3831 struct bwn_dmadesc32 *desc;
3833 *meta = &(dr->dr_meta[slot]);
3834 desc = dr->dr_ring_descbase;
3835 desc = &(desc[slot]);
3837 *gdesc = (struct bwn_dmadesc_generic *)desc;
3841 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3842 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3843 int start, int end, int irq)
3845 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3846 struct bwn_softc *sc = dr->dr_mac->mac_sc;
3847 uint32_t addr, addrext, ctl;
3850 slot = (int)(&(desc->dma.dma32) - descbase);
3851 KASSERT(slot >= 0 && slot < dr->dr_numslots,
3852 ("%s:%d: fail", __func__, __LINE__));
3854 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
3855 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
3856 addr |= siba_dma_translation(sc->sc_dev);
3857 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3858 if (slot == dr->dr_numslots - 1)
3859 ctl |= BWN_DMA32_DCTL_DTABLEEND;
3861 ctl |= BWN_DMA32_DCTL_FRAMESTART;
3863 ctl |= BWN_DMA32_DCTL_FRAMEEND;
3865 ctl |= BWN_DMA32_DCTL_IRQ;
3866 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3867 & BWN_DMA32_DCTL_ADDREXT_MASK;
3869 desc->dma.dma32.control = htole32(ctl);
3870 desc->dma.dma32.address = htole32(addr);
3874 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3877 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3878 (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3882 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3885 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3886 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3890 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3893 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3894 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
3898 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
3902 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
3903 val &= BWN_DMA32_RXDPTR;
3905 return (val / sizeof(struct bwn_dmadesc32));
3909 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
3912 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
3913 (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
3917 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
3918 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3920 struct bwn_dmadesc64 *desc;
3922 *meta = &(dr->dr_meta[slot]);
3923 desc = dr->dr_ring_descbase;
3924 desc = &(desc[slot]);
3926 *gdesc = (struct bwn_dmadesc_generic *)desc;
3930 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
3931 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3932 int start, int end, int irq)
3934 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
3935 struct bwn_softc *sc = dr->dr_mac->mac_sc;
3937 uint32_t ctl0 = 0, ctl1 = 0;
3938 uint32_t addrlo, addrhi;
3941 slot = (int)(&(desc->dma.dma64) - descbase);
3942 KASSERT(slot >= 0 && slot < dr->dr_numslots,
3943 ("%s:%d: fail", __func__, __LINE__));
3945 addrlo = (uint32_t) (dmaaddr & 0xffffffff);
3946 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
3947 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
3949 addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
3950 if (slot == dr->dr_numslots - 1)
3951 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
3953 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
3955 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
3957 ctl0 |= BWN_DMA64_DCTL0_IRQ;
3958 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
3959 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
3960 & BWN_DMA64_DCTL1_ADDREXT_MASK;
3962 desc->dma.dma64.control0 = htole32(ctl0);
3963 desc->dma.dma64.control1 = htole32(ctl1);
3964 desc->dma.dma64.address_low = htole32(addrlo);
3965 desc->dma.dma64.address_high = htole32(addrhi);
3969 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
3972 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
3973 (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
3977 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
3980 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
3981 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
3985 bwn_dma_64_resume(struct bwn_dma_ring *dr)
3988 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
3989 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
3993 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
3997 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
3998 val &= BWN_DMA64_RXSTATDPTR;
4000 return (val / sizeof(struct bwn_dmadesc64));
4004 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4007 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4008 (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4012 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4014 struct bwn_mac *mac = dr->dr_mac;
4015 struct bwn_dma *dma = &mac->mac_method.dma;
4016 struct bwn_softc *sc = mac->mac_sc;
4019 error = bus_dma_tag_create(dma->parent_dtag,
4024 BWN_DMA_RINGMEMSIZE,
4026 BUS_SPACE_MAXSIZE_32BIT,
4030 device_printf(sc->sc_dev,
4031 "can't create TX ring DMA tag: TODO frees\n");
4035 error = bus_dmamem_alloc(dr->dr_ring_dtag,
4036 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4039 device_printf(sc->sc_dev,
4040 "can't allocate DMA mem: TODO frees\n");
4043 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4044 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4045 bwn_dma_ring_addr, &dr->dr_ring_dmabase, 0);
4047 device_printf(sc->sc_dev,
4048 "can't load DMA mem: TODO free\n");
4056 bwn_dma_setup(struct bwn_dma_ring *dr)
4058 struct bwn_softc *sc = dr->dr_mac->mac_sc;
4060 uint32_t addrext, ring32, value;
4061 uint32_t trans = siba_dma_translation(sc->sc_dev);
4064 dr->dr_curslot = -1;
4066 if (dr->dr_type == BWN_DMA_64BIT) {
4067 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4068 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4070 value = BWN_DMA64_TXENABLE;
4071 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4072 & BWN_DMA64_TXADDREXT_MASK;
4073 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4074 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4075 (ring64 & 0xffffffff));
4076 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4078 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4080 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4081 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4082 value = BWN_DMA32_TXENABLE;
4083 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4084 & BWN_DMA32_TXADDREXT_MASK;
4085 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4086 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4087 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4095 dr->dr_usedslot = dr->dr_numslots;
4097 if (dr->dr_type == BWN_DMA_64BIT) {
4098 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4099 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4100 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4101 value |= BWN_DMA64_RXENABLE;
4102 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4103 & BWN_DMA64_RXADDREXT_MASK;
4104 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4105 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4106 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4107 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4109 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4110 sizeof(struct bwn_dmadesc64));
4112 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4113 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4114 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4115 value |= BWN_DMA32_RXENABLE;
4116 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4117 & BWN_DMA32_RXADDREXT_MASK;
4118 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4119 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4120 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4121 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4122 sizeof(struct bwn_dmadesc32));
4127 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4131 bus_dmamap_unload(dr->dr_txring_dtag, dr->dr_txring_dmap);
4132 if (dr->dr_txhdr_cache != NULL)
4133 bus_dmamem_free(dr->dr_txring_dtag, dr->dr_txhdr_cache,
4134 dr->dr_txring_dmap);
4135 bus_dma_tag_destroy(dr->dr_txring_dtag);
4137 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4138 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4140 bus_dma_tag_destroy(dr->dr_ring_dtag);
4144 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4148 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4149 if (dr->dr_type == BWN_DMA_64BIT) {
4150 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4151 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4153 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4155 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4156 if (dr->dr_type == BWN_DMA_64BIT) {
4157 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4158 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4160 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4165 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4167 struct bwn_dmadesc_generic *desc;
4168 struct bwn_dmadesc_meta *meta;
4169 struct bwn_mac *mac = dr->dr_mac;
4170 struct bwn_dma *dma = &mac->mac_method.dma;
4171 struct bwn_softc *sc = mac->mac_sc;
4174 if (!dr->dr_usedslot)
4176 for (i = 0; i < dr->dr_numslots; i++) {
4177 dr->getdesc(dr, i, &desc, &meta);
4179 if (meta->mt_m == NULL) {
4181 device_printf(sc->sc_dev, "%s: not TX?\n",
4186 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) {
4188 } else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) {
4189 bus_dmamap_unload(dma->txbuf_dtag,
4193 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4194 bwn_dma_free_descbuf(dr, meta);
4199 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4202 struct bwn_softc *sc = mac->mac_sc;
4207 for (i = 0; i < 10; i++) {
4208 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4210 value = BWN_READ_4(mac, base + offset);
4211 if (type == BWN_DMA_64BIT) {
4212 value &= BWN_DMA64_TXSTAT;
4213 if (value == BWN_DMA64_TXSTAT_DISABLED ||
4214 value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4215 value == BWN_DMA64_TXSTAT_STOPPED)
4218 value &= BWN_DMA32_TXSTATE;
4219 if (value == BWN_DMA32_TXSTAT_DISABLED ||
4220 value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4221 value == BWN_DMA32_TXSTAT_STOPPED)
4226 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4227 BWN_WRITE_4(mac, base + offset, 0);
4228 for (i = 0; i < 10; i++) {
4229 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4231 value = BWN_READ_4(mac, base + offset);
4232 if (type == BWN_DMA_64BIT) {
4233 value &= BWN_DMA64_TXSTAT;
4234 if (value == BWN_DMA64_TXSTAT_DISABLED) {
4239 value &= BWN_DMA32_TXSTATE;
4240 if (value == BWN_DMA32_TXSTAT_DISABLED) {
4248 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4257 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4260 struct bwn_softc *sc = mac->mac_sc;
4265 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4266 BWN_WRITE_4(mac, base + offset, 0);
4267 for (i = 0; i < 10; i++) {
4268 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4270 value = BWN_READ_4(mac, base + offset);
4271 if (type == BWN_DMA_64BIT) {
4272 value &= BWN_DMA64_RXSTAT;
4273 if (value == BWN_DMA64_RXSTAT_DISABLED) {
4278 value &= BWN_DMA32_RXSTATE;
4279 if (value == BWN_DMA32_RXSTAT_DISABLED) {
4287 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4295 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4296 struct bwn_dmadesc_meta *meta)
4299 if (meta->mt_m != NULL) {
4300 m_freem(meta->mt_m);
4303 if (meta->mt_ni != NULL) {
4304 ieee80211_free_node(meta->mt_ni);
4310 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4312 struct bwn_rxhdr4 *rxhdr;
4313 unsigned char *frame;
4315 rxhdr = mtod(m, struct bwn_rxhdr4 *);
4316 rxhdr->frame_len = 0;
4318 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4319 sizeof(struct bwn_plcp6) + 2,
4320 ("%s:%d: fail", __func__, __LINE__));
4321 frame = mtod(m, char *) + dr->dr_frameoffset;
4322 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4326 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4328 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4330 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4335 bwn_wme_init(struct bwn_mac *mac)
4340 /* enable WME support. */
4341 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4342 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4343 BWN_IFSCTL_USE_EDCF);
4347 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4349 struct bwn_softc *sc = mac->mac_sc;
4350 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
4351 uint16_t delay; /* microsec */
4353 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4354 if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4356 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4357 delay = max(delay, (uint16_t)2400);
4359 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4363 bwn_bt_enable(struct bwn_mac *mac)
4365 struct bwn_softc *sc = mac->mac_sc;
4368 if (bwn_bluetooth == 0)
4370 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4372 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4375 hf = bwn_hf_read(mac);
4376 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4377 hf |= BWN_HF_BT_COEXISTALT;
4379 hf |= BWN_HF_BT_COEXIST;
4380 bwn_hf_write(mac, hf);
4384 bwn_set_macaddr(struct bwn_mac *mac)
4387 bwn_mac_write_bssid(mac);
4388 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
4392 bwn_clear_keys(struct bwn_mac *mac)
4396 for (i = 0; i < mac->mac_max_nr_keys; i++) {
4397 KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4398 ("%s:%d: fail", __func__, __LINE__));
4400 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4401 NULL, BWN_SEC_KEYSIZE, NULL);
4402 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4403 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4404 NULL, BWN_SEC_KEYSIZE, NULL);
4406 mac->mac_key[i].keyconf = NULL;
4411 bwn_crypt_init(struct bwn_mac *mac)
4413 struct bwn_softc *sc = mac->mac_sc;
4415 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4416 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4417 ("%s:%d: fail", __func__, __LINE__));
4418 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4420 if (siba_get_revid(sc->sc_dev) >= 5)
4421 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4422 bwn_clear_keys(mac);
4426 bwn_chip_exit(struct bwn_mac *mac)
4428 struct bwn_softc *sc = mac->mac_sc;
4431 siba_gpio_set(sc->sc_dev, 0);
4435 bwn_fw_fillinfo(struct bwn_mac *mac)
4439 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4442 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4449 bwn_gpio_init(struct bwn_mac *mac)
4451 struct bwn_softc *sc = mac->mac_sc;
4452 uint32_t mask = 0x1f, set = 0xf, value;
4454 BWN_WRITE_4(mac, BWN_MACCTL,
4455 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4456 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4457 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4459 if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4463 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4464 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4465 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4469 if (siba_get_revid(sc->sc_dev) >= 2)
4472 value = siba_gpio_get(sc->sc_dev);
4475 siba_gpio_set(sc->sc_dev, (value & mask) | set);
4481 bwn_fw_loadinitvals(struct bwn_mac *mac)
4483 #define GETFWOFFSET(fwp, offset) \
4484 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4485 const size_t hdr_len = sizeof(struct bwn_fwhdr);
4486 const struct bwn_fwhdr *hdr;
4487 struct bwn_fw *fw = &mac->mac_fw;
4490 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4491 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4492 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4495 if (fw->initvals_band.fw) {
4496 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4497 error = bwn_fwinitvals_write(mac,
4498 GETFWOFFSET(fw->initvals_band, hdr_len),
4500 fw->initvals_band.fw->datasize - hdr_len);
4507 bwn_phy_init(struct bwn_mac *mac)
4509 struct bwn_softc *sc = mac->mac_sc;
4512 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4513 mac->mac_phy.rf_onoff(mac, 1);
4514 error = mac->mac_phy.init(mac);
4516 device_printf(sc->sc_dev, "PHY init failed\n");
4519 error = bwn_switch_channel(mac,
4520 mac->mac_phy.get_default_chan(mac));
4522 device_printf(sc->sc_dev,
4523 "failed to switch default channel\n");
4528 if (mac->mac_phy.exit)
4529 mac->mac_phy.exit(mac);
4531 mac->mac_phy.rf_onoff(mac, 0);
4537 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4542 ant = bwn_ant2phy(antenna);
4545 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4546 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4547 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4548 /* For Probe Resposes */
4549 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4550 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4551 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4555 bwn_set_opmode(struct bwn_mac *mac)
4557 struct bwn_softc *sc = mac->mac_sc;
4558 struct ifnet *ifp = sc->sc_ifp;
4559 struct ieee80211com *ic = ifp->if_l2com;
4561 uint16_t cfp_pretbtt;
4563 ctl = BWN_READ_4(mac, BWN_MACCTL);
4564 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4565 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4566 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4567 ctl |= BWN_MACCTL_STA;
4569 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4570 ic->ic_opmode == IEEE80211_M_MBSS)
4571 ctl |= BWN_MACCTL_HOSTAP;
4572 else if (ic->ic_opmode == IEEE80211_M_IBSS)
4573 ctl &= ~BWN_MACCTL_STA;
4574 ctl |= sc->sc_filters;
4576 if (siba_get_revid(sc->sc_dev) <= 4)
4577 ctl |= BWN_MACCTL_PROMISC;
4579 BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4582 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4583 if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4584 siba_get_chiprev(sc->sc_dev) == 3)
4589 BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4593 bwn_dma_gettype(struct bwn_mac *mac)
4598 tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4599 if (tmp & SIBA_TGSHIGH_DMA64)
4600 return (BWN_DMA_64BIT);
4601 base = bwn_dma_base(0, 0);
4602 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4603 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4604 if (tmp & BWN_DMA32_TXADDREXT_MASK)
4605 return (BWN_DMA_32BIT);
4607 return (BWN_DMA_30BIT);
4611 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4614 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4615 *((bus_addr_t *)arg) = seg->ds_addr;
4620 bwn_phy_g_init_sub(struct bwn_mac *mac)
4622 struct bwn_phy *phy = &mac->mac_phy;
4623 struct bwn_phy_g *pg = &phy->phy_g;
4624 struct bwn_softc *sc = mac->mac_sc;
4628 bwn_phy_init_b5(mac);
4630 bwn_phy_init_b6(mac);
4632 if (phy->rev >= 2 || phy->gmode)
4633 bwn_phy_init_a(mac);
4635 if (phy->rev >= 2) {
4636 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4637 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4639 if (phy->rev == 2) {
4640 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4641 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4644 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4645 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4647 if (phy->gmode || phy->rev >= 2) {
4648 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4649 tmp &= BWN_PHYVER_VERSION;
4650 if (tmp == 3 || tmp == 5) {
4651 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4652 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4655 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4659 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4660 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4661 if (phy->rf_rev == 8) {
4662 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4663 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4665 if (BWN_HAS_LOOPBACK(phy))
4666 bwn_loopback_calcgain(mac);
4668 if (phy->rf_rev != 8) {
4669 if (pg->pg_initval == 0xffff)
4670 pg->pg_initval = bwn_rf_init_bcm2050(mac);
4672 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4675 if (BWN_HAS_TXMAG(phy)) {
4676 BWN_RF_WRITE(mac, 0x52,
4677 (BWN_RF_READ(mac, 0x52) & 0xff00)
4678 | pg->pg_loctl.tx_bias |
4679 pg->pg_loctl.tx_magn);
4681 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4683 if (phy->rev >= 6) {
4684 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4685 (pg->pg_loctl.tx_bias << 12));
4687 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4688 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4690 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4692 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4694 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4695 if (phy->gmode || phy->rev >= 2) {
4696 bwn_lo_g_adjust(mac);
4697 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4700 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4701 for (i = 0; i < 64; i++) {
4702 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4703 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4704 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4707 bwn_nrssi_threshold(mac);
4708 } else if (phy->gmode || phy->rev >= 2) {
4709 if (pg->pg_nrssi[0] == -1000) {
4710 KASSERT(pg->pg_nrssi[1] == -1000,
4711 ("%s:%d: fail", __func__, __LINE__));
4712 bwn_nrssi_slope_11g(mac);
4714 bwn_nrssi_threshold(mac);
4716 if (phy->rf_rev == 8)
4717 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4718 bwn_phy_hwpctl_init(mac);
4719 if ((siba_get_chipid(sc->sc_dev) == 0x4306
4720 && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4721 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4722 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4727 bwn_has_hwpctl(struct bwn_mac *mac)
4730 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4732 return (mac->mac_phy.use_hwpctl(mac));
4736 bwn_phy_init_b5(struct bwn_mac *mac)
4738 struct bwn_phy *phy = &mac->mac_phy;
4739 struct bwn_phy_g *pg = &phy->phy_g;
4740 struct bwn_softc *sc = mac->mac_sc;
4741 uint16_t offset, value;
4742 uint8_t old_channel;
4744 if (phy->analog == 1)
4745 BWN_RF_SET(mac, 0x007a, 0x0050);
4746 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4747 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4749 for (offset = 0x00a8; offset < 0x00c7; offset++) {
4750 BWN_PHY_WRITE(mac, offset, value);
4754 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4755 if (phy->rf_ver == 0x2050)
4756 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4758 if (phy->gmode || phy->rev >= 2) {
4759 if (phy->rf_ver == 0x2050) {
4760 BWN_RF_SET(mac, 0x007a, 0x0020);
4761 BWN_RF_SET(mac, 0x0051, 0x0004);
4763 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4765 BWN_PHY_SET(mac, 0x0802, 0x0100);
4766 BWN_PHY_SET(mac, 0x042b, 0x2000);
4768 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4770 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4771 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4772 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4775 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4776 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4778 if (phy->analog == 1) {
4779 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4780 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4781 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4782 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4783 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4785 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4786 BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4787 BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4789 if (phy->analog == 1)
4790 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4792 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4794 if (phy->analog == 0)
4795 BWN_WRITE_2(mac, 0x03e4, 0x3000);
4797 old_channel = phy->chan;
4798 bwn_phy_g_switch_chan(mac, 7, 0);
4800 if (phy->rf_ver != 0x2050) {
4801 BWN_RF_WRITE(mac, 0x0075, 0x0080);
4802 BWN_RF_WRITE(mac, 0x0079, 0x0081);
4805 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4806 BWN_RF_WRITE(mac, 0x0050, 0x0023);
4808 if (phy->rf_ver == 0x2050) {
4809 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4810 BWN_RF_WRITE(mac, 0x005a, 0x0070);
4813 BWN_RF_WRITE(mac, 0x005b, 0x007b);
4814 BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4815 BWN_RF_SET(mac, 0x007a, 0x0007);
4817 bwn_phy_g_switch_chan(mac, old_channel, 0);
4818 BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4819 BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4820 BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4822 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4825 if (phy->rf_ver == 0x2050)
4826 BWN_RF_WRITE(mac, 0x005d, 0x000d);
4828 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4832 bwn_loopback_calcgain(struct bwn_mac *mac)
4834 struct bwn_phy *phy = &mac->mac_phy;
4835 struct bwn_phy_g *pg = &phy->phy_g;
4836 struct bwn_softc *sc = mac->mac_sc;
4837 uint16_t backup_phy[16] = { 0 };
4838 uint16_t backup_radio[3];
4839 uint16_t backup_bband;
4840 uint16_t i, j, loop_i_max;
4842 uint16_t loop1_outer_done, loop1_inner_done;
4844 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4845 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4846 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4847 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4848 if (phy->rev != 1) {
4849 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4850 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4852 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4853 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4854 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4855 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4856 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4857 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4858 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4859 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4860 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4861 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4862 backup_bband = pg->pg_bbatt.att;
4863 backup_radio[0] = BWN_RF_READ(mac, 0x52);
4864 backup_radio[1] = BWN_RF_READ(mac, 0x43);
4865 backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4867 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4868 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4869 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4870 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4871 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4872 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4873 if (phy->rev != 1) {
4874 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4875 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4876 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4877 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4879 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4880 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4881 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4882 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4884 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4885 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4886 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4888 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4889 if (phy->rev != 1) {
4890 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4891 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4893 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4895 if (phy->rf_rev == 8)
4896 BWN_RF_WRITE(mac, 0x43, 0x000f);
4898 BWN_RF_WRITE(mac, 0x52, 0);
4899 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4901 bwn_phy_g_set_bbatt(mac, 11);
4904 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
4906 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
4907 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
4909 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
4910 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
4912 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
4913 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
4915 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
4916 if (phy->rev >= 7) {
4917 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
4918 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
4921 BWN_RF_MASK(mac, 0x7a, 0x00f7);
4924 loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
4925 for (i = 0; i < loop_i_max; i++) {
4926 for (j = 0; j < 16; j++) {
4927 BWN_RF_WRITE(mac, 0x43, i);
4928 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
4930 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4931 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4933 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4938 loop1_outer_done = i;
4939 loop1_inner_done = j;
4941 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
4943 for (j = j - 8; j < 16; j++) {
4944 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
4945 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4946 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4949 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4956 if (phy->rev != 1) {
4957 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
4958 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
4960 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
4961 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
4962 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
4963 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
4964 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
4965 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
4966 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
4967 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
4968 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
4970 bwn_phy_g_set_bbatt(mac, backup_bband);
4972 BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
4973 BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
4974 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
4976 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
4978 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
4979 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
4980 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
4981 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
4983 pg->pg_max_lb_gain =
4984 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
4985 pg->pg_trsw_rx_gain = trsw_rx * 2;
4989 bwn_rf_init_bcm2050(struct bwn_mac *mac)
4991 struct bwn_phy *phy = &mac->mac_phy;
4992 uint32_t tmp1 = 0, tmp2 = 0;
4993 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
4994 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
4995 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
4996 static const uint8_t rcc_table[] = {
4997 0x02, 0x03, 0x01, 0x0f,
4998 0x06, 0x07, 0x05, 0x0f,
4999 0x0a, 0x0b, 0x09, 0x0f,
5000 0x0e, 0x0f, 0x0d, 0x0f,
5003 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
5004 rfoverval = rfover = cck3 = 0;
5005 radio0 = BWN_RF_READ(mac, 0x43);
5006 radio1 = BWN_RF_READ(mac, 0x51);
5007 radio2 = BWN_RF_READ(mac, 0x52);
5008 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5009 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5010 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5011 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5013 if (phy->type == BWN_PHYTYPE_B) {
5014 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5015 reg0 = BWN_READ_2(mac, 0x3ec);
5017 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5018 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5019 } else if (phy->gmode || phy->rev >= 2) {
5020 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5021 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5022 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5023 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5024 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5025 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5027 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5028 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5029 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5030 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5031 if (BWN_HAS_LOOPBACK(phy)) {
5032 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5033 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5035 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5037 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5038 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5041 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5042 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5044 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5045 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5047 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5049 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5050 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5051 reg1 = BWN_READ_2(mac, 0x3e6);
5052 reg2 = BWN_READ_2(mac, 0x3f4);
5054 if (phy->analog == 0)
5055 BWN_WRITE_2(mac, 0x03e6, 0x0122);
5057 if (phy->analog >= 2)
5058 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5059 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5060 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5063 reg = BWN_RF_READ(mac, 0x60);
5064 index = (reg & 0x001e) >> 1;
5065 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5067 if (phy->type == BWN_PHYTYPE_B)
5068 BWN_RF_WRITE(mac, 0x78, 0x26);
5069 if (phy->gmode || phy->rev >= 2) {
5070 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5071 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5074 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5075 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5076 if (phy->gmode || phy->rev >= 2) {
5077 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5078 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5081 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5082 BWN_RF_SET(mac, 0x51, 0x0004);
5083 if (phy->rf_rev == 8)
5084 BWN_RF_WRITE(mac, 0x43, 0x1f);
5086 BWN_RF_WRITE(mac, 0x52, 0);
5087 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5089 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5091 for (i = 0; i < 16; i++) {
5092 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5093 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5094 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5095 if (phy->gmode || phy->rev >= 2) {
5096 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5097 bwn_rf_2050_rfoverval(mac,
5098 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5100 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5102 if (phy->gmode || phy->rev >= 2) {
5103 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5104 bwn_rf_2050_rfoverval(mac,
5105 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5107 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5109 if (phy->gmode || phy->rev >= 2) {
5110 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5111 bwn_rf_2050_rfoverval(mac,
5112 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5114 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5116 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5117 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5118 if (phy->gmode || phy->rev >= 2) {
5119 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5120 bwn_rf_2050_rfoverval(mac,
5121 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5123 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5127 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5131 for (i = 0; i < 16; i++) {
5132 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5133 BWN_RF_WRITE(mac, 0x78, radio78);
5135 for (j = 0; j < 16; j++) {
5136 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5137 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5138 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5139 if (phy->gmode || phy->rev >= 2) {
5140 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5141 bwn_rf_2050_rfoverval(mac,
5142 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5144 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5146 if (phy->gmode || phy->rev >= 2) {
5147 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5148 bwn_rf_2050_rfoverval(mac,
5149 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5151 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5153 if (phy->gmode || phy->rev >= 2) {
5154 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5155 bwn_rf_2050_rfoverval(mac,
5156 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5158 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5160 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5161 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5162 if (phy->gmode || phy->rev >= 2) {
5163 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5164 bwn_rf_2050_rfoverval(mac,
5165 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5167 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5175 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5176 BWN_RF_WRITE(mac, 0x51, radio1);
5177 BWN_RF_WRITE(mac, 0x52, radio2);
5178 BWN_RF_WRITE(mac, 0x43, radio0);
5179 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5180 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5181 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5182 BWN_WRITE_2(mac, 0x3e6, reg1);
5183 if (phy->analog != 0)
5184 BWN_WRITE_2(mac, 0x3f4, reg2);
5185 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5186 bwn_spu_workaround(mac, phy->chan);
5187 if (phy->type == BWN_PHYTYPE_B) {
5188 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5189 BWN_WRITE_2(mac, 0x3ec, reg0);
5190 } else if (phy->gmode) {
5191 BWN_WRITE_2(mac, BWN_PHY_RADIO,
5192 BWN_READ_2(mac, BWN_PHY_RADIO)
5194 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5195 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5196 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5197 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5199 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5200 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5201 if (BWN_HAS_LOOPBACK(phy)) {
5202 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5203 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5207 return ((i > 15) ? radio78 : rcc);
5211 bwn_phy_init_b6(struct bwn_mac *mac)
5213 struct bwn_phy *phy = &mac->mac_phy;
5214 struct bwn_phy_g *pg = &phy->phy_g;
5215 struct bwn_softc *sc = mac->mac_sc;
5216 uint16_t offset, val;
5217 uint8_t old_channel;
5219 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5220 ("%s:%d: fail", __func__, __LINE__));
5222 BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5223 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5224 if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5225 BWN_RF_WRITE(mac, 0x51, 0x37);
5226 BWN_RF_WRITE(mac, 0x52, 0x70);
5227 BWN_RF_WRITE(mac, 0x53, 0xb3);
5228 BWN_RF_WRITE(mac, 0x54, 0x9b);
5229 BWN_RF_WRITE(mac, 0x5a, 0x88);
5230 BWN_RF_WRITE(mac, 0x5b, 0x88);
5231 BWN_RF_WRITE(mac, 0x5d, 0x88);
5232 BWN_RF_WRITE(mac, 0x5e, 0x88);
5233 BWN_RF_WRITE(mac, 0x7d, 0x88);
5235 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5237 if (phy->rf_rev == 8) {
5238 BWN_RF_WRITE(mac, 0x51, 0);
5239 BWN_RF_WRITE(mac, 0x52, 0x40);
5240 BWN_RF_WRITE(mac, 0x53, 0xb7);
5241 BWN_RF_WRITE(mac, 0x54, 0x98);
5242 BWN_RF_WRITE(mac, 0x5a, 0x88);
5243 BWN_RF_WRITE(mac, 0x5b, 0x6b);
5244 BWN_RF_WRITE(mac, 0x5c, 0x0f);
5245 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5246 BWN_RF_WRITE(mac, 0x5d, 0xfa);
5247 BWN_RF_WRITE(mac, 0x5e, 0xd8);
5249 BWN_RF_WRITE(mac, 0x5d, 0xf5);
5250 BWN_RF_WRITE(mac, 0x5e, 0xb8);
5252 BWN_RF_WRITE(mac, 0x0073, 0x0003);
5253 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5254 BWN_RF_WRITE(mac, 0x007c, 0x0001);
5255 BWN_RF_WRITE(mac, 0x007e, 0x0008);
5257 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5258 BWN_PHY_WRITE(mac, offset, val);
5261 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5262 BWN_PHY_WRITE(mac, offset, val);
5265 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5266 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5269 if (phy->type == BWN_PHYTYPE_G) {
5270 BWN_RF_SET(mac, 0x007a, 0x0020);
5271 BWN_RF_SET(mac, 0x0051, 0x0004);
5272 BWN_PHY_SET(mac, 0x0802, 0x0100);
5273 BWN_PHY_SET(mac, 0x042b, 0x2000);
5274 BWN_PHY_WRITE(mac, 0x5b, 0);
5275 BWN_PHY_WRITE(mac, 0x5c, 0);
5278 old_channel = phy->chan;
5279 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5281 BWN_RF_WRITE(mac, 0x0050, 0x0020);
5282 BWN_RF_WRITE(mac, 0x0050, 0x0023);
5284 if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5285 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5286 BWN_RF_WRITE(mac, 0x50, 0x20);
5288 if (phy->rf_rev <= 2) {
5289 BWN_RF_WRITE(mac, 0x7c, 0x20);
5290 BWN_RF_WRITE(mac, 0x5a, 0x70);
5291 BWN_RF_WRITE(mac, 0x5b, 0x7b);
5292 BWN_RF_WRITE(mac, 0x5c, 0xb0);
5294 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5296 bwn_phy_g_switch_chan(mac, old_channel, 0);
5298 BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5299 if (phy->rf_rev >= 6)
5300 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5302 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5303 BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5304 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5306 if (phy->rf_rev <= 5)
5307 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5308 if (phy->rf_rev <= 2)
5309 BWN_RF_WRITE(mac, 0x005d, 0x000d);
5311 if (phy->analog == 4) {
5312 BWN_WRITE_2(mac, 0x3e4, 9);
5313 BWN_PHY_MASK(mac, 0x61, 0x0fff);
5315 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5316 if (phy->type == BWN_PHYTYPE_B)
5317 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5318 else if (phy->type == BWN_PHYTYPE_G)
5319 BWN_WRITE_2(mac, 0x03e6, 0x0);
5323 bwn_phy_init_a(struct bwn_mac *mac)
5325 struct bwn_phy *phy = &mac->mac_phy;
5326 struct bwn_softc *sc = mac->mac_sc;
5328 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5329 ("%s:%d: fail", __func__, __LINE__));
5331 if (phy->rev >= 6) {
5332 if (phy->type == BWN_PHYTYPE_A)
5333 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5334 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5335 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5337 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5342 if (phy->type == BWN_PHYTYPE_G &&
5343 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5344 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5348 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5352 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5353 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5357 bwn_wa_agc(struct bwn_mac *mac)
5359 struct bwn_phy *phy = &mac->mac_phy;
5361 if (phy->rev == 1) {
5362 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5363 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5364 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5365 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5366 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5367 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5368 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5369 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5370 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5372 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5373 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5374 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5375 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5378 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5380 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5381 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5382 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5383 BWN_RF_SET(mac, 0x7a, 0x0008);
5384 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5385 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5386 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5387 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5389 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5390 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5391 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5392 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5393 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5394 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5395 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5396 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5397 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5398 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5399 if (phy->rev == 1) {
5400 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5401 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5403 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5404 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5405 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5406 if (phy->rev >= 6) {
5407 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5408 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5409 (uint16_t)~0xf000, 0x3000);
5412 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5413 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5414 if (phy->rev == 1) {
5415 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5416 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5417 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5418 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5419 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5420 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5421 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5422 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5424 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5425 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5426 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5427 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5429 if (phy->rev >= 6) {
5430 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5431 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5433 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5437 bwn_wa_grev1(struct bwn_mac *mac)
5439 struct bwn_phy *phy = &mac->mac_phy;
5441 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5442 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5443 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5445 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5447 /* init CRSTHRES and ANTDWELL */
5448 if (phy->rev == 1) {
5449 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5450 } else if (phy->rev == 2) {
5451 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5452 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5453 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5455 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5456 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5457 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5458 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5460 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5461 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5462 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5464 /* XXX support PHY-A??? */
5465 for (i = 0; i < N(bwn_tab_finefreqg); i++)
5466 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5467 bwn_tab_finefreqg[i]);
5469 /* XXX support PHY-A??? */
5471 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5472 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5473 bwn_tab_noise_g1[i]);
5475 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5476 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5477 bwn_tab_noise_g2[i]);
5480 for (i = 0; i < N(bwn_tab_rotor); i++)
5481 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5484 /* XXX support PHY-A??? */
5485 if (phy->rev >= 6) {
5486 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5488 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5490 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5492 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5494 for (i = 0; i < N(bwn_tab_retard); i++)
5495 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5498 if (phy->rev == 1) {
5499 for (i = 0; i < 16; i++)
5500 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5503 for (i = 0; i < 32; i++)
5504 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5511 bwn_wa_grev26789(struct bwn_mac *mac)
5513 struct bwn_phy *phy = &mac->mac_phy;
5515 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5518 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5520 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5522 /* init CRSTHRES and ANTDWELL */
5524 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5525 else if (phy->rev == 2) {
5526 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5527 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5528 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5530 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5531 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5532 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5533 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5536 for (i = 0; i < 64; i++)
5537 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5539 /* XXX support PHY-A??? */
5541 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5542 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5543 bwn_tab_noise_g1[i]);
5545 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5546 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5547 bwn_tab_noise_g2[i]);
5549 /* XXX support PHY-A??? */
5550 if (phy->rev >= 6) {
5551 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5553 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5555 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5557 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5559 for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5560 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5561 bwn_tab_sigmasqr2[i]);
5563 if (phy->rev == 1) {
5564 for (i = 0; i < 16; i++)
5565 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5568 for (i = 0; i < 32; i++)
5569 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5574 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5576 if (phy->type == BWN_PHYTYPE_A)
5577 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5579 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5581 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5582 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5583 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5586 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5587 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5591 bwn_wa_init(struct bwn_mac *mac)
5593 struct bwn_phy *phy = &mac->mac_phy;
5594 struct bwn_softc *sc = mac->mac_sc;
5596 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5607 bwn_wa_grev26789(mac);
5610 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5613 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5614 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5615 siba_get_pci_revid(sc->sc_dev) != 0x17) {
5617 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5619 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5622 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5623 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5624 if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5627 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5628 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5630 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5632 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5634 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5636 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5638 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5643 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5644 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5645 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5648 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5649 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5653 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5656 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5659 addr = table + offset;
5660 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5661 (addr - 1 != pg->pg_ofdmtab_addr)) {
5662 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5663 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5665 pg->pg_ofdmtab_addr = addr;
5666 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5670 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5673 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5676 addr = table + offset;
5677 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5678 (addr - 1 != pg->pg_ofdmtab_addr)) {
5679 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5680 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5682 pg->pg_ofdmtab_addr = addr;
5684 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5685 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5689 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5693 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5694 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5698 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5700 struct bwn_phy *phy = &mac->mac_phy;
5701 struct bwn_softc *sc = mac->mac_sc;
5702 unsigned int i, max_loop;
5704 uint32_t buffer[5] = {
5705 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5710 buffer[0] = 0x000201cc;
5713 buffer[0] = 0x000b846e;
5716 for (i = 0; i < 5; i++)
5717 bwn_ram_write(mac, i * 4, buffer[i]);
5719 BWN_WRITE_2(mac, 0x0568, 0x0000);
5720 BWN_WRITE_2(mac, 0x07c0,
5721 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5722 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5723 BWN_WRITE_2(mac, 0x050c, value);
5724 if (phy->type == BWN_PHYTYPE_LP)
5725 BWN_WRITE_2(mac, 0x0514, 0x1a02);
5726 BWN_WRITE_2(mac, 0x0508, 0x0000);
5727 BWN_WRITE_2(mac, 0x050a, 0x0000);
5728 BWN_WRITE_2(mac, 0x054c, 0x0000);
5729 BWN_WRITE_2(mac, 0x056a, 0x0014);
5730 BWN_WRITE_2(mac, 0x0568, 0x0826);
5731 BWN_WRITE_2(mac, 0x0500, 0x0000);
5732 if (phy->type == BWN_PHYTYPE_LP)
5733 BWN_WRITE_2(mac, 0x0502, 0x0050);
5735 BWN_WRITE_2(mac, 0x0502, 0x0030);
5737 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5738 BWN_RF_WRITE(mac, 0x0051, 0x0017);
5739 for (i = 0x00; i < max_loop; i++) {
5740 value = BWN_READ_2(mac, 0x050e);
5745 for (i = 0x00; i < 0x0a; i++) {
5746 value = BWN_READ_2(mac, 0x050e);
5751 for (i = 0x00; i < 0x19; i++) {
5752 value = BWN_READ_2(mac, 0x0690);
5753 if (!(value & 0x0100))
5757 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5758 BWN_RF_WRITE(mac, 0x0051, 0x0037);
5762 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5766 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5768 macctl = BWN_READ_4(mac, BWN_MACCTL);
5769 if (macctl & BWN_MACCTL_BIGENDIAN)
5770 kprintf("TODO: need swap\n");
5772 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5773 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5774 BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5778 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5782 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5783 ("%s:%d: fail", __func__, __LINE__));
5785 value = (uint8_t) (ctl->q);
5786 value |= ((uint8_t) (ctl->i)) << 8;
5787 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5791 bwn_lo_calcfeed(struct bwn_mac *mac,
5792 uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5794 struct bwn_phy *phy = &mac->mac_phy;
5795 struct bwn_softc *sc = mac->mac_sc;
5797 uint16_t feedthrough;
5800 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5801 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5803 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5804 ("%s:%d: fail", __func__, __LINE__));
5805 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5806 ("%s:%d: fail", __func__, __LINE__));
5808 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5810 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5811 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5813 rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5815 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5816 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5818 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5819 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5821 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5822 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5824 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5826 pga |= BWN_PHY_PGACTL_UNKNOWN;
5827 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5829 pga |= BWN_PHY_PGACTL_LOWBANDW;
5830 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5832 pga |= BWN_PHY_PGACTL_LPF;
5833 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5836 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5838 return (feedthrough);
5842 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5843 uint16_t *value, uint16_t *pad_mix_gain)
5845 struct bwn_phy *phy = &mac->mac_phy;
5846 uint16_t reg, v, padmix;
5848 if (phy->type == BWN_PHYTYPE_B) {
5850 if (phy->rf_rev <= 5) {
5858 if (phy->rev >= 2 && phy->rf_rev == 8) {
5871 *pad_mix_gain = padmix;
5877 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5879 struct bwn_phy *phy = &mac->mac_phy;
5880 struct bwn_phy_g *pg = &phy->phy_g;
5881 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5883 uint16_t trsw_rx, pga;
5884 uint16_t rf_pctl_reg;
5886 static const uint8_t tx_bias_values[] = {
5887 0x09, 0x08, 0x0a, 0x01, 0x00,
5888 0x02, 0x05, 0x04, 0x06,
5890 static const uint8_t tx_magn_values[] = {
5894 if (!BWN_HAS_LOOPBACK(phy)) {
5902 lb_gain = pg->pg_max_lb_gain / 2;
5905 pga = abs(10 - lb_gain) / 6;
5906 pga = MIN(MAX(pga, 0), 15);
5913 if ((phy->rev >= 2) &&
5914 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
5917 if ((10 - lb_gain) < cmp_val)
5918 tmp = (10 - lb_gain);
5926 rf_pctl_reg = cmp_val;
5931 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
5932 bwn_phy_g_set_bbatt(mac, 2);
5934 reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
5936 BWN_RF_MASK(mac, reg, mask);
5938 if (BWN_HAS_TXMAG(phy)) {
5941 int min_feedth = 0xffff;
5942 uint8_t tx_magn, tx_bias;
5944 for (i = 0; i < N(tx_magn_values); i++) {
5945 tx_magn = tx_magn_values[i];
5946 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
5947 for (j = 0; j < N(tx_bias_values); j++) {
5948 tx_bias = tx_bias_values[j];
5949 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
5950 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
5952 if (feedthrough < min_feedth) {
5953 lo->tx_bias = tx_bias;
5954 lo->tx_magn = tx_magn;
5955 min_feedth = feedthrough;
5957 if (lo->tx_bias == 0)
5960 BWN_RF_WRITE(mac, 0x52,
5961 (BWN_RF_READ(mac, 0x52)
5962 & 0xff00) | lo->tx_bias | lo->
5968 BWN_RF_MASK(mac, 0x52, 0xfff0);
5971 BWN_GETTIME(lo->txctl_measured_time);
5975 bwn_lo_get_powervector(struct bwn_mac *mac)
5977 struct bwn_phy *phy = &mac->mac_phy;
5978 struct bwn_phy_g *pg = &phy->phy_g;
5979 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5982 uint64_t power_vector = 0;
5984 for (i = 0; i < 8; i += 2) {
5985 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
5986 power_vector |= (tmp << (i * 8));
5987 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
5990 lo->power_vector = power_vector;
5992 BWN_GETTIME(lo->pwr_vec_read_time);
5996 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
5999 struct bwn_phy *phy = &mac->mac_phy;
6000 struct bwn_phy_g *pg = &phy->phy_g;
6003 if (max_rx_gain < 0)
6006 if (BWN_HAS_LOOPBACK(phy)) {
6011 trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6012 if (max_rx_gain >= trsw_rx_gain) {
6013 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6017 trsw_rx_gain = max_rx_gain;
6018 if (trsw_rx_gain < 9) {
6019 pg->pg_lna_lod_gain = 0;
6021 pg->pg_lna_lod_gain = 1;
6024 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6025 pg->pg_pga_gain = trsw_rx_gain / 3;
6026 if (pg->pg_pga_gain >= 5) {
6027 pg->pg_pga_gain -= 5;
6028 pg->pg_lna_gain = 2;
6030 pg->pg_lna_gain = 0;
6032 pg->pg_lna_gain = 0;
6033 pg->pg_trsw_rx_gain = 0x20;
6034 if (max_rx_gain >= 0x14) {
6035 pg->pg_lna_lod_gain = 1;
6036 pg->pg_pga_gain = 2;
6037 } else if (max_rx_gain >= 0x12) {
6038 pg->pg_lna_lod_gain = 1;
6039 pg->pg_pga_gain = 1;
6040 } else if (max_rx_gain >= 0xf) {
6041 pg->pg_lna_lod_gain = 1;
6042 pg->pg_pga_gain = 0;
6044 pg->pg_lna_lod_gain = 0;
6045 pg->pg_pga_gain = 0;
6049 tmp = BWN_RF_READ(mac, 0x7a);
6050 if (pg->pg_lna_lod_gain == 0)
6054 BWN_RF_WRITE(mac, 0x7a, tmp);
6058 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6060 struct bwn_phy *phy = &mac->mac_phy;
6061 struct bwn_phy_g *pg = &phy->phy_g;
6062 struct bwn_softc *sc = mac->mac_sc;
6063 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6067 if (bwn_has_hwpctl(mac)) {
6068 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6069 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6070 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6071 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6072 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6074 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6075 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6076 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6077 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6079 if (phy->type == BWN_PHYTYPE_B &&
6080 phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6081 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6082 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6084 if (phy->rev >= 2) {
6085 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6086 sav->phy_analogoverval =
6087 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6088 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6089 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6090 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6091 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6092 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6094 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6095 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6096 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6097 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6098 if (phy->type == BWN_PHYTYPE_G) {
6099 if ((phy->rev >= 7) &&
6100 (siba_sprom_get_bf_lo(sc->sc_dev) &
6102 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6104 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6107 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6109 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6111 sav->reg0 = BWN_READ_2(mac, 0x3f4);
6112 sav->reg1 = BWN_READ_2(mac, 0x3e2);
6113 sav->rf0 = BWN_RF_READ(mac, 0x43);
6114 sav->rf1 = BWN_RF_READ(mac, 0x7a);
6115 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6116 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6117 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6118 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6120 if (!BWN_HAS_TXMAG(phy)) {
6121 sav->rf2 = BWN_RF_READ(mac, 0x52);
6124 if (phy->type == BWN_PHYTYPE_B) {
6125 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6126 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6127 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6128 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6130 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6133 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6137 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6138 BWN_PHY_WRITE(mac, tmp, 0x007f);
6140 tmp = sav->phy_syncctl;
6141 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6143 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6145 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6146 if (phy->type == BWN_PHYTYPE_G ||
6147 (phy->type == BWN_PHYTYPE_B &&
6148 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6149 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6151 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6153 bwn_dummy_transmission(mac, 0, 1);
6154 bwn_phy_g_switch_chan(mac, 6, 0);
6155 BWN_RF_READ(mac, 0x51);
6156 if (phy->type == BWN_PHYTYPE_G)
6157 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6160 if (time_before(lo->txctl_measured_time,
6161 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6162 bwn_lo_measure_txctl_values(mac);
6164 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6165 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6167 if (phy->type == BWN_PHYTYPE_B)
6168 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6170 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6175 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6177 struct bwn_phy *phy = &mac->mac_phy;
6178 struct bwn_phy_g *pg = &phy->phy_g;
6181 if (phy->rev >= 2) {
6182 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6183 tmp = (pg->pg_pga_gain << 8);
6184 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6186 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6188 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6190 tmp = (pg->pg_pga_gain | 0xefa0);
6191 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6193 if (phy->type == BWN_PHYTYPE_G) {
6195 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6197 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6199 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6201 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6203 BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6204 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6205 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6206 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6207 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6208 BWN_RF_WRITE(mac, 0x43, sav->rf0);
6209 BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6210 if (!BWN_HAS_TXMAG(phy)) {
6212 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6214 BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6215 if (phy->type == BWN_PHYTYPE_B &&
6216 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6217 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6218 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6220 if (phy->rev >= 2) {
6221 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6222 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6223 sav->phy_analogoverval);
6224 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6225 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6226 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6227 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6228 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6230 if (bwn_has_hwpctl(mac)) {
6231 tmp = (sav->phy_lomask & 0xbfff);
6232 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6233 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6234 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6235 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6236 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6238 bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6242 bwn_lo_probe_loctl(struct bwn_mac *mac,
6243 struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6245 struct bwn_phy *phy = &mac->mac_phy;
6246 struct bwn_phy_g *pg = &phy->phy_g;
6247 struct bwn_loctl orig, test;
6248 struct bwn_loctl prev = { -100, -100 };
6249 static const struct bwn_loctl modifiers[] = {
6250 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,},
6251 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,}
6253 int begin, end, lower = 0, i;
6256 if (d->curstate == 0) {
6259 } else if (d->curstate % 2 == 0) {
6260 begin = d->curstate - 1;
6261 end = d->curstate + 1;
6263 begin = d->curstate - 2;
6264 end = d->curstate + 2;
6271 memcpy(&orig, probe, sizeof(struct bwn_loctl));
6275 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6276 memcpy(&test, &orig, sizeof(struct bwn_loctl));
6277 test.i += modifiers[i - 1].i * d->multipler;
6278 test.q += modifiers[i - 1].q * d->multipler;
6279 if ((test.i != prev.i || test.q != prev.q) &&
6280 (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6281 bwn_lo_write(mac, &test);
6282 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6283 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6284 if (feedth < d->feedth) {
6285 memcpy(probe, &test,
6286 sizeof(struct bwn_loctl));
6289 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6293 memcpy(&prev, &test, sizeof(prev));
6307 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6309 struct bwn_phy *phy = &mac->mac_phy;
6310 struct bwn_phy_g *pg = &phy->phy_g;
6311 struct bwn_lo_g_sm d;
6312 struct bwn_loctl probe;
6313 int lower, repeat, cnt = 0;
6318 if (BWN_HAS_LOOPBACK(phy))
6321 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6322 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6325 bwn_lo_write(mac, &d.loctl);
6326 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6327 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6328 if (feedth < 0x258) {
6329 if (feedth >= 0x12c)
6333 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6334 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6339 KASSERT(d.curstate >= 0 && d.curstate <= 8,
6340 ("%s:%d: fail", __func__, __LINE__));
6341 memcpy(&probe, &d.loctl,
6342 sizeof(struct bwn_loctl));
6343 lower = bwn_lo_probe_loctl(mac, &probe, &d);
6346 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6348 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6350 } while (d.nmeasure < 24);
6351 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6353 if (BWN_HAS_LOOPBACK(phy)) {
6354 if (d.feedth > 0x1194)
6356 else if (d.feedth < 0x5dc)
6359 if (d.feedth <= 0x5dc) {
6364 } else if (cnt == 2)
6367 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6368 } while (++cnt < repeat);
6371 static struct bwn_lo_calib *
6372 bwn_lo_calibset(struct bwn_mac *mac,
6373 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6375 struct bwn_phy *phy = &mac->mac_phy;
6376 struct bwn_phy_g *pg = &phy->phy_g;
6377 struct bwn_loctl loctl = { 0, 0 };
6378 struct bwn_lo_calib *cal;
6379 struct bwn_lo_g_value sval = { 0 };
6381 uint16_t pad, reg, value;
6383 sval.old_channel = phy->chan;
6384 bwn_mac_suspend(mac);
6385 bwn_lo_save(mac, &sval);
6387 reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6388 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6389 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6391 rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6394 if (BWN_HAS_LOOPBACK(phy))
6395 rxgain += pg->pg_max_lb_gain;
6396 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6397 bwn_phy_g_set_bbatt(mac, bbatt->att);
6398 bwn_lo_probe_sm(mac, &loctl, &rxgain);
6400 bwn_lo_restore(mac, &sval);
6401 bwn_mac_enable(mac);
6403 cal = kmalloc(sizeof(*cal), M_DEVBUF, M_INTWAIT | M_ZERO);
6404 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6405 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6406 memcpy(&cal->ctl, &loctl, sizeof(loctl));
6408 BWN_GETTIME(cal->calib_time);
6413 static struct bwn_lo_calib *
6414 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6415 const struct bwn_rfatt *rfatt)
6417 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6418 struct bwn_lo_calib *c;
6420 TAILQ_FOREACH(c, &lo->calib_list, list) {
6421 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6423 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6428 c = bwn_lo_calibset(mac, bbatt, rfatt);
6429 if (c == NULL) /* XXX ivadasz: can't happen */
6431 TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6437 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6439 struct bwn_phy *phy = &mac->mac_phy;
6440 struct bwn_phy_g *pg = &phy->phy_g;
6441 struct bwn_softc *sc = mac->mac_sc;
6442 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6443 const struct bwn_rfatt *rfatt;
6444 const struct bwn_bbatt *bbatt;
6447 int rf_offset, bb_offset;
6448 uint8_t changed = 0;
6450 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6451 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6452 ("%s:%d: fail", __func__, __LINE__));
6454 pvector = lo->power_vector;
6455 if (!update && !pvector)
6458 bwn_mac_suspend(mac);
6460 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6461 struct bwn_lo_calib *cal;
6465 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6467 bb_offset = i / lo->rfatt.len;
6468 rf_offset = i % lo->rfatt.len;
6469 bbatt = &(lo->bbatt.array[bb_offset]);
6470 rfatt = &(lo->rfatt.array[rf_offset]);
6472 cal = bwn_lo_calibset(mac, bbatt, rfatt);
6473 if (cal == NULL) { /* XXX ivadasz: can't happen */
6474 device_printf(sc->sc_dev, "LO: Could not "
6475 "calibrate DC table entry\n");
6478 val = (uint8_t)(cal->ctl.q);
6479 val |= ((uint8_t)(cal->ctl.i)) << 4;
6480 kfree(cal, M_DEVBUF);
6484 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6485 | ((val & 0x00ff) << 8);
6487 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6492 for (i = 0; i < BWN_DC_LT_SIZE; i++)
6493 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6495 bwn_mac_enable(mac);
6499 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6504 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6509 bwn_lo_g_adjust(struct bwn_mac *mac)
6511 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6512 struct bwn_lo_calib *cal;
6513 struct bwn_rfatt rf;
6515 memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6516 bwn_lo_fixup_rfatt(&rf);
6518 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6519 if (cal == NULL) /* XXX ivadasz: can't happen */
6521 bwn_lo_write(mac, &cal->ctl);
6525 bwn_lo_g_init(struct bwn_mac *mac)
6528 if (!bwn_has_hwpctl(mac))
6531 bwn_lo_get_powervector(mac);
6532 bwn_phy_g_dc_lookup_init(mac, 1);
6536 bwn_mac_suspend(struct bwn_mac *mac)
6538 struct bwn_softc *sc = mac->mac_sc;
6542 KASSERT(mac->mac_suspended >= 0,
6543 ("%s:%d: fail", __func__, __LINE__));
6545 if (mac->mac_suspended == 0) {
6546 bwn_psctl(mac, BWN_PS_AWAKE);
6547 BWN_WRITE_4(mac, BWN_MACCTL,
6548 BWN_READ_4(mac, BWN_MACCTL)
6550 BWN_READ_4(mac, BWN_MACCTL);
6551 for (i = 35; i; i--) {
6552 tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6553 if (tmp & BWN_INTR_MAC_SUSPENDED)
6557 for (i = 40; i; i--) {
6558 tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6559 if (tmp & BWN_INTR_MAC_SUSPENDED)
6563 device_printf(sc->sc_dev, "MAC suspend failed\n");
6566 mac->mac_suspended++;
6570 bwn_mac_enable(struct bwn_mac *mac)
6572 struct bwn_softc *sc = mac->mac_sc;
6575 state = bwn_shm_read_2(mac, BWN_SHARED,
6576 BWN_SHARED_UCODESTAT);
6577 if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6578 state != BWN_SHARED_UCODESTAT_SLEEP)
6579 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6581 mac->mac_suspended--;
6582 KASSERT(mac->mac_suspended >= 0,
6583 ("%s:%d: fail", __func__, __LINE__));
6584 if (mac->mac_suspended == 0) {
6585 BWN_WRITE_4(mac, BWN_MACCTL,
6586 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6587 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6588 BWN_READ_4(mac, BWN_MACCTL);
6589 BWN_READ_4(mac, BWN_INTR_REASON);
6595 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6597 struct bwn_softc *sc = mac->mac_sc;
6601 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6602 ("%s:%d: fail", __func__, __LINE__));
6603 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6604 ("%s:%d: fail", __func__, __LINE__));
6606 /* XXX forcibly awake and hwps-off */
6608 BWN_WRITE_4(mac, BWN_MACCTL,
6609 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6611 BWN_READ_4(mac, BWN_MACCTL);
6612 if (siba_get_revid(sc->sc_dev) >= 5) {
6613 for (i = 0; i < 100; i++) {
6614 ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6615 BWN_SHARED_UCODESTAT);
6616 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6624 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6627 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6628 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6632 bwn_nrssi_threshold(struct bwn_mac *mac)
6634 struct bwn_phy *phy = &mac->mac_phy;
6635 struct bwn_phy_g *pg = &phy->phy_g;
6636 struct bwn_softc *sc = mac->mac_sc;
6641 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6643 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6644 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6652 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6653 a += (pg->pg_nrssi[0] << 6);
6654 a += (a < 32) ? 31 : 32;
6656 a = MIN(MAX(a, -31), 31);
6658 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6659 b += (pg->pg_nrssi[0] << 6);
6665 b = MIN(MAX(b, -31), 31);
6667 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6668 tmpu16 |= ((uint32_t)b & 0x0000003f);
6669 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6670 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6674 tmp16 = bwn_nrssi_read(mac, 0x20);
6677 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6681 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6683 #define SAVE_RF_MAX 3
6684 #define SAVE_PHY_COMM_MAX 4
6685 #define SAVE_PHY3_MAX 8
6686 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6687 { 0x7a, 0x52, 0x43 };
6688 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6689 { 0x15, 0x5a, 0x59, 0x58 };
6690 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6691 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6692 0x0801, 0x0060, 0x0014, 0x0478
6694 struct bwn_phy *phy = &mac->mac_phy;
6695 struct bwn_phy_g *pg = &phy->phy_g;
6696 int32_t i, tmp32, phy3_idx = 0;
6697 uint16_t delta, tmp;
6698 uint16_t save_rf[SAVE_RF_MAX];
6699 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6700 uint16_t save_phy3[SAVE_PHY3_MAX];
6701 uint16_t ant_div, phy0, chan_ex;
6702 int16_t nrssi0, nrssi1;
6704 KASSERT(phy->type == BWN_PHYTYPE_G,
6705 ("%s:%d: fail", __func__, __LINE__));
6707 if (phy->rf_rev >= 9)
6709 if (phy->rf_rev == 8)
6710 bwn_nrssi_offset(mac);
6712 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6713 BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6716 * Save RF/PHY registers for later restoration
6718 ant_div = BWN_READ_2(mac, 0x03e2);
6719 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6720 for (i = 0; i < SAVE_RF_MAX; ++i)
6721 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6722 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6723 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6725 phy0 = BWN_READ_2(mac, BWN_PHY0);
6726 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6727 if (phy->rev >= 3) {
6728 for (i = 0; i < SAVE_PHY3_MAX; ++i)
6729 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6730 BWN_PHY_WRITE(mac, 0x002e, 0);
6731 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6736 BWN_PHY_SET(mac, 0x0478, 0x0100);
6737 BWN_PHY_SET(mac, 0x0801, 0x0040);
6741 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6744 BWN_PHY_SET(mac, 0x0060, 0x0040);
6745 BWN_PHY_SET(mac, 0x0014, 0x0200);
6750 BWN_RF_SET(mac, 0x007a, 0x0070);
6751 bwn_set_all_gains(mac, 0, 8, 0);
6752 BWN_RF_MASK(mac, 0x007a, 0x00f7);
6753 if (phy->rev >= 2) {
6754 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6755 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6757 BWN_RF_SET(mac, 0x007a, 0x0080);
6760 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6761 if (nrssi0 >= 0x0020)
6767 BWN_RF_MASK(mac, 0x007a, 0x007f);
6769 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6771 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6772 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6773 BWN_RF_SET(mac, 0x007a, 0x000f);
6774 BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6775 if (phy->rev >= 2) {
6776 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6777 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6780 bwn_set_all_gains(mac, 3, 0, 1);
6781 if (phy->rf_rev == 8) {
6782 BWN_RF_WRITE(mac, 0x0043, 0x001f);
6784 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6785 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6786 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6787 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6789 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6790 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6791 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6793 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6796 * Install calculated narrow RSSI values
6798 if (nrssi1 >= 0x0020)
6800 if (nrssi0 == nrssi1)
6801 pg->pg_nrssi_slope = 0x00010000;
6803 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6805 pg->pg_nrssi[0] = nrssi1;
6806 pg->pg_nrssi[1] = nrssi0;
6810 * Restore saved RF/PHY registers
6812 if (phy->rev >= 3) {
6813 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6814 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6815 save_phy3[phy3_idx]);
6818 if (phy->rev >= 2) {
6819 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6820 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6823 for (i = 0; i < SAVE_RF_MAX; ++i)
6824 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6826 BWN_WRITE_2(mac, 0x03e2, ant_div);
6827 BWN_WRITE_2(mac, 0x03e6, phy0);
6828 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6830 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6831 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6833 bwn_spu_workaround(mac, phy->chan);
6834 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6835 bwn_set_original_gains(mac);
6836 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6837 if (phy->rev >= 3) {
6838 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6839 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6840 save_phy3[phy3_idx]);
6844 delta = 0x1f - pg->pg_nrssi[0];
6845 for (i = 0; i < 64; i++) {
6846 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6847 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6848 pg->pg_nrssi_lt[i] = tmp32;
6851 bwn_nrssi_threshold(mac);
6853 #undef SAVE_PHY_COMM_MAX
6854 #undef SAVE_PHY3_MAX
6858 bwn_nrssi_offset(struct bwn_mac *mac)
6860 #define SAVE_RF_MAX 2
6861 #define SAVE_PHY_COMM_MAX 10
6862 #define SAVE_PHY6_MAX 8
6863 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6865 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6866 0x0001, 0x0811, 0x0812, 0x0814,
6867 0x0815, 0x005a, 0x0059, 0x0058,
6870 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6871 0x002e, 0x002f, 0x080f, 0x0810,
6872 0x0801, 0x0060, 0x0014, 0x0478
6874 struct bwn_phy *phy = &mac->mac_phy;
6875 int i, phy6_idx = 0;
6876 uint16_t save_rf[SAVE_RF_MAX];
6877 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6878 uint16_t save_phy6[SAVE_PHY6_MAX];
6880 uint16_t saved = 0xffff;
6882 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6883 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6884 for (i = 0; i < SAVE_RF_MAX; ++i)
6885 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6887 BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6888 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6889 BWN_PHY_SET(mac, 0x0811, 0x000c);
6890 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6891 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6892 if (phy->rev >= 6) {
6893 for (i = 0; i < SAVE_PHY6_MAX; ++i)
6894 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6896 BWN_PHY_WRITE(mac, 0x002e, 0);
6897 BWN_PHY_WRITE(mac, 0x002f, 0);
6898 BWN_PHY_WRITE(mac, 0x080f, 0);
6899 BWN_PHY_WRITE(mac, 0x0810, 0);
6900 BWN_PHY_SET(mac, 0x0478, 0x0100);
6901 BWN_PHY_SET(mac, 0x0801, 0x0040);
6902 BWN_PHY_SET(mac, 0x0060, 0x0040);
6903 BWN_PHY_SET(mac, 0x0014, 0x0200);
6905 BWN_RF_SET(mac, 0x007a, 0x0070);
6906 BWN_RF_SET(mac, 0x007a, 0x0080);
6909 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6913 for (i = 7; i >= 4; i--) {
6914 BWN_RF_WRITE(mac, 0x007b, i);
6916 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
6920 if (nrssi < 31 && saved == 0xffff)
6923 if (saved == 0xffff)
6926 BWN_RF_MASK(mac, 0x007a, 0x007f);
6927 if (phy->rev != 1) {
6928 BWN_PHY_SET(mac, 0x0814, 0x0001);
6929 BWN_PHY_MASK(mac, 0x0815, 0xfffe);
6931 BWN_PHY_SET(mac, 0x0811, 0x000c);
6932 BWN_PHY_SET(mac, 0x0812, 0x000c);
6933 BWN_PHY_SET(mac, 0x0811, 0x0030);
6934 BWN_PHY_SET(mac, 0x0812, 0x0030);
6935 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6936 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6937 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6939 BWN_PHY_WRITE(mac, 0x0003, 0x0122);
6941 BWN_PHY_SET(mac, 0x000a, 0x2000);
6942 if (phy->rev != 1) {
6943 BWN_PHY_SET(mac, 0x0814, 0x0004);
6944 BWN_PHY_MASK(mac, 0x0815, 0xfffb);
6946 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6947 BWN_RF_SET(mac, 0x007a, 0x000f);
6948 bwn_set_all_gains(mac, 3, 0, 1);
6949 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
6951 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6955 for (i = 0; i < 4; i++) {
6956 BWN_RF_WRITE(mac, 0x007b, i);
6958 nrssi = (int16_t)((BWN_PHY_READ(mac,
6959 0x047f) >> 8) & 0x003f);
6962 if (nrssi > -31 && saved == 0xffff)
6965 if (saved == 0xffff)
6970 BWN_RF_WRITE(mac, 0x007b, saved);
6973 * Restore saved RF/PHY registers
6975 if (phy->rev >= 6) {
6976 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
6977 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
6978 save_phy6[phy6_idx]);
6981 if (phy->rev != 1) {
6982 for (i = 3; i < 5; i++)
6983 BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
6986 for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
6987 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6989 for (i = SAVE_RF_MAX - 1; i >= 0; --i)
6990 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6992 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
6993 BWN_PHY_SET(mac, 0x0429, 0x8000);
6994 bwn_set_original_gains(mac);
6995 if (phy->rev >= 6) {
6996 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
6997 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
6998 save_phy6[phy6_idx]);
7002 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7003 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7004 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7008 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7011 struct bwn_phy *phy = &mac->mac_phy;
7013 uint16_t start = 0x08, end = 0x18;
7017 if (phy->rev <= 1) {
7022 table = BWN_OFDMTAB_GAINX;
7024 table = BWN_OFDMTAB_GAINX_R1;
7025 for (i = 0; i < 4; i++)
7026 bwn_ofdmtab_write_2(mac, table, i, first);
7028 for (i = start; i < end; i++)
7029 bwn_ofdmtab_write_2(mac, table, i, second);
7032 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7033 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7034 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7035 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7037 bwn_dummy_transmission(mac, 0, 1);
7041 bwn_set_original_gains(struct bwn_mac *mac)
7043 struct bwn_phy *phy = &mac->mac_phy;
7046 uint16_t start = 0x0008, end = 0x0018;
7048 if (phy->rev <= 1) {
7053 table = BWN_OFDMTAB_GAINX;
7055 table = BWN_OFDMTAB_GAINX_R1;
7056 for (i = 0; i < 4; i++) {
7058 tmp |= (i & 0x0001) << 1;
7059 tmp |= (i & 0x0002) >> 1;
7061 bwn_ofdmtab_write_2(mac, table, i, tmp);
7064 for (i = start; i < end; i++)
7065 bwn_ofdmtab_write_2(mac, table, i, i - start);
7067 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7068 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7069 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7070 bwn_dummy_transmission(mac, 0, 1);
7074 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7076 struct bwn_phy *phy = &mac->mac_phy;
7077 struct bwn_phy_g *pg = &phy->phy_g;
7078 struct bwn_rfatt old_rfatt, rfatt;
7079 struct bwn_bbatt old_bbatt, bbatt;
7080 struct bwn_softc *sc = mac->mac_sc;
7081 uint8_t old_txctl = 0;
7083 KASSERT(phy->type == BWN_PHYTYPE_G,
7084 ("%s:%d: fail", __func__, __LINE__));
7086 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7087 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7090 BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7092 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7096 bwn_hwpctl_early_init(mac);
7097 if (pg->pg_curtssi == 0) {
7098 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7099 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7101 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7102 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7103 old_txctl = pg->pg_txctl;
7106 if (phy->rf_rev == 8) {
7113 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7115 bwn_dummy_transmission(mac, 0, 1);
7116 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7117 if (phy->rf_ver == 0x2050 && phy->analog == 0)
7118 BWN_RF_MASK(mac, 0x0076, 0xff7b);
7120 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7121 &old_rfatt, old_txctl);
7123 bwn_hwpctl_init_gphy(mac);
7126 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7127 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7128 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7129 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7133 bwn_hwpctl_early_init(struct bwn_mac *mac)
7135 struct bwn_phy *phy = &mac->mac_phy;
7137 if (!bwn_has_hwpctl(mac)) {
7138 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7142 BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7143 BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7144 BWN_PHY_SET(mac, 0x047c, 0x0002);
7145 BWN_PHY_SET(mac, 0x047a, 0xf000);
7146 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7147 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7148 BWN_PHY_SET(mac, 0x005d, 0x8000);
7149 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7150 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7151 BWN_PHY_SET(mac, 0x0036, 0x0400);
7153 BWN_PHY_SET(mac, 0x0036, 0x0200);
7154 BWN_PHY_SET(mac, 0x0036, 0x0400);
7155 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7156 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7157 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7158 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7159 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7164 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7166 struct bwn_phy *phy = &mac->mac_phy;
7167 struct bwn_phy_g *pg = &phy->phy_g;
7168 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7170 uint16_t nr_written = 0, tmp, value;
7173 if (!bwn_has_hwpctl(mac)) {
7174 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7178 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7179 (pg->pg_idletssi - pg->pg_curtssi));
7180 BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7181 (pg->pg_idletssi - pg->pg_curtssi));
7183 for (i = 0; i < 32; i++)
7184 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7185 for (i = 32; i < 64; i++)
7186 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7187 for (i = 0; i < 64; i += 2) {
7188 value = (uint16_t) pg->pg_tssi2dbm[i];
7189 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7190 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7193 for (rf = 0; rf < lo->rfatt.len; rf++) {
7194 for (bb = 0; bb < lo->bbatt.len; bb++) {
7195 if (nr_written >= 0x40)
7197 tmp = lo->bbatt.array[bb].att;
7199 if (phy->rf_rev == 8)
7203 tmp |= lo->rfatt.array[rf].att;
7204 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7209 BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7210 BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7212 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7213 BWN_PHY_SET(mac, 0x0478, 0x0800);
7214 BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7215 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7217 bwn_phy_g_dc_lookup_init(mac, 1);
7218 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7222 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7224 struct bwn_softc *sc = mac->mac_sc;
7227 bwn_spu_workaround(mac, channel);
7229 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7231 if (channel == 14) {
7232 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7234 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7237 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7238 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7239 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7243 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7244 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7248 bwn_phy_g_chan2freq(uint8_t channel)
7250 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7252 KASSERT(channel >= 1 && channel <= 14,
7253 ("%s:%d: fail", __func__, __LINE__));
7255 return (bwn_phy_g_rf_channels[channel - 1]);
7259 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7260 const struct bwn_rfatt *rfatt, uint8_t txctl)
7262 struct bwn_phy *phy = &mac->mac_phy;
7263 struct bwn_phy_g *pg = &phy->phy_g;
7264 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7266 uint16_t tx_bias, tx_magn;
7270 tx_bias = lo->tx_bias;
7271 tx_magn = lo->tx_magn;
7272 if (tx_bias == 0xff)
7275 pg->pg_txctl = txctl;
7276 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7277 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7278 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7279 bwn_phy_g_set_bbatt(mac, bb);
7280 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7281 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7282 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7284 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7285 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7287 if (BWN_HAS_TXMAG(phy))
7288 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7290 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7291 bwn_lo_g_adjust(mac);
7295 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7298 struct bwn_phy *phy = &mac->mac_phy;
7300 if (phy->analog == 0) {
7301 BWN_WRITE_2(mac, BWN_PHY0,
7302 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7305 if (phy->analog > 1) {
7306 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7309 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7313 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7315 struct bwn_phy *phy = &mac->mac_phy;
7316 struct bwn_phy_g *pg = &phy->phy_g;
7317 struct bwn_softc *sc = mac->mac_sc;
7322 if (phy->gmode == 0)
7325 if (BWN_HAS_LOOPBACK(phy)) {
7326 max_lb_gain = pg->pg_max_lb_gain;
7327 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7328 if (max_lb_gain >= 0x46) {
7330 max_lb_gain -= 0x46;
7331 } else if (max_lb_gain >= 0x3a) {
7333 max_lb_gain -= 0x3a;
7334 } else if (max_lb_gain >= 0x2e) {
7336 max_lb_gain -= 0x2e;
7339 max_lb_gain -= 0x10;
7342 for (i = 0; i < 16; i++) {
7343 max_lb_gain -= (i * 6);
7344 if (max_lb_gain < 6)
7348 if ((phy->rev < 7) ||
7349 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7350 if (reg == BWN_PHY_RFOVER) {
7352 } else if (reg == BWN_PHY_RFOVERVAL) {
7355 case BWN_LPD(0, 1, 1):
7357 case BWN_LPD(0, 0, 1):
7358 case BWN_LPD(1, 0, 1):
7359 return (0x0092 | extlna);
7360 case BWN_LPD(1, 0, 0):
7361 return (0x0093 | extlna);
7364 ("%s:%d: fail", __func__, __LINE__));
7366 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7368 if (reg == BWN_PHY_RFOVER)
7370 if (reg == BWN_PHY_RFOVERVAL) {
7375 case BWN_LPD(0, 1, 1):
7377 case BWN_LPD(0, 0, 1):
7378 return (0x8092 | extlna);
7379 case BWN_LPD(1, 0, 1):
7380 return (0x2092 | extlna);
7381 case BWN_LPD(1, 0, 0):
7382 return (0x2093 | extlna);
7385 ("%s:%d: fail", __func__, __LINE__));
7387 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7392 if ((phy->rev < 7) ||
7393 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7394 if (reg == BWN_PHY_RFOVER) {
7396 } else if (reg == BWN_PHY_RFOVERVAL) {
7398 case BWN_LPD(0, 1, 1):
7400 case BWN_LPD(0, 0, 1):
7402 case BWN_LPD(1, 0, 1):
7404 case BWN_LPD(1, 0, 0):
7408 ("%s:%d: fail", __func__, __LINE__));
7410 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7412 if (reg == BWN_PHY_RFOVER) {
7414 } else if (reg == BWN_PHY_RFOVERVAL) {
7416 case BWN_LPD(0, 1, 1):
7418 case BWN_LPD(0, 0, 1):
7420 case BWN_LPD(1, 0, 1):
7422 case BWN_LPD(1, 0, 0):
7426 ("%s:%d: fail", __func__, __LINE__));
7428 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7434 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7437 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7439 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7440 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7442 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7446 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7448 struct bwn_softc *sc = mac->mac_sc;
7449 struct bwn_fw *fw = &mac->mac_fw;
7450 const uint8_t rev = siba_get_revid(sc->sc_dev);
7451 const char *filename;
7456 if (rev >= 5 && rev <= 10)
7457 filename = "ucode5";
7458 else if (rev >= 11 && rev <= 12)
7459 filename = "ucode11";
7461 filename = "ucode13";
7463 filename = "ucode14";
7465 filename = "ucode15";
7467 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7468 bwn_release_firmware(mac);
7469 return (EOPNOTSUPP);
7471 error = bwn_fw_get(mac, type, filename, &fw->ucode);
7473 bwn_release_firmware(mac);
7478 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7479 if (rev >= 5 && rev <= 10) {
7480 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7481 if (error == ENOENT)
7484 bwn_release_firmware(mac);
7487 } else if (rev < 11) {
7488 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7489 return (EOPNOTSUPP);
7493 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7494 switch (mac->mac_phy.type) {
7496 if (rev < 5 || rev > 10)
7498 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7499 filename = "a0g1initvals5";
7501 filename = "a0g0initvals5";
7504 if (rev >= 5 && rev <= 10)
7505 filename = "b0g0initvals5";
7507 filename = "b0g0initvals13";
7511 case BWN_PHYTYPE_LP:
7513 filename = "lp0initvals13";
7515 filename = "lp0initvals14";
7517 filename = "lp0initvals15";
7522 if (rev >= 11 && rev <= 12)
7523 filename = "n0initvals11";
7530 error = bwn_fw_get(mac, type, filename, &fw->initvals);
7532 bwn_release_firmware(mac);
7536 /* bandswitch initvals */
7537 switch (mac->mac_phy.type) {
7539 if (rev >= 5 && rev <= 10) {
7540 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7541 filename = "a0g1bsinitvals5";
7543 filename = "a0g0bsinitvals5";
7544 } else if (rev >= 11)
7550 if (rev >= 5 && rev <= 10)
7551 filename = "b0g0bsinitvals5";
7557 case BWN_PHYTYPE_LP:
7559 filename = "lp0bsinitvals13";
7561 filename = "lp0bsinitvals14";
7563 filename = "lp0bsinitvals15";
7568 if (rev >= 11 && rev <= 12)
7569 filename = "n0bsinitvals11";
7576 error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7578 bwn_release_firmware(mac);
7583 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7584 bwn_release_firmware(mac);
7585 return (EOPNOTSUPP);
7589 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7590 const char *name, struct bwn_fwfile *bfw)
7592 const struct bwn_fwhdr *hdr;
7593 struct bwn_softc *sc = mac->mac_sc;
7594 const struct firmware *fw;
7598 bwn_do_release_fw(bfw);
7601 if (bfw->filename != NULL) {
7602 if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7604 bwn_do_release_fw(bfw);
7607 ksnprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7608 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7609 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7610 wlan_assert_serialized();
7611 wlan_serialize_exit();
7612 fw = firmware_get(namebuf);
7613 wlan_serialize_enter();
7615 device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7619 if (fw->datasize < sizeof(struct bwn_fwhdr))
7621 hdr = (const struct bwn_fwhdr *)(fw->data);
7622 switch (hdr->type) {
7623 case BWN_FWTYPE_UCODE:
7624 case BWN_FWTYPE_PCM:
7625 if (be32toh(hdr->size) !=
7626 (fw->datasize - sizeof(struct bwn_fwhdr)))
7636 bfw->filename = name;
7641 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7643 firmware_put(fw, FIRMWARE_UNLOAD);
7648 bwn_release_firmware(struct bwn_mac *mac)
7651 bwn_do_release_fw(&mac->mac_fw.ucode);
7652 bwn_do_release_fw(&mac->mac_fw.pcm);
7653 bwn_do_release_fw(&mac->mac_fw.initvals);
7654 bwn_do_release_fw(&mac->mac_fw.initvals_band);
7658 bwn_do_release_fw(struct bwn_fwfile *bfw)
7661 if (bfw->fw != NULL)
7662 firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7664 bfw->filename = NULL;
7668 bwn_fw_loaducode(struct bwn_mac *mac)
7670 #define GETFWOFFSET(fwp, offset) \
7671 ((const uint32_t *)((const char *)fwp.fw->data + offset))
7672 #define GETFWSIZE(fwp, offset) \
7673 ((fwp.fw->datasize - offset) / sizeof(uint32_t))
7674 struct bwn_softc *sc = mac->mac_sc;
7675 const uint32_t *data;
7678 uint16_t date, fwcaps, time;
7681 ctl = BWN_READ_4(mac, BWN_MACCTL);
7682 ctl |= BWN_MACCTL_MCODE_JMP0;
7683 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7685 BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7686 for (i = 0; i < 64; i++)
7687 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7688 for (i = 0; i < 4096; i += 2)
7689 bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7691 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7692 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7693 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7695 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7699 if (mac->mac_fw.pcm.fw) {
7700 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7701 bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7702 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7703 bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7704 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7705 sizeof(struct bwn_fwhdr)); i++) {
7706 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7711 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7712 BWN_WRITE_4(mac, BWN_MACCTL,
7713 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7714 BWN_MACCTL_MCODE_RUN);
7716 for (i = 0; i < 21; i++) {
7717 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7720 device_printf(sc->sc_dev, "ucode timeout\n");
7726 BWN_READ_4(mac, BWN_INTR_REASON);
7728 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7729 if (mac->mac_fw.rev <= 0x128) {
7730 device_printf(sc->sc_dev, "the firmware is too old\n");
7734 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7735 BWN_SHARED_UCODE_PATCH);
7736 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7737 mac->mac_fw.opensource = (date == 0xffff);
7739 mac->mac_flags |= BWN_MAC_FLAG_WME;
7740 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7742 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7743 if (mac->mac_fw.opensource == 0) {
7744 device_printf(sc->sc_dev,
7745 "firmware version (rev %u patch %u date %#x time %#x)\n",
7746 mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7747 if (mac->mac_fw.no_pcmfile)
7748 device_printf(sc->sc_dev,
7749 "no HW crypto acceleration due to pcm5\n");
7751 mac->mac_fw.patch = time;
7752 fwcaps = bwn_fwcaps_read(mac);
7753 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7754 device_printf(sc->sc_dev,
7755 "disabling HW crypto acceleration\n");
7756 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7758 if (!(fwcaps & BWN_FWCAPS_WME)) {
7759 device_printf(sc->sc_dev, "disabling WME support\n");
7760 mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7764 if (BWN_ISOLDFMT(mac))
7765 device_printf(sc->sc_dev, "using old firmware image\n");
7770 BWN_WRITE_4(mac, BWN_MACCTL,
7771 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7772 BWN_MACCTL_MCODE_JMP0);
7779 /* OpenFirmware only */
7781 bwn_fwcaps_read(struct bwn_mac *mac)
7784 KASSERT(mac->mac_fw.opensource == 1,
7785 ("%s:%d: fail", __func__, __LINE__));
7786 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7790 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7791 size_t count, size_t array_size)
7793 #define GET_NEXTIV16(iv) \
7794 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \
7795 sizeof(uint16_t) + sizeof(uint16_t)))
7796 #define GET_NEXTIV32(iv) \
7797 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \
7798 sizeof(uint16_t) + sizeof(uint32_t)))
7799 struct bwn_softc *sc = mac->mac_sc;
7800 const struct bwn_fwinitvals *iv;
7805 KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7806 ("%s:%d: fail", __func__, __LINE__));
7808 for (i = 0; i < count; i++) {
7809 if (array_size < sizeof(iv->offset_size))
7811 array_size -= sizeof(iv->offset_size);
7812 offset = be16toh(iv->offset_size);
7813 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7814 offset &= BWN_FWINITVALS_OFFSET_MASK;
7815 if (offset >= 0x1000)
7818 if (array_size < sizeof(iv->data.d32))
7820 array_size -= sizeof(iv->data.d32);
7821 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7822 iv = GET_NEXTIV32(iv);
7825 if (array_size < sizeof(iv->data.d16))
7827 array_size -= sizeof(iv->data.d16);
7828 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7830 iv = GET_NEXTIV16(iv);
7833 if (array_size != 0)
7837 device_printf(sc->sc_dev, "initvals: invalid format\n");
7844 bwn_switch_channel(struct bwn_mac *mac, int chan)
7846 struct bwn_phy *phy = &(mac->mac_phy);
7847 struct bwn_softc *sc = mac->mac_sc;
7848 struct ifnet *ifp = sc->sc_ifp;
7849 struct ieee80211com *ic = ifp->if_l2com;
7850 uint16_t channelcookie, savedcookie;
7854 chan = phy->get_default_chan(mac);
7856 channelcookie = chan;
7857 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
7858 channelcookie |= 0x100;
7859 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
7860 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
7861 error = phy->switch_channel(mac, chan);
7865 mac->mac_phy.chan = chan;
7869 device_printf(sc->sc_dev, "failed to switch channel\n");
7870 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
7875 bwn_ant2phy(int antenna)
7880 return (BWN_TX_PHY_ANT0);
7882 return (BWN_TX_PHY_ANT1);
7884 return (BWN_TX_PHY_ANT2);
7886 return (BWN_TX_PHY_ANT3);
7888 return (BWN_TX_PHY_ANT01AUTO);
7890 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7895 bwn_wme_load(struct bwn_mac *mac)
7897 struct bwn_softc *sc = mac->mac_sc;
7900 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
7901 ("%s:%d: fail", __func__, __LINE__));
7903 bwn_mac_suspend(mac);
7904 for (i = 0; i < N(sc->sc_wmeParams); i++)
7905 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
7906 bwn_wme_shm_offsets[i]);
7907 bwn_mac_enable(mac);
7911 bwn_wme_loadparams(struct bwn_mac *mac,
7912 const struct wmeParams *p, uint16_t shm_offset)
7914 #define SM(_v, _f) (((_v) << _f##_S) & _f)
7915 struct bwn_softc *sc = mac->mac_sc;
7916 uint16_t params[BWN_NR_WMEPARAMS];
7920 slot = BWN_READ_2(mac, BWN_RNG) &
7921 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7923 memset(¶ms, 0, sizeof(params));
7925 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
7926 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
7927 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
7929 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
7930 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7931 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
7932 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7933 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
7934 params[BWN_WMEPARAM_BSLOTS] = slot;
7935 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
7937 for (i = 0; i < N(params); i++) {
7938 if (i == BWN_WMEPARAM_STATUS) {
7939 tmp = bwn_shm_read_2(mac, BWN_SHARED,
7940 shm_offset + (i * 2));
7942 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
7945 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
7952 bwn_mac_write_bssid(struct bwn_mac *mac)
7954 struct bwn_softc *sc = mac->mac_sc;
7957 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
7959 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
7960 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
7961 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
7962 IEEE80211_ADDR_LEN);
7964 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
7965 tmp = (uint32_t) (mac_bssid[i + 0]);
7966 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
7967 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
7968 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
7969 bwn_ram_write(mac, 0x20 + i, tmp);
7974 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
7975 const uint8_t *macaddr)
7977 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
7984 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
7987 data |= macaddr[1] << 8;
7988 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7990 data |= macaddr[3] << 8;
7991 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7993 data |= macaddr[5] << 8;
7994 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7998 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
7999 const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
8001 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
8002 uint8_t per_sta_keys_start = 8;
8004 if (BWN_SEC_NEWAPI(mac))
8005 per_sta_keys_start = 4;
8007 KASSERT(index < mac->mac_max_nr_keys,
8008 ("%s:%d: fail", __func__, __LINE__));
8009 KASSERT(key_len <= BWN_SEC_KEYSIZE,
8010 ("%s:%d: fail", __func__, __LINE__));
8012 if (index >= per_sta_keys_start)
8013 bwn_key_macwrite(mac, index, NULL);
8015 memcpy(buf, key, key_len);
8016 bwn_key_write(mac, index, algorithm, buf);
8017 if (index >= per_sta_keys_start)
8018 bwn_key_macwrite(mac, index, mac_addr);
8020 mac->mac_key[index].algorithm = algorithm;
8024 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8026 struct bwn_softc *sc = mac->mac_sc;
8027 uint32_t addrtmp[2] = { 0, 0 };
8030 if (BWN_SEC_NEWAPI(mac))
8033 KASSERT(index >= start,
8034 ("%s:%d: fail", __func__, __LINE__));
8038 addrtmp[0] = addr[0];
8039 addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8040 addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8041 addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8042 addrtmp[1] = addr[4];
8043 addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8046 if (siba_get_revid(sc->sc_dev) >= 5) {
8047 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8048 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8051 bwn_shm_write_4(mac, BWN_SHARED,
8052 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8053 bwn_shm_write_2(mac, BWN_SHARED,
8054 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8060 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8065 uint16_t kidx, value;
8067 kidx = BWN_SEC_KEY2FW(mac, index);
8068 bwn_shm_write_2(mac, BWN_SHARED,
8069 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8071 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8072 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8074 value |= (uint16_t)(key[i + 1]) << 8;
8075 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8080 bwn_phy_exit(struct bwn_mac *mac)
8083 mac->mac_phy.rf_onoff(mac, 0);
8084 if (mac->mac_phy.exit != NULL)
8085 mac->mac_phy.exit(mac);
8089 bwn_dma_free(struct bwn_mac *mac)
8091 struct bwn_dma *dma;
8093 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8095 dma = &mac->mac_method.dma;
8097 bwn_dma_ringfree(&dma->rx);
8098 bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8099 bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8100 bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8101 bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8102 bwn_dma_ringfree(&dma->mcast);
8106 bwn_core_stop(struct bwn_mac *mac)
8108 struct bwn_softc *sc = mac->mac_sc;
8110 wlan_assert_serialized();
8112 if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8115 callout_stop(&sc->sc_rfswitch_ch);
8116 callout_stop(&sc->sc_task_ch);
8117 callout_stop(&sc->sc_watchdog_ch);
8118 sc->sc_watchdog_timer = 0;
8119 BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8120 BWN_READ_4(mac, BWN_INTR_MASK);
8121 bwn_mac_suspend(mac);
8123 mac->mac_status = BWN_MAC_STATUS_INITED;
8127 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8129 struct bwn_mac *up_dev = NULL;
8130 struct bwn_mac *down_dev;
8131 struct bwn_mac *mac;
8135 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8136 if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8137 mac->mac_phy.supports_2ghz) {
8140 } else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8141 mac->mac_phy.supports_5ghz) {
8145 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8151 if (up_dev == NULL) {
8152 device_printf(sc->sc_dev, "Could not find a device\n");
8155 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8158 device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8159 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8161 down_dev = sc->sc_curmac;
8162 status = down_dev->mac_status;
8163 if (status >= BWN_MAC_STATUS_STARTED)
8164 bwn_core_stop(down_dev);
8165 if (status >= BWN_MAC_STATUS_INITED)
8166 bwn_core_exit(down_dev);
8168 if (down_dev != up_dev)
8169 bwn_phy_reset(down_dev);
8171 up_dev->mac_phy.gmode = gmode;
8172 if (status >= BWN_MAC_STATUS_INITED) {
8173 err = bwn_core_init(up_dev);
8175 device_printf(sc->sc_dev,
8176 "fatal: failed to initialize for %s-GHz\n",
8177 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8181 if (status >= BWN_MAC_STATUS_STARTED)
8182 bwn_core_start(up_dev);
8183 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8184 sc->sc_curmac = up_dev;
8188 sc->sc_curmac = NULL;
8193 bwn_rf_turnon(struct bwn_mac *mac)
8196 bwn_mac_suspend(mac);
8197 mac->mac_phy.rf_onoff(mac, 1);
8198 mac->mac_phy.rf_on = 1;
8199 bwn_mac_enable(mac);
8203 bwn_rf_turnoff(struct bwn_mac *mac)
8206 bwn_mac_suspend(mac);
8207 mac->mac_phy.rf_onoff(mac, 0);
8208 mac->mac_phy.rf_on = 0;
8209 bwn_mac_enable(mac);
8213 bwn_phy_reset(struct bwn_mac *mac)
8215 struct bwn_softc *sc = mac->mac_sc;
8217 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8218 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8219 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8221 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8222 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8223 BWN_TGSLOW_PHYRESET);
8228 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8230 struct bwn_vap *bvp = BWN_VAP(vap);
8231 struct ieee80211com *ic= vap->iv_ic;
8232 struct ifnet *ifp = ic->ic_ifp;
8233 enum ieee80211_state ostate = vap->iv_state;
8234 struct bwn_softc *sc = ifp->if_softc;
8235 struct bwn_mac *mac = sc->sc_curmac;
8238 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8239 ieee80211_state_name[vap->iv_state],
8240 ieee80211_state_name[nstate]);
8242 error = bvp->bv_newstate(vap, nstate, arg);
8246 bwn_led_newstate(mac, nstate);
8249 * Clear the BSSID when we stop a STA
8251 if (vap->iv_opmode == IEEE80211_M_STA) {
8252 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8254 * Clear out the BSSID. If we reassociate to
8255 * the same AP, this will reinialize things
8258 if (ic->ic_opmode == IEEE80211_M_STA &&
8259 (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8260 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8261 bwn_set_macaddr(mac);
8266 if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8267 vap->iv_opmode == IEEE80211_M_AHDEMO) {
8268 /* XXX nothing to do? */
8269 } else if (nstate == IEEE80211_S_RUN) {
8270 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8271 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
8272 bwn_set_opmode(mac);
8273 bwn_set_pretbtt(mac);
8274 bwn_spu_setdelay(mac, 0);
8275 bwn_set_macaddr(mac);
8282 bwn_set_pretbtt(struct bwn_mac *mac)
8284 struct bwn_softc *sc = mac->mac_sc;
8285 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8288 if (ic->ic_opmode == IEEE80211_M_IBSS)
8291 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8292 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8293 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8299 struct bwn_mac *mac = arg;
8300 struct bwn_softc *sc = mac->mac_sc;
8303 if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8304 (sc->sc_flags & BWN_FLAG_INVALID))
8307 reason = BWN_READ_4(mac, BWN_INTR_REASON);
8308 if (reason == 0xffffffff) /* shared IRQ */
8310 reason &= mac->mac_intr_mask;
8314 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001fc00;
8315 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8316 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8317 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8318 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8319 BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8320 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8321 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8322 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8323 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8324 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8326 /* Disable interrupts. */
8327 BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8329 mac->mac_reason_intr = reason;
8331 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8332 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8334 taskqueue_enqueue(sc->sc_tq, &mac->mac_intrtask);
8339 bwn_intrtask(void *arg, int npending)
8341 struct bwn_mac *mac = arg;
8342 struct bwn_softc *sc = mac->mac_sc;
8343 struct ifnet *ifp = sc->sc_ifp;
8344 uint32_t merged = 0;
8345 int i, tx = 0, rx = 0;
8347 wlan_serialize_enter();
8348 if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8349 (sc->sc_flags & BWN_FLAG_INVALID)) {
8350 wlan_serialize_exit();
8354 for (i = 0; i < N(mac->mac_reason); i++)
8355 merged |= mac->mac_reason[i];
8357 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8358 device_printf(sc->sc_dev, "MAC trans error\n");
8360 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8361 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8362 mac->mac_phy.txerrors--;
8363 if (mac->mac_phy.txerrors == 0) {
8364 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8365 bwn_restart(mac, "PHY TX errors");
8369 if (merged & BWN_DMAINTR_FATALMASK) {
8370 device_printf(sc->sc_dev,
8371 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8372 mac->mac_reason[0], mac->mac_reason[1],
8373 mac->mac_reason[2], mac->mac_reason[3],
8374 mac->mac_reason[4], mac->mac_reason[5]);
8375 bwn_restart(mac, "DMA error");
8376 wlan_serialize_exit();
8380 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8381 bwn_intr_ucode_debug(mac);
8382 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8383 bwn_intr_tbtt_indication(mac);
8384 if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8385 bwn_intr_atim_end(mac);
8386 if (mac->mac_reason_intr & BWN_INTR_BEACON)
8387 bwn_intr_beacon(mac);
8388 if (mac->mac_reason_intr & BWN_INTR_PMQ)
8390 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8391 bwn_intr_noise(mac);
8393 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8394 if (mac->mac_reason[0] & BWN_DMAINTR_RDESC_UFLOW) {
8395 device_printf(sc->sc_dev, "RX descriptor overflow\n");
8396 bwn_dma_rx_handle_overflow(mac->mac_method.dma.rx);
8398 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8399 bwn_dma_rx(mac->mac_method.dma.rx);
8403 rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8405 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8406 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8407 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8408 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8409 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8411 if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8412 bwn_intr_txeof(mac);
8416 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8418 if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8419 int evt = BWN_LED_EVENT_NONE;
8422 if (sc->sc_rx_rate > sc->sc_tx_rate)
8423 evt = BWN_LED_EVENT_RX;
8425 evt = BWN_LED_EVENT_TX;
8427 evt = BWN_LED_EVENT_TX;
8429 evt = BWN_LED_EVENT_RX;
8430 } else if (rx == 0) {
8431 evt = BWN_LED_EVENT_POLL;
8434 if (evt != BWN_LED_EVENT_NONE)
8435 bwn_led_event(mac, evt);
8438 if (!ifq_is_oactive(&ifp->if_snd)) {
8439 if (!ifq_is_empty(&ifp->if_snd))
8440 bwn_start_locked(ifp);
8443 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8444 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8446 wlan_serialize_exit();
8450 bwn_restart(struct bwn_mac *mac, const char *msg)
8452 struct bwn_softc *sc = mac->mac_sc;
8453 struct ifnet *ifp = sc->sc_ifp;
8454 struct ieee80211com *ic = ifp->if_l2com;
8456 if (mac->mac_status < BWN_MAC_STATUS_INITED)
8459 device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8460 ieee80211_runtask(ic, &mac->mac_hwreset);
8464 bwn_intr_ucode_debug(struct bwn_mac *mac)
8466 struct bwn_softc *sc = mac->mac_sc;
8469 if (mac->mac_fw.opensource == 0)
8472 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8474 case BWN_DEBUGINTR_PANIC:
8475 bwn_handle_fwpanic(mac);
8477 case BWN_DEBUGINTR_DUMP_SHM:
8478 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8480 case BWN_DEBUGINTR_DUMP_REGS:
8481 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8483 case BWN_DEBUGINTR_MARKER:
8484 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8487 device_printf(sc->sc_dev,
8488 "ucode debug unknown reason: %#x\n", reason);
8491 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8496 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8498 struct bwn_softc *sc = mac->mac_sc;
8499 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8501 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8503 if (ic->ic_opmode == IEEE80211_M_IBSS)
8504 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8508 bwn_intr_atim_end(struct bwn_mac *mac)
8511 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8512 BWN_WRITE_4(mac, BWN_MACCMD,
8513 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8514 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8519 bwn_intr_beacon(struct bwn_mac *mac)
8521 struct bwn_softc *sc = mac->mac_sc;
8522 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8523 uint32_t cmd, beacon0, beacon1;
8525 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8526 ic->ic_opmode == IEEE80211_M_MBSS)
8529 mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8531 cmd = BWN_READ_4(mac, BWN_MACCMD);
8532 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8533 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8535 if (beacon0 && beacon1) {
8536 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8537 mac->mac_intr_mask |= BWN_INTR_BEACON;
8541 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8542 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8543 bwn_load_beacon0(mac);
8544 bwn_load_beacon1(mac);
8545 cmd = BWN_READ_4(mac, BWN_MACCMD);
8546 cmd |= BWN_MACCMD_BEACON0_VALID;
8547 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8550 bwn_load_beacon0(mac);
8551 cmd = BWN_READ_4(mac, BWN_MACCMD);
8552 cmd |= BWN_MACCMD_BEACON0_VALID;
8553 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8554 } else if (!beacon1) {
8555 bwn_load_beacon1(mac);
8556 cmd = BWN_READ_4(mac, BWN_MACCMD);
8557 cmd |= BWN_MACCMD_BEACON1_VALID;
8558 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8564 bwn_intr_pmq(struct bwn_mac *mac)
8569 tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8570 if (!(tmp & 0x00000008))
8573 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8577 bwn_intr_noise(struct bwn_mac *mac)
8579 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8585 if (mac->mac_phy.type != BWN_PHYTYPE_G)
8588 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8589 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8590 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8594 KASSERT(mac->mac_noise.noi_nsamples < 8,
8595 ("%s:%d: fail", __func__, __LINE__));
8596 i = mac->mac_noise.noi_nsamples;
8597 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8598 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8599 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8600 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8601 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8602 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8603 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8604 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8605 mac->mac_noise.noi_nsamples++;
8606 if (mac->mac_noise.noi_nsamples == 8) {
8608 for (i = 0; i < 8; i++) {
8609 for (j = 0; j < 4; j++)
8610 average += mac->mac_noise.noi_samples[i][j];
8612 average = (((average / 32) * 125) + 64) / 128;
8613 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8618 average -= (tmp == 8) ? 72 : 48;
8620 mac->mac_stats.link_noise = average;
8621 mac->mac_noise.noi_running = 0;
8625 bwn_noise_gensample(mac);
8629 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8631 struct bwn_mac *mac = prq->prq_mac;
8632 struct bwn_softc *sc = mac->mac_sc;
8635 if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8638 for (i = 0; i < 5000; i++) {
8639 if (bwn_pio_rxeof(prq) == 0)
8643 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8644 return ((i > 0) ? 1 : 0);
8648 bwn_dma_rx_handle_overflow(struct bwn_dma_ring *dr)
8650 int curslot, prevslot;
8652 curslot = dr->get_curslot(dr);
8654 prevslot = dr->dr_numslots - 1;
8656 prevslot = curslot - 1;
8657 dr->set_curslot(dr, prevslot);
8661 bwn_dma_rx(struct bwn_dma_ring *dr)
8665 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8666 curslot = dr->get_curslot(dr);
8667 KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8668 ("%s:%d: fail", __func__, __LINE__));
8670 slot = dr->dr_curslot;
8671 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8672 bwn_dma_rxeof(dr, &slot);
8674 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8675 BUS_DMASYNC_PREWRITE);
8677 dr->set_curslot(dr, slot);
8678 dr->dr_curslot = slot;
8682 bwn_intr_txeof(struct bwn_mac *mac)
8684 struct bwn_txstatus stat;
8685 uint32_t stat0, stat1;
8689 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8690 if (!(stat0 & 0x00000001))
8692 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8694 stat.cookie = (stat0 >> 16);
8695 stat.seq = (stat1 & 0x0000ffff);
8696 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8697 tmp = (stat0 & 0x0000ffff);
8698 stat.framecnt = ((tmp & 0xf000) >> 12);
8699 stat.rtscnt = ((tmp & 0x0f00) >> 8);
8700 stat.sreason = ((tmp & 0x001c) >> 2);
8701 stat.pm = (tmp & 0x0080) ? 1 : 0;
8702 stat.im = (tmp & 0x0040) ? 1 : 0;
8703 stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8704 stat.ack = (tmp & 0x0002) ? 1 : 0;
8706 bwn_handle_txeof(mac, &stat);
8711 bwn_hwreset(void *arg, int npending)
8713 struct bwn_mac *mac = arg;
8714 struct bwn_softc *sc = mac->mac_sc;
8718 wlan_serialize_enter();
8720 prev_status = mac->mac_status;
8721 if (prev_status >= BWN_MAC_STATUS_STARTED)
8723 if (prev_status >= BWN_MAC_STATUS_INITED)
8726 if (prev_status >= BWN_MAC_STATUS_INITED) {
8727 error = bwn_core_init(mac);
8731 if (prev_status >= BWN_MAC_STATUS_STARTED)
8732 bwn_core_start(mac);
8735 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8736 sc->sc_curmac = NULL;
8738 wlan_serialize_exit();
8742 bwn_handle_fwpanic(struct bwn_mac *mac)
8744 struct bwn_softc *sc = mac->mac_sc;
8747 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8748 device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8750 if (reason == BWN_FWPANIC_RESTART)
8751 bwn_restart(mac, "ucode panic");
8755 bwn_load_beacon0(struct bwn_mac *mac)
8758 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8762 bwn_load_beacon1(struct bwn_mac *mac)
8765 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8769 bwn_jssi_read(struct bwn_mac *mac)
8773 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8775 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8781 bwn_noise_gensample(struct bwn_mac *mac)
8783 uint32_t jssi = 0x7f7f7f7f;
8785 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8786 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8787 BWN_WRITE_4(mac, BWN_MACCMD,
8788 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8792 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8794 return (dr->dr_numslots - dr->dr_usedslot);
8798 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8800 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8801 ("%s:%d: fail", __func__, __LINE__));
8802 if (slot == dr->dr_numslots - 1)
8808 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8810 struct bwn_mac *mac = dr->dr_mac;
8811 struct bwn_softc *sc = mac->mac_sc;
8812 struct bwn_dma *dma = &mac->mac_method.dma;
8813 struct bwn_dmadesc_generic *desc;
8814 struct bwn_dmadesc_meta *meta;
8815 struct bwn_rxhdr4 *rxhdr;
8816 struct ifnet *ifp = sc->sc_ifp;
8823 dr->getdesc(dr, *slot, &desc, &meta);
8825 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8828 if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8833 rxhdr = mtod(m, struct bwn_rxhdr4 *);
8834 len = le16toh(rxhdr->frame_len);
8839 if (bwn_dma_check_redzone(dr, m)) {
8840 device_printf(sc->sc_dev, "redzone error.\n");
8841 bwn_dma_set_redzone(dr, m);
8842 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8843 BUS_DMASYNC_PREWRITE);
8846 if (len > dr->dr_rx_bufsize) {
8849 dr->getdesc(dr, *slot, &desc, &meta);
8850 bwn_dma_set_redzone(dr, meta->mt_m);
8851 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8852 BUS_DMASYNC_PREWRITE);
8853 *slot = bwn_dma_nextslot(dr, *slot);
8855 tmp -= dr->dr_rx_bufsize;
8859 device_printf(sc->sc_dev, "too small buffer "
8860 "(len %u buffer %u dropped %d)\n",
8861 len, dr->dr_rx_bufsize, cnt);
8864 macstat = le32toh(rxhdr->mac_status);
8865 if (macstat & BWN_RX_MAC_FCSERR) {
8866 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8867 device_printf(sc->sc_dev, "RX drop\n");
8872 m->m_pkthdr.rcvif = ifp;
8873 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8874 m_adj(m, dr->dr_frameoffset);
8876 bwn_rxeof(dr->dr_mac, m, rxhdr);
8880 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8882 struct bwn_dma_ring *dr;
8883 struct bwn_dmadesc_generic *desc;
8884 struct bwn_dmadesc_meta *meta;
8885 struct bwn_pio_txqueue *tq;
8886 struct bwn_pio_txpkt *tp = NULL;
8887 struct bwn_softc *sc = mac->mac_sc;
8888 struct bwn_stats *stats = &mac->mac_stats;
8889 struct ieee80211_node *ni;
8890 struct ieee80211vap *vap;
8891 int retrycnt = 0, slot;
8894 device_printf(sc->sc_dev, "TODO: STATUS IM\n");
8896 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
8897 if (status->rtscnt) {
8898 if (status->rtscnt == 0xf)
8904 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8906 dr = bwn_dma_parse_cookie(mac, status,
8907 status->cookie, &slot);
8909 device_printf(sc->sc_dev,
8910 "failed to parse cookie\n");
8914 dr->getdesc(dr, slot, &desc, &meta);
8915 if (meta->mt_islast) {
8918 ieee80211_ratectl_tx_complete(vap, ni,
8920 IEEE80211_RATECTL_TX_SUCCESS :
8921 IEEE80211_RATECTL_TX_FAILURE,
8925 slot = bwn_dma_nextslot(dr, slot);
8928 bwn_dma_handle_txeof(mac, status);
8931 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
8933 device_printf(sc->sc_dev,
8934 "failed to parse cookie\n");
8939 ieee80211_ratectl_tx_complete(vap, ni,
8941 IEEE80211_RATECTL_TX_SUCCESS :
8942 IEEE80211_RATECTL_TX_FAILURE,
8945 bwn_pio_handle_txeof(mac, status);
8948 bwn_phy_txpower_check(mac, 0);
8952 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
8954 struct bwn_mac *mac = prq->prq_mac;
8955 struct bwn_softc *sc = mac->mac_sc;
8956 struct bwn_rxhdr4 rxhdr;
8957 struct ifnet *ifp = sc->sc_ifp;
8959 uint32_t ctl32, macstat, v32;
8960 unsigned int i, padding;
8961 uint16_t ctl16, len, totlen, v16;
8965 memset(&rxhdr, 0, sizeof(rxhdr));
8967 if (prq->prq_rev >= 8) {
8968 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
8969 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
8971 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
8972 BWN_PIO8_RXCTL_FRAMEREADY);
8973 for (i = 0; i < 10; i++) {
8974 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
8975 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
8980 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
8981 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
8983 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
8984 BWN_PIO_RXCTL_FRAMEREADY);
8985 for (i = 0; i < 10; i++) {
8986 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
8987 if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
8992 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
8995 if (prq->prq_rev >= 8)
8996 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
8997 prq->prq_base + BWN_PIO8_RXDATA);
8999 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9000 prq->prq_base + BWN_PIO_RXDATA);
9001 len = le16toh(rxhdr.frame_len);
9003 device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9007 device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9011 macstat = le32toh(rxhdr.mac_status);
9012 if (macstat & BWN_RX_MAC_FCSERR) {
9013 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9014 device_printf(sc->sc_dev, "%s: FCS error", __func__);
9019 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9020 totlen = len + padding;
9021 KASSERT(totlen <= MCLBYTES, ("too big..\n"));
9022 m = m_getcl(M_INTWAIT, MT_DATA, M_PKTHDR);
9024 device_printf(sc->sc_dev, "%s: out of memory", __func__);
9027 mp = mtod(m, unsigned char *);
9028 if (prq->prq_rev >= 8) {
9029 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3),
9030 prq->prq_base + BWN_PIO8_RXDATA);
9032 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9033 data = &(mp[totlen - 1]);
9034 switch (totlen & 3) {
9036 *data = (v32 >> 16);
9046 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1),
9047 prq->prq_base + BWN_PIO_RXDATA);
9049 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9050 mp[totlen - 1] = v16;
9054 m->m_pkthdr.rcvif = ifp;
9055 m->m_len = m->m_pkthdr.len = totlen;
9057 bwn_rxeof(prq->prq_mac, m, &rxhdr);
9061 if (prq->prq_rev >= 8)
9062 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9063 BWN_PIO8_RXCTL_DATAREADY);
9065 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9070 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9071 struct bwn_dmadesc_meta *meta, int init)
9073 struct bwn_mac *mac = dr->dr_mac;
9074 struct bwn_dma *dma = &mac->mac_method.dma;
9075 struct bwn_rxhdr4 *hdr;
9081 m = m_getcl(M_INTWAIT, MT_DATA, M_PKTHDR);
9086 * If the NIC is up and running, we need to:
9087 * - Clear RX buffer's header.
9088 * - Restore RX descriptor settings.
9095 m->m_len = m->m_pkthdr.len = MCLBYTES;
9097 bwn_dma_set_redzone(dr, m);
9100 * Try to load RX buf into temporary DMA map
9102 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9103 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9108 * See the comment above
9117 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9119 meta->mt_paddr = paddr;
9122 * Swap RX buf's DMA map with the loaded temporary one
9124 map = meta->mt_dmap;
9125 meta->mt_dmap = dr->dr_spare_dmap;
9126 dr->dr_spare_dmap = map;
9130 * Clear RX buf header
9132 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9133 bzero(hdr, sizeof(*hdr));
9134 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9135 BUS_DMASYNC_PREWRITE);
9138 * Setup RX buf descriptor
9140 dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len -
9141 sizeof(*hdr), 0, 0, 0);
9146 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9147 bus_size_t mapsz __unused, int error)
9151 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9152 *((bus_addr_t *)arg) = seg->ds_addr;
9157 bwn_hwrate2ieeerate(int rate)
9161 case BWN_CCK_RATE_1MB:
9163 case BWN_CCK_RATE_2MB:
9165 case BWN_CCK_RATE_5MB:
9167 case BWN_CCK_RATE_11MB:
9169 case BWN_OFDM_RATE_6MB:
9171 case BWN_OFDM_RATE_9MB:
9173 case BWN_OFDM_RATE_12MB:
9175 case BWN_OFDM_RATE_18MB:
9177 case BWN_OFDM_RATE_24MB:
9179 case BWN_OFDM_RATE_36MB:
9181 case BWN_OFDM_RATE_48MB:
9183 case BWN_OFDM_RATE_54MB:
9192 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9194 const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9195 struct bwn_plcp6 *plcp;
9196 struct bwn_softc *sc = mac->mac_sc;
9197 struct ieee80211_frame_min *wh;
9198 struct ieee80211_node *ni;
9199 struct ifnet *ifp = sc->sc_ifp;
9200 struct ieee80211com *ic = ifp->if_l2com;
9202 int padding, rate, rssi = 0, noise = 0, type;
9203 uint16_t phytype, phystat0, phystat3, chanstat;
9204 unsigned char *mp = mtod(m, unsigned char *);
9205 static int rx_mac_dec_rpt = 0;
9207 phystat0 = le16toh(rxhdr->phy_status0);
9208 phystat3 = le16toh(rxhdr->phy_status3);
9209 macstat = le32toh(rxhdr->mac_status);
9210 chanstat = le16toh(rxhdr->channel);
9211 phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9213 if (macstat & BWN_RX_MAC_FCSERR)
9214 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9215 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9216 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9217 if (macstat & BWN_RX_MAC_DECERR)
9220 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9221 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9222 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9226 plcp = (struct bwn_plcp6 *)(mp + padding);
9227 m_adj(m, sizeof(struct bwn_plcp6) + padding);
9228 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9229 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9233 wh = mtod(m, struct ieee80211_frame_min *);
9235 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9236 device_printf(sc->sc_dev,
9237 "RX decryption attempted (old %d keyidx %#x)\n",
9239 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9241 /* XXX calculating RSSI & noise & antenna */
9243 if (phystat0 & BWN_RX_PHYST0_OFDM)
9244 rate = bwn_plcp_get_ofdmrate(mac, plcp,
9245 phytype == BWN_PHYTYPE_A);
9247 rate = bwn_plcp_get_cckrate(mac, plcp);
9249 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9252 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9255 if (ieee80211_radiotap_active(ic))
9256 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9257 m_adj(m, -IEEE80211_CRC_LEN);
9259 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */
9260 noise = mac->mac_stats.link_noise;
9264 ni = ieee80211_find_rxnode(ic, wh);
9266 type = ieee80211_input(ni, m, rssi, noise);
9267 ieee80211_free_node(ni);
9269 type = ieee80211_input_all(ic, m, rssi, noise);
9273 device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9277 bwn_dma_handle_txeof(struct bwn_mac *mac,
9278 const struct bwn_txstatus *status)
9280 struct bwn_dma *dma = &mac->mac_method.dma;
9281 struct bwn_dma_ring *dr;
9282 struct bwn_dmadesc_generic *desc;
9283 struct bwn_dmadesc_meta *meta;
9284 struct bwn_softc *sc = mac->mac_sc;
9285 struct ieee80211_node *ni;
9286 struct ifnet *ifp = sc->sc_ifp;
9290 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9292 device_printf(sc->sc_dev, "failed to parse cookie\n");
9295 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9298 KASSERT(slot >= 0 && slot < dr->dr_numslots,
9299 ("%s:%d: fail", __func__, __LINE__));
9300 dr->getdesc(dr, slot, &desc, &meta);
9302 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER) {
9303 bus_dmamap_sync(dr->dr_txring_dtag, meta->mt_dmap,
9304 BUS_DMASYNC_POSTWRITE);
9305 } else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY) {
9306 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9309 if (meta->mt_islast) {
9310 KASSERT(meta->mt_m != NULL,
9311 ("%s:%d: fail", __func__, __LINE__));
9317 * Do any tx complete callback. Note this must
9318 * be done before releasing the node reference.
9320 if (m->m_flags & M_TXCB)
9321 ieee80211_process_callback(ni, m, 0);
9322 ieee80211_free_node(ni);
9328 KASSERT(meta->mt_m == NULL,
9329 ("%s:%d: fail", __func__, __LINE__));
9333 if (meta->mt_islast) {
9337 slot = bwn_dma_nextslot(dr, slot);
9339 sc->sc_watchdog_timer = 0;
9341 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9342 ("%s:%d: fail", __func__, __LINE__));
9343 ifq_clr_oactive(&ifp->if_snd);
9349 bwn_pio_handle_txeof(struct bwn_mac *mac,
9350 const struct bwn_txstatus *status)
9352 struct bwn_pio_txqueue *tq;
9353 struct bwn_pio_txpkt *tp = NULL;
9354 struct bwn_softc *sc = mac->mac_sc;
9355 struct ifnet *ifp = sc->sc_ifp;
9357 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9361 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9364 if (tp->tp_ni != NULL) {
9366 * Do any tx complete callback. Note this must
9367 * be done before releasing the node reference.
9369 if (tp->tp_m->m_flags & M_TXCB)
9370 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9371 ieee80211_free_node(tp->tp_ni);
9376 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9380 sc->sc_watchdog_timer = 0;
9382 ifq_clr_oactive(&ifp->if_snd);
9388 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9390 struct bwn_softc *sc = mac->mac_sc;
9391 struct bwn_phy *phy = &mac->mac_phy;
9392 struct ifnet *ifp = sc->sc_ifp;
9393 struct ieee80211com *ic = ifp->if_l2com;
9399 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9401 phy->nexttime = now + 2 * 1000;
9403 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9404 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9407 if (phy->recalc_txpwr != NULL) {
9408 result = phy->recalc_txpwr(mac,
9409 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9410 if (result == BWN_TXPWR_RES_DONE)
9412 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9413 ("%s: fail", __func__));
9414 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9416 ieee80211_runtask(ic, &mac->mac_txpower);
9421 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9424 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9428 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9431 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9435 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9438 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9442 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9445 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9449 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9453 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9455 return (BWN_OFDM_RATE_6MB);
9457 return (BWN_OFDM_RATE_9MB);
9459 return (BWN_OFDM_RATE_12MB);
9461 return (BWN_OFDM_RATE_18MB);
9463 return (BWN_OFDM_RATE_24MB);
9465 return (BWN_OFDM_RATE_36MB);
9467 return (BWN_OFDM_RATE_48MB);
9469 return (BWN_OFDM_RATE_54MB);
9470 /* CCK rates (NB: not IEEE std, device-specific) */
9472 return (BWN_CCK_RATE_1MB);
9474 return (BWN_CCK_RATE_2MB);
9476 return (BWN_CCK_RATE_5MB);
9478 return (BWN_CCK_RATE_11MB);
9481 device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9482 return (BWN_CCK_RATE_1MB);
9486 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9487 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9489 const struct bwn_phy *phy = &mac->mac_phy;
9490 struct bwn_softc *sc = mac->mac_sc;
9491 struct ieee80211_frame *wh;
9492 struct ieee80211_frame *protwh;
9493 struct ieee80211_frame_cts *cts;
9494 struct ieee80211_frame_rts *rts;
9495 const struct ieee80211_txparam *tp;
9496 struct ieee80211vap *vap = ni->ni_vap;
9497 struct ifnet *ifp = sc->sc_ifp;
9498 struct ieee80211com *ic = ifp->if_l2com;
9501 uint32_t macctl = 0;
9502 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9503 uint16_t phyctl = 0;
9504 uint8_t rate, rate_fb;
9506 wh = mtod(m, struct ieee80211_frame *);
9507 memset(txhdr, 0, sizeof(*txhdr));
9509 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9510 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9511 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9516 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9517 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9518 rate = rate_fb = tp->mgmtrate;
9520 rate = rate_fb = tp->mcastrate;
9521 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9522 rate = rate_fb = tp->ucastrate;
9524 rix = ieee80211_ratectl_rate(ni, NULL, 0);
9525 rate = ni->ni_txrate;
9528 rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9534 sc->sc_tx_rate = rate;
9536 rate = bwn_ieeerate2hwrate(sc, rate);
9537 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9539 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9540 bwn_plcp_getcck(rate);
9541 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9542 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9544 if ((rate_fb == rate) ||
9545 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9546 (*(u_int16_t *)wh->i_dur == htole16(0)))
9547 txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9549 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9550 m->m_pkthdr.len, rate, isshort);
9552 /* XXX TX encryption */
9553 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9554 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9555 (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9556 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9557 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9558 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9560 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9562 txhdr->chan = phy->chan;
9563 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9565 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9566 rate == BWN_CCK_RATE_11MB))
9567 phyctl |= BWN_TX_PHY_SHORTPRMBL;
9569 /* XXX TX antenna selection */
9571 switch (bwn_antenna_sanitize(mac, 0)) {
9573 phyctl |= BWN_TX_PHY_ANT01AUTO;
9576 phyctl |= BWN_TX_PHY_ANT0;
9579 phyctl |= BWN_TX_PHY_ANT1;
9582 phyctl |= BWN_TX_PHY_ANT2;
9585 phyctl |= BWN_TX_PHY_ANT3;
9588 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9592 macctl |= BWN_TX_MAC_ACK;
9594 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9595 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9596 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9597 macctl |= BWN_TX_MAC_LONGFRAME;
9599 if (ic->ic_flags & IEEE80211_F_USEPROT) {
9600 /* XXX RTS rate is always 1MB??? */
9601 rts_rate = BWN_CCK_RATE_1MB;
9602 rts_rate_fb = bwn_get_fbrate(rts_rate);
9604 protdur = ieee80211_compute_duration(ic->ic_rt,
9605 m->m_pkthdr.len, rate, isshort) +
9606 + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9608 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9609 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9610 (txhdr->body.old.rts_frame) :
9611 (txhdr->body.new.rts_frame));
9612 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9614 KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9615 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9616 mprot->m_pkthdr.len);
9618 macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9619 len = sizeof(struct ieee80211_frame_cts);
9621 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9622 (txhdr->body.old.rts_frame) :
9623 (txhdr->body.new.rts_frame));
9624 protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9626 mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9627 wh->i_addr2, protdur);
9628 KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9629 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9630 mprot->m_pkthdr.len);
9632 macctl |= BWN_TX_MAC_SEND_RTSCTS;
9633 len = sizeof(struct ieee80211_frame_rts);
9635 len += IEEE80211_CRC_LEN;
9636 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9637 &txhdr->body.old.rts_plcp :
9638 &txhdr->body.new.rts_plcp), len, rts_rate);
9639 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9642 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9643 (&txhdr->body.old.rts_frame) :
9644 (&txhdr->body.new.rts_frame));
9645 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9647 if (BWN_ISOFDMRATE(rts_rate)) {
9648 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9649 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9651 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9652 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9654 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9655 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9658 if (BWN_ISOLDFMT(mac))
9659 txhdr->body.old.cookie = htole16(cookie);
9661 txhdr->body.new.cookie = htole16(cookie);
9663 txhdr->macctl = htole32(macctl);
9664 txhdr->phyctl = htole16(phyctl);
9669 if (ieee80211_radiotap_active_vap(vap)) {
9670 sc->sc_tx_th.wt_flags = 0;
9671 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
9672 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9674 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9675 rate == BWN_CCK_RATE_11MB))
9676 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9677 sc->sc_tx_th.wt_rate = rate;
9679 ieee80211_radiotap_tx(vap, m);
9686 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9690 uint8_t *raw = plcp->o.raw;
9692 if (BWN_ISOFDMRATE(rate)) {
9693 d = bwn_plcp_getofdm(rate);
9694 KASSERT(!(octets & 0xf000),
9695 ("%s:%d: fail", __func__, __LINE__));
9697 plcp->o.data = htole32(d);
9699 plen = octets * 16 / rate;
9700 if ((octets * 16 % rate) > 0) {
9702 if ((rate == BWN_CCK_RATE_11MB)
9703 && ((octets * 8 % 11) < 4)) {
9709 plcp->o.data |= htole32(plen << 16);
9710 raw[0] = bwn_plcp_getcck(rate);
9715 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9717 struct bwn_softc *sc = mac->mac_sc;
9722 if (mac->mac_phy.gmode)
9723 mask = siba_sprom_get_ant_bg(sc->sc_dev);
9725 mask = siba_sprom_get_ant_a(sc->sc_dev);
9726 if (!(mask & (1 << (n - 1))))
9732 bwn_get_fbrate(uint8_t bitrate)
9735 case BWN_CCK_RATE_1MB:
9736 return (BWN_CCK_RATE_1MB);
9737 case BWN_CCK_RATE_2MB:
9738 return (BWN_CCK_RATE_1MB);
9739 case BWN_CCK_RATE_5MB:
9740 return (BWN_CCK_RATE_2MB);
9741 case BWN_CCK_RATE_11MB:
9742 return (BWN_CCK_RATE_5MB);
9743 case BWN_OFDM_RATE_6MB:
9744 return (BWN_CCK_RATE_5MB);
9745 case BWN_OFDM_RATE_9MB:
9746 return (BWN_OFDM_RATE_6MB);
9747 case BWN_OFDM_RATE_12MB:
9748 return (BWN_OFDM_RATE_9MB);
9749 case BWN_OFDM_RATE_18MB:
9750 return (BWN_OFDM_RATE_12MB);
9751 case BWN_OFDM_RATE_24MB:
9752 return (BWN_OFDM_RATE_18MB);
9753 case BWN_OFDM_RATE_36MB:
9754 return (BWN_OFDM_RATE_24MB);
9755 case BWN_OFDM_RATE_48MB:
9756 return (BWN_OFDM_RATE_36MB);
9757 case BWN_OFDM_RATE_54MB:
9758 return (BWN_OFDM_RATE_48MB);
9760 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9765 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9766 uint32_t ctl, const void *_data, int len)
9768 struct bwn_softc *sc = mac->mac_sc;
9770 const uint8_t *data = _data;
9772 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9773 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9774 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9776 siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9777 tq->tq_base + BWN_PIO8_TXDATA);
9779 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9780 BWN_PIO8_TXCTL_24_31);
9781 data = &(data[len - 1]);
9784 ctl |= BWN_PIO8_TXCTL_16_23;
9785 value |= (uint32_t)(*data) << 16;
9788 ctl |= BWN_PIO8_TXCTL_8_15;
9789 value |= (uint32_t)(*data) << 8;
9792 value |= (uint32_t)(*data);
9794 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9795 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9802 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9803 uint16_t offset, uint32_t value)
9806 BWN_WRITE_4(mac, tq->tq_base + offset, value);
9810 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9811 uint16_t ctl, const void *_data, int len)
9813 struct bwn_softc *sc = mac->mac_sc;
9814 const uint8_t *data = _data;
9816 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9817 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9819 siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9820 tq->tq_base + BWN_PIO_TXDATA);
9822 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9823 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9824 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9831 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9832 uint16_t ctl, struct mbuf *m0)
9837 struct mbuf *m = m0;
9839 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9840 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9842 for (; m != NULL; m = m->m_next) {
9843 buf = mtod(m, const uint8_t *);
9844 for (i = 0; i < m->m_len; i++) {
9848 data |= (buf[i] << 8);
9849 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9854 if (m0->m_pkthdr.len % 2) {
9855 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9856 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9857 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9864 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9867 if (mac->mac_phy.type != BWN_PHYTYPE_G)
9869 BWN_WRITE_2(mac, 0x684, 510 + time);
9872 * XXX ivadasz: Linux's b43 comments this. Enabling this causes a
9873 * a severe performance penalty (especially when sending).
9876 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9880 static struct bwn_dma_ring *
9881 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9884 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9885 return (mac->mac_method.dma.wme[WME_AC_BE]);
9889 return (mac->mac_method.dma.wme[WME_AC_VO]);
9891 return (mac->mac_method.dma.wme[WME_AC_VI]);
9893 return (mac->mac_method.dma.wme[WME_AC_BE]);
9895 return (mac->mac_method.dma.wme[WME_AC_BK]);
9897 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9902 bwn_dma_getslot(struct bwn_dma_ring *dr)
9906 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9907 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
9908 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
9910 slot = bwn_dma_nextslot(dr, dr->dr_curslot);
9911 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
9912 dr->dr_curslot = slot;
9919 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
9921 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
9922 unsigned int a, b, c, d;
9926 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
9928 b = (tmp >> 8) & 0xff;
9929 c = (tmp >> 16) & 0xff;
9930 d = (tmp >> 24) & 0xff;
9931 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
9932 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
9934 bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
9935 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
9936 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
9939 a = (a + 32) & 0x3f;
9940 b = (b + 32) & 0x3f;
9941 c = (c + 32) & 0x3f;
9942 d = (d + 32) & 0x3f;
9945 avg = (a + b + c + d + 2) / 4;
9947 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
9948 & BWN_HF_4DB_CCK_POWERBOOST)
9949 avg = (avg >= 13) ? (avg - 13) : 0;
9955 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
9957 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
9958 int rfatt = *rfattp;
9959 int bbatt = *bbattp;
9962 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
9964 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
9966 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
9968 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
9970 if (bbatt > lo->bbatt.max) {
9975 if (bbatt < lo->bbatt.min) {
9980 if (rfatt > lo->rfatt.max) {
9985 if (rfatt < lo->rfatt.min) {
9993 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
9994 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
9998 bwn_phy_lock(struct bwn_mac *mac)
10000 struct bwn_softc *sc = mac->mac_sc;
10001 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10003 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10004 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10006 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10007 bwn_psctl(mac, BWN_PS_AWAKE);
10011 bwn_phy_unlock(struct bwn_mac *mac)
10013 struct bwn_softc *sc = mac->mac_sc;
10014 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10016 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10017 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10019 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10024 bwn_rf_lock(struct bwn_mac *mac)
10027 BWN_WRITE_4(mac, BWN_MACCTL,
10028 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
10029 BWN_READ_4(mac, BWN_MACCTL);
10034 bwn_rf_unlock(struct bwn_mac *mac)
10037 BWN_READ_2(mac, BWN_PHYVER);
10038 BWN_WRITE_4(mac, BWN_MACCTL,
10039 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10042 static struct bwn_pio_txqueue *
10043 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10044 struct bwn_pio_txpkt **pack)
10046 struct bwn_pio *pio = &mac->mac_method.pio;
10047 struct bwn_pio_txqueue *tq = NULL;
10048 unsigned int index;
10050 switch (cookie & 0xf000) {
10052 tq = &pio->wme[WME_AC_BK];
10055 tq = &pio->wme[WME_AC_BE];
10058 tq = &pio->wme[WME_AC_VI];
10061 tq = &pio->wme[WME_AC_VO];
10067 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10070 index = (cookie & 0x0fff);
10071 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10072 if (index >= N(tq->tq_pkts))
10074 *pack = &tq->tq_pkts[index];
10075 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10080 bwn_txpwr(void *arg, int npending)
10082 struct bwn_mac *mac = arg;
10084 wlan_serialize_enter();
10085 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10086 mac->mac_phy.set_txpwr != NULL)
10087 mac->mac_phy.set_txpwr(mac);
10088 wlan_serialize_exit();
10092 bwn_task_15s(struct bwn_mac *mac)
10096 if (mac->mac_fw.opensource) {
10097 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10099 bwn_restart(mac, "fw watchdog");
10102 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10104 if (mac->mac_phy.task_15s)
10105 mac->mac_phy.task_15s(mac);
10107 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10111 bwn_task_30s(struct bwn_mac *mac)
10114 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10116 mac->mac_noise.noi_running = 1;
10117 mac->mac_noise.noi_nsamples = 0;
10119 bwn_noise_gensample(mac);
10123 bwn_task_60s(struct bwn_mac *mac)
10126 if (mac->mac_phy.task_60s)
10127 mac->mac_phy.task_60s(mac);
10128 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10132 bwn_tasks(void *arg)
10134 struct bwn_mac *mac = arg;
10135 struct bwn_softc *sc = mac->mac_sc;
10137 wlan_serialize_enter();
10139 if (mac->mac_status != BWN_MAC_STATUS_STARTED) {
10140 wlan_serialize_exit();
10144 if (mac->mac_task_state % 4 == 0)
10146 if (mac->mac_task_state % 2 == 0)
10150 mac->mac_task_state++;
10151 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10152 wlan_serialize_exit();
10156 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10158 struct bwn_softc *sc = mac->mac_sc;
10160 KASSERT(a == 0, ("not support APHY\n"));
10162 switch (plcp->o.raw[0] & 0xf) {
10164 return (BWN_OFDM_RATE_6MB);
10166 return (BWN_OFDM_RATE_9MB);
10168 return (BWN_OFDM_RATE_12MB);
10170 return (BWN_OFDM_RATE_18MB);
10172 return (BWN_OFDM_RATE_24MB);
10174 return (BWN_OFDM_RATE_36MB);
10176 return (BWN_OFDM_RATE_48MB);
10178 return (BWN_OFDM_RATE_54MB);
10180 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10181 plcp->o.raw[0] & 0xf);
10186 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10188 struct bwn_softc *sc = mac->mac_sc;
10190 switch (plcp->o.raw[0]) {
10192 return (BWN_CCK_RATE_1MB);
10194 return (BWN_CCK_RATE_2MB);
10196 return (BWN_CCK_RATE_5MB);
10198 return (BWN_CCK_RATE_11MB);
10200 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10205 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10206 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10207 int rssi, int noise)
10209 struct bwn_softc *sc = mac->mac_sc;
10210 const struct ieee80211_frame_min *wh;
10212 uint16_t low_mactime_now;
10214 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10215 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10217 wh = mtod(m, const struct ieee80211_frame_min *);
10218 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
10219 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10221 bwn_tsf_read(mac, &tsf);
10222 low_mactime_now = tsf;
10223 tsf = tsf & ~0xffffULL;
10224 tsf += le16toh(rxhdr->mac_time);
10225 if (low_mactime_now < le16toh(rxhdr->mac_time))
10228 sc->sc_rx_th.wr_tsf = tsf;
10229 sc->sc_rx_th.wr_rate = rate;
10230 sc->sc_rx_th.wr_antsignal = rssi;
10231 sc->sc_rx_th.wr_antnoise = noise;
10235 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10237 uint32_t low, high;
10239 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10240 ("%s:%d: fail", __func__, __LINE__));
10242 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10243 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10250 bwn_dma_attach(struct bwn_mac *mac)
10252 struct bwn_dma *dma = &mac->mac_method.dma;
10253 struct bwn_softc *sc = mac->mac_sc;
10254 bus_addr_t lowaddr = 0;
10257 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10260 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10262 mac->mac_flags |= BWN_MAC_FLAG_DMA;
10264 dma->dmatype = bwn_dma_gettype(mac);
10265 if (dma->dmatype == BWN_DMA_30BIT)
10266 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10267 else if (dma->dmatype == BWN_DMA_32BIT)
10268 lowaddr = BUS_SPACE_MAXADDR_32BIT;
10270 lowaddr = BUS_SPACE_MAXADDR;
10273 * Create top level DMA tag
10275 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
10276 BWN_ALIGN, 0, /* alignment, bounds */
10277 lowaddr, /* lowaddr */
10278 BUS_SPACE_MAXADDR, /* highaddr */
10279 NULL, NULL, /* filter, filterarg */
10280 MAXBSIZE, /* maxsize */
10281 BUS_SPACE_UNRESTRICTED, /* nsegments */
10282 BUS_SPACE_MAXSIZE, /* maxsegsize */
10284 &dma->parent_dtag);
10286 device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10291 * Create TX/RX mbuf DMA tag
10293 error = bus_dma_tag_create(dma->parent_dtag,
10301 BUS_SPACE_MAXSIZE_32BIT,
10305 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10308 error = bus_dma_tag_create(dma->parent_dtag,
10316 BUS_SPACE_MAXSIZE_32BIT,
10320 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10324 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10325 if (dma->wme[WME_AC_BK] == NULL)
10328 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10329 if (dma->wme[WME_AC_BE] == NULL)
10332 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10333 if (dma->wme[WME_AC_VI] == NULL)
10336 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10337 if (dma->wme[WME_AC_VO] == NULL)
10340 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10341 if (dma->mcast == NULL)
10343 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10344 if (dma->rx == NULL)
10349 fail7: bwn_dma_ringfree(&dma->mcast);
10350 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10351 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10352 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10353 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10354 fail2: bus_dma_tag_destroy(dma->txbuf_dtag);
10355 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag);
10356 fail0: bus_dma_tag_destroy(dma->parent_dtag);
10360 static struct bwn_dma_ring *
10361 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10362 uint16_t cookie, int *slot)
10364 struct bwn_dma *dma = &mac->mac_method.dma;
10365 struct bwn_dma_ring *dr;
10366 struct bwn_softc *sc = mac->mac_sc;
10368 switch (cookie & 0xf000) {
10370 dr = dma->wme[WME_AC_BK];
10373 dr = dma->wme[WME_AC_BE];
10376 dr = dma->wme[WME_AC_VI];
10379 dr = dma->wme[WME_AC_VO];
10387 ("invalid cookie value %d", cookie & 0xf000));
10389 *slot = (cookie & 0x0fff);
10390 if (*slot < 0 || *slot >= dr->dr_numslots) {
10392 * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10393 * that it occurs events which have same H/W sequence numbers.
10394 * When it's occurred just prints a WARNING msgs and ignores.
10396 KASSERT(status->seq == dma->lastseq,
10397 ("%s:%d: fail", __func__, __LINE__));
10398 device_printf(sc->sc_dev,
10399 "out of slot ranges (0 < %d < %d)\n", *slot,
10403 dma->lastseq = status->seq;
10408 bwn_dma_stop(struct bwn_mac *mac)
10410 struct bwn_dma *dma;
10412 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10414 dma = &mac->mac_method.dma;
10416 bwn_dma_ringstop(&dma->rx);
10417 bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10418 bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10419 bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10420 bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10421 bwn_dma_ringstop(&dma->mcast);
10425 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10431 bwn_dma_cleanup(*dr);
10435 bwn_pio_stop(struct bwn_mac *mac)
10437 struct bwn_pio *pio;
10439 if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10441 pio = &mac->mac_method.pio;
10443 bwn_destroy_queue_tx(&pio->mcast);
10444 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10445 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10446 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10447 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10451 bwn_led_attach(struct bwn_mac *mac)
10453 struct bwn_softc *sc = mac->mac_sc;
10454 const uint8_t *led_act = NULL;
10455 uint16_t val[BWN_LED_MAX];
10458 sc->sc_led_idle = (2350 * hz) / 1000;
10459 sc->sc_led_blink = 1;
10461 for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10462 if (siba_get_pci_subvendor(sc->sc_dev) ==
10463 bwn_vendor_led_act[i].vid) {
10464 led_act = bwn_vendor_led_act[i].led_act;
10468 if (led_act == NULL)
10469 led_act = bwn_default_led_act;
10471 val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10472 val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10473 val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10474 val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10476 for (i = 0; i < BWN_LED_MAX; ++i) {
10477 struct bwn_led *led = &sc->sc_leds[i];
10479 if (val[i] == 0xff) {
10480 led->led_act = led_act[i];
10482 if (val[i] & BWN_LED_ACT_LOW)
10483 led->led_flags |= BWN_LED_F_ACTLOW;
10484 led->led_act = val[i] & BWN_LED_ACT_MASK;
10486 led->led_mask = (1 << i);
10488 if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10489 led->led_act == BWN_LED_ACT_BLINK_POLL ||
10490 led->led_act == BWN_LED_ACT_BLINK) {
10491 led->led_flags |= BWN_LED_F_BLINK;
10492 if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10493 led->led_flags |= BWN_LED_F_POLLABLE;
10494 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10495 led->led_flags |= BWN_LED_F_SLOW;
10497 if (sc->sc_blink_led == NULL) {
10498 sc->sc_blink_led = led;
10499 if (led->led_flags & BWN_LED_F_SLOW)
10500 BWN_LED_SLOWDOWN(sc->sc_led_idle);
10504 DPRINTF(sc, BWN_DEBUG_LED,
10505 "%dth led, act %d, lowact %d\n", i,
10506 led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10508 callout_init(&sc->sc_led_blink_ch);
10511 static __inline uint16_t
10512 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10515 if (led->led_flags & BWN_LED_F_ACTLOW)
10518 val |= led->led_mask;
10520 val &= ~led->led_mask;
10525 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10527 struct bwn_softc *sc = mac->mac_sc;
10528 struct ifnet *ifp = sc->sc_ifp;
10529 struct ieee80211com *ic = ifp->if_l2com;
10533 if (nstate == IEEE80211_S_INIT) {
10534 callout_stop(&sc->sc_led_blink_ch);
10535 sc->sc_led_blinking = 0;
10538 if ((ic->ic_ifp->if_flags & IFF_RUNNING) == 0)
10541 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10542 for (i = 0; i < BWN_LED_MAX; ++i) {
10543 struct bwn_led *led = &sc->sc_leds[i];
10546 if (led->led_act == BWN_LED_ACT_UNKN ||
10547 led->led_act == BWN_LED_ACT_NULL)
10550 if ((led->led_flags & BWN_LED_F_BLINK) &&
10551 nstate != IEEE80211_S_INIT)
10554 switch (led->led_act) {
10555 case BWN_LED_ACT_ON: /* Always on */
10558 case BWN_LED_ACT_OFF: /* Always off */
10559 case BWN_LED_ACT_5GHZ: /* TODO: 11A */
10565 case IEEE80211_S_INIT:
10568 case IEEE80211_S_RUN:
10569 if (led->led_act == BWN_LED_ACT_11G &&
10570 ic->ic_curmode != IEEE80211_MODE_11G)
10574 if (led->led_act == BWN_LED_ACT_ASSOC)
10581 val = bwn_led_onoff(led, val, on);
10583 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10587 bwn_led_event(struct bwn_mac *mac, int event)
10589 struct bwn_softc *sc = mac->mac_sc;
10590 struct bwn_led *led = sc->sc_blink_led;
10593 if (event == BWN_LED_EVENT_POLL) {
10594 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10596 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10600 sc->sc_led_ticks = ticks;
10601 if (sc->sc_led_blinking)
10605 case BWN_LED_EVENT_RX:
10606 rate = sc->sc_rx_rate;
10608 case BWN_LED_EVENT_TX:
10609 rate = sc->sc_tx_rate;
10611 case BWN_LED_EVENT_POLL:
10615 panic("unknown LED event %d\n", event);
10618 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10619 bwn_led_duration[rate].off_dur);
10623 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10625 struct bwn_softc *sc = mac->mac_sc;
10626 struct bwn_led *led = sc->sc_blink_led;
10629 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10630 val = bwn_led_onoff(led, val, 1);
10631 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10633 if (led->led_flags & BWN_LED_F_SLOW) {
10634 BWN_LED_SLOWDOWN(on_dur);
10635 BWN_LED_SLOWDOWN(off_dur);
10638 sc->sc_led_blinking = 1;
10639 sc->sc_led_blink_offdur = off_dur;
10641 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10645 bwn_led_blink_next(void *arg)
10647 struct bwn_mac *mac = arg;
10648 struct bwn_softc *sc = mac->mac_sc;
10651 wlan_serialize_enter();
10653 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10654 val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10655 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10657 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10658 bwn_led_blink_end, mac);
10659 wlan_serialize_exit();
10663 bwn_led_blink_end(void *arg)
10665 struct bwn_mac *mac = arg;
10666 struct bwn_softc *sc = mac->mac_sc;
10668 sc->sc_led_blinking = 0;
10672 bwn_suspend(device_t dev)
10674 struct bwn_softc *sc = device_get_softc(dev);
10676 wlan_serialize_enter();
10678 wlan_serialize_exit();
10684 bwn_resume(device_t dev)
10686 struct bwn_softc *sc = device_get_softc(dev);
10687 struct ifnet *ifp = sc->sc_ifp;
10689 wlan_serialize_enter();
10690 if (ifp->if_flags & IFF_UP)
10692 wlan_serialize_exit();
10697 bwn_rfswitch(void *arg)
10699 struct bwn_softc *sc = arg;
10700 struct bwn_mac *mac = sc->sc_curmac;
10701 int cur = 0, prev = 0;
10703 wlan_serialize_enter();
10705 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10706 ("%s: invalid MAC status %d", __func__, mac->mac_status));
10708 if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10709 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10710 & BWN_RF_HWENABLED_HI_MASK))
10713 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10714 & BWN_RF_HWENABLED_LO_MASK)
10718 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10723 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10725 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10727 device_printf(sc->sc_dev,
10728 "status of RF switch is changed to %s\n",
10729 cur ? "ON" : "OFF");
10730 if (cur != mac->mac_phy.rf_on) {
10732 bwn_rf_turnon(mac);
10734 bwn_rf_turnoff(mac);
10738 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
10739 wlan_serialize_exit();
10743 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10745 struct bwn_phy *phy = &mac->mac_phy;
10746 struct bwn_phy_lp *plp = &phy->phy_lp;
10748 plp->plp_antenna = BWN_ANT_DEFAULT;
10752 bwn_phy_lp_init(struct bwn_mac *mac)
10754 static const struct bwn_stxtable tables[] = {
10755 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10756 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff },
10757 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff },
10758 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10759 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f },
10760 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10761 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 },
10762 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f },
10763 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10764 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 },
10765 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10766 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 },
10767 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f },
10768 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f },
10769 { 2, 11, 0x40, 0, 0x0f }
10771 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10772 struct bwn_softc *sc = mac->mac_sc;
10773 const struct bwn_stxtable *st;
10774 struct ifnet *ifp = sc->sc_ifp;
10775 struct ieee80211com *ic = ifp->if_l2com;
10779 bwn_phy_lp_readsprom(mac); /* XXX bad place */
10780 bwn_phy_lp_bbinit(mac);
10782 /* initialize RF */
10783 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10785 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10788 if (mac->mac_phy.rf_ver == 0x2062)
10789 bwn_phy_lp_b2062_init(mac);
10791 bwn_phy_lp_b2063_init(mac);
10793 /* synchronize stx table. */
10794 for (i = 0; i < N(tables); i++) {
10796 tmp = BWN_RF_READ(mac, st->st_rfaddr);
10797 tmp >>= st->st_rfshift;
10798 tmp <<= st->st_physhift;
10799 BWN_PHY_SETMASK(mac,
10800 BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10801 ~(st->st_mask << st->st_physhift), tmp);
10804 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10805 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10809 if (mac->mac_phy.rev >= 2)
10810 bwn_phy_lp_rxcal_r2(mac);
10811 else if (!plp->plp_rccap) {
10812 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10813 bwn_phy_lp_rccal_r12(mac);
10815 bwn_phy_lp_set_rccap(mac);
10817 error = bwn_phy_lp_switch_channel(mac, 7);
10819 device_printf(sc->sc_dev,
10820 "failed to change channel 7 (%d)\n", error);
10821 bwn_phy_lp_txpctl_init(mac);
10822 bwn_phy_lp_calib(mac);
10827 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10830 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10831 return (BWN_READ_2(mac, BWN_PHYDATA));
10835 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10838 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10839 BWN_WRITE_2(mac, BWN_PHYDATA, value);
10843 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10847 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10848 BWN_WRITE_2(mac, BWN_PHYDATA,
10849 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10853 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10856 KASSERT(reg != 1, ("unaccessible register %d", reg));
10857 if (mac->mac_phy.rev < 2 && reg != 0x4001)
10859 if (mac->mac_phy.rev >= 2)
10861 BWN_WRITE_2(mac, BWN_RFCTL, reg);
10862 return BWN_READ_2(mac, BWN_RFDATALO);
10866 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10869 KASSERT(reg != 1, ("unaccessible register %d", reg));
10870 BWN_WRITE_2(mac, BWN_RFCTL, reg);
10871 BWN_WRITE_2(mac, BWN_RFDATALO, value);
10875 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10879 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10880 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10881 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10885 if (mac->mac_phy.rev >= 2) {
10886 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10887 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10888 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10889 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10890 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
10894 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
10895 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10896 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
10897 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
10901 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
10903 struct bwn_phy *phy = &mac->mac_phy;
10904 struct bwn_phy_lp *plp = &phy->phy_lp;
10907 if (phy->rf_ver == 0x2063) {
10908 error = bwn_phy_lp_b2063_switch_channel(mac, chan);
10912 error = bwn_phy_lp_b2062_switch_channel(mac, chan);
10915 bwn_phy_lp_set_anafilter(mac, chan);
10916 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
10919 plp->plp_chan = chan;
10920 BWN_WRITE_2(mac, BWN_CHANNEL, chan);
10925 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
10927 struct bwn_softc *sc = mac->mac_sc;
10928 struct ifnet *ifp = sc->sc_ifp;
10929 struct ieee80211com *ic = ifp->if_l2com;
10931 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
10935 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
10937 struct bwn_phy *phy = &mac->mac_phy;
10938 struct bwn_phy_lp *plp = &phy->phy_lp;
10940 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
10943 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
10944 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
10945 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
10946 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
10947 plp->plp_antenna = antenna;
10951 bwn_phy_lp_task_60s(struct bwn_mac *mac)
10954 bwn_phy_lp_calib(mac);
10958 bwn_phy_lp_readsprom(struct bwn_mac *mac)
10960 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10961 struct bwn_softc *sc = mac->mac_sc;
10962 struct ifnet *ifp = sc->sc_ifp;
10963 struct ieee80211com *ic = ifp->if_l2com;
10965 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
10966 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
10967 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
10968 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
10969 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
10970 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
10971 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
10975 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
10976 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
10977 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
10978 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
10979 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
10980 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
10981 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
10982 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
10986 bwn_phy_lp_bbinit(struct bwn_mac *mac)
10989 bwn_phy_lp_tblinit(mac);
10990 if (mac->mac_phy.rev >= 2)
10991 bwn_phy_lp_bbinit_r2(mac);
10993 bwn_phy_lp_bbinit_r01(mac);
10997 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
10999 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
11000 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
11001 struct bwn_softc *sc = mac->mac_sc;
11002 struct ifnet *ifp = sc->sc_ifp;
11003 struct ieee80211com *ic = ifp->if_l2com;
11005 bwn_phy_lp_set_txgain(mac,
11006 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
11007 bwn_phy_lp_set_bbmult(mac, 150);
11011 bwn_phy_lp_calib(struct bwn_mac *mac)
11013 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11014 struct bwn_softc *sc = mac->mac_sc;
11015 struct ifnet *ifp = sc->sc_ifp;
11016 struct ieee80211com *ic = ifp->if_l2com;
11017 const struct bwn_rxcompco *rc = NULL;
11018 struct bwn_txgain ogain;
11019 int i, omode, oafeovr, orf, obbmult;
11020 uint8_t mode, fc = 0;
11022 if (plp->plp_chanfullcal != plp->plp_chan) {
11023 plp->plp_chanfullcal = plp->plp_chan;
11027 bwn_mac_suspend(mac);
11029 /* BlueTooth Coexistance Override */
11030 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
11031 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
11033 if (mac->mac_phy.rev >= 2)
11034 bwn_phy_lp_digflt_save(mac);
11035 bwn_phy_lp_get_txpctlmode(mac);
11036 mode = plp->plp_txpctlmode;
11037 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11038 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
11039 bwn_phy_lp_bugfix(mac);
11040 if (mac->mac_phy.rev >= 2 && fc == 1) {
11041 bwn_phy_lp_get_txpctlmode(mac);
11042 omode = plp->plp_txpctlmode;
11043 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11045 ogain = bwn_phy_lp_get_txgain(mac);
11046 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11047 obbmult = bwn_phy_lp_get_bbmult(mac);
11048 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11050 bwn_phy_lp_set_txgain(mac, &ogain);
11051 bwn_phy_lp_set_bbmult(mac, obbmult);
11052 bwn_phy_lp_set_txpctlmode(mac, omode);
11053 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11055 bwn_phy_lp_set_txpctlmode(mac, mode);
11056 if (mac->mac_phy.rev >= 2)
11057 bwn_phy_lp_digflt_restore(mac);
11059 /* do RX IQ Calculation; assumes that noise is true. */
11060 if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11061 for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11062 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11063 rc = &bwn_rxcompco_5354[i];
11065 } else if (mac->mac_phy.rev >= 2)
11066 rc = &bwn_rxcompco_r2;
11068 for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11069 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11070 rc = &bwn_rxcompco_r12[i];
11076 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11077 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11079 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11081 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11082 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11083 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11085 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11086 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11089 bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11090 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11091 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11092 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11093 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11094 bwn_phy_lp_set_deaf(mac, 0);
11095 /* XXX no checking return value? */
11096 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11097 bwn_phy_lp_clear_deaf(mac, 0);
11098 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11099 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11100 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11102 /* disable RX GAIN override. */
11103 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11104 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11105 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11106 if (mac->mac_phy.rev >= 2) {
11107 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11108 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11109 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11110 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11113 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11116 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11117 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11119 bwn_mac_enable(mac);
11123 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11127 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11131 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11132 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11136 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11138 static const struct bwn_b206x_chan *bc = NULL;
11139 struct bwn_softc *sc = mac->mac_sc;
11140 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11142 uint16_t old, scale, tmp16;
11145 for (i = 0; i < N(bwn_b2063_chantable); i++) {
11146 if (bwn_b2063_chantable[i].bc_chan == chan) {
11147 bc = &bwn_b2063_chantable[i];
11154 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11155 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11156 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11157 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11158 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11159 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11160 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11161 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11162 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11163 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11164 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11165 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11167 old = BWN_RF_READ(mac, BWN_B2063_COM15);
11168 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11170 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11171 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11172 freqref = freqxtal * 3;
11173 div = (freqxtal <= 26000000 ? 1 : 2);
11174 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11175 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11176 999999) / 1000000) + 1;
11178 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11179 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11180 0xfff8, timeout >> 2);
11181 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11182 0xff9f,timeout << 5);
11183 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11185 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11186 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11187 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11189 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11190 (timeoutref + 1)) - 1;
11191 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11193 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11195 tmp[0] = ((val[2] * 62500) / freqref) << 4;
11196 tmp[1] = ((val[2] * 62500) % freqref) << 4;
11197 while (tmp[1] >= freqref) {
11201 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11202 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11203 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11204 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11205 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11207 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11208 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11209 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11210 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11212 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11213 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11215 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11217 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11220 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11222 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11223 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11225 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11230 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11231 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11233 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11234 if (freqxtal > 26000000)
11235 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11237 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11240 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11242 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11244 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11246 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11248 /* VCO Calibration */
11249 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11250 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11251 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11253 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11255 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11257 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11259 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11261 BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11266 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11268 struct bwn_softc *sc = mac->mac_sc;
11269 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11270 const struct bwn_b206x_chan *bc = NULL;
11271 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11275 for (i = 0; i < N(bwn_b2062_chantable); i++) {
11276 if (bwn_b2062_chantable[i].bc_chan == chan) {
11277 bc = &bwn_b2062_chantable[i];
11285 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11286 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11287 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11288 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11289 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11290 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11291 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11292 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11293 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11294 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11296 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11297 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11298 bwn_phy_lp_b2062_reset_pllbias(mac);
11299 tmp[0] = freqxtal / 1000;
11300 tmp[1] = plp->plp_div * 1000;
11301 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11302 if (ieee80211_ieee2mhz(chan, 0) < 4000)
11304 tmp[3] = 48 * tmp[0];
11305 tmp[5] = tmp[2] / tmp[3];
11306 tmp[6] = tmp[2] % tmp[3];
11307 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11308 tmp[4] = tmp[6] * 0x100;
11309 tmp[5] = tmp[4] / tmp[3];
11310 tmp[6] = tmp[4] % tmp[3];
11311 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11312 tmp[4] = tmp[6] * 0x100;
11313 tmp[5] = tmp[4] / tmp[3];
11314 tmp[6] = tmp[4] % tmp[3];
11315 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11316 tmp[4] = tmp[6] * 0x100;
11317 tmp[5] = tmp[4] / tmp[3];
11318 tmp[6] = tmp[4] % tmp[3];
11319 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11320 tmp[5] + ((2 * tmp[6]) / tmp[3]));
11321 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11322 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11323 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11324 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11326 bwn_phy_lp_b2062_vco_calib(mac);
11327 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11328 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11329 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11330 bwn_phy_lp_b2062_reset_pllbias(mac);
11331 bwn_phy_lp_b2062_vco_calib(mac);
11332 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11333 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11337 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11342 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11344 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11345 uint16_t tmp = (channel == 14);
11347 if (mac->mac_phy.rev < 2) {
11348 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11349 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11350 bwn_phy_lp_set_rccap(mac);
11354 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11358 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11360 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11361 struct bwn_softc *sc = mac->mac_sc;
11362 struct ifnet *ifp = sc->sc_ifp;
11363 struct ieee80211com *ic = ifp->if_l2com;
11364 uint16_t iso, tmp[3];
11366 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11368 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11369 iso = plp->plp_txisoband_m;
11370 else if (freq <= 5320)
11371 iso = plp->plp_txisoband_l;
11372 else if (freq <= 5700)
11373 iso = plp->plp_txisoband_m;
11375 iso = plp->plp_txisoband_h;
11377 tmp[0] = ((iso - 26) / 12) << 12;
11378 tmp[1] = tmp[0] + 0x1000;
11379 tmp[2] = tmp[0] + 0x2000;
11381 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11382 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11386 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11388 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11390 static const uint16_t addr[] = {
11391 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11392 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11393 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11394 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11395 BWN_PHY_OFDM(0xcf),
11397 static const uint16_t val[] = {
11398 0xde5e, 0xe832, 0xe331, 0x4d26,
11399 0x0026, 0x1420, 0x0020, 0xfe08,
11403 for (i = 0; i < N(addr); i++) {
11404 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11405 BWN_PHY_WRITE(mac, addr[i], val[i]);
11410 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11412 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11413 struct bwn_softc *sc = mac->mac_sc;
11416 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11417 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11418 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11419 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11421 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11422 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11424 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11425 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11428 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11429 device_printf(sc->sc_dev, "unknown command mode\n");
11435 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11437 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11441 bwn_phy_lp_get_txpctlmode(mac);
11442 old = plp->plp_txpctlmode;
11445 plp->plp_txpctlmode = mode;
11447 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11448 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11450 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11451 0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11453 /* disable TX GAIN override */
11454 if (mac->mac_phy.rev < 2)
11455 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11457 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11458 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11460 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11462 plp->plp_txpwridx = -1;
11464 if (mac->mac_phy.rev >= 2) {
11465 if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11466 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11468 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11471 /* writes TX Power Control mode */
11472 switch (plp->plp_txpctlmode) {
11473 case BWN_PHYLP_TXPCTL_OFF:
11474 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11476 case BWN_PHYLP_TXPCTL_ON_HW:
11477 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11479 case BWN_PHYLP_TXPCTL_ON_SW:
11480 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11484 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11486 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11487 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11491 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11493 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11494 const unsigned int size = 256;
11495 struct bwn_txgain tg;
11496 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11497 uint16_t tssinpt, tssiidx, value[2];
11501 tabs = (uint32_t *)kmalloc(sizeof(uint32_t) * size, M_DEVBUF,
11502 M_INTWAIT | M_ZERO);
11504 bwn_phy_lp_get_txpctlmode(mac);
11505 mode = plp->plp_txpctlmode;
11506 txpwridx = plp->plp_txpwridx;
11507 tssinpt = plp->plp_tssinpt;
11508 tssiidx = plp->plp_tssiidx;
11510 bwn_tab_read_multi(mac,
11511 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11512 BWN_TAB_4(7, 0x140), size, tabs);
11514 bwn_phy_lp_tblinit(mac);
11515 bwn_phy_lp_bbinit(mac);
11516 bwn_phy_lp_txpctl_init(mac);
11517 bwn_phy_lp_rf_onoff(mac, 1);
11518 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11520 bwn_tab_write_multi(mac,
11521 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11522 BWN_TAB_4(7, 0x140), size, tabs);
11524 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11525 plp->plp_tssinpt = tssinpt;
11526 plp->plp_tssiidx = tssiidx;
11527 bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11528 if (txpwridx != -1) {
11529 /* set TX power by index */
11530 plp->plp_txpwridx = txpwridx;
11531 bwn_phy_lp_get_txpctlmode(mac);
11532 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11533 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11534 if (mac->mac_phy.rev >= 2) {
11535 rxcomp = bwn_tab_read(mac,
11536 BWN_TAB_4(7, txpwridx + 320));
11537 txgain = bwn_tab_read(mac,
11538 BWN_TAB_4(7, txpwridx + 192));
11539 tg.tg_pad = (txgain >> 16) & 0xff;
11540 tg.tg_gm = txgain & 0xff;
11541 tg.tg_pga = (txgain >> 8) & 0xff;
11542 tg.tg_dac = (rxcomp >> 28) & 0xff;
11543 bwn_phy_lp_set_txgain(mac, &tg);
11545 rxcomp = bwn_tab_read(mac,
11546 BWN_TAB_4(10, txpwridx + 320));
11547 txgain = bwn_tab_read(mac,
11548 BWN_TAB_4(10, txpwridx + 192));
11549 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11550 0xf800, (txgain >> 4) & 0x7fff);
11551 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11552 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11554 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11557 value[0] = (rxcomp >> 10) & 0x3ff;
11558 value[1] = rxcomp & 0x3ff;
11559 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11561 coeff = bwn_tab_read(mac,
11562 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11563 BWN_TAB_4(10, txpwridx + 448));
11564 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11565 if (mac->mac_phy.rev >= 2) {
11566 rfpwr = bwn_tab_read(mac,
11567 BWN_TAB_4(7, txpwridx + 576));
11568 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11571 bwn_phy_lp_set_txgain_override(mac);
11573 if (plp->plp_rccap)
11574 bwn_phy_lp_set_rccap(mac);
11575 bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11576 bwn_phy_lp_set_txpctlmode(mac, mode);
11577 kfree(tabs, M_DEVBUF);
11581 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11583 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11585 static const uint16_t addr[] = {
11586 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11587 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11588 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11589 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11590 BWN_PHY_OFDM(0xcf),
11593 for (i = 0; i < N(addr); i++)
11594 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11598 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11600 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11602 if (mac->mac_phy.rev < 2) {
11603 bwn_phy_lp_tblinit_r01(mac);
11604 bwn_phy_lp_tblinit_txgain(mac);
11605 bwn_phy_lp_set_gaintbl(mac, freq);
11609 bwn_phy_lp_tblinit_r2(mac);
11610 bwn_phy_lp_tblinit_txgain(mac);
11618 struct bwn_smpair {
11625 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11627 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11628 struct bwn_softc *sc = mac->mac_sc;
11629 struct ifnet *ifp = sc->sc_ifp;
11630 struct ieee80211com *ic = ifp->if_l2com;
11631 static const struct bwn_wpair v1[] = {
11632 { BWN_PHY_AFE_DAC_CTL, 0x50 },
11633 { BWN_PHY_AFE_CTL, 0x8800 },
11634 { BWN_PHY_AFE_CTL_OVR, 0 },
11635 { BWN_PHY_AFE_CTL_OVRVAL, 0 },
11636 { BWN_PHY_RF_OVERRIDE_0, 0 },
11637 { BWN_PHY_RF_OVERRIDE_2, 0 },
11638 { BWN_PHY_OFDM(0xf9), 0 },
11639 { BWN_PHY_TR_LOOKUP_1, 0 }
11641 static const struct bwn_smpair v2[] = {
11642 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11643 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11644 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11645 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11646 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11648 static const struct bwn_smpair v3[] = {
11649 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11650 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11651 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11652 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11653 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11654 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11655 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11656 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11657 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11658 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11663 for (i = 0; i < N(v1); i++)
11664 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11665 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11666 for (i = 0; i < N(v2); i++)
11667 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11669 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11670 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11671 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11672 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11673 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11674 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11676 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11678 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11679 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11680 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11681 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11682 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11683 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11684 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11685 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11686 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11687 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11688 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11689 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11690 (siba_get_chiprev(sc->sc_dev) == 0)) {
11691 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11692 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11694 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11695 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11697 for (i = 0; i < N(v3); i++)
11698 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11699 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11700 (siba_get_chiprev(sc->sc_dev) == 0)) {
11701 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11702 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11705 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11706 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11707 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11708 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11709 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11710 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11711 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11713 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11715 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11716 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11717 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11718 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11719 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11720 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11721 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11722 0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11723 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11725 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11726 (siba_get_chiprev(sc->sc_dev) == 0)) {
11727 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11728 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11729 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11732 bwn_phy_lp_digflt_save(mac);
11736 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11738 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11739 struct bwn_softc *sc = mac->mac_sc;
11740 struct ifnet *ifp = sc->sc_ifp;
11741 struct ieee80211com *ic = ifp->if_l2com;
11742 static const struct bwn_smpair v1[] = {
11743 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11744 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11745 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11746 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11747 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11748 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11749 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11751 static const struct bwn_smpair v2[] = {
11752 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11753 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11754 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11755 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11756 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11757 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11758 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11759 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11760 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11761 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11762 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11763 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11764 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11765 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11766 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11767 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11769 static const struct bwn_smpair v3[] = {
11770 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11771 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11772 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11773 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11774 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11775 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11776 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11777 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11779 static const struct bwn_smpair v4[] = {
11780 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11781 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11782 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11783 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11784 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11785 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11786 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11787 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11789 static const struct bwn_smpair v5[] = {
11790 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11791 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11792 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11793 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11794 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11795 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11796 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11797 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11800 uint16_t tmp, tmp2;
11802 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11803 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11804 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11805 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11806 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11807 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11808 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11809 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11810 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11811 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11812 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11813 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11814 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11815 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11816 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11817 for (i = 0; i < N(v1); i++)
11818 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11819 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11820 0xff00, plp->plp_rxpwroffset);
11821 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11822 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11823 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11824 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11825 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11826 if (mac->mac_phy.rev == 0)
11827 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11829 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11831 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11832 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11833 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11835 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11836 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11837 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11838 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11840 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11841 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11842 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11843 0xfff9, (plp->plp_bxarch << 1));
11844 if (mac->mac_phy.rev == 1 &&
11845 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11846 for (i = 0; i < N(v2); i++)
11847 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11849 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11850 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11851 ((mac->mac_phy.rev == 0) &&
11852 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11853 for (i = 0; i < N(v3); i++)
11854 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11856 } else if (mac->mac_phy.rev == 1 ||
11857 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11858 for (i = 0; i < N(v4); i++)
11859 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11862 for (i = 0; i < N(v5); i++)
11863 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11866 if (mac->mac_phy.rev == 1 &&
11867 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11868 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11869 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11870 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11871 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11873 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11874 (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11875 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11876 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11877 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11878 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11879 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11881 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11882 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11883 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11884 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11885 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11886 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11887 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
11888 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
11889 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11891 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
11892 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
11894 if (mac->mac_phy.rev == 1) {
11895 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
11896 tmp2 = (tmp & 0x03e0) >> 5;
11898 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
11899 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
11900 tmp2 = (tmp & 0x1f00) >> 8;
11902 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
11903 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
11904 tmp2 = tmp & 0x00ff;
11906 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
11910 struct bwn_b2062_freq {
11916 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
11918 #define CALC_CTL7(freq, div) \
11919 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
11920 #define CALC_CTL18(freq, div) \
11921 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
11922 #define CALC_CTL19(freq, div) \
11923 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
11924 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11925 struct bwn_softc *sc = mac->mac_sc;
11926 struct ifnet *ifp = sc->sc_ifp;
11927 struct ieee80211com *ic = ifp->if_l2com;
11928 static const struct bwn_b2062_freq freqdata_tab[] = {
11929 { 12000, { 6, 6, 6, 6, 10, 6 } },
11930 { 13000, { 4, 4, 4, 4, 11, 7 } },
11931 { 14400, { 3, 3, 3, 3, 12, 7 } },
11932 { 16200, { 3, 3, 3, 3, 13, 8 } },
11933 { 18000, { 2, 2, 2, 2, 14, 8 } },
11934 { 19200, { 1, 1, 1, 1, 14, 9 } }
11936 static const struct bwn_wpair v1[] = {
11937 { BWN_B2062_N_TXCTL3, 0 },
11938 { BWN_B2062_N_TXCTL4, 0 },
11939 { BWN_B2062_N_TXCTL5, 0 },
11940 { BWN_B2062_N_TXCTL6, 0 },
11941 { BWN_B2062_N_PDNCTL0, 0x40 },
11942 { BWN_B2062_N_PDNCTL0, 0 },
11943 { BWN_B2062_N_CALIB_TS, 0x10 },
11944 { BWN_B2062_N_CALIB_TS, 0 }
11946 const struct bwn_b2062_freq *f = NULL;
11947 uint32_t xtalfreq, ref;
11950 bwn_phy_lp_b2062_tblinit(mac);
11952 for (i = 0; i < N(v1); i++)
11953 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
11954 if (mac->mac_phy.rev > 0)
11955 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
11956 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
11957 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11958 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
11960 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
11962 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
11963 ("%s:%d: fail", __func__, __LINE__));
11964 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11965 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
11967 if (xtalfreq <= 30000000) {
11969 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
11972 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
11975 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
11976 CALC_CTL7(xtalfreq, plp->plp_div));
11977 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
11978 CALC_CTL18(xtalfreq, plp->plp_div));
11979 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
11980 CALC_CTL19(xtalfreq, plp->plp_div));
11982 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
11984 for (i = 0; i < N(freqdata_tab); i++) {
11985 if (ref < freqdata_tab[i].freq) {
11986 f = &freqdata_tab[i];
11991 f = &freqdata_tab[N(freqdata_tab) - 1];
11992 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
11993 ((uint16_t)(f->value[1]) << 4) | f->value[0]);
11994 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
11995 ((uint16_t)(f->value[3]) << 4) | f->value[2]);
11996 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
11997 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
12004 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
12007 bwn_phy_lp_b2063_tblinit(mac);
12008 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
12009 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
12010 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
12011 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
12012 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
12013 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
12014 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
12015 if (mac->mac_phy.rev == 2) {
12016 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
12017 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
12018 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
12020 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
12021 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
12026 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
12028 struct bwn_softc *sc = mac->mac_sc;
12029 static const struct bwn_wpair v1[] = {
12030 { BWN_B2063_RX_BB_SP8, 0x0 },
12031 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12032 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12033 { BWN_B2063_RC_CALIB_CTL2, 0x15 },
12034 { BWN_B2063_RC_CALIB_CTL3, 0x70 },
12035 { BWN_B2063_RC_CALIB_CTL4, 0x52 },
12036 { BWN_B2063_RC_CALIB_CTL5, 0x1 },
12037 { BWN_B2063_RC_CALIB_CTL1, 0x7d }
12039 static const struct bwn_wpair v2[] = {
12040 { BWN_B2063_TX_BB_SP3, 0x0 },
12041 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12042 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12043 { BWN_B2063_RC_CALIB_CTL2, 0x55 },
12044 { BWN_B2063_RC_CALIB_CTL3, 0x76 }
12046 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12050 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12052 for (i = 0; i < 2; i++)
12053 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12054 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12055 for (i = 2; i < N(v1); i++)
12056 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12057 for (i = 0; i < 10000; i++) {
12058 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12063 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12064 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12066 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12068 for (i = 0; i < N(v2); i++)
12069 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12070 if (freqxtal == 24000000) {
12071 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12072 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12074 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12075 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12077 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12078 for (i = 0; i < 10000; i++) {
12079 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12083 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12084 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12085 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12089 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12091 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12092 struct bwn_softc *sc = mac->mac_sc;
12093 struct bwn_phy_lp_iq_est ie;
12094 struct bwn_txgain tx_gains;
12095 static const uint32_t pwrtbl[21] = {
12096 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12097 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12098 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12099 0x0004c, 0x0002c, 0x0001a,
12101 uint32_t npwr, ipwr, sqpwr, tmp;
12102 int loopback, i, j, sum, error;
12104 uint8_t txo, bbmult, txpctlmode;
12106 error = bwn_phy_lp_switch_channel(mac, 7);
12108 device_printf(sc->sc_dev,
12109 "failed to change channel to 7 (%d)\n", error);
12110 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12111 bbmult = bwn_phy_lp_get_bbmult(mac);
12113 tx_gains = bwn_phy_lp_get_txgain(mac);
12115 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12116 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12117 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12118 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12119 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12120 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12121 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12123 bwn_phy_lp_get_txpctlmode(mac);
12124 txpctlmode = plp->plp_txpctlmode;
12125 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12128 bwn_phy_lp_set_deaf(mac, 1);
12129 bwn_phy_lp_set_trsw_over(mac, 0, 1);
12130 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12131 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12132 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12133 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12134 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12135 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12136 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12137 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12138 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12139 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12140 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12141 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12142 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12143 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12144 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12145 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12146 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12147 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12148 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12149 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12150 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12151 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12152 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12154 loopback = bwn_phy_lp_loopback(mac);
12155 if (loopback == -1)
12157 bwn_phy_lp_set_rxgain_idx(mac, loopback);
12158 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12159 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12160 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12161 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12164 memset(&ie, 0, sizeof(ie));
12165 for (i = 128; i <= 159; i++) {
12166 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12168 for (j = 5; j <= 25; j++) {
12169 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12170 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12172 sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12173 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12174 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12176 sum += ((ipwr - npwr) * (ipwr - npwr));
12177 if ((i == 128) || (sum < tmp)) {
12178 plp->plp_rccap = i;
12183 bwn_phy_lp_ddfs_turnoff(mac);
12186 bwn_phy_lp_clear_deaf(mac, 1);
12187 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12188 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12190 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12191 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12192 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12193 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12194 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12195 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12196 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12198 bwn_phy_lp_set_bbmult(mac, bbmult);
12200 bwn_phy_lp_set_txgain(mac, &tx_gains);
12201 bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12202 if (plp->plp_rccap)
12203 bwn_phy_lp_set_rccap(mac);
12207 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12209 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12210 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12212 if (mac->mac_phy.rev == 1)
12213 rc_cap = MIN(rc_cap + 5, 15);
12215 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12216 MAX(plp->plp_rccap - 4, 0x80));
12217 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12218 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12219 ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12223 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12230 for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12232 if (r << 1 >= div) {
12234 r = (r << 1) - div;
12243 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12245 struct bwn_softc *sc = mac->mac_sc;
12247 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12249 if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12250 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12251 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12253 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12259 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12262 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12263 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12268 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12270 #define FLAG_A 0x01
12271 #define FLAG_G 0x02
12272 struct bwn_softc *sc = mac->mac_sc;
12273 struct ifnet *ifp = sc->sc_ifp;
12274 struct ieee80211com *ic = ifp->if_l2com;
12275 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12276 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12277 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12278 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12279 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12280 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12281 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12282 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12283 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12284 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12285 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12286 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12287 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12288 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12289 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12290 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12291 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12292 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12293 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12294 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12295 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12296 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12297 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12298 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12299 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12300 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12301 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12302 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12303 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12304 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12305 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12306 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12307 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12308 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12309 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12310 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12311 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12312 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12313 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12314 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12315 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12316 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12317 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12318 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12319 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12320 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12321 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12322 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12324 const struct bwn_b206x_rfinit_entry *br;
12327 for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12328 br = &bwn_b2062_init_tab[i];
12329 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12330 if (br->br_flags & FLAG_G)
12331 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12333 if (br->br_flags & FLAG_A)
12334 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12342 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12344 #define FLAG_A 0x01
12345 #define FLAG_G 0x02
12346 struct bwn_softc *sc = mac->mac_sc;
12347 struct ifnet *ifp = sc->sc_ifp;
12348 struct ieee80211com *ic = ifp->if_l2com;
12349 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12350 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12351 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12352 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12353 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12354 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12355 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12356 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12357 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12358 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12359 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12360 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12361 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12362 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12363 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12364 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12365 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12366 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12367 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12368 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12369 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12370 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12371 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12372 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12373 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12374 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12375 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12376 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12377 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12378 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12379 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12380 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12381 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12382 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12383 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12384 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12385 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12386 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12387 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12388 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12389 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12390 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12391 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12393 const struct bwn_b206x_rfinit_entry *br;
12396 for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12397 br = &bwn_b2063_init_tab[i];
12398 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12399 if (br->br_flags & FLAG_G)
12400 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12402 if (br->br_flags & FLAG_A)
12403 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12411 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12412 int count, void *_data)
12415 uint32_t offset, type;
12416 uint8_t *data = _data;
12418 type = BWN_TAB_GETTYPE(typenoffset);
12419 offset = BWN_TAB_GETOFFSET(typenoffset);
12420 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12422 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12424 for (i = 0; i < count; i++) {
12427 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12430 case BWN_TAB_16BIT:
12431 *((uint16_t *)data) = BWN_PHY_READ(mac,
12432 BWN_PHY_TABLEDATALO);
12435 case BWN_TAB_32BIT:
12436 *((uint32_t *)data) = BWN_PHY_READ(mac,
12437 BWN_PHY_TABLEDATAHI);
12438 *((uint32_t *)data) <<= 16;
12439 *((uint32_t *)data) |= BWN_PHY_READ(mac,
12440 BWN_PHY_TABLEDATALO);
12444 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12450 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12451 int count, const void *_data)
12453 uint32_t offset, type, value;
12454 const uint8_t *data = _data;
12457 type = BWN_TAB_GETTYPE(typenoffset);
12458 offset = BWN_TAB_GETOFFSET(typenoffset);
12459 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12461 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12463 for (i = 0; i < count; i++) {
12468 KASSERT(!(value & ~0xff),
12469 ("%s:%d: fail", __func__, __LINE__));
12470 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12472 case BWN_TAB_16BIT:
12473 value = *((const uint16_t *)data);
12475 KASSERT(!(value & ~0xffff),
12476 ("%s:%d: fail", __func__, __LINE__));
12477 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12479 case BWN_TAB_32BIT:
12480 value = *((const uint32_t *)data);
12482 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12483 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12486 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12491 static struct bwn_txgain
12492 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12494 struct bwn_txgain tg;
12497 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12498 if (mac->mac_phy.rev < 2) {
12499 tmp = BWN_PHY_READ(mac,
12500 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12501 tg.tg_gm = tmp & 0x0007;
12502 tg.tg_pga = (tmp & 0x0078) >> 3;
12503 tg.tg_pad = (tmp & 0x780) >> 7;
12507 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12508 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12509 tg.tg_gm = tmp & 0xff;
12510 tg.tg_pga = (tmp >> 8) & 0xff;
12515 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12518 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12522 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12526 if (mac->mac_phy.rev < 2) {
12527 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12528 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12529 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12530 bwn_phy_lp_set_txgain_override(mac);
12534 pa = bwn_phy_lp_get_pa_gain(mac);
12535 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12536 (tg->tg_pga << 8) | tg->tg_gm);
12537 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12538 tg->tg_pad | (pa << 6));
12539 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12540 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12541 tg->tg_pad | (pa << 8));
12542 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12543 bwn_phy_lp_set_txgain_override(mac);
12547 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12550 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12554 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12556 uint16_t trsw = (tx << 1) | rx;
12558 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12559 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12563 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12565 struct bwn_softc *sc = mac->mac_sc;
12566 struct ifnet *ifp = sc->sc_ifp;
12567 struct ieee80211com *ic = ifp->if_l2com;
12568 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12570 if (mac->mac_phy.rev < 2) {
12572 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12573 ext_lna = (gain & 2) >> 1;
12575 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12576 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12577 0xfbff, ext_lna << 10);
12578 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12579 0xf7ff, ext_lna << 11);
12580 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12582 low_gain = gain & 0xffff;
12583 high_gain = (gain >> 16) & 0xf;
12584 ext_lna = (gain >> 21) & 0x1;
12585 trsw = ~(gain >> 20) & 0x1;
12587 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12588 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12589 0xfdff, ext_lna << 9);
12590 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12591 0xfbff, ext_lna << 10);
12592 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12593 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12594 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12595 tmp = (gain >> 2) & 0x3;
12596 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12598 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12603 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12604 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12605 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12606 if (mac->mac_phy.rev >= 2) {
12607 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12608 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12609 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12610 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12614 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12618 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12620 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12623 plp->plp_crsusr_off = 1;
12625 plp->plp_crssys_off = 1;
12627 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12631 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12633 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12634 struct bwn_softc *sc = mac->mac_sc;
12635 struct ifnet *ifp = sc->sc_ifp;
12636 struct ieee80211com *ic = ifp->if_l2com;
12639 plp->plp_crsusr_off = 0;
12641 plp->plp_crssys_off = 0;
12643 if (plp->plp_crsusr_off || plp->plp_crssys_off)
12646 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12647 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12649 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12652 static unsigned int
12653 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12655 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12656 static uint8_t sqrt_table[256] = {
12657 10, 14, 17, 20, 22, 24, 26, 28,
12658 30, 31, 33, 34, 36, 37, 38, 40,
12659 41, 42, 43, 44, 45, 46, 47, 48,
12660 50, 50, 51, 52, 53, 54, 55, 56,
12661 57, 58, 59, 60, 60, 61, 62, 63,
12662 64, 64, 65, 66, 67, 67, 68, 69,
12663 70, 70, 71, 72, 72, 73, 74, 74,
12664 75, 76, 76, 77, 78, 78, 79, 80,
12665 80, 81, 81, 82, 83, 83, 84, 84,
12666 85, 86, 86, 87, 87, 88, 88, 89,
12667 90, 90, 91, 91, 92, 92, 93, 93,
12668 94, 94, 95, 95, 96, 96, 97, 97,
12669 98, 98, 99, 100, 100, 100, 101, 101,
12670 102, 102, 103, 103, 104, 104, 105, 105,
12671 106, 106, 107, 107, 108, 108, 109, 109,
12672 110, 110, 110, 111, 111, 112, 112, 113,
12673 113, 114, 114, 114, 115, 115, 116, 116,
12674 117, 117, 117, 118, 118, 119, 119, 120,
12675 120, 120, 121, 121, 122, 122, 122, 123,
12676 123, 124, 124, 124, 125, 125, 126, 126,
12677 126, 127, 127, 128, 128, 128, 129, 129,
12678 130, 130, 130, 131, 131, 131, 132, 132,
12679 133, 133, 133, 134, 134, 134, 135, 135,
12680 136, 136, 136, 137, 137, 137, 138, 138,
12681 138, 139, 139, 140, 140, 140, 141, 141,
12682 141, 142, 142, 142, 143, 143, 143, 144,
12683 144, 144, 145, 145, 145, 146, 146, 146,
12684 147, 147, 147, 148, 148, 148, 149, 149,
12685 150, 150, 150, 150, 151, 151, 151, 152,
12686 152, 152, 153, 153, 153, 154, 154, 154,
12687 155, 155, 155, 156, 156, 156, 157, 157,
12688 157, 158, 158, 158, 159, 159, 159, 160
12696 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12700 return (sqrt_table[x - 1] / 10);
12704 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12706 #define CALC_COEFF(_v, _x, _y, _z) do { \
12710 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12712 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12715 #define CALC_COEFF2(_v, _x, _y, _z) do { \
12719 _v = (_y << (31 - _x)) / (_z >> _t); \
12721 _v = (_y << (31 - _x)) / (_z << -_t); \
12723 struct bwn_phy_lp_iq_est ie;
12727 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12731 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12732 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12734 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12738 if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12743 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12744 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12746 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12750 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12751 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12758 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12760 static const uint16_t noisescale[] = {
12761 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12762 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12763 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12764 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12765 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12767 static const uint16_t crsgainnft[] = {
12768 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12769 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12770 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12771 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12774 static const uint16_t filterctl[] = {
12775 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12778 static const uint32_t psctl[] = {
12779 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12780 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12781 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12782 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12783 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12784 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12785 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12786 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12788 static const uint16_t ofdmcckgain_r0[] = {
12789 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12790 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12791 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12792 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12795 static const uint16_t ofdmcckgain_r1[] = {
12796 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12797 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12798 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12799 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12802 static const uint16_t gaindelta[] = {
12803 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12806 static const uint32_t txpwrctl[] = {
12807 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12808 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12809 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12810 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12811 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12812 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12813 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12814 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12815 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12816 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12817 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12818 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12819 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
12820 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12821 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12822 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12823 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12824 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12825 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12826 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12827 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12828 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12829 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12830 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12831 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12832 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12833 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12834 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12835 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12836 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12837 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12838 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12839 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12840 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12841 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12842 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12843 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12844 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12845 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12846 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12847 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12848 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12849 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12850 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12851 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12852 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12853 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12854 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12855 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12856 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12857 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12858 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12859 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12860 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12861 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12862 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12863 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12864 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12865 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12866 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12867 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12868 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12869 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12870 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12871 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12872 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12873 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12874 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12875 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12876 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12877 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12878 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12879 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12880 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12881 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12882 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12883 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12884 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12885 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12886 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12887 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12888 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12889 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12890 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12891 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12892 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12893 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12894 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12895 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12896 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
12897 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
12898 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
12899 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
12900 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
12901 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
12902 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
12903 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
12904 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
12905 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
12906 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
12907 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
12908 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
12909 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
12910 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
12911 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
12912 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
12913 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
12914 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
12915 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
12916 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
12917 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
12918 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
12919 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
12920 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
12921 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
12925 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
12927 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
12928 bwn_tab_sigsq_tbl);
12929 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
12930 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
12931 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
12932 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
12933 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
12934 bwn_tab_pllfrac_tbl);
12935 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
12936 bwn_tabl_iqlocal_tbl);
12937 if (mac->mac_phy.rev == 0) {
12938 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
12940 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
12943 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
12945 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
12948 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
12949 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
12953 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
12955 struct bwn_softc *sc = mac->mac_sc;
12957 static const uint16_t noisescale[] = {
12958 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12959 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12960 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12961 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12962 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12963 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12964 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
12966 static const uint32_t filterctl[] = {
12967 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
12968 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
12970 static const uint32_t psctl[] = {
12971 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
12972 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
12973 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
12974 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
12976 static const uint32_t gainidx[] = {
12977 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12978 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12979 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12980 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
12981 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
12982 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
12983 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
12984 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
12985 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
12986 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
12987 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
12988 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
12989 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
12990 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
12991 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
12992 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12993 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12994 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12995 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
12996 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
12997 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
12998 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
12999 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
13000 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
13001 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
13002 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
13003 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
13004 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
13005 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
13006 0x0000001a, 0x64ca55ad, 0x0000001a
13008 static const uint16_t auxgainidx[] = {
13009 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13010 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
13011 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
13014 static const uint16_t swctl[] = {
13015 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13016 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13017 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13018 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
13019 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13020 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13021 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13022 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
13024 static const uint8_t hf[] = {
13025 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
13026 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
13028 static const uint32_t gainval[] = {
13029 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13030 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13031 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13032 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13033 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13034 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13035 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13036 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13037 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13038 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13039 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13040 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13041 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
13042 0x000000f1, 0x00000000, 0x00000000
13044 static const uint16_t gain[] = {
13045 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13046 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13047 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13048 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13049 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13050 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
13051 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13052 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13053 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13054 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13055 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13056 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13058 static const uint32_t papdeps[] = {
13059 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13060 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13061 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13062 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13063 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13064 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13065 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13066 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13067 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13068 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13069 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13070 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13071 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13073 static const uint32_t papdmult[] = {
13074 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13075 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13076 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13077 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13078 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13079 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13080 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13081 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13082 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13083 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13084 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13085 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13086 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13088 static const uint32_t gainidx_a0[] = {
13089 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13090 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13091 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13092 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13093 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13094 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13095 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13096 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13097 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13098 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13099 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13100 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13101 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13103 static const uint16_t auxgainidx_a0[] = {
13104 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13105 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13106 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13109 static const uint32_t gainval_a0[] = {
13110 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13111 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13112 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13113 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13114 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13115 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13116 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13117 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13118 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13119 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13120 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13121 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13122 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13123 0x000000f7, 0x00000000, 0x00000000
13125 static const uint16_t gain_a0[] = {
13126 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13127 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13128 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13129 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13130 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13131 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
13132 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13133 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13134 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13135 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13136 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13137 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13140 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13142 for (i = 0; i < 704; i++)
13143 bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13145 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13146 bwn_tab_sigsq_tbl);
13147 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13148 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13149 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13150 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13151 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13152 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13153 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13154 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13155 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13156 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13157 bwn_tab_pllfrac_tbl);
13158 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13159 bwn_tabl_iqlocal_tbl);
13160 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13161 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13163 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13164 (siba_get_chiprev(sc->sc_dev) == 0)) {
13165 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13167 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13169 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13171 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13176 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13178 struct bwn_softc *sc = mac->mac_sc;
13179 struct ifnet *ifp = sc->sc_ifp;
13180 struct ieee80211com *ic = ifp->if_l2com;
13181 static struct bwn_txgain_entry txgain_r2[] = {
13182 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13183 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13184 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13185 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13186 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13187 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13188 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13189 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13190 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13191 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13192 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13193 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13194 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13195 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13196 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13197 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13198 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13199 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13200 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13201 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13202 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13203 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13204 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13205 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13206 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13207 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13208 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13209 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13210 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13211 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13212 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13213 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13214 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13215 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13216 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13217 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13218 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13219 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13220 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13221 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13222 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13223 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13224 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13225 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13226 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13227 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13228 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13229 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13230 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13231 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13232 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13233 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13234 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13235 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13236 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13237 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13238 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13239 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13240 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13241 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13242 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13243 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13244 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13245 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13247 static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13248 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13249 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13250 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13251 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13252 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13253 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13254 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13255 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13256 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13257 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13258 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13259 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13260 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13261 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13262 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13263 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13264 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13265 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13266 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13267 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13268 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13269 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13270 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13271 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13272 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13273 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13274 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13275 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13276 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13277 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13278 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13279 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13280 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13281 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13282 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13283 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13284 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13285 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13286 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13287 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13288 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13289 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13290 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13291 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13292 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13293 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13294 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13295 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13296 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13297 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13298 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13299 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13300 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13301 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13302 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13303 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13304 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13305 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13306 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13307 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13308 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13309 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13310 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13311 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13313 static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13314 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13315 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13316 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13317 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13318 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13319 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13320 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13321 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13322 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13323 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13324 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13325 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13326 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13327 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13328 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13329 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13330 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13331 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13332 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13333 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13334 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13335 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13336 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13337 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13338 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13339 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13340 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13341 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13342 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13343 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13344 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13345 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13346 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13347 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13348 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13349 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13350 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13351 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13352 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13353 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13354 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13355 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13356 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13357 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13358 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13359 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13360 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13361 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13362 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13363 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13364 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13365 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13366 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13367 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13368 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13369 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13370 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13371 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13372 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13373 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13374 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13375 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13376 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13377 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13379 static struct bwn_txgain_entry txgain_r0[] = {
13380 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13381 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13382 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13383 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13384 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13385 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13386 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13387 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13388 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13389 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13390 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13391 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13392 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13393 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13394 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13395 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13396 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13397 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13398 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13399 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13400 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13401 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13402 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13403 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13404 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13405 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13406 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13407 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13408 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13409 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13410 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13411 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13412 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13413 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13414 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13415 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13416 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13417 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13418 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13419 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13420 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13421 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13422 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13423 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13424 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13425 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13426 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13427 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13428 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13429 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13430 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13431 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13432 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13433 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13434 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13435 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13436 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13437 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13438 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13439 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13440 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13441 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13442 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13443 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13445 static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13446 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13447 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13448 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13449 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13450 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13451 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13452 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13453 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13454 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13455 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13456 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13457 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13458 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13459 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13460 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13461 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13462 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13463 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13464 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13465 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13466 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13467 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13468 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13469 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13470 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13471 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13472 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13473 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13474 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13475 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13476 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13477 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13478 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13479 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13480 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13481 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13482 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13483 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13484 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13485 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13486 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13487 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13488 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13489 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13490 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13491 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13492 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13493 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13494 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13495 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13496 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13497 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13498 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13499 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13500 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13501 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13502 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13503 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13504 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13505 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13506 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13507 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13508 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13509 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13511 static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13512 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13513 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13514 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13515 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13516 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13517 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13518 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13519 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13520 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13521 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13522 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13523 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13524 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13525 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13526 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13527 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13528 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13529 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13530 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13531 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13532 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13533 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13534 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13535 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13536 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13537 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13538 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13539 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13540 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13541 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13542 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13543 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13544 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13545 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13546 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13547 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13548 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13549 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13550 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13551 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13552 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13553 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13554 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13555 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13556 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13557 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13558 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13559 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13560 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13561 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13562 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13563 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13564 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13565 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13566 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13567 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13568 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13569 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13570 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13571 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13572 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13573 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13574 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13575 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13577 static struct bwn_txgain_entry txgain_r1[] = {
13578 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13579 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13580 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13581 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13582 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13583 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13584 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13585 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13586 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13587 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13588 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13589 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13590 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13591 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13592 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13593 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13594 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13595 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13596 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13597 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13598 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13599 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13600 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13601 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13602 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13603 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13604 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13605 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13606 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13607 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13608 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13609 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13610 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13611 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13612 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13613 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13614 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13615 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13616 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13617 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13618 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13619 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13620 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13621 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13622 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13623 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13624 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13625 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13626 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13627 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13628 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13629 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13630 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13631 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13632 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13633 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13634 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13635 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13636 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13637 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13638 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13639 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13640 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13641 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13642 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13643 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13644 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13645 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13646 { 7, 11, 6, 0, 71 }
13648 static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13649 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13650 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13651 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13652 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13653 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13654 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13655 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13656 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13657 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13658 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13659 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13660 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13661 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13662 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13663 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13664 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13665 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13666 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13667 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13668 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13669 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13670 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13671 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13672 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13673 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13674 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13675 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13676 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13677 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13678 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13679 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13680 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13681 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13682 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13683 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13684 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13685 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13686 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13687 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13688 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13689 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13690 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13691 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13692 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13693 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13694 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13695 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13696 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13697 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13698 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13699 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13700 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13701 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13702 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13703 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13704 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13705 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13706 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13707 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13708 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13709 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13710 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13711 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13712 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13714 static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13715 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13716 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13717 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13718 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13719 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13720 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13721 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13722 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13723 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13724 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13725 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13726 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13727 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13728 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13729 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13730 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13731 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13732 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13733 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13734 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13735 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13736 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13737 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13738 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13739 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13740 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13741 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13742 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13743 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13744 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13745 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13746 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13747 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13748 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13749 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13750 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13751 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13752 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13753 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13754 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13755 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13756 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13757 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13758 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13759 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13760 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13761 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13762 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13763 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13764 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13765 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13766 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13767 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13768 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13769 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13770 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13771 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13772 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13773 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13774 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13775 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13776 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13777 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13778 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13781 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13782 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13783 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13784 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13785 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13788 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13793 if (mac->mac_phy.rev == 0) {
13794 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13795 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13796 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13797 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13798 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13801 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13806 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13807 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13808 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13809 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13810 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13812 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13816 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13818 uint32_t offset, type;
13820 type = BWN_TAB_GETTYPE(typeoffset);
13821 offset = BWN_TAB_GETOFFSET(typeoffset);
13822 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13826 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13827 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13828 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13830 case BWN_TAB_16BIT:
13831 KASSERT(!(value & ~0xffff),
13832 ("%s:%d: fail", __func__, __LINE__));
13833 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13834 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13836 case BWN_TAB_32BIT:
13837 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13838 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13839 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13842 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13847 bwn_phy_lp_loopback(struct bwn_mac *mac)
13849 struct bwn_phy_lp_iq_est ie;
13853 memset(&ie, 0, sizeof(ie));
13855 bwn_phy_lp_set_trsw_over(mac, 1, 1);
13856 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13857 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13858 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13859 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13860 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13861 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13862 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13863 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13864 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13865 for (i = 0; i < 32; i++) {
13866 bwn_phy_lp_set_rxgain_idx(mac, i);
13867 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13868 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13870 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13871 if ((tmp > 4000) && (tmp < 10000)) {
13876 bwn_phy_lp_ddfs_turnoff(mac);
13881 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13884 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
13888 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
13889 int incr1, int incr2, int scale_idx)
13892 bwn_phy_lp_ddfs_turnoff(mac);
13893 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
13894 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
13895 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
13896 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
13897 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
13898 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
13899 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
13900 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
13901 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
13902 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
13906 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
13907 struct bwn_phy_lp_iq_est *ie)
13911 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
13912 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
13913 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
13914 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
13915 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
13917 for (i = 0; i < 500; i++) {
13918 if (!(BWN_PHY_READ(mac,
13919 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
13923 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
13924 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
13928 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
13929 ie->ie_iqprod <<= 16;
13930 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
13931 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
13932 ie->ie_ipwr <<= 16;
13933 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
13934 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
13935 ie->ie_qpwr <<= 16;
13936 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
13938 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
13943 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
13945 uint32_t offset, type, value;
13947 type = BWN_TAB_GETTYPE(typeoffset);
13948 offset = BWN_TAB_GETOFFSET(typeoffset);
13949 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13953 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13954 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
13956 case BWN_TAB_16BIT:
13957 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13958 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
13960 case BWN_TAB_32BIT:
13961 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13962 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
13964 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
13967 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13975 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
13978 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
13979 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
13983 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
13987 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
13989 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
13993 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
13996 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
13997 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
14001 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
14004 if (mac->mac_phy.rev < 2)
14005 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
14007 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
14008 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
14010 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
14014 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
14017 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
14021 bwn_nbits(int32_t val)
14026 for (tmp = abs(val); tmp != 0; tmp >>= 1)
14032 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
14033 struct bwn_txgain_entry *table)
14037 for (i = offset; i < count; i++)
14038 bwn_phy_lp_gaintbl_write(mac, i, table[i]);
14042 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
14043 struct bwn_txgain_entry data)
14046 if (mac->mac_phy.rev >= 2)
14047 bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14049 bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14053 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14054 struct bwn_txgain_entry te)
14056 struct bwn_softc *sc = mac->mac_sc;
14057 struct ifnet *ifp = sc->sc_ifp;
14058 struct ieee80211com *ic = ifp->if_l2com;
14061 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14063 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14064 if (mac->mac_phy.rev >= 3) {
14065 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14066 (0x10 << 24) : (0x70 << 24));
14068 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14069 (0x14 << 24) : (0x7f << 24));
14071 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14072 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14073 te.te_bbmult << 20 | te.te_dac << 28);
14077 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14078 struct bwn_txgain_entry te)
14081 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14083 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14084 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) |
14086 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14090 bwn_sysctl_node(struct bwn_softc *sc)
14092 struct bwn_mac *mac;
14093 struct bwn_stats *stats;
14094 struct sysctl_ctx_list *ctx;
14095 struct sysctl_oid *tree;
14097 /* XXX assume that count of MAC is only 1. */
14099 if ((mac = sc->sc_curmac) == NULL)
14101 stats = &mac->mac_stats;
14103 ctx = device_get_sysctl_ctx(sc->sc_dev);
14104 tree = device_get_sysctl_tree(sc->sc_dev);
14105 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14106 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14107 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14108 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14109 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14110 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14113 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
14114 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14118 static device_method_t bwn_methods[] = {
14119 /* Device interface */
14120 DEVMETHOD(device_probe, bwn_probe),
14121 DEVMETHOD(device_attach, bwn_attach),
14122 DEVMETHOD(device_detach, bwn_detach),
14123 DEVMETHOD(device_suspend, bwn_suspend),
14124 DEVMETHOD(device_resume, bwn_resume),
14127 static driver_t bwn_driver = {
14130 sizeof(struct bwn_softc)
14132 static devclass_t bwn_devclass;
14133 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, NULL, NULL);
14134 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14135 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */
14136 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */
14137 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);