2 * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13 * redistribution must be conditioned upon including a substantially
14 * similar Disclaimer requirement for further binary redistribution.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
34 * The Broadcom Wireless LAN controller driver.
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/module.h>
40 #include <sys/kernel.h>
41 #include <sys/endian.h>
42 #include <sys/errno.h>
43 #include <sys/firmware.h>
45 #include <sys/mutex.h>
46 #include <machine/bus.h>
47 #include <machine/resource.h>
50 #include <sys/socket.h>
51 #include <sys/sockio.h>
53 #include <net/ethernet.h>
55 #include <net/if_arp.h>
56 #include <net/if_dl.h>
57 #include <net/if_llc.h>
58 #include <net/if_media.h>
59 #include <net/if_types.h>
61 #include <dev/pci/pcivar.h>
62 #include <dev/pci/pcireg.h>
63 #include <dev/siba/siba_ids.h>
64 #include <dev/siba/sibareg.h>
65 #include <dev/siba/sibavar.h>
67 #include <net80211/ieee80211_var.h>
68 #include <net80211/ieee80211_radiotap.h>
69 #include <net80211/ieee80211_regdomain.h>
70 #include <net80211/ieee80211_amrr.h>
71 #include <net80211/ieee80211_phy.h>
73 #include <dev/bwn/if_bwnreg.h>
74 #include <dev/bwn/if_bwnvar.h>
76 SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0, "Broadcom driver parameters");
79 * Tunable & sysctl variables.
83 static int bwn_debug = 0;
84 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RW, &bwn_debug, 0,
85 "Broadcom debugging printfs");
86 TUNABLE_INT("hw.bwn.debug", &bwn_debug);
88 BWN_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
89 BWN_DEBUG_RECV = 0x00000002, /* basic recv operation */
90 BWN_DEBUG_STATE = 0x00000004, /* 802.11 state transitions */
91 BWN_DEBUG_TXPOW = 0x00000008, /* tx power processing */
92 BWN_DEBUG_RESET = 0x00000010, /* reset processing */
93 BWN_DEBUG_OPS = 0x00000020, /* bwn_ops processing */
94 BWN_DEBUG_BEACON = 0x00000040, /* beacon handling */
95 BWN_DEBUG_WATCHDOG = 0x00000080, /* watchdog timeout */
96 BWN_DEBUG_INTR = 0x00000100, /* ISR */
97 BWN_DEBUG_CALIBRATE = 0x00000200, /* periodic calibration */
98 BWN_DEBUG_NODE = 0x00000400, /* node management */
99 BWN_DEBUG_LED = 0x00000800, /* led management */
100 BWN_DEBUG_CMD = 0x00001000, /* cmd submission */
101 BWN_DEBUG_LO = 0x00002000, /* LO */
102 BWN_DEBUG_FW = 0x00004000, /* firmware */
103 BWN_DEBUG_WME = 0x00008000, /* WME */
104 BWN_DEBUG_RF = 0x00010000, /* RF */
105 BWN_DEBUG_FATAL = 0x80000000, /* fatal errors */
106 BWN_DEBUG_ANY = 0xffffffff
108 #define DPRINTF(sc, m, fmt, ...) do { \
109 if (sc->sc_debug & (m)) \
110 printf(fmt, __VA_ARGS__); \
113 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
116 static int bwn_bfp = 0; /* use "Bad Frames Preemption" */
117 SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0,
118 "uses Bad Frames Preemption");
119 static int bwn_bluetooth = 1;
120 SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0,
121 "turns on Bluetooth Coexistence");
122 static int bwn_hwpctl = 0;
123 SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0,
124 "uses H/W power control");
125 static int bwn_msi_disable = 0; /* MSI disabled */
126 TUNABLE_INT("hw.bwn.msi_disable", &bwn_msi_disable);
127 static int bwn_usedma = 1;
128 SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0,
130 TUNABLE_INT("hw.bwn.usedma", &bwn_usedma);
131 static int bwn_wme = 1;
132 SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0,
135 static int bwn_attach_pre(struct bwn_softc *);
136 static int bwn_attach_post(struct bwn_softc *);
137 static void bwn_sprom_bugfixes(device_t);
138 static void bwn_init(void *);
139 static int bwn_init_locked(struct bwn_softc *);
140 static int bwn_ioctl(struct ifnet *, u_long, caddr_t);
141 static void bwn_start(struct ifnet *);
142 static int bwn_attach_core(struct bwn_mac *);
143 static void bwn_reset_core(struct bwn_mac *, uint32_t);
144 static int bwn_phy_getinfo(struct bwn_mac *, int);
145 static int bwn_chiptest(struct bwn_mac *);
146 static int bwn_setup_channels(struct bwn_mac *, int, int);
147 static int bwn_phy_g_attach(struct bwn_mac *);
148 static void bwn_phy_g_detach(struct bwn_mac *);
149 static void bwn_phy_g_init_pre(struct bwn_mac *);
150 static int bwn_phy_g_prepare_hw(struct bwn_mac *);
151 static int bwn_phy_g_init(struct bwn_mac *);
152 static void bwn_phy_g_exit(struct bwn_mac *);
153 static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t);
154 static void bwn_phy_g_write(struct bwn_mac *, uint16_t,
156 static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t);
157 static void bwn_phy_g_rf_write(struct bwn_mac *, uint16_t,
159 static int bwn_phy_g_hwpctl(struct bwn_mac *);
160 static void bwn_phy_g_rf_onoff(struct bwn_mac *, int);
161 static int bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t);
162 static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *);
163 static void bwn_phy_g_set_antenna(struct bwn_mac *, int);
164 static int bwn_phy_g_im(struct bwn_mac *, int);
165 static int bwn_phy_g_recalc_txpwr(struct bwn_mac *, int);
166 static void bwn_phy_g_set_txpwr(struct bwn_mac *);
167 static void bwn_phy_g_task_15s(struct bwn_mac *);
168 static void bwn_phy_g_task_60s(struct bwn_mac *);
169 static uint16_t bwn_phy_g_txctl(struct bwn_mac *);
170 static void bwn_phy_switch_analog(struct bwn_mac *, int);
171 static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t);
172 static void bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t,
174 static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t);
175 static void bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t,
177 static void bwn_shm_ctlword(struct bwn_mac *, uint16_t,
179 static void bwn_addchannels(struct ieee80211_channel [], int, int *,
180 const struct bwn_channelinfo *, int);
181 static int bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
182 const struct ieee80211_bpf_params *);
183 static void bwn_newassoc(struct ieee80211_node *, int);
184 static void bwn_updateslot(struct ifnet *);
185 static void bwn_update_promisc(struct ifnet *);
186 static void bwn_wme_init(struct bwn_mac *);
187 static int bwn_wme_update(struct ieee80211com *);
188 static struct ieee80211_node *bwn_node_alloc(struct ieee80211vap *,
189 const uint8_t [IEEE80211_ADDR_LEN]);
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_node_cleanup(struct ieee80211_node *);
195 static void bwn_scan_start(struct ieee80211com *);
196 static void bwn_scan_end(struct ieee80211com *);
197 static void bwn_set_channel(struct ieee80211com *);
198 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *,
199 const char [IFNAMSIZ], int, int,
200 int, const uint8_t [IEEE80211_ADDR_LEN],
201 const uint8_t [IEEE80211_ADDR_LEN]);
202 static void bwn_vap_delete(struct ieee80211vap *);
203 static void bwn_stop(struct bwn_softc *, int);
204 static void bwn_stop_locked(struct bwn_softc *, int);
205 static int bwn_core_init(struct bwn_mac *);
206 static void bwn_core_start(struct bwn_mac *);
207 static void bwn_core_exit(struct bwn_mac *);
208 static void bwn_bt_disable(struct bwn_mac *);
209 static int bwn_chip_init(struct bwn_mac *);
210 static uint64_t bwn_hf_read(struct bwn_mac *);
211 static void bwn_hf_write(struct bwn_mac *, uint64_t);
212 static void bwn_set_txretry(struct bwn_mac *, int, int);
213 static void bwn_rate_init(struct bwn_mac *);
214 static void bwn_set_phytxctl(struct bwn_mac *);
215 static void bwn_spu_setdelay(struct bwn_mac *, int);
216 static void bwn_bt_enable(struct bwn_mac *);
217 static void bwn_set_macaddr(struct bwn_mac *);
218 static void bwn_crypt_init(struct bwn_mac *);
219 static void bwn_chip_exit(struct bwn_mac *);
220 static int bwn_fw_fillinfo(struct bwn_mac *);
221 static int bwn_fw_loaducode(struct bwn_mac *);
222 static int bwn_gpio_init(struct bwn_mac *);
223 static int bwn_fw_loadinitvals(struct bwn_mac *);
224 static int bwn_phy_init(struct bwn_mac *);
225 static void bwn_set_txantenna(struct bwn_mac *, int);
226 static void bwn_set_opmode(struct bwn_mac *);
227 static void bwn_rate_write(struct bwn_mac *, uint16_t, int);
228 static uint8_t bwn_plcp_getcck(const uint8_t);
229 static uint8_t bwn_plcp_getofdm(const uint8_t);
230 static void bwn_pio_init(struct bwn_mac *);
231 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int);
232 static void bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *,
234 static void bwn_pio_setupqueue_rx(struct bwn_mac *,
235 struct bwn_pio_rxqueue *, int);
236 static void bwn_destroy_queue_tx(struct bwn_pio_txqueue *);
237 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *,
239 static void bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *);
240 static int bwn_pio_rx(struct bwn_pio_rxqueue *);
241 static uint8_t bwn_pio_rxeof(struct bwn_pio_rxqueue *);
242 static void bwn_pio_handle_txeof(struct bwn_mac *,
243 const struct bwn_txstatus *);
244 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t);
245 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t);
246 static void bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t,
248 static void bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t,
250 static int bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *,
252 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t);
253 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *,
254 struct bwn_pio_txqueue *, uint32_t, const void *, int);
255 static void bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *,
257 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *,
258 struct bwn_pio_txqueue *, uint16_t, const void *, int);
259 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *,
260 struct bwn_pio_txqueue *, uint16_t, struct mbuf *);
261 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *,
262 uint16_t, struct bwn_pio_txpkt **);
263 static void bwn_dma_init(struct bwn_mac *);
264 static void bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t);
265 static int bwn_dma_mask2type(uint64_t);
266 static uint64_t bwn_dma_mask(struct bwn_mac *);
267 static uint16_t bwn_dma_base(int, int);
268 static void bwn_dma_ringfree(struct bwn_dma_ring **);
269 static void bwn_dma_32_getdesc(struct bwn_dma_ring *,
270 int, struct bwn_dmadesc_generic **,
271 struct bwn_dmadesc_meta **);
272 static void bwn_dma_32_setdesc(struct bwn_dma_ring *,
273 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
275 static void bwn_dma_32_start_transfer(struct bwn_dma_ring *, int);
276 static void bwn_dma_32_suspend(struct bwn_dma_ring *);
277 static void bwn_dma_32_resume(struct bwn_dma_ring *);
278 static int bwn_dma_32_get_curslot(struct bwn_dma_ring *);
279 static void bwn_dma_32_set_curslot(struct bwn_dma_ring *, int);
280 static void bwn_dma_64_getdesc(struct bwn_dma_ring *,
281 int, struct bwn_dmadesc_generic **,
282 struct bwn_dmadesc_meta **);
283 static void bwn_dma_64_setdesc(struct bwn_dma_ring *,
284 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
286 static void bwn_dma_64_start_transfer(struct bwn_dma_ring *, int);
287 static void bwn_dma_64_suspend(struct bwn_dma_ring *);
288 static void bwn_dma_64_resume(struct bwn_dma_ring *);
289 static int bwn_dma_64_get_curslot(struct bwn_dma_ring *);
290 static void bwn_dma_64_set_curslot(struct bwn_dma_ring *, int);
291 static int bwn_dma_allocringmemory(struct bwn_dma_ring *);
292 static void bwn_dma_setup(struct bwn_dma_ring *);
293 static void bwn_dma_free_ringmemory(struct bwn_dma_ring *);
294 static void bwn_dma_cleanup(struct bwn_dma_ring *);
295 static void bwn_dma_free_descbufs(struct bwn_dma_ring *);
296 static int bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int);
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 int 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 struct resource_spec bwn_res_spec_legacy[] = {
540 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE },
544 static struct resource_spec bwn_res_spec_msi[] = {
545 { SYS_RES_IRQ, 1, RF_ACTIVE },
549 static const struct bwn_channelinfo bwn_chantable_bg = {
551 { 2412, 1, 30 }, { 2417, 2, 30 }, { 2422, 3, 30 },
552 { 2427, 4, 30 }, { 2432, 5, 30 }, { 2437, 6, 30 },
553 { 2442, 7, 30 }, { 2447, 8, 30 }, { 2452, 9, 30 },
554 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 },
555 { 2472, 13, 30 }, { 2484, 14, 30 } },
559 static const struct bwn_channelinfo bwn_chantable_a = {
561 { 5170, 34, 30 }, { 5180, 36, 30 }, { 5190, 38, 30 },
562 { 5200, 40, 30 }, { 5210, 42, 30 }, { 5220, 44, 30 },
563 { 5230, 46, 30 }, { 5240, 48, 30 }, { 5260, 52, 30 },
564 { 5280, 56, 30 }, { 5300, 60, 30 }, { 5320, 64, 30 },
565 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 },
566 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 },
567 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 },
568 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 },
569 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 },
570 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 },
571 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 },
572 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 },
577 static const struct bwn_channelinfo bwn_chantable_n = {
579 { 5160, 32, 30 }, { 5170, 34, 30 }, { 5180, 36, 30 },
580 { 5190, 38, 30 }, { 5200, 40, 30 }, { 5210, 42, 30 },
581 { 5220, 44, 30 }, { 5230, 46, 30 }, { 5240, 48, 30 },
582 { 5250, 50, 30 }, { 5260, 52, 30 }, { 5270, 54, 30 },
583 { 5280, 56, 30 }, { 5290, 58, 30 }, { 5300, 60, 30 },
584 { 5310, 62, 30 }, { 5320, 64, 30 }, { 5330, 66, 30 },
585 { 5340, 68, 30 }, { 5350, 70, 30 }, { 5360, 72, 30 },
586 { 5370, 74, 30 }, { 5380, 76, 30 }, { 5390, 78, 30 },
587 { 5400, 80, 30 }, { 5410, 82, 30 }, { 5420, 84, 30 },
588 { 5430, 86, 30 }, { 5440, 88, 30 }, { 5450, 90, 30 },
589 { 5460, 92, 30 }, { 5470, 94, 30 }, { 5480, 96, 30 },
590 { 5490, 98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 },
591 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 },
592 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 },
593 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 },
594 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 },
595 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 },
596 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 },
597 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 },
598 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 },
599 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 },
600 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 },
601 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 },
602 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 },
603 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 },
604 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 },
605 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 },
606 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 },
607 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 },
608 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 },
609 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 },
610 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 },
611 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
612 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
613 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
614 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
615 { 6130, 226, 30 }, { 6140, 228, 30 } },
619 static const uint8_t bwn_b2063_chantable_data[33][12] = {
620 { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
621 { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
622 { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
623 { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
624 { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
625 { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 },
626 { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 },
627 { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 },
628 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 },
629 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 },
630 { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 },
631 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 },
632 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 },
633 { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 },
634 { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
635 { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
636 { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 },
637 { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 },
638 { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 },
639 { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
640 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
641 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
642 { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
643 { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
644 { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 },
645 { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
646 { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
647 { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
648 { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
649 { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
650 { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
651 { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
652 { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }
655 static const struct bwn_b206x_chan bwn_b2063_chantable[] = {
656 { 1, 2412, bwn_b2063_chantable_data[0] },
657 { 2, 2417, bwn_b2063_chantable_data[0] },
658 { 3, 2422, bwn_b2063_chantable_data[0] },
659 { 4, 2427, bwn_b2063_chantable_data[1] },
660 { 5, 2432, bwn_b2063_chantable_data[1] },
661 { 6, 2437, bwn_b2063_chantable_data[1] },
662 { 7, 2442, bwn_b2063_chantable_data[1] },
663 { 8, 2447, bwn_b2063_chantable_data[1] },
664 { 9, 2452, bwn_b2063_chantable_data[2] },
665 { 10, 2457, bwn_b2063_chantable_data[2] },
666 { 11, 2462, bwn_b2063_chantable_data[3] },
667 { 12, 2467, bwn_b2063_chantable_data[3] },
668 { 13, 2472, bwn_b2063_chantable_data[3] },
669 { 14, 2484, bwn_b2063_chantable_data[4] },
670 { 34, 5170, bwn_b2063_chantable_data[5] },
671 { 36, 5180, bwn_b2063_chantable_data[6] },
672 { 38, 5190, bwn_b2063_chantable_data[7] },
673 { 40, 5200, bwn_b2063_chantable_data[8] },
674 { 42, 5210, bwn_b2063_chantable_data[9] },
675 { 44, 5220, bwn_b2063_chantable_data[10] },
676 { 46, 5230, bwn_b2063_chantable_data[11] },
677 { 48, 5240, bwn_b2063_chantable_data[12] },
678 { 52, 5260, bwn_b2063_chantable_data[13] },
679 { 56, 5280, bwn_b2063_chantable_data[14] },
680 { 60, 5300, bwn_b2063_chantable_data[14] },
681 { 64, 5320, bwn_b2063_chantable_data[15] },
682 { 100, 5500, bwn_b2063_chantable_data[16] },
683 { 104, 5520, bwn_b2063_chantable_data[17] },
684 { 108, 5540, bwn_b2063_chantable_data[18] },
685 { 112, 5560, bwn_b2063_chantable_data[19] },
686 { 116, 5580, bwn_b2063_chantable_data[20] },
687 { 120, 5600, bwn_b2063_chantable_data[21] },
688 { 124, 5620, bwn_b2063_chantable_data[21] },
689 { 128, 5640, bwn_b2063_chantable_data[22] },
690 { 132, 5660, bwn_b2063_chantable_data[22] },
691 { 136, 5680, bwn_b2063_chantable_data[22] },
692 { 140, 5700, bwn_b2063_chantable_data[23] },
693 { 149, 5745, bwn_b2063_chantable_data[23] },
694 { 153, 5765, bwn_b2063_chantable_data[23] },
695 { 157, 5785, bwn_b2063_chantable_data[23] },
696 { 161, 5805, bwn_b2063_chantable_data[23] },
697 { 165, 5825, bwn_b2063_chantable_data[23] },
698 { 184, 4920, bwn_b2063_chantable_data[24] },
699 { 188, 4940, bwn_b2063_chantable_data[25] },
700 { 192, 4960, bwn_b2063_chantable_data[26] },
701 { 196, 4980, bwn_b2063_chantable_data[27] },
702 { 200, 5000, bwn_b2063_chantable_data[28] },
703 { 204, 5020, bwn_b2063_chantable_data[29] },
704 { 208, 5040, bwn_b2063_chantable_data[30] },
705 { 212, 5060, bwn_b2063_chantable_data[31] },
706 { 216, 5080, bwn_b2063_chantable_data[32] }
709 static const uint8_t bwn_b2062_chantable_data[22][12] = {
710 { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 },
711 { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
712 { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
713 { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
714 { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
715 { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
716 { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
717 { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
718 { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
719 { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
720 { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
721 { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
722 { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
723 { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
724 { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
725 { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
726 { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
727 { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
728 { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
729 { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
730 { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
731 { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }
734 static const struct bwn_b206x_chan bwn_b2062_chantable[] = {
735 { 1, 2412, bwn_b2062_chantable_data[0] },
736 { 2, 2417, bwn_b2062_chantable_data[0] },
737 { 3, 2422, bwn_b2062_chantable_data[0] },
738 { 4, 2427, bwn_b2062_chantable_data[0] },
739 { 5, 2432, bwn_b2062_chantable_data[0] },
740 { 6, 2437, bwn_b2062_chantable_data[0] },
741 { 7, 2442, bwn_b2062_chantable_data[0] },
742 { 8, 2447, bwn_b2062_chantable_data[0] },
743 { 9, 2452, bwn_b2062_chantable_data[0] },
744 { 10, 2457, bwn_b2062_chantable_data[0] },
745 { 11, 2462, bwn_b2062_chantable_data[0] },
746 { 12, 2467, bwn_b2062_chantable_data[0] },
747 { 13, 2472, bwn_b2062_chantable_data[0] },
748 { 14, 2484, bwn_b2062_chantable_data[0] },
749 { 34, 5170, bwn_b2062_chantable_data[1] },
750 { 38, 5190, bwn_b2062_chantable_data[2] },
751 { 42, 5210, bwn_b2062_chantable_data[2] },
752 { 46, 5230, bwn_b2062_chantable_data[3] },
753 { 36, 5180, bwn_b2062_chantable_data[4] },
754 { 40, 5200, bwn_b2062_chantable_data[5] },
755 { 44, 5220, bwn_b2062_chantable_data[6] },
756 { 48, 5240, bwn_b2062_chantable_data[3] },
757 { 52, 5260, bwn_b2062_chantable_data[3] },
758 { 56, 5280, bwn_b2062_chantable_data[3] },
759 { 60, 5300, bwn_b2062_chantable_data[7] },
760 { 64, 5320, bwn_b2062_chantable_data[8] },
761 { 100, 5500, bwn_b2062_chantable_data[9] },
762 { 104, 5520, bwn_b2062_chantable_data[10] },
763 { 108, 5540, bwn_b2062_chantable_data[10] },
764 { 112, 5560, bwn_b2062_chantable_data[10] },
765 { 116, 5580, bwn_b2062_chantable_data[11] },
766 { 120, 5600, bwn_b2062_chantable_data[12] },
767 { 124, 5620, bwn_b2062_chantable_data[12] },
768 { 128, 5640, bwn_b2062_chantable_data[12] },
769 { 132, 5660, bwn_b2062_chantable_data[12] },
770 { 136, 5680, bwn_b2062_chantable_data[12] },
771 { 140, 5700, bwn_b2062_chantable_data[12] },
772 { 149, 5745, bwn_b2062_chantable_data[12] },
773 { 153, 5765, bwn_b2062_chantable_data[12] },
774 { 157, 5785, bwn_b2062_chantable_data[12] },
775 { 161, 5805, bwn_b2062_chantable_data[12] },
776 { 165, 5825, bwn_b2062_chantable_data[12] },
777 { 184, 4920, bwn_b2062_chantable_data[13] },
778 { 188, 4940, bwn_b2062_chantable_data[14] },
779 { 192, 4960, bwn_b2062_chantable_data[15] },
780 { 196, 4980, bwn_b2062_chantable_data[16] },
781 { 200, 5000, bwn_b2062_chantable_data[17] },
782 { 204, 5020, bwn_b2062_chantable_data[18] },
783 { 208, 5040, bwn_b2062_chantable_data[19] },
784 { 212, 5060, bwn_b2062_chantable_data[20] },
785 { 216, 5080, bwn_b2062_chantable_data[21] }
789 static const struct bwn_rxcompco bwn_rxcompco_5354[] = {
790 { 1, -66, 15 }, { 2, -66, 15 }, { 3, -66, 15 }, { 4, -66, 15 },
791 { 5, -66, 15 }, { 6, -66, 15 }, { 7, -66, 14 }, { 8, -66, 14 },
792 { 9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 },
793 { 13, -66, 13 }, { 14, -66, 13 },
797 static const struct bwn_rxcompco bwn_rxcompco_r12[] = {
798 { 1, -64, 13 }, { 2, -64, 13 }, { 3, -64, 13 }, { 4, -64, 13 },
799 { 5, -64, 12 }, { 6, -64, 12 }, { 7, -64, 12 }, { 8, -64, 12 },
800 { 9, -64, 12 }, { 10, -64, 11 }, { 11, -64, 11 }, { 12, -64, 11 },
801 { 13, -64, 11 }, { 14, -64, 10 }, { 34, -62, 24 }, { 38, -62, 24 },
802 { 42, -62, 24 }, { 46, -62, 23 }, { 36, -62, 24 }, { 40, -62, 24 },
803 { 44, -62, 23 }, { 48, -62, 23 }, { 52, -62, 23 }, { 56, -62, 22 },
804 { 60, -62, 22 }, { 64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 },
805 { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 },
806 { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 },
807 { 140, -62, 10 }, { 149, -61, 9 }, { 153, -61, 9 }, { 157, -61, 9 },
808 { 161, -61, 8 }, { 165, -61, 8 }, { 184, -62, 25 }, { 188, -62, 25 },
809 { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 },
810 { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 },
813 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 };
815 static const uint8_t bwn_tab_sigsq_tbl[] = {
816 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd,
817 0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
818 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00,
819 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
820 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
821 0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
824 static const uint8_t bwn_tab_pllfrac_tbl[] = {
825 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80,
826 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
829 static const uint16_t bwn_tabl_iqlocal_tbl[] = {
830 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002,
831 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
832 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
833 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
834 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006,
835 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
836 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
837 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
838 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
839 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
840 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
841 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
844 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
845 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
846 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
847 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
848 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
849 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
851 #define VENDOR_LED_ACT(vendor) \
853 .vid = PCI_VENDOR_##vendor, \
854 .led_act = { BWN_VENDOR_LED_ACT_##vendor } \
857 static const struct {
859 uint8_t led_act[BWN_LED_MAX];
860 } bwn_vendor_led_act[] = {
861 VENDOR_LED_ACT(COMPAQ),
862 VENDOR_LED_ACT(ASUSTEK)
865 static const uint8_t bwn_default_led_act[BWN_LED_MAX] =
866 { BWN_VENDOR_LED_ACT_DEFAULT };
868 #undef VENDOR_LED_ACT
870 static const struct {
873 } bwn_led_duration[109] = {
889 static const uint16_t bwn_wme_shm_offsets[] = {
890 [0] = BWN_WME_BESTEFFORT,
891 [1] = BWN_WME_BACKGROUND,
896 static const struct siba_devid bwn_devs[] = {
897 SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"),
898 SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"),
899 SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"),
900 SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"),
901 SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"),
902 SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"),
903 SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"),
904 SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"),
905 SIBA_DEV(BROADCOM, 80211, 16, "Revision 16")
909 bwn_probe(device_t dev)
913 for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) {
914 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor &&
915 siba_get_device(dev) == bwn_devs[i].sd_device &&
916 siba_get_revid(dev) == bwn_devs[i].sd_rev)
917 return (BUS_PROBE_DEFAULT);
924 bwn_attach(device_t dev)
927 struct bwn_softc *sc = device_get_softc(dev);
928 int error, i, msic, reg;
932 sc->sc_debug = bwn_debug;
935 if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
936 error = bwn_attach_pre(sc);
939 bwn_sprom_bugfixes(dev);
940 sc->sc_flags |= BWN_FLAG_ATTACHED;
943 if (!TAILQ_EMPTY(&sc->sc_maclist)) {
944 if (siba_get_pci_device(dev) != 0x4313 &&
945 siba_get_pci_device(dev) != 0x431a &&
946 siba_get_pci_device(dev) != 0x4321) {
947 device_printf(sc->sc_dev,
948 "skip 802.11 cores\n");
953 mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF,
958 mac->mac_status = BWN_MAC_STATUS_UNINIT;
960 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
962 TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac);
963 TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac);
964 TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac);
966 error = bwn_attach_core(mac);
971 device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) "
972 "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
973 siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev),
974 mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev,
975 mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver,
976 mac->mac_phy.rf_rev);
977 if (mac->mac_flags & BWN_MAC_FLAG_DMA)
978 device_printf(sc->sc_dev, "DMA (%d bits)\n",
979 mac->mac_method.dma.dmatype);
981 device_printf(sc->sc_dev, "PIO\n");
984 * setup PCI resources and interrupt.
986 if (pci_find_extcap(dev, PCIY_EXPRESS, ®) == 0) {
987 msic = pci_msi_count(dev);
989 device_printf(sc->sc_dev, "MSI count : %d\n", msic);
993 mac->mac_intr_spec = bwn_res_spec_legacy;
994 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) {
995 if (pci_alloc_msi(dev, &msic) == 0) {
996 device_printf(sc->sc_dev,
997 "Using %d MSI messages\n", msic);
998 mac->mac_intr_spec = bwn_res_spec_msi;
1003 error = bus_alloc_resources(dev, mac->mac_intr_spec,
1006 device_printf(sc->sc_dev,
1007 "couldn't allocate IRQ resources (%d)\n", error);
1011 if (mac->mac_msi == 0)
1012 error = bus_setup_intr(dev, mac->mac_res_irq[0],
1013 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1014 &mac->mac_intrhand[0]);
1016 for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1017 error = bus_setup_intr(dev, mac->mac_res_irq[i],
1018 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1019 &mac->mac_intrhand[i]);
1021 device_printf(sc->sc_dev,
1022 "couldn't setup interrupt (%d)\n", error);
1028 TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list);
1031 * calls attach-post routine
1033 if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0)
1034 bwn_attach_post(sc);
1038 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0)
1039 pci_release_msi(dev);
1041 free(mac, M_DEVBUF);
1046 bwn_is_valid_ether_addr(uint8_t *addr)
1048 char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
1050 if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN)))
1057 bwn_attach_post(struct bwn_softc *sc)
1059 struct ieee80211com *ic;
1060 struct ifnet *ifp = sc->sc_ifp;
1064 /* XXX not right but it's not used anywhere important */
1065 ic->ic_phytype = IEEE80211_T_OFDM;
1066 ic->ic_opmode = IEEE80211_M_STA;
1068 IEEE80211_C_STA /* station mode supported */
1069 | IEEE80211_C_MONITOR /* monitor mode */
1070 | IEEE80211_C_AHDEMO /* adhoc demo mode */
1071 | IEEE80211_C_SHPREAMBLE /* short preamble supported */
1072 | IEEE80211_C_SHSLOT /* short slot time supported */
1073 | IEEE80211_C_WME /* WME/WMM supported */
1074 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */
1075 | IEEE80211_C_BGSCAN /* capable of bg scanning */
1076 | IEEE80211_C_TXPMGT /* capable of txpow mgt */
1079 /* call MI attach routine. */
1080 ieee80211_ifattach(ic,
1081 bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
1082 siba_sprom_get_mac_80211a(sc->sc_dev) :
1083 siba_sprom_get_mac_80211bg(sc->sc_dev));
1085 ic->ic_headroom = sizeof(struct bwn_txhdr);
1087 /* override default methods */
1088 ic->ic_raw_xmit = bwn_raw_xmit;
1089 ic->ic_newassoc = bwn_newassoc;
1090 ic->ic_updateslot = bwn_updateslot;
1091 ic->ic_update_promisc = bwn_update_promisc;
1092 ic->ic_wme.wme_update = bwn_wme_update;
1094 ic->ic_node_alloc = bwn_node_alloc;
1095 sc->sc_node_cleanup = ic->ic_node_cleanup;
1096 ic->ic_node_cleanup = bwn_node_cleanup;
1098 ic->ic_scan_start = bwn_scan_start;
1099 ic->ic_scan_end = bwn_scan_end;
1100 ic->ic_set_channel = bwn_set_channel;
1102 ic->ic_vap_create = bwn_vap_create;
1103 ic->ic_vap_delete = bwn_vap_delete;
1105 ieee80211_radiotap_attach(ic,
1106 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
1107 BWN_TX_RADIOTAP_PRESENT,
1108 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
1109 BWN_RX_RADIOTAP_PRESENT);
1111 bwn_sysctl_node(sc);
1114 ieee80211_announce(ic);
1119 bwn_phy_detach(struct bwn_mac *mac)
1122 if (mac->mac_phy.detach != NULL)
1123 mac->mac_phy.detach(mac);
1127 bwn_detach(device_t dev)
1129 struct bwn_softc *sc = device_get_softc(dev);
1130 struct bwn_mac *mac = sc->sc_curmac;
1131 struct ifnet *ifp = sc->sc_ifp;
1132 struct ieee80211com *ic = ifp->if_l2com;
1135 sc->sc_flags |= BWN_FLAG_INVALID;
1137 if (device_is_attached(sc->sc_dev)) {
1140 callout_drain(&sc->sc_led_blink_ch);
1141 callout_drain(&sc->sc_rfswitch_ch);
1142 callout_drain(&sc->sc_task_ch);
1143 callout_drain(&sc->sc_watchdog_ch);
1144 bwn_phy_detach(mac);
1146 ieee80211_draintask(ic, &mac->mac_hwreset);
1147 ieee80211_draintask(ic, &mac->mac_txpower);
1148 ieee80211_ifdetach(ic);
1152 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
1153 taskqueue_free(sc->sc_tq);
1155 for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1156 if (mac->mac_intrhand[i] != NULL) {
1157 bus_teardown_intr(dev, mac->mac_res_irq[i],
1158 mac->mac_intrhand[i]);
1159 mac->mac_intrhand[i] = NULL;
1162 bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq);
1163 if (mac->mac_msi != 0)
1164 pci_release_msi(dev);
1166 BWN_LOCK_DESTROY(sc);
1171 bwn_attach_pre(struct bwn_softc *sc)
1177 TAILQ_INIT(&sc->sc_maclist);
1178 callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0);
1179 callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0);
1180 callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0);
1182 sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT,
1183 taskqueue_thread_enqueue, &sc->sc_tq);
1184 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
1185 "%s taskq", device_get_nameunit(sc->sc_dev));
1187 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
1189 device_printf(sc->sc_dev, "can not if_alloc()\n");
1194 /* set these up early for if_printf use */
1195 if_initname(ifp, device_get_name(sc->sc_dev),
1196 device_get_unit(sc->sc_dev));
1199 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1200 ifp->if_init = bwn_init;
1201 ifp->if_ioctl = bwn_ioctl;
1202 ifp->if_start = bwn_start;
1203 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
1204 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
1205 IFQ_SET_READY(&ifp->if_snd);
1209 fail: BWN_LOCK_DESTROY(sc);
1214 bwn_sprom_bugfixes(device_t dev)
1216 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \
1217 ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \
1218 (siba_get_pci_device(dev) == _device) && \
1219 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \
1220 (siba_get_pci_subdevice(dev) == _subdevice))
1222 if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
1223 siba_get_pci_subdevice(dev) == 0x4e &&
1224 siba_get_pci_revid(dev) > 0x40)
1225 siba_sprom_set_bf_lo(dev,
1226 siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
1227 if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
1228 siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
1229 siba_sprom_set_bf_lo(dev,
1230 siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
1231 if (siba_get_type(dev) == SIBA_TYPE_PCI) {
1232 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1233 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1234 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1235 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1236 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1237 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1238 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1239 siba_sprom_set_bf_lo(dev,
1240 siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
1246 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1248 #define IS_RUNNING(ifp) \
1249 ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
1250 struct bwn_softc *sc = ifp->if_softc;
1251 struct ieee80211com *ic = ifp->if_l2com;
1252 struct ifreq *ifr = (struct ifreq *)data;
1253 int error = 0, startall;
1258 if (IS_RUNNING(ifp)) {
1259 bwn_update_promisc(ifp);
1260 } else if (ifp->if_flags & IFF_UP) {
1261 if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
1268 ieee80211_start_all(ic);
1271 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1274 error = ether_ioctl(ifp, cmd, data);
1284 bwn_start(struct ifnet *ifp)
1286 struct bwn_softc *sc = ifp->if_softc;
1289 bwn_start_locked(ifp);
1294 bwn_start_locked(struct ifnet *ifp)
1296 struct bwn_softc *sc = ifp->if_softc;
1297 struct bwn_mac *mac = sc->sc_curmac;
1298 struct ieee80211_frame *wh;
1299 struct ieee80211_node *ni;
1300 struct ieee80211_key *k;
1303 BWN_ASSERT_LOCKED(sc);
1305 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL ||
1306 mac->mac_status < BWN_MAC_STATUS_STARTED)
1310 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */
1314 if (bwn_tx_isfull(sc, m))
1316 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1318 device_printf(sc->sc_dev, "unexpected NULL ni\n");
1323 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
1324 wh = mtod(m, struct ieee80211_frame *);
1325 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1326 k = ieee80211_crypto_encap(ni, m);
1328 ieee80211_free_node(ni);
1334 wh = NULL; /* Catch any invalid use */
1336 if (bwn_tx_start(sc, ni, m) != 0) {
1338 ieee80211_free_node(ni);
1343 sc->sc_watchdog_timer = 5;
1348 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1350 struct bwn_dma_ring *dr;
1351 struct bwn_mac *mac = sc->sc_curmac;
1352 struct bwn_pio_txqueue *tq;
1353 struct ifnet *ifp = sc->sc_ifp;
1354 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1356 BWN_ASSERT_LOCKED(sc);
1358 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1359 dr = bwn_dma_select(mac, M_WME_GETAC(m));
1360 if (dr->dr_stop == 1 ||
1361 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1366 tq = bwn_pio_select(mac, M_WME_GETAC(m));
1367 if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1368 pktlen > (tq->tq_size - tq->tq_used)) {
1375 IFQ_DRV_PREPEND(&ifp->if_snd, m);
1376 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1381 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1383 struct bwn_mac *mac = sc->sc_curmac;
1386 BWN_ASSERT_LOCKED(sc);
1388 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1393 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1394 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1403 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1405 struct bwn_pio_txpkt *tp;
1406 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1407 struct bwn_softc *sc = mac->mac_sc;
1408 struct bwn_txhdr txhdr;
1414 BWN_ASSERT_LOCKED(sc);
1416 /* XXX TODO send packets after DTIM */
1418 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1419 tp = TAILQ_FIRST(&tq->tq_pktlist);
1423 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1425 device_printf(sc->sc_dev, "tx fail\n");
1429 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1430 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1433 if (siba_get_revid(sc->sc_dev) >= 8) {
1435 * XXX please removes m_defrag(9)
1437 m_new = m_defrag(m, M_DONTWAIT);
1438 if (m_new == NULL) {
1439 device_printf(sc->sc_dev,
1440 "%s: can't defrag TX buffer\n",
1444 if (m_new->m_next != NULL)
1445 device_printf(sc->sc_dev,
1446 "TODO: fragmented packets for PIO\n");
1450 ctl32 = bwn_pio_write_multi_4(mac, tq,
1451 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1452 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1453 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1455 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1456 mtod(m_new, const void *), m_new->m_pkthdr.len);
1457 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1458 ctl32 | BWN_PIO8_TXCTL_EOF);
1460 ctl16 = bwn_pio_write_multi_2(mac, tq,
1461 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1462 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1463 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1464 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1465 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1466 ctl16 | BWN_PIO_TXCTL_EOF);
1472 static struct bwn_pio_txqueue *
1473 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1476 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1477 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1481 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1483 return (&mac->mac_method.pio.wme[WME_AC_BK]);
1485 return (&mac->mac_method.pio.wme[WME_AC_VI]);
1487 return (&mac->mac_method.pio.wme[WME_AC_VO]);
1489 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1494 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1496 #define BWN_GET_TXHDRCACHE(slot) \
1497 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)])
1498 struct bwn_dma *dma = &mac->mac_method.dma;
1499 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1500 struct bwn_dmadesc_generic *desc;
1501 struct bwn_dmadesc_meta *mt;
1502 struct bwn_softc *sc = mac->mac_sc;
1503 struct ifnet *ifp = sc->sc_ifp;
1504 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1505 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1507 BWN_ASSERT_LOCKED(sc);
1508 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1510 /* XXX send after DTIM */
1512 slot = bwn_dma_getslot(dr);
1513 dr->getdesc(dr, slot, &desc, &mt);
1514 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1515 ("%s:%d: fail", __func__, __LINE__));
1517 error = bwn_set_txhdr(dr->dr_mac, ni, m,
1518 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1519 BWN_DMA_COOKIE(dr, slot));
1522 error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap,
1523 BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr,
1524 &mt->mt_paddr, BUS_DMA_NOWAIT);
1526 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1530 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1531 BUS_DMASYNC_PREWRITE);
1532 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1533 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1534 BUS_DMASYNC_PREWRITE);
1536 slot = bwn_dma_getslot(dr);
1537 dr->getdesc(dr, slot, &desc, &mt);
1538 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1539 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1543 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1544 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1545 if (error && error != EFBIG) {
1546 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1550 if (error) { /* error == EFBIG */
1553 m_new = m_defrag(m, M_DONTWAIT);
1554 if (m_new == NULL) {
1555 if_printf(ifp, "%s: can't defrag TX buffer\n",
1564 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1565 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1567 if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
1572 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1573 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1574 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1575 BUS_DMASYNC_PREWRITE);
1577 /* XXX send after DTIM */
1579 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1582 dr->dr_curslot = backup[0];
1583 dr->dr_usedslot = backup[1];
1585 #undef BWN_GET_TXHDRCACHE
1589 bwn_watchdog(void *arg)
1591 struct bwn_softc *sc = arg;
1592 struct ifnet *ifp = sc->sc_ifp;
1594 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1595 if_printf(ifp, "device timeout\n");
1598 callout_schedule(&sc->sc_watchdog_ch, hz);
1602 bwn_attach_core(struct bwn_mac *mac)
1604 struct bwn_softc *sc = mac->mac_sc;
1605 int error, have_bg = 0, have_a = 0;
1608 KASSERT(siba_get_revid(sc->sc_dev) >= 5,
1609 ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
1611 siba_powerup(sc->sc_dev, 0);
1613 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
1615 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1616 error = bwn_phy_getinfo(mac, high);
1620 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1621 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1622 if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
1623 siba_get_pci_device(sc->sc_dev) != 0x4319 &&
1624 siba_get_pci_device(sc->sc_dev) != 0x4324) {
1625 have_a = have_bg = 0;
1626 if (mac->mac_phy.type == BWN_PHYTYPE_A)
1628 else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1629 mac->mac_phy.type == BWN_PHYTYPE_N ||
1630 mac->mac_phy.type == BWN_PHYTYPE_LP)
1633 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1634 mac->mac_phy.type));
1636 /* XXX turns off PHY A because it's not supported */
1637 if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1638 mac->mac_phy.type != BWN_PHYTYPE_N) {
1643 if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1644 mac->mac_phy.attach = bwn_phy_g_attach;
1645 mac->mac_phy.detach = bwn_phy_g_detach;
1646 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1647 mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1648 mac->mac_phy.init = bwn_phy_g_init;
1649 mac->mac_phy.exit = bwn_phy_g_exit;
1650 mac->mac_phy.phy_read = bwn_phy_g_read;
1651 mac->mac_phy.phy_write = bwn_phy_g_write;
1652 mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1653 mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1654 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1655 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1656 mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1657 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1658 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1659 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1660 mac->mac_phy.set_im = bwn_phy_g_im;
1661 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1662 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1663 mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1664 mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1665 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1666 mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1667 mac->mac_phy.init = bwn_phy_lp_init;
1668 mac->mac_phy.phy_read = bwn_phy_lp_read;
1669 mac->mac_phy.phy_write = bwn_phy_lp_write;
1670 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1671 mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1672 mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1673 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1674 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1675 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1676 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1677 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1678 mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1680 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1686 mac->mac_phy.gmode = have_bg;
1687 if (mac->mac_phy.attach != NULL) {
1688 error = mac->mac_phy.attach(mac);
1690 device_printf(sc->sc_dev, "failed\n");
1695 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1697 error = bwn_chiptest(mac);
1700 error = bwn_setup_channels(mac, have_bg, have_a);
1702 device_printf(sc->sc_dev, "failed to setup channels\n");
1706 if (sc->sc_curmac == NULL)
1707 sc->sc_curmac = mac;
1709 error = bwn_dma_attach(mac);
1711 device_printf(sc->sc_dev, "failed to initialize DMA\n");
1715 mac->mac_phy.switch_analog(mac, 0);
1717 siba_dev_down(sc->sc_dev, 0);
1719 siba_powerdown(sc->sc_dev);
1724 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1726 struct bwn_softc *sc = mac->mac_sc;
1729 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1731 siba_dev_up(sc->sc_dev, flags);
1734 low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1735 ~BWN_TGSLOW_PHYRESET;
1736 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
1737 siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1739 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1740 siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1743 if (mac->mac_phy.switch_analog != NULL)
1744 mac->mac_phy.switch_analog(mac, 1);
1746 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1747 if (flags & BWN_TGSLOW_SUPPORT_G)
1748 ctl |= BWN_MACCTL_GMODE;
1749 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1753 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1755 struct bwn_phy *phy = &mac->mac_phy;
1756 struct bwn_softc *sc = mac->mac_sc;
1760 tmp = BWN_READ_2(mac, BWN_PHYVER);
1761 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1763 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1764 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1765 phy->rev = (tmp & BWN_PHYVER_VERSION);
1766 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1767 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1768 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1769 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1770 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1771 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1775 if (siba_get_chipid(sc->sc_dev) == 0x4317) {
1776 if (siba_get_chiprev(sc->sc_dev) == 0)
1778 else if (siba_get_chiprev(sc->sc_dev) == 1)
1783 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1784 tmp = BWN_READ_2(mac, BWN_RFDATALO);
1785 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1786 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1788 phy->rf_rev = (tmp & 0xf0000000) >> 28;
1789 phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1790 phy->rf_manuf = (tmp & 0x00000fff);
1791 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */
1793 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1794 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1795 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1796 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1797 (phy->type == BWN_PHYTYPE_N &&
1798 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1799 (phy->type == BWN_PHYTYPE_LP &&
1800 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1805 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1807 phy->type, phy->rev, phy->analog);
1810 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1812 phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1817 bwn_chiptest(struct bwn_mac *mac)
1819 #define TESTVAL0 0x55aaaa55
1820 #define TESTVAL1 0xaa5555aa
1821 struct bwn_softc *sc = mac->mac_sc;
1826 backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1828 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1829 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1831 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1832 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1835 bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1837 if ((siba_get_revid(sc->sc_dev) >= 3) &&
1838 (siba_get_revid(sc->sc_dev) <= 10)) {
1839 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1840 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1841 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1843 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1846 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1848 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1849 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1856 device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1860 #define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1861 #define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1864 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1866 struct bwn_softc *sc = mac->mac_sc;
1867 struct ifnet *ifp = sc->sc_ifp;
1868 struct ieee80211com *ic = ifp->if_l2com;
1870 memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1874 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1875 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1876 if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1878 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1879 &ic->ic_nchans, &bwn_chantable_n,
1880 IEEE80211_CHAN_HTA);
1883 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1884 &ic->ic_nchans, &bwn_chantable_a,
1888 mac->mac_phy.supports_2ghz = have_bg;
1889 mac->mac_phy.supports_5ghz = have_a;
1891 return (ic->ic_nchans == 0 ? ENXIO : 0);
1895 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1899 BWN_ASSERT_LOCKED(mac->mac_sc);
1901 if (way == BWN_SHARED) {
1902 KASSERT((offset & 0x0001) == 0,
1903 ("%s:%d warn", __func__, __LINE__));
1904 if (offset & 0x0003) {
1905 bwn_shm_ctlword(mac, way, offset >> 2);
1906 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1908 bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1909 ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1914 bwn_shm_ctlword(mac, way, offset);
1915 ret = BWN_READ_4(mac, BWN_SHM_DATA);
1921 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1925 BWN_ASSERT_LOCKED(mac->mac_sc);
1927 if (way == BWN_SHARED) {
1928 KASSERT((offset & 0x0001) == 0,
1929 ("%s:%d warn", __func__, __LINE__));
1930 if (offset & 0x0003) {
1931 bwn_shm_ctlword(mac, way, offset >> 2);
1932 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1937 bwn_shm_ctlword(mac, way, offset);
1938 ret = BWN_READ_2(mac, BWN_SHM_DATA);
1945 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1953 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1957 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1960 BWN_ASSERT_LOCKED(mac->mac_sc);
1962 if (way == BWN_SHARED) {
1963 KASSERT((offset & 0x0001) == 0,
1964 ("%s:%d warn", __func__, __LINE__));
1965 if (offset & 0x0003) {
1966 bwn_shm_ctlword(mac, way, offset >> 2);
1967 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1968 (value >> 16) & 0xffff);
1969 bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1970 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1975 bwn_shm_ctlword(mac, way, offset);
1976 BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1980 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1983 BWN_ASSERT_LOCKED(mac->mac_sc);
1985 if (way == BWN_SHARED) {
1986 KASSERT((offset & 0x0001) == 0,
1987 ("%s:%d warn", __func__, __LINE__));
1988 if (offset & 0x0003) {
1989 bwn_shm_ctlword(mac, way, offset >> 2);
1990 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1995 bwn_shm_ctlword(mac, way, offset);
1996 BWN_WRITE_2(mac, BWN_SHM_DATA, value);
2000 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
2005 c->ic_flags = flags;
2008 c->ic_maxpower = 2 * txpow;
2009 c->ic_maxregpower = txpow;
2013 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
2014 const struct bwn_channelinfo *ci, int flags)
2016 struct ieee80211_channel *c;
2019 c = &chans[*nchans];
2021 for (i = 0; i < ci->nchannels; i++) {
2022 const struct bwn_channel *hc;
2024 hc = &ci->channels[i];
2025 if (*nchans >= maxchans)
2027 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
2029 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
2030 /* g channel have a separate b-only entry */
2031 if (*nchans >= maxchans)
2034 c[-1].ic_flags = IEEE80211_CHAN_B;
2037 if (flags == IEEE80211_CHAN_HTG) {
2038 /* HT g channel have a separate g-only entry */
2039 if (*nchans >= maxchans)
2041 c[-1].ic_flags = IEEE80211_CHAN_G;
2043 c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2044 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */
2047 if (flags == IEEE80211_CHAN_HTA) {
2048 /* HT a channel have a separate a-only entry */
2049 if (*nchans >= maxchans)
2051 c[-1].ic_flags = IEEE80211_CHAN_A;
2053 c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2054 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */
2061 bwn_phy_g_attach(struct bwn_mac *mac)
2063 struct bwn_softc *sc = mac->mac_sc;
2064 struct bwn_phy *phy = &mac->mac_phy;
2065 struct bwn_phy_g *pg = &phy->phy_g;
2067 int16_t pab0, pab1, pab2;
2068 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2071 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
2072 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
2073 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
2074 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
2076 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
2077 device_printf(sc->sc_dev, "not supported anymore\n");
2080 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2082 pg->pg_idletssi = 52;
2083 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2087 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2088 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
2089 if (pg->pg_tssi2dbm == NULL) {
2090 device_printf(sc->sc_dev, "failed to allocate buffer\n");
2093 for (i = 0; i < 64; i++) {
2094 int32_t m1, m2, f, q, delta;
2097 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2098 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2103 device_printf(sc->sc_dev,
2104 "failed to generate tssi2dBm\n");
2105 free(pg->pg_tssi2dbm, M_DEVBUF);
2108 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2113 } while (delta >= 2);
2115 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2119 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2124 bwn_phy_g_detach(struct bwn_mac *mac)
2126 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2128 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2129 free(pg->pg_tssi2dbm, M_DEVBUF);
2130 pg->pg_tssi2dbm = NULL;
2136 bwn_phy_g_init_pre(struct bwn_mac *mac)
2138 struct bwn_phy *phy = &mac->mac_phy;
2139 struct bwn_phy_g *pg = &phy->phy_g;
2144 tssi2dbm = pg->pg_tssi2dbm;
2145 idletssi = pg->pg_idletssi;
2147 memset(pg, 0, sizeof(*pg));
2149 pg->pg_tssi2dbm = tssi2dbm;
2150 pg->pg_idletssi = idletssi;
2152 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2154 for (i = 0; i < N(pg->pg_nrssi); i++)
2155 pg->pg_nrssi[i] = -1000;
2156 for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2157 pg->pg_nrssi_lt[i] = i;
2158 pg->pg_lofcal = 0xffff;
2159 pg->pg_initval = 0xffff;
2160 pg->pg_immode = BWN_IMMODE_NONE;
2161 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2162 pg->pg_avgtssi = 0xff;
2164 pg->pg_loctl.tx_bias = 0xff;
2165 TAILQ_INIT(&pg->pg_loctl.calib_list);
2169 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2171 struct bwn_phy *phy = &mac->mac_phy;
2172 struct bwn_phy_g *pg = &phy->phy_g;
2173 struct bwn_softc *sc = mac->mac_sc;
2174 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2175 static const struct bwn_rfatt rfatt0[] = {
2176 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
2177 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2180 static const struct bwn_rfatt rfatt1[] = {
2181 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2184 static const struct bwn_rfatt rfatt2[] = {
2185 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2188 static const struct bwn_bbatt bbatt_0[] = {
2189 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2192 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2194 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2195 pg->pg_bbatt.att = 0;
2197 pg->pg_bbatt.att = 2;
2199 /* prepare Radio Attenuation */
2200 pg->pg_rfatt.padmix = 0;
2202 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
2203 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
2204 if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
2205 pg->pg_rfatt.att = 2;
2207 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
2208 pg->pg_rfatt.att = 3;
2213 if (phy->type == BWN_PHYTYPE_A) {
2214 pg->pg_rfatt.att = 0x60;
2218 switch (phy->rf_ver) {
2220 switch (phy->rf_rev) {
2222 pg->pg_rfatt.att = 5;
2225 if (phy->type == BWN_PHYTYPE_G) {
2226 if (siba_get_pci_subvendor(sc->sc_dev) ==
2227 SIBA_BOARDVENDOR_BCM &&
2228 siba_get_pci_subdevice(sc->sc_dev) ==
2229 SIBA_BOARD_BCM4309G &&
2230 siba_get_pci_revid(sc->sc_dev) >= 30)
2231 pg->pg_rfatt.att = 3;
2232 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2233 SIBA_BOARDVENDOR_BCM &&
2234 siba_get_pci_subdevice(sc->sc_dev) ==
2236 pg->pg_rfatt.att = 3;
2238 pg->pg_rfatt.att = 1;
2240 if (siba_get_pci_subvendor(sc->sc_dev) ==
2241 SIBA_BOARDVENDOR_BCM &&
2242 siba_get_pci_subdevice(sc->sc_dev) ==
2243 SIBA_BOARD_BCM4309G &&
2244 siba_get_pci_revid(sc->sc_dev) >= 30)
2245 pg->pg_rfatt.att = 7;
2247 pg->pg_rfatt.att = 6;
2251 if (phy->type == BWN_PHYTYPE_G) {
2252 if (siba_get_pci_subvendor(sc->sc_dev) ==
2253 SIBA_BOARDVENDOR_BCM &&
2254 siba_get_pci_subdevice(sc->sc_dev) ==
2255 SIBA_BOARD_BCM4309G &&
2256 siba_get_pci_revid(sc->sc_dev) >= 30)
2257 pg->pg_rfatt.att = 3;
2258 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2259 SIBA_BOARDVENDOR_BCM &&
2260 siba_get_pci_subdevice(sc->sc_dev) ==
2262 pg->pg_rfatt.att = 5;
2263 else if (siba_get_chipid(sc->sc_dev) == 0x4320)
2264 pg->pg_rfatt.att = 4;
2266 pg->pg_rfatt.att = 3;
2268 pg->pg_rfatt.att = 6;
2271 pg->pg_rfatt.att = 5;
2275 pg->pg_rfatt.att = 1;
2279 pg->pg_rfatt.att = 5;
2282 pg->pg_rfatt.att = 0xa;
2283 pg->pg_rfatt.padmix = 1;
2287 pg->pg_rfatt.att = 5;
2292 switch (phy->rf_rev) {
2294 pg->pg_rfatt.att = 6;
2299 pg->pg_rfatt.att = 5;
2301 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2303 if (!bwn_has_hwpctl(mac)) {
2304 lo->rfatt.array = rfatt0;
2305 lo->rfatt.len = N(rfatt0);
2310 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2311 lo->rfatt.array = rfatt1;
2312 lo->rfatt.len = N(rfatt1);
2317 lo->rfatt.array = rfatt2;
2318 lo->rfatt.len = N(rfatt2);
2322 lo->bbatt.array = bbatt_0;
2323 lo->bbatt.len = N(bbatt_0);
2327 BWN_READ_4(mac, BWN_MACCTL);
2328 if (phy->rev == 1) {
2330 bwn_reset_core(mac, 0);
2331 bwn_phy_g_init_sub(mac);
2333 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2339 bwn_phy_g_txctl(struct bwn_mac *mac)
2341 struct bwn_phy *phy = &mac->mac_phy;
2343 if (phy->rf_ver != 0x2050)
2345 if (phy->rf_rev == 1)
2346 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2347 if (phy->rf_rev < 6)
2348 return (BWN_TXCTL_PA2DB);
2349 if (phy->rf_rev == 8)
2350 return (BWN_TXCTL_TXMIX);
2355 bwn_phy_g_init(struct bwn_mac *mac)
2358 bwn_phy_g_init_sub(mac);
2363 bwn_phy_g_exit(struct bwn_mac *mac)
2365 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2366 struct bwn_lo_calib *cal, *tmp;
2370 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2371 TAILQ_REMOVE(&lo->calib_list, cal, list);
2372 free(cal, M_DEVBUF);
2377 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2380 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2381 return (BWN_READ_2(mac, BWN_PHYDATA));
2385 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2388 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2389 BWN_WRITE_2(mac, BWN_PHYDATA, value);
2393 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2396 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2397 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2398 return (BWN_READ_2(mac, BWN_RFDATALO));
2402 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2405 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2406 BWN_WRITE_2(mac, BWN_RFCTL, reg);
2407 BWN_WRITE_2(mac, BWN_RFDATALO, value);
2411 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2414 return (mac->mac_phy.rev >= 6);
2418 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2420 struct bwn_phy *phy = &mac->mac_phy;
2421 struct bwn_phy_g *pg = &phy->phy_g;
2422 unsigned int channel;
2423 uint16_t rfover, rfoverval;
2429 BWN_PHY_WRITE(mac, 0x15, 0x8000);
2430 BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2431 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2432 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2433 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2434 pg->pg_radioctx_over);
2435 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2436 pg->pg_radioctx_overval);
2437 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2439 channel = phy->chan;
2440 bwn_phy_g_switch_chan(mac, 6, 1);
2441 bwn_phy_g_switch_chan(mac, channel, 0);
2445 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2446 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2447 pg->pg_radioctx_over = rfover;
2448 pg->pg_radioctx_overval = rfoverval;
2449 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2450 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2451 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2455 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2458 if ((newchan < 1) || (newchan > 14))
2460 bwn_phy_g_switch_chan(mac, newchan, 0);
2466 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2473 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2475 struct bwn_phy *phy = &mac->mac_phy;
2480 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2483 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2484 bwn_hf_write(mac, hf);
2486 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2487 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2488 ((autodiv ? BWN_ANTAUTO1 : antenna)
2489 << BWN_PHY_BBANDCFG_RXANT_SHIFT));
2492 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2493 if (antenna == BWN_ANTAUTO1)
2494 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2496 tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2497 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2499 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2501 tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2503 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2504 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2505 if (phy->rev >= 2) {
2506 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2507 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2508 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2509 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2512 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2514 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2515 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2519 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2521 hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2522 bwn_hf_write(mac, hf);
2526 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2528 struct bwn_phy *phy = &mac->mac_phy;
2529 struct bwn_phy_g *pg = &phy->phy_g;
2531 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2532 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2534 if (phy->rev == 0 || !phy->gmode)
2537 pg->pg_aci_wlan_automatic = 0;
2542 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2544 struct bwn_phy *phy = &mac->mac_phy;
2545 struct bwn_phy_g *pg = &phy->phy_g;
2546 struct bwn_softc *sc = mac->mac_sc;
2553 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2555 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2556 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2557 if (cck < 0 && ofdm < 0) {
2558 if (ignore_tssi == 0)
2559 return (BWN_TXPWR_RES_DONE);
2563 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2564 if (pg->pg_avgtssi != 0xff)
2565 tssi = (tssi + pg->pg_avgtssi) / 2;
2566 pg->pg_avgtssi = tssi;
2567 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2569 max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2570 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2573 device_printf(sc->sc_dev, "invalid max TX-power value\n");
2575 siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2578 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2579 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2580 tssi, 0x00), 0x3f)]);
2582 return (BWN_TXPWR_RES_DONE);
2584 rfatt = -((power + 7) / 8);
2585 bbatt = (-(power / 2)) - (4 * rfatt);
2586 if ((rfatt == 0) && (bbatt == 0))
2587 return (BWN_TXPWR_RES_DONE);
2588 pg->pg_bbatt_delta = bbatt;
2589 pg->pg_rfatt_delta = rfatt;
2590 return (BWN_TXPWR_RES_NEED_ADJUST);
2594 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2596 struct bwn_phy *phy = &mac->mac_phy;
2597 struct bwn_phy_g *pg = &phy->phy_g;
2598 struct bwn_softc *sc = mac->mac_sc;
2602 bwn_mac_suspend(mac);
2604 BWN_ASSERT_LOCKED(sc);
2606 bbatt = pg->pg_bbatt.att;
2607 bbatt += pg->pg_bbatt_delta;
2608 rfatt = pg->pg_rfatt.att;
2609 rfatt += pg->pg_rfatt_delta;
2611 bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2612 txctl = pg->pg_txctl;
2613 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2616 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2619 } else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2621 bbatt += 4 * (rfatt - 2);
2624 } else if (rfatt > 4 && txctl) {
2635 pg->pg_txctl = txctl;
2636 bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2637 pg->pg_rfatt.att = rfatt;
2638 pg->pg_bbatt.att = bbatt;
2640 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2644 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2647 bwn_phy_unlock(mac);
2649 bwn_mac_enable(mac);
2653 bwn_phy_g_task_15s(struct bwn_mac *mac)
2655 struct bwn_phy *phy = &mac->mac_phy;
2656 struct bwn_phy_g *pg = &phy->phy_g;
2657 struct bwn_softc *sc = mac->mac_sc;
2658 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2659 unsigned long expire, now;
2660 struct bwn_lo_calib *cal, *tmp;
2661 uint8_t expired = 0;
2663 bwn_mac_suspend(mac);
2669 if (bwn_has_hwpctl(mac)) {
2670 expire = now - BWN_LO_PWRVEC_EXPIRE;
2671 if (time_before(lo->pwr_vec_read_time, expire)) {
2672 bwn_lo_get_powervector(mac);
2673 bwn_phy_g_dc_lookup_init(mac, 0);
2678 expire = now - BWN_LO_CALIB_EXPIRE;
2679 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2680 if (!time_before(cal->calib_time, expire))
2682 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2683 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2684 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2688 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2689 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2690 cal->ctl.i, cal->ctl.q);
2692 TAILQ_REMOVE(&lo->calib_list, cal, list);
2693 free(cal, M_DEVBUF);
2695 if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2696 cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2699 device_printf(sc->sc_dev,
2700 "failed to recalibrate LO\n");
2703 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2704 bwn_lo_write(mac, &cal->ctl);
2708 bwn_mac_enable(mac);
2712 bwn_phy_g_task_60s(struct bwn_mac *mac)
2714 struct bwn_phy *phy = &mac->mac_phy;
2715 struct bwn_softc *sc = mac->mac_sc;
2716 uint8_t old = phy->chan;
2718 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2721 bwn_mac_suspend(mac);
2722 bwn_nrssi_slope_11g(mac);
2723 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2724 bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2725 bwn_switch_channel(mac, old);
2727 bwn_mac_enable(mac);
2731 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2734 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2738 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2739 const struct ieee80211_bpf_params *params)
2741 struct ieee80211com *ic = ni->ni_ic;
2742 struct ifnet *ifp = ic->ic_ifp;
2743 struct bwn_softc *sc = ifp->if_softc;
2744 struct bwn_mac *mac = sc->sc_curmac;
2746 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
2747 mac->mac_status < BWN_MAC_STATUS_STARTED) {
2748 ieee80211_free_node(ni);
2754 if (bwn_tx_isfull(sc, m)) {
2755 ieee80211_free_node(ni);
2762 if (bwn_tx_start(sc, ni, m) != 0) {
2764 ieee80211_free_node(ni);
2767 sc->sc_watchdog_timer = 5;
2773 * Setup driver-specific state for a newly associated node.
2774 * Note that we're called also on a re-associate, the isnew
2775 * param tells us if this is the first time or not.
2778 bwn_newassoc(struct ieee80211_node *ni, int isnew)
2780 struct ieee80211vap *vap = ni->ni_vap;
2782 ieee80211_amrr_node_init(&BWN_VAP(vap)->bv_amrr,
2783 &BWN_NODE(ni)->bn_amn, ni);
2787 * Callback from the 802.11 layer to update the slot time
2788 * based on the current setting. We use it to notify the
2789 * firmware of ERP changes and the f/w takes care of things
2790 * like slot time and preamble.
2793 bwn_updateslot(struct ifnet *ifp)
2795 struct bwn_softc *sc = ifp->if_softc;
2796 struct ieee80211com *ic = ifp->if_l2com;
2797 struct bwn_mac *mac;
2800 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
2801 mac = (struct bwn_mac *)sc->sc_curmac;
2802 bwn_set_slot_time(mac,
2803 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2809 * Callback from the 802.11 layer after a promiscuous mode change.
2810 * Note this interface does not check the operating mode as this
2811 * is an internal callback and we are expected to honor the current
2812 * state (e.g. this is used for setting the interface in promiscuous
2813 * mode when operating in hostap mode to do ACS).
2816 bwn_update_promisc(struct ifnet *ifp)
2818 struct bwn_softc *sc = ifp->if_softc;
2819 struct bwn_mac *mac = sc->sc_curmac;
2822 mac = sc->sc_curmac;
2823 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2824 if (ifp->if_flags & IFF_PROMISC)
2825 sc->sc_filters |= BWN_MACCTL_PROMISC;
2827 sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2828 bwn_set_opmode(mac);
2834 * Callback from the 802.11 layer to update WME parameters.
2837 bwn_wme_update(struct ieee80211com *ic)
2839 struct bwn_softc *sc = ic->ic_ifp->if_softc;
2840 struct bwn_mac *mac = sc->sc_curmac;
2841 struct wmeParams *wmep;
2845 mac = sc->sc_curmac;
2846 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2847 bwn_mac_suspend(mac);
2848 for (i = 0; i < N(sc->sc_wmeParams); i++) {
2849 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2850 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2852 bwn_mac_enable(mac);
2858 static struct ieee80211_node *
2859 bwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
2861 struct ieee80211com *ic = vap->iv_ic;
2862 struct bwn_softc *sc = ic->ic_ifp->if_softc;
2863 const size_t space = sizeof(struct bwn_node);
2864 struct bwn_node *bn;
2866 bn = malloc(space, M_80211_NODE, M_NOWAIT|M_ZERO);
2871 DPRINTF(sc, BWN_DEBUG_NODE, "%s: bn %p\n", __func__, bn);
2872 return (&bn->bn_node);
2876 bwn_node_cleanup(struct ieee80211_node *ni)
2878 struct ieee80211com *ic = ni->ni_ic;
2879 struct bwn_softc *sc = ic->ic_ifp->if_softc;
2881 sc->sc_node_cleanup(ni);
2885 bwn_scan_start(struct ieee80211com *ic)
2887 struct ifnet *ifp = ic->ic_ifp;
2888 struct bwn_softc *sc = ifp->if_softc;
2889 struct bwn_mac *mac;
2892 mac = sc->sc_curmac;
2893 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2894 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2895 bwn_set_opmode(mac);
2896 /* disable CFP update during scan */
2897 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2903 bwn_scan_end(struct ieee80211com *ic)
2905 struct ifnet *ifp = ic->ic_ifp;
2906 struct bwn_softc *sc = ifp->if_softc;
2907 struct bwn_mac *mac;
2910 mac = sc->sc_curmac;
2911 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2912 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2913 bwn_set_opmode(mac);
2914 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2920 bwn_set_channel(struct ieee80211com *ic)
2922 struct ifnet *ifp = ic->ic_ifp;
2923 struct bwn_softc *sc = ifp->if_softc;
2924 struct bwn_mac *mac = sc->sc_curmac;
2925 struct bwn_phy *phy = &mac->mac_phy;
2930 error = bwn_switch_band(sc, ic->ic_curchan);
2933 bwn_mac_suspend(mac);
2934 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2935 chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2936 if (chan != phy->chan)
2937 bwn_switch_channel(mac, chan);
2939 /* TX power level */
2940 if (ic->ic_curchan->ic_maxpower != 0 &&
2941 ic->ic_curchan->ic_maxpower != phy->txpower) {
2942 phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2943 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2944 BWN_TXPWR_IGNORE_TSSI);
2947 bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2948 if (phy->set_antenna)
2949 phy->set_antenna(mac, BWN_ANT_DEFAULT);
2951 if (sc->sc_rf_enabled != phy->rf_on) {
2952 if (sc->sc_rf_enabled) {
2954 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2955 device_printf(sc->sc_dev,
2956 "please turns on the RF switch\n");
2958 bwn_rf_turnoff(mac);
2961 bwn_mac_enable(mac);
2965 * Setup radio tap channel freq and flags
2967 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2968 htole16(ic->ic_curchan->ic_freq);
2969 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2970 htole16(ic->ic_curchan->ic_flags & 0xffff);
2975 static struct ieee80211vap *
2976 bwn_vap_create(struct ieee80211com *ic,
2977 const char name[IFNAMSIZ], int unit, int opmode, int flags,
2978 const uint8_t bssid[IEEE80211_ADDR_LEN],
2979 const uint8_t mac0[IEEE80211_ADDR_LEN])
2981 struct ifnet *ifp = ic->ic_ifp;
2982 struct bwn_softc *sc = ifp->if_softc;
2983 struct ieee80211vap *vap;
2984 struct bwn_vap *bvp;
2985 uint8_t mac[IEEE80211_ADDR_LEN];
2987 IEEE80211_ADDR_COPY(mac, mac0);
2989 case IEEE80211_M_HOSTAP:
2990 case IEEE80211_M_MBSS:
2991 case IEEE80211_M_STA:
2992 case IEEE80211_M_WDS:
2993 case IEEE80211_M_MONITOR:
2994 case IEEE80211_M_IBSS:
2995 case IEEE80211_M_AHDEMO:
3001 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
3003 bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap),
3004 M_80211_VAP, M_NOWAIT | M_ZERO);
3006 device_printf(sc->sc_dev, "failed to allocate a buffer\n");
3010 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
3011 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
3012 /* override with driver methods */
3013 bvp->bv_newstate = vap->iv_newstate;
3014 vap->iv_newstate = bwn_newstate;
3016 /* override max aid so sta's cannot assoc when we're out of sta id's */
3017 vap->iv_max_aid = BWN_STAID_MAX;
3019 ieee80211_amrr_init(&bvp->bv_amrr, vap,
3020 IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
3021 IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
3024 /* complete setup */
3025 ieee80211_vap_attach(vap, ieee80211_media_change,
3026 ieee80211_media_status);
3031 bwn_vap_delete(struct ieee80211vap *vap)
3033 struct bwn_vap *bvp = BWN_VAP(vap);
3035 ieee80211_amrr_cleanup(&bvp->bv_amrr);
3036 ieee80211_vap_detach(vap);
3037 free(bvp, M_80211_VAP);
3043 struct bwn_softc *sc = arg;
3044 struct ifnet *ifp = sc->sc_ifp;
3045 struct ieee80211com *ic = ifp->if_l2com;
3048 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
3049 __func__, ifp->if_flags);
3052 error = bwn_init_locked(sc);
3056 ieee80211_start_all(ic); /* start all vap's */
3060 bwn_init_locked(struct bwn_softc *sc)
3062 struct bwn_mac *mac;
3063 struct ifnet *ifp = sc->sc_ifp;
3066 BWN_ASSERT_LOCKED(sc);
3068 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
3069 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
3072 sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
3073 sc->sc_rf_enabled = 1;
3075 mac = sc->sc_curmac;
3076 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
3077 error = bwn_core_init(mac);
3081 if (mac->mac_status == BWN_MAC_STATUS_INITED)
3082 bwn_core_start(mac);
3084 bwn_set_opmode(mac);
3085 bwn_set_pretbtt(mac);
3086 bwn_spu_setdelay(mac, 0);
3087 bwn_set_macaddr(mac);
3089 ifp->if_drv_flags |= IFF_DRV_RUNNING;
3090 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
3091 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
3097 bwn_stop(struct bwn_softc *sc, int statechg)
3101 bwn_stop_locked(sc, statechg);
3106 bwn_stop_locked(struct bwn_softc *sc, int statechg)
3108 struct bwn_mac *mac = sc->sc_curmac;
3109 struct ifnet *ifp = sc->sc_ifp;
3111 BWN_ASSERT_LOCKED(sc);
3113 if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
3114 /* XXX FIXME opmode not based on VAP */
3115 bwn_set_opmode(mac);
3116 bwn_set_macaddr(mac);
3119 if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
3122 callout_stop(&sc->sc_led_blink_ch);
3123 sc->sc_led_blinking = 0;
3126 sc->sc_rf_enabled = 0;
3128 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
3132 bwn_wme_clear(struct bwn_softc *sc)
3134 #define MS(_v, _f) (((_v) & _f) >> _f##_S)
3135 struct wmeParams *p;
3138 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
3139 ("%s:%d: fail", __func__, __LINE__));
3141 for (i = 0; i < N(sc->sc_wmeParams); i++) {
3142 p = &(sc->sc_wmeParams[i]);
3144 switch (bwn_wme_shm_offsets[i]) {
3146 p->wmep_txopLimit = 0;
3148 /* XXX FIXME: log2(cwmin) */
3149 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3150 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3153 p->wmep_txopLimit = 0;
3155 /* XXX FIXME: log2(cwmin) */
3156 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3157 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3159 case BWN_WME_BESTEFFORT:
3160 p->wmep_txopLimit = 0;
3162 /* XXX FIXME: log2(cwmin) */
3163 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3164 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3166 case BWN_WME_BACKGROUND:
3167 p->wmep_txopLimit = 0;
3169 /* XXX FIXME: log2(cwmin) */
3170 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3171 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3174 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3180 bwn_core_init(struct bwn_mac *mac)
3182 struct bwn_softc *sc = mac->mac_sc;
3186 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3187 ("%s:%d: fail", __func__, __LINE__));
3189 siba_powerup(sc->sc_dev, 0);
3190 if (!siba_dev_isup(sc->sc_dev))
3192 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3194 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3195 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3196 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3197 BWN_GETTIME(mac->mac_phy.nexttime);
3198 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3199 bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3200 mac->mac_stats.link_noise = -95;
3201 mac->mac_reason_intr = 0;
3202 bzero(mac->mac_reason, sizeof(mac->mac_reason));
3203 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3205 if (sc->sc_debug & BWN_DEBUG_XMIT)
3206 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3208 mac->mac_suspended = 1;
3209 mac->mac_task_state = 0;
3210 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3212 mac->mac_phy.init_pre(mac);
3214 siba_pcicore_intr(sc->sc_dev);
3216 siba_fix_imcfglobug(sc->sc_dev);
3217 bwn_bt_disable(mac);
3218 if (mac->mac_phy.prepare_hw) {
3219 error = mac->mac_phy.prepare_hw(mac);
3223 error = bwn_chip_init(mac);
3226 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3227 siba_get_revid(sc->sc_dev));
3228 hf = bwn_hf_read(mac);
3229 if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3230 hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3231 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3232 hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3233 if (mac->mac_phy.rev == 1)
3234 hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3236 if (mac->mac_phy.rf_ver == 0x2050) {
3237 if (mac->mac_phy.rf_rev < 6)
3238 hf |= BWN_HF_FORCE_VCO_RECALC;
3239 if (mac->mac_phy.rf_rev == 6)
3240 hf |= BWN_HF_4318_TSSI;
3242 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3243 hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3244 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3245 (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3246 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3247 hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3248 bwn_hf_write(mac, hf);
3250 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3251 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3252 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3253 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3256 bwn_set_phytxctl(mac);
3258 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3259 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3260 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3262 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3269 bwn_spu_setdelay(mac, 1);
3272 siba_powerup(sc->sc_dev,
3273 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3274 bwn_set_macaddr(mac);
3275 bwn_crypt_init(mac);
3277 /* XXX LED initializatin */
3279 mac->mac_status = BWN_MAC_STATUS_INITED;
3286 siba_powerdown(sc->sc_dev);
3287 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3288 ("%s:%d: fail", __func__, __LINE__));
3293 bwn_core_start(struct bwn_mac *mac)
3295 struct bwn_softc *sc = mac->mac_sc;
3298 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3299 ("%s:%d: fail", __func__, __LINE__));
3301 if (siba_get_revid(sc->sc_dev) < 5)
3305 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3306 if (!(tmp & 0x00000001))
3308 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3311 bwn_mac_enable(mac);
3312 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3313 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3315 mac->mac_status = BWN_MAC_STATUS_STARTED;
3319 bwn_core_exit(struct bwn_mac *mac)
3321 struct bwn_softc *sc = mac->mac_sc;
3324 BWN_ASSERT_LOCKED(mac->mac_sc);
3326 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3327 ("%s:%d: fail", __func__, __LINE__));
3329 if (mac->mac_status != BWN_MAC_STATUS_INITED)
3331 mac->mac_status = BWN_MAC_STATUS_UNINIT;
3333 macctl = BWN_READ_4(mac, BWN_MACCTL);
3334 macctl &= ~BWN_MACCTL_MCODE_RUN;
3335 macctl |= BWN_MACCTL_MCODE_JMP0;
3336 BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3341 mac->mac_phy.switch_analog(mac, 0);
3342 siba_dev_down(sc->sc_dev, 0);
3343 siba_powerdown(sc->sc_dev);
3347 bwn_bt_disable(struct bwn_mac *mac)
3349 struct bwn_softc *sc = mac->mac_sc;
3352 /* XXX do nothing yet */
3356 bwn_chip_init(struct bwn_mac *mac)
3358 struct bwn_softc *sc = mac->mac_sc;
3359 struct bwn_phy *phy = &mac->mac_phy;
3363 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3365 macctl |= BWN_MACCTL_GMODE;
3366 BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3368 error = bwn_fw_fillinfo(mac);
3371 error = bwn_fw_loaducode(mac);
3375 error = bwn_gpio_init(mac);
3379 error = bwn_fw_loadinitvals(mac);
3381 siba_gpio_set(sc->sc_dev, 0);
3384 phy->switch_analog(mac, 1);
3385 error = bwn_phy_init(mac);
3387 siba_gpio_set(sc->sc_dev, 0);
3391 phy->set_im(mac, BWN_IMMODE_NONE);
3392 if (phy->set_antenna)
3393 phy->set_antenna(mac, BWN_ANT_DEFAULT);
3394 bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3396 if (phy->type == BWN_PHYTYPE_B)
3397 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3398 BWN_WRITE_4(mac, 0x0100, 0x01000000);
3399 if (siba_get_revid(sc->sc_dev) < 5)
3400 BWN_WRITE_4(mac, 0x010c, 0x01000000);
3402 BWN_WRITE_4(mac, BWN_MACCTL,
3403 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3404 BWN_WRITE_4(mac, BWN_MACCTL,
3405 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3406 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3408 bwn_set_opmode(mac);
3409 if (siba_get_revid(sc->sc_dev) < 3) {
3410 BWN_WRITE_2(mac, 0x060e, 0x0000);
3411 BWN_WRITE_2(mac, 0x0610, 0x8000);
3412 BWN_WRITE_2(mac, 0x0604, 0x0000);
3413 BWN_WRITE_2(mac, 0x0606, 0x0200);
3415 BWN_WRITE_4(mac, 0x0188, 0x80000000);
3416 BWN_WRITE_4(mac, 0x018c, 0x02000000);
3418 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3419 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
3420 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3421 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3422 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3423 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3424 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3425 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3426 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3427 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3431 /* read hostflags */
3433 bwn_hf_read(struct bwn_mac *mac)
3437 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3439 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3441 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3446 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3449 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3450 (value & 0x00000000ffffull));
3451 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3452 (value & 0x0000ffff0000ull) >> 16);
3453 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3454 (value & 0xffff00000000ULL) >> 32);
3458 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3461 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3462 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3466 bwn_rate_init(struct bwn_mac *mac)
3469 switch (mac->mac_phy.type) {
3472 case BWN_PHYTYPE_LP:
3474 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3475 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3476 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3477 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3478 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3479 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3480 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3481 if (mac->mac_phy.type == BWN_PHYTYPE_A)
3485 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3486 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3487 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3488 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3491 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3496 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3502 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3505 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3507 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3508 bwn_shm_read_2(mac, BWN_SHARED, offset));
3512 bwn_plcp_getcck(const uint8_t bitrate)
3516 case BWN_CCK_RATE_1MB:
3518 case BWN_CCK_RATE_2MB:
3520 case BWN_CCK_RATE_5MB:
3522 case BWN_CCK_RATE_11MB:
3525 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3530 bwn_plcp_getofdm(const uint8_t bitrate)
3534 case BWN_OFDM_RATE_6MB:
3536 case BWN_OFDM_RATE_9MB:
3538 case BWN_OFDM_RATE_12MB:
3540 case BWN_OFDM_RATE_18MB:
3542 case BWN_OFDM_RATE_24MB:
3544 case BWN_OFDM_RATE_36MB:
3546 case BWN_OFDM_RATE_48MB:
3548 case BWN_OFDM_RATE_54MB:
3551 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3556 bwn_set_phytxctl(struct bwn_mac *mac)
3560 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3562 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3563 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3564 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3568 bwn_pio_init(struct bwn_mac *mac)
3570 struct bwn_pio *pio = &mac->mac_method.pio;
3572 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3573 & ~BWN_MACCTL_BIGENDIAN);
3574 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3576 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3577 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3578 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3579 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3580 bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3581 bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3585 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3588 struct bwn_pio_txpkt *tp;
3589 struct bwn_softc *sc = mac->mac_sc;
3592 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3593 tq->tq_index = index;
3595 tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3596 if (siba_get_revid(sc->sc_dev) >= 8)
3599 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3603 TAILQ_INIT(&tq->tq_pktlist);
3604 for (i = 0; i < N(tq->tq_pkts); i++) {
3605 tp = &(tq->tq_pkts[i]);
3608 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3613 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3615 struct bwn_softc *sc = mac->mac_sc;
3616 static const uint16_t bases[] = {
3626 static const uint16_t bases_rev11[] = {
3635 if (siba_get_revid(sc->sc_dev) >= 11) {
3636 if (index >= N(bases_rev11))
3637 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3638 return (bases_rev11[index]);
3640 if (index >= N(bases))
3641 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3642 return (bases[index]);
3646 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3649 struct bwn_softc *sc = mac->mac_sc;
3652 prq->prq_rev = siba_get_revid(sc->sc_dev);
3653 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3654 bwn_dma_rxdirectfifo(mac, index, 1);
3658 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3662 bwn_pio_cancel_tx_packets(tq);
3666 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3669 bwn_destroy_pioqueue_tx(pio);
3673 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3677 return (BWN_READ_2(mac, tq->tq_base + offset));
3681 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3687 type = bwn_dma_mask2type(bwn_dma_mask(mac));
3688 base = bwn_dma_base(type, idx);
3689 if (type == BWN_DMA_64BIT) {
3690 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3691 ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3693 ctl |= BWN_DMA64_RXDIRECTFIFO;
3694 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3696 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3697 ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3699 ctl |= BWN_DMA32_RXDIRECTFIFO;
3700 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3705 bwn_dma_mask(struct bwn_mac *mac)
3710 tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3711 if (tmp & SIBA_TGSHIGH_DMA64)
3712 return (BWN_DMA_BIT_MASK(64));
3713 base = bwn_dma_base(0, 0);
3714 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3715 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3716 if (tmp & BWN_DMA32_TXADDREXT_MASK)
3717 return (BWN_DMA_BIT_MASK(32));
3719 return (BWN_DMA_BIT_MASK(30));
3723 bwn_dma_mask2type(uint64_t dmamask)
3726 if (dmamask == BWN_DMA_BIT_MASK(30))
3727 return (BWN_DMA_30BIT);
3728 if (dmamask == BWN_DMA_BIT_MASK(32))
3729 return (BWN_DMA_32BIT);
3730 if (dmamask == BWN_DMA_BIT_MASK(64))
3731 return (BWN_DMA_64BIT);
3732 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3733 return (BWN_DMA_30BIT);
3737 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3739 struct bwn_pio_txpkt *tp;
3742 for (i = 0; i < N(tq->tq_pkts); i++) {
3743 tp = &(tq->tq_pkts[i]);
3752 bwn_dma_base(int type, int controller_idx)
3754 static const uint16_t map64[] = {
3762 static const uint16_t map32[] = {
3771 if (type == BWN_DMA_64BIT) {
3772 KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3773 ("%s:%d: fail", __func__, __LINE__));
3774 return (map64[controller_idx]);
3776 KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3777 ("%s:%d: fail", __func__, __LINE__));
3778 return (map32[controller_idx]);
3782 bwn_dma_init(struct bwn_mac *mac)
3784 struct bwn_dma *dma = &mac->mac_method.dma;
3786 /* setup TX DMA channels. */
3787 bwn_dma_setup(dma->wme[WME_AC_BK]);
3788 bwn_dma_setup(dma->wme[WME_AC_BE]);
3789 bwn_dma_setup(dma->wme[WME_AC_VI]);
3790 bwn_dma_setup(dma->wme[WME_AC_VO]);
3791 bwn_dma_setup(dma->mcast);
3792 /* setup RX DMA channel. */
3793 bwn_dma_setup(dma->rx);
3796 static struct bwn_dma_ring *
3797 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3798 int for_tx, int type)
3800 struct bwn_dma *dma = &mac->mac_method.dma;
3801 struct bwn_dma_ring *dr;
3802 struct bwn_dmadesc_generic *desc;
3803 struct bwn_dmadesc_meta *mt;
3804 struct bwn_softc *sc = mac->mac_sc;
3807 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO);
3810 dr->dr_numslots = BWN_RXRING_SLOTS;
3812 dr->dr_numslots = BWN_TXRING_SLOTS;
3814 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3815 M_DEVBUF, M_NOWAIT | M_ZERO);
3816 if (dr->dr_meta == NULL)
3821 dr->dr_base = bwn_dma_base(type, controller_index);
3822 dr->dr_index = controller_index;
3823 if (type == BWN_DMA_64BIT) {
3824 dr->getdesc = bwn_dma_64_getdesc;
3825 dr->setdesc = bwn_dma_64_setdesc;
3826 dr->start_transfer = bwn_dma_64_start_transfer;
3827 dr->suspend = bwn_dma_64_suspend;
3828 dr->resume = bwn_dma_64_resume;
3829 dr->get_curslot = bwn_dma_64_get_curslot;
3830 dr->set_curslot = bwn_dma_64_set_curslot;
3832 dr->getdesc = bwn_dma_32_getdesc;
3833 dr->setdesc = bwn_dma_32_setdesc;
3834 dr->start_transfer = bwn_dma_32_start_transfer;
3835 dr->suspend = bwn_dma_32_suspend;
3836 dr->resume = bwn_dma_32_resume;
3837 dr->get_curslot = bwn_dma_32_get_curslot;
3838 dr->set_curslot = bwn_dma_32_set_curslot;
3842 dr->dr_curslot = -1;
3844 if (dr->dr_index == 0) {
3845 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3846 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3848 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3851 error = bwn_dma_allocringmemory(dr);
3857 * Assumption: BWN_TXRING_SLOTS can be divided by
3858 * BWN_TX_SLOTS_PER_FRAME
3860 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3861 ("%s:%d: fail", __func__, __LINE__));
3863 dr->dr_txhdr_cache =
3864 malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3865 BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO);
3866 KASSERT(dr->dr_txhdr_cache != NULL,
3867 ("%s:%d: fail", __func__, __LINE__));
3870 * Create TX ring DMA stuffs
3872 error = bus_dma_tag_create(dma->parent_dtag,
3879 BUS_SPACE_MAXSIZE_32BIT,
3882 &dr->dr_txring_dtag);
3884 device_printf(sc->sc_dev,
3885 "can't create TX ring DMA tag: TODO frees\n");
3889 for (i = 0; i < dr->dr_numslots; i += 2) {
3890 dr->getdesc(dr, i, &desc, &mt);
3892 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3896 error = bus_dmamap_create(dr->dr_txring_dtag, 0,
3899 device_printf(sc->sc_dev,
3900 "can't create RX buf DMA map\n");
3904 dr->getdesc(dr, i + 1, &desc, &mt);
3906 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3910 error = bus_dmamap_create(dma->txbuf_dtag, 0,
3913 device_printf(sc->sc_dev,
3914 "can't create RX buf DMA map\n");
3919 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3920 &dr->dr_spare_dmap);
3922 device_printf(sc->sc_dev,
3923 "can't create RX buf DMA map\n");
3924 goto out; /* XXX wrong! */
3927 for (i = 0; i < dr->dr_numslots; i++) {
3928 dr->getdesc(dr, i, &desc, &mt);
3930 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3933 device_printf(sc->sc_dev,
3934 "can't create RX buf DMA map\n");
3935 goto out; /* XXX wrong! */
3937 error = bwn_dma_newbuf(dr, desc, mt, 1);
3939 device_printf(sc->sc_dev,
3940 "failed to allocate RX buf\n");
3941 goto out; /* XXX wrong! */
3945 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3946 BUS_DMASYNC_PREWRITE);
3948 dr->dr_usedslot = dr->dr_numslots;
3955 free(dr->dr_txhdr_cache, M_DEVBUF);
3957 free(dr->dr_meta, M_DEVBUF);
3964 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3970 bwn_dma_free_descbufs(*dr);
3971 bwn_dma_free_ringmemory(*dr);
3973 free((*dr)->dr_txhdr_cache, M_DEVBUF);
3974 free((*dr)->dr_meta, M_DEVBUF);
3975 free(*dr, M_DEVBUF);
3981 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3982 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3984 struct bwn_dmadesc32 *desc;
3986 *meta = &(dr->dr_meta[slot]);
3987 desc = dr->dr_ring_descbase;
3988 desc = &(desc[slot]);
3990 *gdesc = (struct bwn_dmadesc_generic *)desc;
3994 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3995 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3996 int start, int end, int irq)
3998 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3999 struct bwn_softc *sc = dr->dr_mac->mac_sc;
4000 uint32_t addr, addrext, ctl;
4003 slot = (int)(&(desc->dma.dma32) - descbase);
4004 KASSERT(slot >= 0 && slot < dr->dr_numslots,
4005 ("%s:%d: fail", __func__, __LINE__));
4007 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
4008 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
4009 addr |= siba_dma_translation(sc->sc_dev);
4010 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
4011 if (slot == dr->dr_numslots - 1)
4012 ctl |= BWN_DMA32_DCTL_DTABLEEND;
4014 ctl |= BWN_DMA32_DCTL_FRAMESTART;
4016 ctl |= BWN_DMA32_DCTL_FRAMEEND;
4018 ctl |= BWN_DMA32_DCTL_IRQ;
4019 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
4020 & BWN_DMA32_DCTL_ADDREXT_MASK;
4022 desc->dma.dma32.control = htole32(ctl);
4023 desc->dma.dma32.address = htole32(addr);
4027 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
4030 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
4031 (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
4035 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
4038 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
4039 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
4043 bwn_dma_32_resume(struct bwn_dma_ring *dr)
4046 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
4047 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
4051 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
4055 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
4056 val &= BWN_DMA32_RXDPTR;
4058 return (val / sizeof(struct bwn_dmadesc32));
4062 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
4065 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
4066 (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
4070 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
4071 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
4073 struct bwn_dmadesc64 *desc;
4075 *meta = &(dr->dr_meta[slot]);
4076 desc = dr->dr_ring_descbase;
4077 desc = &(desc[slot]);
4079 *gdesc = (struct bwn_dmadesc_generic *)desc;
4083 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
4084 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
4085 int start, int end, int irq)
4087 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
4088 struct bwn_softc *sc = dr->dr_mac->mac_sc;
4090 uint32_t ctl0 = 0, ctl1 = 0;
4091 uint32_t addrlo, addrhi;
4094 slot = (int)(&(desc->dma.dma64) - descbase);
4095 KASSERT(slot >= 0 && slot < dr->dr_numslots,
4096 ("%s:%d: fail", __func__, __LINE__));
4098 addrlo = (uint32_t) (dmaaddr & 0xffffffff);
4099 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
4100 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
4102 addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
4103 if (slot == dr->dr_numslots - 1)
4104 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
4106 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
4108 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
4110 ctl0 |= BWN_DMA64_DCTL0_IRQ;
4111 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
4112 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
4113 & BWN_DMA64_DCTL1_ADDREXT_MASK;
4115 desc->dma.dma64.control0 = htole32(ctl0);
4116 desc->dma.dma64.control1 = htole32(ctl1);
4117 desc->dma.dma64.address_low = htole32(addrlo);
4118 desc->dma.dma64.address_high = htole32(addrhi);
4122 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
4125 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
4126 (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4130 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
4133 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4134 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
4138 bwn_dma_64_resume(struct bwn_dma_ring *dr)
4141 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4142 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
4146 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
4150 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
4151 val &= BWN_DMA64_RXSTATDPTR;
4153 return (val / sizeof(struct bwn_dmadesc64));
4157 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4160 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4161 (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4165 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4167 struct bwn_mac *mac = dr->dr_mac;
4168 struct bwn_dma *dma = &mac->mac_method.dma;
4169 struct bwn_softc *sc = mac->mac_sc;
4172 error = bus_dma_tag_create(dma->parent_dtag,
4177 BWN_DMA_RINGMEMSIZE,
4179 BUS_SPACE_MAXSIZE_32BIT,
4184 device_printf(sc->sc_dev,
4185 "can't create TX ring DMA tag: TODO frees\n");
4189 error = bus_dmamem_alloc(dr->dr_ring_dtag,
4190 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4193 device_printf(sc->sc_dev,
4194 "can't allocate DMA mem: TODO frees\n");
4197 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4198 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4199 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
4201 device_printf(sc->sc_dev,
4202 "can't load DMA mem: TODO free\n");
4210 bwn_dma_setup(struct bwn_dma_ring *dr)
4212 struct bwn_softc *sc = dr->dr_mac->mac_sc;
4214 uint32_t addrext, ring32, value;
4215 uint32_t trans = siba_dma_translation(sc->sc_dev);
4218 dr->dr_curslot = -1;
4220 if (dr->dr_type == BWN_DMA_64BIT) {
4221 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4222 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4224 value = BWN_DMA64_TXENABLE;
4225 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4226 & BWN_DMA64_TXADDREXT_MASK;
4227 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4228 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4229 (ring64 & 0xffffffff));
4230 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4232 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4234 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4235 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4236 value = BWN_DMA32_TXENABLE;
4237 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4238 & BWN_DMA32_TXADDREXT_MASK;
4239 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4240 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4241 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4249 dr->dr_usedslot = dr->dr_numslots;
4251 if (dr->dr_type == BWN_DMA_64BIT) {
4252 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4253 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4254 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4255 value |= BWN_DMA64_RXENABLE;
4256 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4257 & BWN_DMA64_RXADDREXT_MASK;
4258 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4259 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4260 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4261 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4263 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4264 sizeof(struct bwn_dmadesc64));
4266 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4267 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4268 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4269 value |= BWN_DMA32_RXENABLE;
4270 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4271 & BWN_DMA32_RXADDREXT_MASK;
4272 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4273 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4274 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4275 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4276 sizeof(struct bwn_dmadesc32));
4281 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4284 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4285 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4290 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4294 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4295 if (dr->dr_type == BWN_DMA_64BIT) {
4296 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4297 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4299 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4301 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4302 if (dr->dr_type == BWN_DMA_64BIT) {
4303 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4304 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4306 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4311 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4313 struct bwn_dmadesc_generic *desc;
4314 struct bwn_dmadesc_meta *meta;
4315 struct bwn_mac *mac = dr->dr_mac;
4316 struct bwn_dma *dma = &mac->mac_method.dma;
4317 struct bwn_softc *sc = mac->mac_sc;
4320 if (!dr->dr_usedslot)
4322 for (i = 0; i < dr->dr_numslots; i++) {
4323 dr->getdesc(dr, i, &desc, &meta);
4325 if (meta->mt_m == NULL) {
4327 device_printf(sc->sc_dev, "%s: not TX?\n",
4332 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
4333 bus_dmamap_unload(dr->dr_txring_dtag,
4335 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
4336 bus_dmamap_unload(dma->txbuf_dtag,
4339 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4340 bwn_dma_free_descbuf(dr, meta);
4345 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4348 struct bwn_softc *sc = mac->mac_sc;
4353 for (i = 0; i < 10; i++) {
4354 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4356 value = BWN_READ_4(mac, base + offset);
4357 if (type == BWN_DMA_64BIT) {
4358 value &= BWN_DMA64_TXSTAT;
4359 if (value == BWN_DMA64_TXSTAT_DISABLED ||
4360 value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4361 value == BWN_DMA64_TXSTAT_STOPPED)
4364 value &= BWN_DMA32_TXSTATE;
4365 if (value == BWN_DMA32_TXSTAT_DISABLED ||
4366 value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4367 value == BWN_DMA32_TXSTAT_STOPPED)
4372 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4373 BWN_WRITE_4(mac, base + offset, 0);
4374 for (i = 0; i < 10; i++) {
4375 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4377 value = BWN_READ_4(mac, base + offset);
4378 if (type == BWN_DMA_64BIT) {
4379 value &= BWN_DMA64_TXSTAT;
4380 if (value == BWN_DMA64_TXSTAT_DISABLED) {
4385 value &= BWN_DMA32_TXSTATE;
4386 if (value == BWN_DMA32_TXSTAT_DISABLED) {
4394 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4403 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4406 struct bwn_softc *sc = mac->mac_sc;
4411 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4412 BWN_WRITE_4(mac, base + offset, 0);
4413 for (i = 0; i < 10; i++) {
4414 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4416 value = BWN_READ_4(mac, base + offset);
4417 if (type == BWN_DMA_64BIT) {
4418 value &= BWN_DMA64_RXSTAT;
4419 if (value == BWN_DMA64_RXSTAT_DISABLED) {
4424 value &= BWN_DMA32_RXSTATE;
4425 if (value == BWN_DMA32_RXSTAT_DISABLED) {
4433 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4441 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4442 struct bwn_dmadesc_meta *meta)
4445 if (meta->mt_m != NULL) {
4446 m_freem(meta->mt_m);
4449 if (meta->mt_ni != NULL) {
4450 ieee80211_free_node(meta->mt_ni);
4456 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4458 struct bwn_rxhdr4 *rxhdr;
4459 unsigned char *frame;
4461 rxhdr = mtod(m, struct bwn_rxhdr4 *);
4462 rxhdr->frame_len = 0;
4464 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4465 sizeof(struct bwn_plcp6) + 2,
4466 ("%s:%d: fail", __func__, __LINE__));
4467 frame = mtod(m, char *) + dr->dr_frameoffset;
4468 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4472 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4474 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4476 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4481 bwn_wme_init(struct bwn_mac *mac)
4486 /* enable WME support. */
4487 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4488 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4489 BWN_IFSCTL_USE_EDCF);
4493 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4495 struct bwn_softc *sc = mac->mac_sc;
4496 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
4497 uint16_t delay; /* microsec */
4499 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4500 if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4502 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4503 delay = max(delay, (uint16_t)2400);
4505 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4509 bwn_bt_enable(struct bwn_mac *mac)
4511 struct bwn_softc *sc = mac->mac_sc;
4514 if (bwn_bluetooth == 0)
4516 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4518 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4521 hf = bwn_hf_read(mac);
4522 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4523 hf |= BWN_HF_BT_COEXISTALT;
4525 hf |= BWN_HF_BT_COEXIST;
4526 bwn_hf_write(mac, hf);
4530 bwn_set_macaddr(struct bwn_mac *mac)
4533 bwn_mac_write_bssid(mac);
4534 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
4538 bwn_clear_keys(struct bwn_mac *mac)
4542 for (i = 0; i < mac->mac_max_nr_keys; i++) {
4543 KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4544 ("%s:%d: fail", __func__, __LINE__));
4546 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4547 NULL, BWN_SEC_KEYSIZE, NULL);
4548 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4549 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4550 NULL, BWN_SEC_KEYSIZE, NULL);
4552 mac->mac_key[i].keyconf = NULL;
4557 bwn_crypt_init(struct bwn_mac *mac)
4559 struct bwn_softc *sc = mac->mac_sc;
4561 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4562 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4563 ("%s:%d: fail", __func__, __LINE__));
4564 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4566 if (siba_get_revid(sc->sc_dev) >= 5)
4567 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4568 bwn_clear_keys(mac);
4572 bwn_chip_exit(struct bwn_mac *mac)
4574 struct bwn_softc *sc = mac->mac_sc;
4577 siba_gpio_set(sc->sc_dev, 0);
4581 bwn_fw_fillinfo(struct bwn_mac *mac)
4585 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4588 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4595 bwn_gpio_init(struct bwn_mac *mac)
4597 struct bwn_softc *sc = mac->mac_sc;
4598 uint32_t mask = 0x1f, set = 0xf, value;
4600 BWN_WRITE_4(mac, BWN_MACCTL,
4601 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4602 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4603 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4605 if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4609 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4610 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4611 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4615 if (siba_get_revid(sc->sc_dev) >= 2)
4618 value = siba_gpio_get(sc->sc_dev);
4621 siba_gpio_set(sc->sc_dev, (value & mask) | set);
4627 bwn_fw_loadinitvals(struct bwn_mac *mac)
4629 #define GETFWOFFSET(fwp, offset) \
4630 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4631 const size_t hdr_len = sizeof(struct bwn_fwhdr);
4632 const struct bwn_fwhdr *hdr;
4633 struct bwn_fw *fw = &mac->mac_fw;
4636 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4637 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4638 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4641 if (fw->initvals_band.fw) {
4642 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4643 error = bwn_fwinitvals_write(mac,
4644 GETFWOFFSET(fw->initvals_band, hdr_len),
4646 fw->initvals_band.fw->datasize - hdr_len);
4653 bwn_phy_init(struct bwn_mac *mac)
4655 struct bwn_softc *sc = mac->mac_sc;
4658 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4659 mac->mac_phy.rf_onoff(mac, 1);
4660 error = mac->mac_phy.init(mac);
4662 device_printf(sc->sc_dev, "PHY init failed\n");
4665 error = bwn_switch_channel(mac,
4666 mac->mac_phy.get_default_chan(mac));
4668 device_printf(sc->sc_dev,
4669 "failed to switch default channel\n");
4674 if (mac->mac_phy.exit)
4675 mac->mac_phy.exit(mac);
4677 mac->mac_phy.rf_onoff(mac, 0);
4683 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4688 ant = bwn_ant2phy(antenna);
4691 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4692 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4693 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4694 /* For Probe Resposes */
4695 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4696 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4697 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4701 bwn_set_opmode(struct bwn_mac *mac)
4703 struct bwn_softc *sc = mac->mac_sc;
4704 struct ifnet *ifp = sc->sc_ifp;
4705 struct ieee80211com *ic = ifp->if_l2com;
4707 uint16_t cfp_pretbtt;
4709 ctl = BWN_READ_4(mac, BWN_MACCTL);
4710 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4711 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4712 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4713 ctl |= BWN_MACCTL_STA;
4715 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4716 ic->ic_opmode == IEEE80211_M_MBSS)
4717 ctl |= BWN_MACCTL_HOSTAP;
4718 else if (ic->ic_opmode == IEEE80211_M_IBSS)
4719 ctl &= ~BWN_MACCTL_STA;
4720 ctl |= sc->sc_filters;
4722 if (siba_get_revid(sc->sc_dev) <= 4)
4723 ctl |= BWN_MACCTL_PROMISC;
4725 BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4728 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4729 if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4730 siba_get_chiprev(sc->sc_dev) == 3)
4735 BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4739 bwn_dma_gettype(struct bwn_mac *mac)
4744 tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4745 if (tmp & SIBA_TGSHIGH_DMA64)
4746 return (BWN_DMA_64BIT);
4747 base = bwn_dma_base(0, 0);
4748 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4749 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4750 if (tmp & BWN_DMA32_TXADDREXT_MASK)
4751 return (BWN_DMA_32BIT);
4753 return (BWN_DMA_30BIT);
4757 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4760 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4761 *((bus_addr_t *)arg) = seg->ds_addr;
4766 bwn_phy_g_init_sub(struct bwn_mac *mac)
4768 struct bwn_phy *phy = &mac->mac_phy;
4769 struct bwn_phy_g *pg = &phy->phy_g;
4770 struct bwn_softc *sc = mac->mac_sc;
4774 bwn_phy_init_b5(mac);
4776 bwn_phy_init_b6(mac);
4778 if (phy->rev >= 2 || phy->gmode)
4779 bwn_phy_init_a(mac);
4781 if (phy->rev >= 2) {
4782 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4783 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4785 if (phy->rev == 2) {
4786 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4787 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4790 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4791 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4793 if (phy->gmode || phy->rev >= 2) {
4794 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4795 tmp &= BWN_PHYVER_VERSION;
4796 if (tmp == 3 || tmp == 5) {
4797 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4798 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4801 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4805 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4806 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4807 if (phy->rf_rev == 8) {
4808 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4809 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4811 if (BWN_HAS_LOOPBACK(phy))
4812 bwn_loopback_calcgain(mac);
4814 if (phy->rf_rev != 8) {
4815 if (pg->pg_initval == 0xffff)
4816 pg->pg_initval = bwn_rf_init_bcm2050(mac);
4818 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4821 if (BWN_HAS_TXMAG(phy)) {
4822 BWN_RF_WRITE(mac, 0x52,
4823 (BWN_RF_READ(mac, 0x52) & 0xff00)
4824 | pg->pg_loctl.tx_bias |
4825 pg->pg_loctl.tx_magn);
4827 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4829 if (phy->rev >= 6) {
4830 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4831 (pg->pg_loctl.tx_bias << 12));
4833 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4834 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4836 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4838 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4840 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4841 if (phy->gmode || phy->rev >= 2) {
4842 bwn_lo_g_adjust(mac);
4843 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4846 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4847 for (i = 0; i < 64; i++) {
4848 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4849 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4850 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4853 bwn_nrssi_threshold(mac);
4854 } else if (phy->gmode || phy->rev >= 2) {
4855 if (pg->pg_nrssi[0] == -1000) {
4856 KASSERT(pg->pg_nrssi[1] == -1000,
4857 ("%s:%d: fail", __func__, __LINE__));
4858 bwn_nrssi_slope_11g(mac);
4860 bwn_nrssi_threshold(mac);
4862 if (phy->rf_rev == 8)
4863 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4864 bwn_phy_hwpctl_init(mac);
4865 if ((siba_get_chipid(sc->sc_dev) == 0x4306
4866 && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4867 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4868 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4873 bwn_has_hwpctl(struct bwn_mac *mac)
4876 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4878 return (mac->mac_phy.use_hwpctl(mac));
4882 bwn_phy_init_b5(struct bwn_mac *mac)
4884 struct bwn_phy *phy = &mac->mac_phy;
4885 struct bwn_phy_g *pg = &phy->phy_g;
4886 struct bwn_softc *sc = mac->mac_sc;
4887 uint16_t offset, value;
4888 uint8_t old_channel;
4890 if (phy->analog == 1)
4891 BWN_RF_SET(mac, 0x007a, 0x0050);
4892 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4893 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4895 for (offset = 0x00a8; offset < 0x00c7; offset++) {
4896 BWN_PHY_WRITE(mac, offset, value);
4900 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4901 if (phy->rf_ver == 0x2050)
4902 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4904 if (phy->gmode || phy->rev >= 2) {
4905 if (phy->rf_ver == 0x2050) {
4906 BWN_RF_SET(mac, 0x007a, 0x0020);
4907 BWN_RF_SET(mac, 0x0051, 0x0004);
4909 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4911 BWN_PHY_SET(mac, 0x0802, 0x0100);
4912 BWN_PHY_SET(mac, 0x042b, 0x2000);
4914 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4916 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4917 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4918 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4921 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4922 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4924 if (phy->analog == 1) {
4925 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4926 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4927 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4928 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4929 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4931 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4932 BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4933 BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4935 if (phy->analog == 1)
4936 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4938 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4940 if (phy->analog == 0)
4941 BWN_WRITE_2(mac, 0x03e4, 0x3000);
4943 old_channel = phy->chan;
4944 bwn_phy_g_switch_chan(mac, 7, 0);
4946 if (phy->rf_ver != 0x2050) {
4947 BWN_RF_WRITE(mac, 0x0075, 0x0080);
4948 BWN_RF_WRITE(mac, 0x0079, 0x0081);
4951 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4952 BWN_RF_WRITE(mac, 0x0050, 0x0023);
4954 if (phy->rf_ver == 0x2050) {
4955 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4956 BWN_RF_WRITE(mac, 0x005a, 0x0070);
4959 BWN_RF_WRITE(mac, 0x005b, 0x007b);
4960 BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4961 BWN_RF_SET(mac, 0x007a, 0x0007);
4963 bwn_phy_g_switch_chan(mac, old_channel, 0);
4964 BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4965 BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4966 BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4968 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4971 if (phy->rf_ver == 0x2050)
4972 BWN_RF_WRITE(mac, 0x005d, 0x000d);
4974 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4978 bwn_loopback_calcgain(struct bwn_mac *mac)
4980 struct bwn_phy *phy = &mac->mac_phy;
4981 struct bwn_phy_g *pg = &phy->phy_g;
4982 struct bwn_softc *sc = mac->mac_sc;
4983 uint16_t backup_phy[16] = { 0 };
4984 uint16_t backup_radio[3];
4985 uint16_t backup_bband;
4986 uint16_t i, j, loop_i_max;
4988 uint16_t loop1_outer_done, loop1_inner_done;
4990 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4991 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4992 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4993 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4994 if (phy->rev != 1) {
4995 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4996 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4998 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4999 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5000 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5001 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
5002 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
5003 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5004 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5005 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
5006 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5007 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5008 backup_bband = pg->pg_bbatt.att;
5009 backup_radio[0] = BWN_RF_READ(mac, 0x52);
5010 backup_radio[1] = BWN_RF_READ(mac, 0x43);
5011 backup_radio[2] = BWN_RF_READ(mac, 0x7a);
5013 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
5014 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
5015 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
5016 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
5017 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
5018 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
5019 if (phy->rev != 1) {
5020 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
5021 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
5022 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
5023 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
5025 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
5026 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
5027 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
5028 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
5030 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
5031 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5032 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5034 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
5035 if (phy->rev != 1) {
5036 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
5037 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
5039 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
5041 if (phy->rf_rev == 8)
5042 BWN_RF_WRITE(mac, 0x43, 0x000f);
5044 BWN_RF_WRITE(mac, 0x52, 0);
5045 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
5047 bwn_phy_g_set_bbatt(mac, 11);
5050 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5052 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5053 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5055 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
5056 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
5058 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
5059 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
5061 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
5062 if (phy->rev >= 7) {
5063 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
5064 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
5067 BWN_RF_MASK(mac, 0x7a, 0x00f7);
5070 loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
5071 for (i = 0; i < loop_i_max; i++) {
5072 for (j = 0; j < 16; j++) {
5073 BWN_RF_WRITE(mac, 0x43, i);
5074 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
5076 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5077 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5079 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5084 loop1_outer_done = i;
5085 loop1_inner_done = j;
5087 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
5089 for (j = j - 8; j < 16; j++) {
5090 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
5091 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5092 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5095 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5102 if (phy->rev != 1) {
5103 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
5104 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
5106 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
5107 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
5108 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
5109 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
5110 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
5111 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
5112 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
5113 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
5114 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
5116 bwn_phy_g_set_bbatt(mac, backup_bband);
5118 BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
5119 BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
5120 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
5122 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
5124 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
5125 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
5126 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
5127 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
5129 pg->pg_max_lb_gain =
5130 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
5131 pg->pg_trsw_rx_gain = trsw_rx * 2;
5135 bwn_rf_init_bcm2050(struct bwn_mac *mac)
5137 struct bwn_phy *phy = &mac->mac_phy;
5138 uint32_t tmp1 = 0, tmp2 = 0;
5139 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
5140 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
5141 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
5142 static const uint8_t rcc_table[] = {
5143 0x02, 0x03, 0x01, 0x0f,
5144 0x06, 0x07, 0x05, 0x0f,
5145 0x0a, 0x0b, 0x09, 0x0f,
5146 0x0e, 0x0f, 0x0d, 0x0f,
5149 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
5150 rfoverval = rfover = cck3 = 0;
5151 radio0 = BWN_RF_READ(mac, 0x43);
5152 radio1 = BWN_RF_READ(mac, 0x51);
5153 radio2 = BWN_RF_READ(mac, 0x52);
5154 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5155 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5156 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5157 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5159 if (phy->type == BWN_PHYTYPE_B) {
5160 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5161 reg0 = BWN_READ_2(mac, 0x3ec);
5163 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5164 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5165 } else if (phy->gmode || phy->rev >= 2) {
5166 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5167 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5168 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5169 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5170 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5171 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5173 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5174 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5175 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5176 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5177 if (BWN_HAS_LOOPBACK(phy)) {
5178 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5179 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5181 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5183 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5184 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5187 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5188 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5190 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5191 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5193 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5195 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5196 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5197 reg1 = BWN_READ_2(mac, 0x3e6);
5198 reg2 = BWN_READ_2(mac, 0x3f4);
5200 if (phy->analog == 0)
5201 BWN_WRITE_2(mac, 0x03e6, 0x0122);
5203 if (phy->analog >= 2)
5204 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5205 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5206 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5209 reg = BWN_RF_READ(mac, 0x60);
5210 index = (reg & 0x001e) >> 1;
5211 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5213 if (phy->type == BWN_PHYTYPE_B)
5214 BWN_RF_WRITE(mac, 0x78, 0x26);
5215 if (phy->gmode || phy->rev >= 2) {
5216 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5217 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5220 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5221 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5222 if (phy->gmode || phy->rev >= 2) {
5223 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5224 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5227 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5228 BWN_RF_SET(mac, 0x51, 0x0004);
5229 if (phy->rf_rev == 8)
5230 BWN_RF_WRITE(mac, 0x43, 0x1f);
5232 BWN_RF_WRITE(mac, 0x52, 0);
5233 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5235 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5237 for (i = 0; i < 16; i++) {
5238 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5239 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5240 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5241 if (phy->gmode || phy->rev >= 2) {
5242 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5243 bwn_rf_2050_rfoverval(mac,
5244 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5246 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5248 if (phy->gmode || phy->rev >= 2) {
5249 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5250 bwn_rf_2050_rfoverval(mac,
5251 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5253 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5255 if (phy->gmode || phy->rev >= 2) {
5256 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5257 bwn_rf_2050_rfoverval(mac,
5258 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5260 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5262 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5263 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5264 if (phy->gmode || phy->rev >= 2) {
5265 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5266 bwn_rf_2050_rfoverval(mac,
5267 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5269 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5273 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5277 for (i = 0; i < 16; i++) {
5278 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5279 BWN_RF_WRITE(mac, 0x78, radio78);
5281 for (j = 0; j < 16; j++) {
5282 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5283 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5284 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5285 if (phy->gmode || phy->rev >= 2) {
5286 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5287 bwn_rf_2050_rfoverval(mac,
5288 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5290 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5292 if (phy->gmode || phy->rev >= 2) {
5293 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5294 bwn_rf_2050_rfoverval(mac,
5295 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5297 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5299 if (phy->gmode || phy->rev >= 2) {
5300 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5301 bwn_rf_2050_rfoverval(mac,
5302 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5304 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5306 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5307 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5308 if (phy->gmode || phy->rev >= 2) {
5309 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5310 bwn_rf_2050_rfoverval(mac,
5311 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5313 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5321 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5322 BWN_RF_WRITE(mac, 0x51, radio1);
5323 BWN_RF_WRITE(mac, 0x52, radio2);
5324 BWN_RF_WRITE(mac, 0x43, radio0);
5325 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5326 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5327 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5328 BWN_WRITE_2(mac, 0x3e6, reg1);
5329 if (phy->analog != 0)
5330 BWN_WRITE_2(mac, 0x3f4, reg2);
5331 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5332 bwn_spu_workaround(mac, phy->chan);
5333 if (phy->type == BWN_PHYTYPE_B) {
5334 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5335 BWN_WRITE_2(mac, 0x3ec, reg0);
5336 } else if (phy->gmode) {
5337 BWN_WRITE_2(mac, BWN_PHY_RADIO,
5338 BWN_READ_2(mac, BWN_PHY_RADIO)
5340 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5341 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5342 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5343 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5345 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5346 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5347 if (BWN_HAS_LOOPBACK(phy)) {
5348 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5349 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5353 return ((i > 15) ? radio78 : rcc);
5357 bwn_phy_init_b6(struct bwn_mac *mac)
5359 struct bwn_phy *phy = &mac->mac_phy;
5360 struct bwn_phy_g *pg = &phy->phy_g;
5361 struct bwn_softc *sc = mac->mac_sc;
5362 uint16_t offset, val;
5363 uint8_t old_channel;
5365 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5366 ("%s:%d: fail", __func__, __LINE__));
5368 BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5369 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5370 if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5371 BWN_RF_WRITE(mac, 0x51, 0x37);
5372 BWN_RF_WRITE(mac, 0x52, 0x70);
5373 BWN_RF_WRITE(mac, 0x53, 0xb3);
5374 BWN_RF_WRITE(mac, 0x54, 0x9b);
5375 BWN_RF_WRITE(mac, 0x5a, 0x88);
5376 BWN_RF_WRITE(mac, 0x5b, 0x88);
5377 BWN_RF_WRITE(mac, 0x5d, 0x88);
5378 BWN_RF_WRITE(mac, 0x5e, 0x88);
5379 BWN_RF_WRITE(mac, 0x7d, 0x88);
5381 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5383 if (phy->rf_rev == 8) {
5384 BWN_RF_WRITE(mac, 0x51, 0);
5385 BWN_RF_WRITE(mac, 0x52, 0x40);
5386 BWN_RF_WRITE(mac, 0x53, 0xb7);
5387 BWN_RF_WRITE(mac, 0x54, 0x98);
5388 BWN_RF_WRITE(mac, 0x5a, 0x88);
5389 BWN_RF_WRITE(mac, 0x5b, 0x6b);
5390 BWN_RF_WRITE(mac, 0x5c, 0x0f);
5391 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5392 BWN_RF_WRITE(mac, 0x5d, 0xfa);
5393 BWN_RF_WRITE(mac, 0x5e, 0xd8);
5395 BWN_RF_WRITE(mac, 0x5d, 0xf5);
5396 BWN_RF_WRITE(mac, 0x5e, 0xb8);
5398 BWN_RF_WRITE(mac, 0x0073, 0x0003);
5399 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5400 BWN_RF_WRITE(mac, 0x007c, 0x0001);
5401 BWN_RF_WRITE(mac, 0x007e, 0x0008);
5403 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5404 BWN_PHY_WRITE(mac, offset, val);
5407 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5408 BWN_PHY_WRITE(mac, offset, val);
5411 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5412 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5415 if (phy->type == BWN_PHYTYPE_G) {
5416 BWN_RF_SET(mac, 0x007a, 0x0020);
5417 BWN_RF_SET(mac, 0x0051, 0x0004);
5418 BWN_PHY_SET(mac, 0x0802, 0x0100);
5419 BWN_PHY_SET(mac, 0x042b, 0x2000);
5420 BWN_PHY_WRITE(mac, 0x5b, 0);
5421 BWN_PHY_WRITE(mac, 0x5c, 0);
5424 old_channel = phy->chan;
5425 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5427 BWN_RF_WRITE(mac, 0x0050, 0x0020);
5428 BWN_RF_WRITE(mac, 0x0050, 0x0023);
5430 if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5431 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5432 BWN_RF_WRITE(mac, 0x50, 0x20);
5434 if (phy->rf_rev <= 2) {
5435 BWN_RF_WRITE(mac, 0x7c, 0x20);
5436 BWN_RF_WRITE(mac, 0x5a, 0x70);
5437 BWN_RF_WRITE(mac, 0x5b, 0x7b);
5438 BWN_RF_WRITE(mac, 0x5c, 0xb0);
5440 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5442 bwn_phy_g_switch_chan(mac, old_channel, 0);
5444 BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5445 if (phy->rf_rev >= 6)
5446 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5448 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5449 BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5450 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5452 if (phy->rf_rev <= 5)
5453 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5454 if (phy->rf_rev <= 2)
5455 BWN_RF_WRITE(mac, 0x005d, 0x000d);
5457 if (phy->analog == 4) {
5458 BWN_WRITE_2(mac, 0x3e4, 9);
5459 BWN_PHY_MASK(mac, 0x61, 0x0fff);
5461 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5462 if (phy->type == BWN_PHYTYPE_B)
5463 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5464 else if (phy->type == BWN_PHYTYPE_G)
5465 BWN_WRITE_2(mac, 0x03e6, 0x0);
5469 bwn_phy_init_a(struct bwn_mac *mac)
5471 struct bwn_phy *phy = &mac->mac_phy;
5472 struct bwn_softc *sc = mac->mac_sc;
5474 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5475 ("%s:%d: fail", __func__, __LINE__));
5477 if (phy->rev >= 6) {
5478 if (phy->type == BWN_PHYTYPE_A)
5479 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5480 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5481 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5483 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5488 if (phy->type == BWN_PHYTYPE_G &&
5489 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5490 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5494 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5498 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5499 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5503 bwn_wa_agc(struct bwn_mac *mac)
5505 struct bwn_phy *phy = &mac->mac_phy;
5507 if (phy->rev == 1) {
5508 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5509 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5510 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5511 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5512 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5513 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5514 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5515 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5516 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5518 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5519 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5520 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5521 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5524 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5526 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5527 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5528 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5529 BWN_RF_SET(mac, 0x7a, 0x0008);
5530 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5531 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5532 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5533 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5535 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5536 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5537 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5538 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5539 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5540 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5541 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5542 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5543 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5544 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5545 if (phy->rev == 1) {
5546 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5547 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5549 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5550 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5551 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5552 if (phy->rev >= 6) {
5553 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5554 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5555 (uint16_t)~0xf000, 0x3000);
5558 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5559 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5560 if (phy->rev == 1) {
5561 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5562 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5563 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5564 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5565 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5566 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5567 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5568 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5570 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5571 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5572 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5573 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5575 if (phy->rev >= 6) {
5576 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5577 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5579 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5583 bwn_wa_grev1(struct bwn_mac *mac)
5585 struct bwn_phy *phy = &mac->mac_phy;
5587 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5588 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5589 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5591 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5593 /* init CRSTHRES and ANTDWELL */
5594 if (phy->rev == 1) {
5595 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5596 } else if (phy->rev == 2) {
5597 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5598 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5599 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5601 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5602 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5603 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5604 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5606 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5607 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5608 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5610 /* XXX support PHY-A??? */
5611 for (i = 0; i < N(bwn_tab_finefreqg); i++)
5612 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5613 bwn_tab_finefreqg[i]);
5615 /* XXX support PHY-A??? */
5617 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5618 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5619 bwn_tab_noise_g1[i]);
5621 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5622 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5623 bwn_tab_noise_g2[i]);
5626 for (i = 0; i < N(bwn_tab_rotor); i++)
5627 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5630 /* XXX support PHY-A??? */
5631 if (phy->rev >= 6) {
5632 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5634 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5636 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5638 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5640 for (i = 0; i < N(bwn_tab_retard); i++)
5641 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5644 if (phy->rev == 1) {
5645 for (i = 0; i < 16; i++)
5646 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5649 for (i = 0; i < 32; i++)
5650 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5657 bwn_wa_grev26789(struct bwn_mac *mac)
5659 struct bwn_phy *phy = &mac->mac_phy;
5661 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5664 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5666 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5668 /* init CRSTHRES and ANTDWELL */
5670 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5671 else if (phy->rev == 2) {
5672 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5673 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5674 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5676 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5677 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5678 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5679 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5682 for (i = 0; i < 64; i++)
5683 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5685 /* XXX support PHY-A??? */
5687 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5688 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5689 bwn_tab_noise_g1[i]);
5691 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5692 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5693 bwn_tab_noise_g2[i]);
5695 /* XXX support PHY-A??? */
5696 if (phy->rev >= 6) {
5697 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5699 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5701 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5703 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5705 for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5706 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5707 bwn_tab_sigmasqr2[i]);
5709 if (phy->rev == 1) {
5710 for (i = 0; i < 16; i++)
5711 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5714 for (i = 0; i < 32; i++)
5715 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5720 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5722 if (phy->type == BWN_PHYTYPE_A)
5723 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5725 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5727 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5728 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5729 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5732 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5733 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5737 bwn_wa_init(struct bwn_mac *mac)
5739 struct bwn_phy *phy = &mac->mac_phy;
5740 struct bwn_softc *sc = mac->mac_sc;
5742 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5753 bwn_wa_grev26789(mac);
5756 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5759 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5760 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5761 siba_get_pci_revid(sc->sc_dev) != 0x17) {
5763 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5765 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5768 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5769 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5770 if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5773 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5774 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5776 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5778 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5780 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5782 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5784 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5789 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5790 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5791 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5794 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5795 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5799 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5802 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5805 addr = table + offset;
5806 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5807 (addr - 1 != pg->pg_ofdmtab_addr)) {
5808 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5809 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5811 pg->pg_ofdmtab_addr = addr;
5812 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5816 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5819 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5822 addr = table + offset;
5823 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5824 (addr - 1 != pg->pg_ofdmtab_addr)) {
5825 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5826 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5828 pg->pg_ofdmtab_addr = addr;
5830 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5831 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5835 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5839 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5840 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5844 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5846 struct bwn_phy *phy = &mac->mac_phy;
5847 struct bwn_softc *sc = mac->mac_sc;
5848 unsigned int i, max_loop;
5850 uint32_t buffer[5] = {
5851 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5856 buffer[0] = 0x000201cc;
5859 buffer[0] = 0x000b846e;
5862 BWN_ASSERT_LOCKED(mac->mac_sc);
5864 for (i = 0; i < 5; i++)
5865 bwn_ram_write(mac, i * 4, buffer[i]);
5867 BWN_WRITE_2(mac, 0x0568, 0x0000);
5868 BWN_WRITE_2(mac, 0x07c0,
5869 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5870 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5871 BWN_WRITE_2(mac, 0x050c, value);
5872 if (phy->type == BWN_PHYTYPE_LP)
5873 BWN_WRITE_2(mac, 0x0514, 0x1a02);
5874 BWN_WRITE_2(mac, 0x0508, 0x0000);
5875 BWN_WRITE_2(mac, 0x050a, 0x0000);
5876 BWN_WRITE_2(mac, 0x054c, 0x0000);
5877 BWN_WRITE_2(mac, 0x056a, 0x0014);
5878 BWN_WRITE_2(mac, 0x0568, 0x0826);
5879 BWN_WRITE_2(mac, 0x0500, 0x0000);
5880 if (phy->type == BWN_PHYTYPE_LP)
5881 BWN_WRITE_2(mac, 0x0502, 0x0050);
5883 BWN_WRITE_2(mac, 0x0502, 0x0030);
5885 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5886 BWN_RF_WRITE(mac, 0x0051, 0x0017);
5887 for (i = 0x00; i < max_loop; i++) {
5888 value = BWN_READ_2(mac, 0x050e);
5893 for (i = 0x00; i < 0x0a; i++) {
5894 value = BWN_READ_2(mac, 0x050e);
5899 for (i = 0x00; i < 0x19; i++) {
5900 value = BWN_READ_2(mac, 0x0690);
5901 if (!(value & 0x0100))
5905 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5906 BWN_RF_WRITE(mac, 0x0051, 0x0037);
5910 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5914 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5916 macctl = BWN_READ_4(mac, BWN_MACCTL);
5917 if (macctl & BWN_MACCTL_BIGENDIAN)
5918 printf("TODO: need swap\n");
5920 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5921 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5922 BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5926 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5930 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5931 ("%s:%d: fail", __func__, __LINE__));
5933 value = (uint8_t) (ctl->q);
5934 value |= ((uint8_t) (ctl->i)) << 8;
5935 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5939 bwn_lo_calcfeed(struct bwn_mac *mac,
5940 uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5942 struct bwn_phy *phy = &mac->mac_phy;
5943 struct bwn_softc *sc = mac->mac_sc;
5945 uint16_t feedthrough;
5948 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5949 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5951 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5952 ("%s:%d: fail", __func__, __LINE__));
5953 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5954 ("%s:%d: fail", __func__, __LINE__));
5956 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5958 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5959 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5961 rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5963 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5964 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5966 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5967 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5969 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5970 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5972 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5974 pga |= BWN_PHY_PGACTL_UNKNOWN;
5975 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5977 pga |= BWN_PHY_PGACTL_LOWBANDW;
5978 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5980 pga |= BWN_PHY_PGACTL_LPF;
5981 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5984 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5986 return (feedthrough);
5990 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5991 uint16_t *value, uint16_t *pad_mix_gain)
5993 struct bwn_phy *phy = &mac->mac_phy;
5994 uint16_t reg, v, padmix;
5996 if (phy->type == BWN_PHYTYPE_B) {
5998 if (phy->rf_rev <= 5) {
6006 if (phy->rev >= 2 && phy->rf_rev == 8) {
6019 *pad_mix_gain = padmix;
6025 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
6027 struct bwn_phy *phy = &mac->mac_phy;
6028 struct bwn_phy_g *pg = &phy->phy_g;
6029 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6031 uint16_t trsw_rx, pga;
6032 uint16_t rf_pctl_reg;
6034 static const uint8_t tx_bias_values[] = {
6035 0x09, 0x08, 0x0a, 0x01, 0x00,
6036 0x02, 0x05, 0x04, 0x06,
6038 static const uint8_t tx_magn_values[] = {
6042 if (!BWN_HAS_LOOPBACK(phy)) {
6050 lb_gain = pg->pg_max_lb_gain / 2;
6053 pga = abs(10 - lb_gain) / 6;
6054 pga = MIN(MAX(pga, 0), 15);
6061 if ((phy->rev >= 2) &&
6062 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
6065 if ((10 - lb_gain) < cmp_val)
6066 tmp = (10 - lb_gain);
6074 rf_pctl_reg = cmp_val;
6079 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
6080 bwn_phy_g_set_bbatt(mac, 2);
6082 reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
6084 BWN_RF_MASK(mac, reg, mask);
6086 if (BWN_HAS_TXMAG(phy)) {
6089 int min_feedth = 0xffff;
6090 uint8_t tx_magn, tx_bias;
6092 for (i = 0; i < N(tx_magn_values); i++) {
6093 tx_magn = tx_magn_values[i];
6094 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
6095 for (j = 0; j < N(tx_bias_values); j++) {
6096 tx_bias = tx_bias_values[j];
6097 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
6098 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
6100 if (feedthrough < min_feedth) {
6101 lo->tx_bias = tx_bias;
6102 lo->tx_magn = tx_magn;
6103 min_feedth = feedthrough;
6105 if (lo->tx_bias == 0)
6108 BWN_RF_WRITE(mac, 0x52,
6109 (BWN_RF_READ(mac, 0x52)
6110 & 0xff00) | lo->tx_bias | lo->
6116 BWN_RF_MASK(mac, 0x52, 0xfff0);
6119 BWN_GETTIME(lo->txctl_measured_time);
6123 bwn_lo_get_powervector(struct bwn_mac *mac)
6125 struct bwn_phy *phy = &mac->mac_phy;
6126 struct bwn_phy_g *pg = &phy->phy_g;
6127 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6130 uint64_t power_vector = 0;
6132 for (i = 0; i < 8; i += 2) {
6133 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
6134 power_vector |= (tmp << (i * 8));
6135 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
6138 lo->power_vector = power_vector;
6140 BWN_GETTIME(lo->pwr_vec_read_time);
6144 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
6147 struct bwn_phy *phy = &mac->mac_phy;
6148 struct bwn_phy_g *pg = &phy->phy_g;
6151 if (max_rx_gain < 0)
6154 if (BWN_HAS_LOOPBACK(phy)) {
6159 trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6160 if (max_rx_gain >= trsw_rx_gain) {
6161 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6165 trsw_rx_gain = max_rx_gain;
6166 if (trsw_rx_gain < 9) {
6167 pg->pg_lna_lod_gain = 0;
6169 pg->pg_lna_lod_gain = 1;
6172 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6173 pg->pg_pga_gain = trsw_rx_gain / 3;
6174 if (pg->pg_pga_gain >= 5) {
6175 pg->pg_pga_gain -= 5;
6176 pg->pg_lna_gain = 2;
6178 pg->pg_lna_gain = 0;
6180 pg->pg_lna_gain = 0;
6181 pg->pg_trsw_rx_gain = 0x20;
6182 if (max_rx_gain >= 0x14) {
6183 pg->pg_lna_lod_gain = 1;
6184 pg->pg_pga_gain = 2;
6185 } else if (max_rx_gain >= 0x12) {
6186 pg->pg_lna_lod_gain = 1;
6187 pg->pg_pga_gain = 1;
6188 } else if (max_rx_gain >= 0xf) {
6189 pg->pg_lna_lod_gain = 1;
6190 pg->pg_pga_gain = 0;
6192 pg->pg_lna_lod_gain = 0;
6193 pg->pg_pga_gain = 0;
6197 tmp = BWN_RF_READ(mac, 0x7a);
6198 if (pg->pg_lna_lod_gain == 0)
6202 BWN_RF_WRITE(mac, 0x7a, tmp);
6206 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6208 struct bwn_phy *phy = &mac->mac_phy;
6209 struct bwn_phy_g *pg = &phy->phy_g;
6210 struct bwn_softc *sc = mac->mac_sc;
6211 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6215 if (bwn_has_hwpctl(mac)) {
6216 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6217 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6218 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6219 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6220 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6222 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6223 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6224 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6225 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6227 if (phy->type == BWN_PHYTYPE_B &&
6228 phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6229 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6230 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6232 if (phy->rev >= 2) {
6233 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6234 sav->phy_analogoverval =
6235 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6236 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6237 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6238 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6239 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6240 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6242 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6243 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6244 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6245 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6246 if (phy->type == BWN_PHYTYPE_G) {
6247 if ((phy->rev >= 7) &&
6248 (siba_sprom_get_bf_lo(sc->sc_dev) &
6250 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6252 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6255 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6257 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6259 sav->reg0 = BWN_READ_2(mac, 0x3f4);
6260 sav->reg1 = BWN_READ_2(mac, 0x3e2);
6261 sav->rf0 = BWN_RF_READ(mac, 0x43);
6262 sav->rf1 = BWN_RF_READ(mac, 0x7a);
6263 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6264 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6265 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6266 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6268 if (!BWN_HAS_TXMAG(phy)) {
6269 sav->rf2 = BWN_RF_READ(mac, 0x52);
6272 if (phy->type == BWN_PHYTYPE_B) {
6273 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6274 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6275 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6276 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6278 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6281 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6285 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6286 BWN_PHY_WRITE(mac, tmp, 0x007f);
6288 tmp = sav->phy_syncctl;
6289 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6291 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6293 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6294 if (phy->type == BWN_PHYTYPE_G ||
6295 (phy->type == BWN_PHYTYPE_B &&
6296 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6297 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6299 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6301 bwn_dummy_transmission(mac, 0, 1);
6302 bwn_phy_g_switch_chan(mac, 6, 0);
6303 BWN_RF_READ(mac, 0x51);
6304 if (phy->type == BWN_PHYTYPE_G)
6305 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6308 if (time_before(lo->txctl_measured_time,
6309 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6310 bwn_lo_measure_txctl_values(mac);
6312 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6313 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6315 if (phy->type == BWN_PHYTYPE_B)
6316 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6318 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6323 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6325 struct bwn_phy *phy = &mac->mac_phy;
6326 struct bwn_phy_g *pg = &phy->phy_g;
6329 if (phy->rev >= 2) {
6330 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6331 tmp = (pg->pg_pga_gain << 8);
6332 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6334 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6336 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6338 tmp = (pg->pg_pga_gain | 0xefa0);
6339 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6341 if (phy->type == BWN_PHYTYPE_G) {
6343 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6345 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6347 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6349 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6351 BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6352 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6353 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6354 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6355 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6356 BWN_RF_WRITE(mac, 0x43, sav->rf0);
6357 BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6358 if (!BWN_HAS_TXMAG(phy)) {
6360 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6362 BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6363 if (phy->type == BWN_PHYTYPE_B &&
6364 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6365 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6366 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6368 if (phy->rev >= 2) {
6369 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6370 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6371 sav->phy_analogoverval);
6372 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6373 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6374 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6375 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6376 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6378 if (bwn_has_hwpctl(mac)) {
6379 tmp = (sav->phy_lomask & 0xbfff);
6380 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6381 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6382 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6383 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6384 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6386 bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6390 bwn_lo_probe_loctl(struct bwn_mac *mac,
6391 struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6393 struct bwn_phy *phy = &mac->mac_phy;
6394 struct bwn_phy_g *pg = &phy->phy_g;
6395 struct bwn_loctl orig, test;
6396 struct bwn_loctl prev = { -100, -100 };
6397 static const struct bwn_loctl modifiers[] = {
6398 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,},
6399 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,}
6401 int begin, end, lower = 0, i;
6404 if (d->curstate == 0) {
6407 } else if (d->curstate % 2 == 0) {
6408 begin = d->curstate - 1;
6409 end = d->curstate + 1;
6411 begin = d->curstate - 2;
6412 end = d->curstate + 2;
6419 memcpy(&orig, probe, sizeof(struct bwn_loctl));
6423 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6424 memcpy(&test, &orig, sizeof(struct bwn_loctl));
6425 test.i += modifiers[i - 1].i * d->multipler;
6426 test.q += modifiers[i - 1].q * d->multipler;
6427 if ((test.i != prev.i || test.q != prev.q) &&
6428 (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6429 bwn_lo_write(mac, &test);
6430 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6431 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6432 if (feedth < d->feedth) {
6433 memcpy(probe, &test,
6434 sizeof(struct bwn_loctl));
6437 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6441 memcpy(&prev, &test, sizeof(prev));
6455 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6457 struct bwn_phy *phy = &mac->mac_phy;
6458 struct bwn_phy_g *pg = &phy->phy_g;
6459 struct bwn_lo_g_sm d;
6460 struct bwn_loctl probe;
6461 int lower, repeat, cnt = 0;
6466 if (BWN_HAS_LOOPBACK(phy))
6469 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6470 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6473 bwn_lo_write(mac, &d.loctl);
6474 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6475 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6476 if (feedth < 0x258) {
6477 if (feedth >= 0x12c)
6481 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6482 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6487 KASSERT(d.curstate >= 0 && d.curstate <= 8,
6488 ("%s:%d: fail", __func__, __LINE__));
6489 memcpy(&probe, &d.loctl,
6490 sizeof(struct bwn_loctl));
6491 lower = bwn_lo_probe_loctl(mac, &probe, &d);
6494 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6496 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6498 } while (d.nmeasure < 24);
6499 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6501 if (BWN_HAS_LOOPBACK(phy)) {
6502 if (d.feedth > 0x1194)
6504 else if (d.feedth < 0x5dc)
6507 if (d.feedth <= 0x5dc) {
6512 } else if (cnt == 2)
6515 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6516 } while (++cnt < repeat);
6519 static struct bwn_lo_calib *
6520 bwn_lo_calibset(struct bwn_mac *mac,
6521 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6523 struct bwn_phy *phy = &mac->mac_phy;
6524 struct bwn_phy_g *pg = &phy->phy_g;
6525 struct bwn_loctl loctl = { 0, 0 };
6526 struct bwn_lo_calib *cal;
6527 struct bwn_lo_g_value sval = { 0 };
6529 uint16_t pad, reg, value;
6531 sval.old_channel = phy->chan;
6532 bwn_mac_suspend(mac);
6533 bwn_lo_save(mac, &sval);
6535 reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6536 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6537 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6539 rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6542 if (BWN_HAS_LOOPBACK(phy))
6543 rxgain += pg->pg_max_lb_gain;
6544 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6545 bwn_phy_g_set_bbatt(mac, bbatt->att);
6546 bwn_lo_probe_sm(mac, &loctl, &rxgain);
6548 bwn_lo_restore(mac, &sval);
6549 bwn_mac_enable(mac);
6551 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
6553 device_printf(mac->mac_sc->sc_dev, "out of memory\n");
6556 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6557 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6558 memcpy(&cal->ctl, &loctl, sizeof(loctl));
6560 BWN_GETTIME(cal->calib_time);
6565 static struct bwn_lo_calib *
6566 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6567 const struct bwn_rfatt *rfatt)
6569 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6570 struct bwn_lo_calib *c;
6572 TAILQ_FOREACH(c, &lo->calib_list, list) {
6573 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6575 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6580 c = bwn_lo_calibset(mac, bbatt, rfatt);
6583 TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6589 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6591 struct bwn_phy *phy = &mac->mac_phy;
6592 struct bwn_phy_g *pg = &phy->phy_g;
6593 struct bwn_softc *sc = mac->mac_sc;
6594 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6595 const struct bwn_rfatt *rfatt;
6596 const struct bwn_bbatt *bbatt;
6599 int rf_offset, bb_offset;
6600 uint8_t changed = 0;
6602 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6603 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6604 ("%s:%d: fail", __func__, __LINE__));
6606 pvector = lo->power_vector;
6607 if (!update && !pvector)
6610 bwn_mac_suspend(mac);
6612 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6613 struct bwn_lo_calib *cal;
6617 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6619 bb_offset = i / lo->rfatt.len;
6620 rf_offset = i % lo->rfatt.len;
6621 bbatt = &(lo->bbatt.array[bb_offset]);
6622 rfatt = &(lo->rfatt.array[rf_offset]);
6624 cal = bwn_lo_calibset(mac, bbatt, rfatt);
6626 device_printf(sc->sc_dev, "LO: Could not "
6627 "calibrate DC table entry\n");
6630 val = (uint8_t)(cal->ctl.q);
6631 val |= ((uint8_t)(cal->ctl.i)) << 4;
6632 free(cal, M_DEVBUF);
6636 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6637 | ((val & 0x00ff) << 8);
6639 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6644 for (i = 0; i < BWN_DC_LT_SIZE; i++)
6645 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6647 bwn_mac_enable(mac);
6651 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6656 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6661 bwn_lo_g_adjust(struct bwn_mac *mac)
6663 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6664 struct bwn_lo_calib *cal;
6665 struct bwn_rfatt rf;
6667 memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6668 bwn_lo_fixup_rfatt(&rf);
6670 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6673 bwn_lo_write(mac, &cal->ctl);
6677 bwn_lo_g_init(struct bwn_mac *mac)
6680 if (!bwn_has_hwpctl(mac))
6683 bwn_lo_get_powervector(mac);
6684 bwn_phy_g_dc_lookup_init(mac, 1);
6688 bwn_mac_suspend(struct bwn_mac *mac)
6690 struct bwn_softc *sc = mac->mac_sc;
6694 KASSERT(mac->mac_suspended >= 0,
6695 ("%s:%d: fail", __func__, __LINE__));
6697 if (mac->mac_suspended == 0) {
6698 bwn_psctl(mac, BWN_PS_AWAKE);
6699 BWN_WRITE_4(mac, BWN_MACCTL,
6700 BWN_READ_4(mac, BWN_MACCTL)
6702 BWN_READ_4(mac, BWN_MACCTL);
6703 for (i = 35; i; i--) {
6704 tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6705 if (tmp & BWN_INTR_MAC_SUSPENDED)
6709 for (i = 40; i; i--) {
6710 tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6711 if (tmp & BWN_INTR_MAC_SUSPENDED)
6715 device_printf(sc->sc_dev, "MAC suspend failed\n");
6718 mac->mac_suspended++;
6722 bwn_mac_enable(struct bwn_mac *mac)
6724 struct bwn_softc *sc = mac->mac_sc;
6727 state = bwn_shm_read_2(mac, BWN_SHARED,
6728 BWN_SHARED_UCODESTAT);
6729 if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6730 state != BWN_SHARED_UCODESTAT_SLEEP)
6731 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6733 mac->mac_suspended--;
6734 KASSERT(mac->mac_suspended >= 0,
6735 ("%s:%d: fail", __func__, __LINE__));
6736 if (mac->mac_suspended == 0) {
6737 BWN_WRITE_4(mac, BWN_MACCTL,
6738 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6739 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6740 BWN_READ_4(mac, BWN_MACCTL);
6741 BWN_READ_4(mac, BWN_INTR_REASON);
6747 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6749 struct bwn_softc *sc = mac->mac_sc;
6753 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6754 ("%s:%d: fail", __func__, __LINE__));
6755 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6756 ("%s:%d: fail", __func__, __LINE__));
6758 /* XXX forcibly awake and hwps-off */
6760 BWN_WRITE_4(mac, BWN_MACCTL,
6761 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6763 BWN_READ_4(mac, BWN_MACCTL);
6764 if (siba_get_revid(sc->sc_dev) >= 5) {
6765 for (i = 0; i < 100; i++) {
6766 ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6767 BWN_SHARED_UCODESTAT);
6768 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6776 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6779 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6780 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6784 bwn_nrssi_threshold(struct bwn_mac *mac)
6786 struct bwn_phy *phy = &mac->mac_phy;
6787 struct bwn_phy_g *pg = &phy->phy_g;
6788 struct bwn_softc *sc = mac->mac_sc;
6793 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6795 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6796 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6804 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6805 a += (pg->pg_nrssi[0] << 6);
6806 a += (a < 32) ? 31 : 32;
6808 a = MIN(MAX(a, -31), 31);
6810 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6811 b += (pg->pg_nrssi[0] << 6);
6817 b = MIN(MAX(b, -31), 31);
6819 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6820 tmpu16 |= ((uint32_t)b & 0x0000003f);
6821 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6822 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6826 tmp16 = bwn_nrssi_read(mac, 0x20);
6829 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6833 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6835 #define SAVE_RF_MAX 3
6836 #define SAVE_PHY_COMM_MAX 4
6837 #define SAVE_PHY3_MAX 8
6838 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6839 { 0x7a, 0x52, 0x43 };
6840 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6841 { 0x15, 0x5a, 0x59, 0x58 };
6842 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6843 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6844 0x0801, 0x0060, 0x0014, 0x0478
6846 struct bwn_phy *phy = &mac->mac_phy;
6847 struct bwn_phy_g *pg = &phy->phy_g;
6848 int32_t i, tmp32, phy3_idx = 0;
6849 uint16_t delta, tmp;
6850 uint16_t save_rf[SAVE_RF_MAX];
6851 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6852 uint16_t save_phy3[SAVE_PHY3_MAX];
6853 uint16_t ant_div, phy0, chan_ex;
6854 int16_t nrssi0, nrssi1;
6856 KASSERT(phy->type == BWN_PHYTYPE_G,
6857 ("%s:%d: fail", __func__, __LINE__));
6859 if (phy->rf_rev >= 9)
6861 if (phy->rf_rev == 8)
6862 bwn_nrssi_offset(mac);
6864 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6865 BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6868 * Save RF/PHY registers for later restoration
6870 ant_div = BWN_READ_2(mac, 0x03e2);
6871 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6872 for (i = 0; i < SAVE_RF_MAX; ++i)
6873 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6874 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6875 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6877 phy0 = BWN_READ_2(mac, BWN_PHY0);
6878 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6879 if (phy->rev >= 3) {
6880 for (i = 0; i < SAVE_PHY3_MAX; ++i)
6881 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6882 BWN_PHY_WRITE(mac, 0x002e, 0);
6883 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6888 BWN_PHY_SET(mac, 0x0478, 0x0100);
6889 BWN_PHY_SET(mac, 0x0801, 0x0040);
6893 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6896 BWN_PHY_SET(mac, 0x0060, 0x0040);
6897 BWN_PHY_SET(mac, 0x0014, 0x0200);
6902 BWN_RF_SET(mac, 0x007a, 0x0070);
6903 bwn_set_all_gains(mac, 0, 8, 0);
6904 BWN_RF_MASK(mac, 0x007a, 0x00f7);
6905 if (phy->rev >= 2) {
6906 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6907 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6909 BWN_RF_SET(mac, 0x007a, 0x0080);
6912 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6913 if (nrssi0 >= 0x0020)
6919 BWN_RF_MASK(mac, 0x007a, 0x007f);
6921 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6923 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6924 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6925 BWN_RF_SET(mac, 0x007a, 0x000f);
6926 BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6927 if (phy->rev >= 2) {
6928 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6929 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6932 bwn_set_all_gains(mac, 3, 0, 1);
6933 if (phy->rf_rev == 8) {
6934 BWN_RF_WRITE(mac, 0x0043, 0x001f);
6936 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6937 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6938 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6939 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6941 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6942 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6943 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6945 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6948 * Install calculated narrow RSSI values
6950 if (nrssi1 >= 0x0020)
6952 if (nrssi0 == nrssi1)
6953 pg->pg_nrssi_slope = 0x00010000;
6955 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6957 pg->pg_nrssi[0] = nrssi1;
6958 pg->pg_nrssi[1] = nrssi0;
6962 * Restore saved RF/PHY registers
6964 if (phy->rev >= 3) {
6965 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6966 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6967 save_phy3[phy3_idx]);
6970 if (phy->rev >= 2) {
6971 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6972 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6975 for (i = 0; i < SAVE_RF_MAX; ++i)
6976 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6978 BWN_WRITE_2(mac, 0x03e2, ant_div);
6979 BWN_WRITE_2(mac, 0x03e6, phy0);
6980 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6982 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6983 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6985 bwn_spu_workaround(mac, phy->chan);
6986 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6987 bwn_set_original_gains(mac);
6988 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6989 if (phy->rev >= 3) {
6990 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6991 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6992 save_phy3[phy3_idx]);
6996 delta = 0x1f - pg->pg_nrssi[0];
6997 for (i = 0; i < 64; i++) {
6998 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6999 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
7000 pg->pg_nrssi_lt[i] = tmp32;
7003 bwn_nrssi_threshold(mac);
7005 #undef SAVE_PHY_COMM_MAX
7006 #undef SAVE_PHY3_MAX
7010 bwn_nrssi_offset(struct bwn_mac *mac)
7012 #define SAVE_RF_MAX 2
7013 #define SAVE_PHY_COMM_MAX 10
7014 #define SAVE_PHY6_MAX 8
7015 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
7017 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
7018 0x0001, 0x0811, 0x0812, 0x0814,
7019 0x0815, 0x005a, 0x0059, 0x0058,
7022 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
7023 0x002e, 0x002f, 0x080f, 0x0810,
7024 0x0801, 0x0060, 0x0014, 0x0478
7026 struct bwn_phy *phy = &mac->mac_phy;
7027 int i, phy6_idx = 0;
7028 uint16_t save_rf[SAVE_RF_MAX];
7029 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
7030 uint16_t save_phy6[SAVE_PHY6_MAX];
7032 uint16_t saved = 0xffff;
7034 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
7035 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
7036 for (i = 0; i < SAVE_RF_MAX; ++i)
7037 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
7039 BWN_PHY_MASK(mac, 0x0429, 0x7fff);
7040 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
7041 BWN_PHY_SET(mac, 0x0811, 0x000c);
7042 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
7043 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
7044 if (phy->rev >= 6) {
7045 for (i = 0; i < SAVE_PHY6_MAX; ++i)
7046 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
7048 BWN_PHY_WRITE(mac, 0x002e, 0);
7049 BWN_PHY_WRITE(mac, 0x002f, 0);
7050 BWN_PHY_WRITE(mac, 0x080f, 0);
7051 BWN_PHY_WRITE(mac, 0x0810, 0);
7052 BWN_PHY_SET(mac, 0x0478, 0x0100);
7053 BWN_PHY_SET(mac, 0x0801, 0x0040);
7054 BWN_PHY_SET(mac, 0x0060, 0x0040);
7055 BWN_PHY_SET(mac, 0x0014, 0x0200);
7057 BWN_RF_SET(mac, 0x007a, 0x0070);
7058 BWN_RF_SET(mac, 0x007a, 0x0080);
7061 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7065 for (i = 7; i >= 4; i--) {
7066 BWN_RF_WRITE(mac, 0x007b, i);
7068 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
7072 if (nrssi < 31 && saved == 0xffff)
7075 if (saved == 0xffff)
7078 BWN_RF_MASK(mac, 0x007a, 0x007f);
7079 if (phy->rev != 1) {
7080 BWN_PHY_SET(mac, 0x0814, 0x0001);
7081 BWN_PHY_MASK(mac, 0x0815, 0xfffe);
7083 BWN_PHY_SET(mac, 0x0811, 0x000c);
7084 BWN_PHY_SET(mac, 0x0812, 0x000c);
7085 BWN_PHY_SET(mac, 0x0811, 0x0030);
7086 BWN_PHY_SET(mac, 0x0812, 0x0030);
7087 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
7088 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
7089 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
7091 BWN_PHY_WRITE(mac, 0x0003, 0x0122);
7093 BWN_PHY_SET(mac, 0x000a, 0x2000);
7094 if (phy->rev != 1) {
7095 BWN_PHY_SET(mac, 0x0814, 0x0004);
7096 BWN_PHY_MASK(mac, 0x0815, 0xfffb);
7098 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
7099 BWN_RF_SET(mac, 0x007a, 0x000f);
7100 bwn_set_all_gains(mac, 3, 0, 1);
7101 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
7103 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7107 for (i = 0; i < 4; i++) {
7108 BWN_RF_WRITE(mac, 0x007b, i);
7110 nrssi = (int16_t)((BWN_PHY_READ(mac,
7111 0x047f) >> 8) & 0x003f);
7114 if (nrssi > -31 && saved == 0xffff)
7117 if (saved == 0xffff)
7122 BWN_RF_WRITE(mac, 0x007b, saved);
7125 * Restore saved RF/PHY registers
7127 if (phy->rev >= 6) {
7128 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
7129 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7130 save_phy6[phy6_idx]);
7133 if (phy->rev != 1) {
7134 for (i = 3; i < 5; i++)
7135 BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
7138 for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
7139 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
7141 for (i = SAVE_RF_MAX - 1; i >= 0; --i)
7142 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
7144 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
7145 BWN_PHY_SET(mac, 0x0429, 0x8000);
7146 bwn_set_original_gains(mac);
7147 if (phy->rev >= 6) {
7148 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
7149 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7150 save_phy6[phy6_idx]);
7154 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7155 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7156 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7160 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7163 struct bwn_phy *phy = &mac->mac_phy;
7165 uint16_t start = 0x08, end = 0x18;
7169 if (phy->rev <= 1) {
7174 table = BWN_OFDMTAB_GAINX;
7176 table = BWN_OFDMTAB_GAINX_R1;
7177 for (i = 0; i < 4; i++)
7178 bwn_ofdmtab_write_2(mac, table, i, first);
7180 for (i = start; i < end; i++)
7181 bwn_ofdmtab_write_2(mac, table, i, second);
7184 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7185 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7186 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7187 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7189 bwn_dummy_transmission(mac, 0, 1);
7193 bwn_set_original_gains(struct bwn_mac *mac)
7195 struct bwn_phy *phy = &mac->mac_phy;
7198 uint16_t start = 0x0008, end = 0x0018;
7200 if (phy->rev <= 1) {
7205 table = BWN_OFDMTAB_GAINX;
7207 table = BWN_OFDMTAB_GAINX_R1;
7208 for (i = 0; i < 4; i++) {
7210 tmp |= (i & 0x0001) << 1;
7211 tmp |= (i & 0x0002) >> 1;
7213 bwn_ofdmtab_write_2(mac, table, i, tmp);
7216 for (i = start; i < end; i++)
7217 bwn_ofdmtab_write_2(mac, table, i, i - start);
7219 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7220 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7221 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7222 bwn_dummy_transmission(mac, 0, 1);
7226 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7228 struct bwn_phy *phy = &mac->mac_phy;
7229 struct bwn_phy_g *pg = &phy->phy_g;
7230 struct bwn_rfatt old_rfatt, rfatt;
7231 struct bwn_bbatt old_bbatt, bbatt;
7232 struct bwn_softc *sc = mac->mac_sc;
7233 uint8_t old_txctl = 0;
7235 KASSERT(phy->type == BWN_PHYTYPE_G,
7236 ("%s:%d: fail", __func__, __LINE__));
7238 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7239 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7242 BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7244 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7248 bwn_hwpctl_early_init(mac);
7249 if (pg->pg_curtssi == 0) {
7250 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7251 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7253 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7254 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7255 old_txctl = pg->pg_txctl;
7258 if (phy->rf_rev == 8) {
7265 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7267 bwn_dummy_transmission(mac, 0, 1);
7268 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7269 if (phy->rf_ver == 0x2050 && phy->analog == 0)
7270 BWN_RF_MASK(mac, 0x0076, 0xff7b);
7272 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7273 &old_rfatt, old_txctl);
7275 bwn_hwpctl_init_gphy(mac);
7278 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7279 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7280 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7281 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7285 bwn_hwpctl_early_init(struct bwn_mac *mac)
7287 struct bwn_phy *phy = &mac->mac_phy;
7289 if (!bwn_has_hwpctl(mac)) {
7290 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7294 BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7295 BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7296 BWN_PHY_SET(mac, 0x047c, 0x0002);
7297 BWN_PHY_SET(mac, 0x047a, 0xf000);
7298 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7299 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7300 BWN_PHY_SET(mac, 0x005d, 0x8000);
7301 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7302 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7303 BWN_PHY_SET(mac, 0x0036, 0x0400);
7305 BWN_PHY_SET(mac, 0x0036, 0x0200);
7306 BWN_PHY_SET(mac, 0x0036, 0x0400);
7307 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7308 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7309 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7310 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7311 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7316 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7318 struct bwn_phy *phy = &mac->mac_phy;
7319 struct bwn_phy_g *pg = &phy->phy_g;
7320 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7322 uint16_t nr_written = 0, tmp, value;
7325 if (!bwn_has_hwpctl(mac)) {
7326 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7330 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7331 (pg->pg_idletssi - pg->pg_curtssi));
7332 BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7333 (pg->pg_idletssi - pg->pg_curtssi));
7335 for (i = 0; i < 32; i++)
7336 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7337 for (i = 32; i < 64; i++)
7338 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7339 for (i = 0; i < 64; i += 2) {
7340 value = (uint16_t) pg->pg_tssi2dbm[i];
7341 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7342 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7345 for (rf = 0; rf < lo->rfatt.len; rf++) {
7346 for (bb = 0; bb < lo->bbatt.len; bb++) {
7347 if (nr_written >= 0x40)
7349 tmp = lo->bbatt.array[bb].att;
7351 if (phy->rf_rev == 8)
7355 tmp |= lo->rfatt.array[rf].att;
7356 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7361 BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7362 BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7364 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7365 BWN_PHY_SET(mac, 0x0478, 0x0800);
7366 BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7367 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7369 bwn_phy_g_dc_lookup_init(mac, 1);
7370 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7374 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7376 struct bwn_softc *sc = mac->mac_sc;
7379 bwn_spu_workaround(mac, channel);
7381 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7383 if (channel == 14) {
7384 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7386 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7389 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7390 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7391 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7395 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7396 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7400 bwn_phy_g_chan2freq(uint8_t channel)
7402 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7404 KASSERT(channel >= 1 && channel <= 14,
7405 ("%s:%d: fail", __func__, __LINE__));
7407 return (bwn_phy_g_rf_channels[channel - 1]);
7411 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7412 const struct bwn_rfatt *rfatt, uint8_t txctl)
7414 struct bwn_phy *phy = &mac->mac_phy;
7415 struct bwn_phy_g *pg = &phy->phy_g;
7416 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7418 uint16_t tx_bias, tx_magn;
7422 tx_bias = lo->tx_bias;
7423 tx_magn = lo->tx_magn;
7424 if (tx_bias == 0xff)
7427 pg->pg_txctl = txctl;
7428 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7429 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7430 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7431 bwn_phy_g_set_bbatt(mac, bb);
7432 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7433 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7434 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7436 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7437 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7439 if (BWN_HAS_TXMAG(phy))
7440 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7442 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7443 bwn_lo_g_adjust(mac);
7447 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7450 struct bwn_phy *phy = &mac->mac_phy;
7452 if (phy->analog == 0) {
7453 BWN_WRITE_2(mac, BWN_PHY0,
7454 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7457 if (phy->analog > 1) {
7458 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7461 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7465 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7467 struct bwn_phy *phy = &mac->mac_phy;
7468 struct bwn_phy_g *pg = &phy->phy_g;
7469 struct bwn_softc *sc = mac->mac_sc;
7474 if (phy->gmode == 0)
7477 if (BWN_HAS_LOOPBACK(phy)) {
7478 max_lb_gain = pg->pg_max_lb_gain;
7479 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7480 if (max_lb_gain >= 0x46) {
7482 max_lb_gain -= 0x46;
7483 } else if (max_lb_gain >= 0x3a) {
7485 max_lb_gain -= 0x3a;
7486 } else if (max_lb_gain >= 0x2e) {
7488 max_lb_gain -= 0x2e;
7491 max_lb_gain -= 0x10;
7494 for (i = 0; i < 16; i++) {
7495 max_lb_gain -= (i * 6);
7496 if (max_lb_gain < 6)
7500 if ((phy->rev < 7) ||
7501 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7502 if (reg == BWN_PHY_RFOVER) {
7504 } else if (reg == BWN_PHY_RFOVERVAL) {
7507 case BWN_LPD(0, 1, 1):
7509 case BWN_LPD(0, 0, 1):
7510 case BWN_LPD(1, 0, 1):
7511 return (0x0092 | extlna);
7512 case BWN_LPD(1, 0, 0):
7513 return (0x0093 | extlna);
7516 ("%s:%d: fail", __func__, __LINE__));
7518 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7520 if (reg == BWN_PHY_RFOVER)
7522 if (reg == BWN_PHY_RFOVERVAL) {
7527 case BWN_LPD(0, 1, 1):
7529 case BWN_LPD(0, 0, 1):
7530 return (0x8092 | extlna);
7531 case BWN_LPD(1, 0, 1):
7532 return (0x2092 | extlna);
7533 case BWN_LPD(1, 0, 0):
7534 return (0x2093 | extlna);
7537 ("%s:%d: fail", __func__, __LINE__));
7539 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7544 if ((phy->rev < 7) ||
7545 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7546 if (reg == BWN_PHY_RFOVER) {
7548 } else if (reg == BWN_PHY_RFOVERVAL) {
7550 case BWN_LPD(0, 1, 1):
7552 case BWN_LPD(0, 0, 1):
7554 case BWN_LPD(1, 0, 1):
7556 case BWN_LPD(1, 0, 0):
7560 ("%s:%d: fail", __func__, __LINE__));
7562 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7564 if (reg == BWN_PHY_RFOVER) {
7566 } else if (reg == BWN_PHY_RFOVERVAL) {
7568 case BWN_LPD(0, 1, 1):
7570 case BWN_LPD(0, 0, 1):
7572 case BWN_LPD(1, 0, 1):
7574 case BWN_LPD(1, 0, 0):
7578 ("%s:%d: fail", __func__, __LINE__));
7580 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7586 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7589 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7591 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7592 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7594 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7598 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7600 struct bwn_softc *sc = mac->mac_sc;
7601 struct bwn_fw *fw = &mac->mac_fw;
7602 const uint8_t rev = siba_get_revid(sc->sc_dev);
7603 const char *filename;
7608 if (rev >= 5 && rev <= 10)
7609 filename = "ucode5";
7610 else if (rev >= 11 && rev <= 12)
7611 filename = "ucode11";
7613 filename = "ucode13";
7615 filename = "ucode14";
7617 filename = "ucode15";
7619 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7620 bwn_release_firmware(mac);
7621 return (EOPNOTSUPP);
7623 error = bwn_fw_get(mac, type, filename, &fw->ucode);
7625 bwn_release_firmware(mac);
7630 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7631 if (rev >= 5 && rev <= 10) {
7632 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7633 if (error == ENOENT)
7636 bwn_release_firmware(mac);
7639 } else if (rev < 11) {
7640 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7641 return (EOPNOTSUPP);
7645 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7646 switch (mac->mac_phy.type) {
7648 if (rev < 5 || rev > 10)
7650 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7651 filename = "a0g1initvals5";
7653 filename = "a0g0initvals5";
7656 if (rev >= 5 && rev <= 10)
7657 filename = "b0g0initvals5";
7659 filename = "b0g0initvals13";
7663 case BWN_PHYTYPE_LP:
7665 filename = "lp0initvals13";
7667 filename = "lp0initvals14";
7669 filename = "lp0initvals15";
7674 if (rev >= 11 && rev <= 12)
7675 filename = "n0initvals11";
7682 error = bwn_fw_get(mac, type, filename, &fw->initvals);
7684 bwn_release_firmware(mac);
7688 /* bandswitch initvals */
7689 switch (mac->mac_phy.type) {
7691 if (rev >= 5 && rev <= 10) {
7692 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7693 filename = "a0g1bsinitvals5";
7695 filename = "a0g0bsinitvals5";
7696 } else if (rev >= 11)
7702 if (rev >= 5 && rev <= 10)
7703 filename = "b0g0bsinitvals5";
7709 case BWN_PHYTYPE_LP:
7711 filename = "lp0bsinitvals13";
7713 filename = "lp0bsinitvals14";
7715 filename = "lp0bsinitvals15";
7720 if (rev >= 11 && rev <= 12)
7721 filename = "n0bsinitvals11";
7728 error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7730 bwn_release_firmware(mac);
7735 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7736 bwn_release_firmware(mac);
7737 return (EOPNOTSUPP);
7741 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7742 const char *name, struct bwn_fwfile *bfw)
7744 const struct bwn_fwhdr *hdr;
7745 struct bwn_softc *sc = mac->mac_sc;
7746 const struct firmware *fw;
7750 bwn_do_release_fw(bfw);
7753 if (bfw->filename != NULL) {
7754 if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7756 bwn_do_release_fw(bfw);
7759 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7760 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7761 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7762 /* XXX Sleeping on "fwload" with the non-sleepable locks held */
7763 fw = firmware_get(namebuf);
7765 device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7769 if (fw->datasize < sizeof(struct bwn_fwhdr))
7771 hdr = (const struct bwn_fwhdr *)(fw->data);
7772 switch (hdr->type) {
7773 case BWN_FWTYPE_UCODE:
7774 case BWN_FWTYPE_PCM:
7775 if (be32toh(hdr->size) !=
7776 (fw->datasize - sizeof(struct bwn_fwhdr)))
7786 bfw->filename = name;
7791 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7793 firmware_put(fw, FIRMWARE_UNLOAD);
7798 bwn_release_firmware(struct bwn_mac *mac)
7801 bwn_do_release_fw(&mac->mac_fw.ucode);
7802 bwn_do_release_fw(&mac->mac_fw.pcm);
7803 bwn_do_release_fw(&mac->mac_fw.initvals);
7804 bwn_do_release_fw(&mac->mac_fw.initvals_band);
7808 bwn_do_release_fw(struct bwn_fwfile *bfw)
7811 if (bfw->fw != NULL)
7812 firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7814 bfw->filename = NULL;
7818 bwn_fw_loaducode(struct bwn_mac *mac)
7820 #define GETFWOFFSET(fwp, offset) \
7821 ((const uint32_t *)((const char *)fwp.fw->data + offset))
7822 #define GETFWSIZE(fwp, offset) \
7823 ((fwp.fw->datasize - offset) / sizeof(uint32_t))
7824 struct bwn_softc *sc = mac->mac_sc;
7825 const uint32_t *data;
7828 uint16_t date, fwcaps, time;
7831 ctl = BWN_READ_4(mac, BWN_MACCTL);
7832 ctl |= BWN_MACCTL_MCODE_JMP0;
7833 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7835 BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7836 for (i = 0; i < 64; i++)
7837 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7838 for (i = 0; i < 4096; i += 2)
7839 bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7841 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7842 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7843 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7845 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7849 if (mac->mac_fw.pcm.fw) {
7850 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7851 bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7852 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7853 bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7854 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7855 sizeof(struct bwn_fwhdr)); i++) {
7856 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7861 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7862 BWN_WRITE_4(mac, BWN_MACCTL,
7863 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7864 BWN_MACCTL_MCODE_RUN);
7866 for (i = 0; i < 21; i++) {
7867 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7870 device_printf(sc->sc_dev, "ucode timeout\n");
7876 BWN_READ_4(mac, BWN_INTR_REASON);
7878 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7879 if (mac->mac_fw.rev <= 0x128) {
7880 device_printf(sc->sc_dev, "the firmware is too old\n");
7884 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7885 BWN_SHARED_UCODE_PATCH);
7886 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7887 mac->mac_fw.opensource = (date == 0xffff);
7889 mac->mac_flags |= BWN_MAC_FLAG_WME;
7890 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7892 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7893 if (mac->mac_fw.opensource == 0) {
7894 device_printf(sc->sc_dev,
7895 "firmware version (rev %u patch %u date %#x time %#x)\n",
7896 mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7897 if (mac->mac_fw.no_pcmfile)
7898 device_printf(sc->sc_dev,
7899 "no HW crypto acceleration due to pcm5\n");
7901 mac->mac_fw.patch = time;
7902 fwcaps = bwn_fwcaps_read(mac);
7903 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7904 device_printf(sc->sc_dev,
7905 "disabling HW crypto acceleration\n");
7906 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7908 if (!(fwcaps & BWN_FWCAPS_WME)) {
7909 device_printf(sc->sc_dev, "disabling WME support\n");
7910 mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7914 if (BWN_ISOLDFMT(mac))
7915 device_printf(sc->sc_dev, "using old firmware image\n");
7920 BWN_WRITE_4(mac, BWN_MACCTL,
7921 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7922 BWN_MACCTL_MCODE_JMP0);
7929 /* OpenFirmware only */
7931 bwn_fwcaps_read(struct bwn_mac *mac)
7934 KASSERT(mac->mac_fw.opensource == 1,
7935 ("%s:%d: fail", __func__, __LINE__));
7936 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7940 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7941 size_t count, size_t array_size)
7943 #define GET_NEXTIV16(iv) \
7944 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \
7945 sizeof(uint16_t) + sizeof(uint16_t)))
7946 #define GET_NEXTIV32(iv) \
7947 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \
7948 sizeof(uint16_t) + sizeof(uint32_t)))
7949 struct bwn_softc *sc = mac->mac_sc;
7950 const struct bwn_fwinitvals *iv;
7955 KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7956 ("%s:%d: fail", __func__, __LINE__));
7958 for (i = 0; i < count; i++) {
7959 if (array_size < sizeof(iv->offset_size))
7961 array_size -= sizeof(iv->offset_size);
7962 offset = be16toh(iv->offset_size);
7963 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7964 offset &= BWN_FWINITVALS_OFFSET_MASK;
7965 if (offset >= 0x1000)
7968 if (array_size < sizeof(iv->data.d32))
7970 array_size -= sizeof(iv->data.d32);
7971 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7972 iv = GET_NEXTIV32(iv);
7975 if (array_size < sizeof(iv->data.d16))
7977 array_size -= sizeof(iv->data.d16);
7978 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7980 iv = GET_NEXTIV16(iv);
7983 if (array_size != 0)
7987 device_printf(sc->sc_dev, "initvals: invalid format\n");
7994 bwn_switch_channel(struct bwn_mac *mac, int chan)
7996 struct bwn_phy *phy = &(mac->mac_phy);
7997 struct bwn_softc *sc = mac->mac_sc;
7998 struct ifnet *ifp = sc->sc_ifp;
7999 struct ieee80211com *ic = ifp->if_l2com;
8000 uint16_t channelcookie, savedcookie;
8004 chan = phy->get_default_chan(mac);
8006 channelcookie = chan;
8007 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
8008 channelcookie |= 0x100;
8009 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
8010 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
8011 error = phy->switch_channel(mac, chan);
8015 mac->mac_phy.chan = chan;
8019 device_printf(sc->sc_dev, "failed to switch channel\n");
8020 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
8025 bwn_ant2phy(int antenna)
8030 return (BWN_TX_PHY_ANT0);
8032 return (BWN_TX_PHY_ANT1);
8034 return (BWN_TX_PHY_ANT2);
8036 return (BWN_TX_PHY_ANT3);
8038 return (BWN_TX_PHY_ANT01AUTO);
8040 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8045 bwn_wme_load(struct bwn_mac *mac)
8047 struct bwn_softc *sc = mac->mac_sc;
8050 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
8051 ("%s:%d: fail", __func__, __LINE__));
8053 bwn_mac_suspend(mac);
8054 for (i = 0; i < N(sc->sc_wmeParams); i++)
8055 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
8056 bwn_wme_shm_offsets[i]);
8057 bwn_mac_enable(mac);
8061 bwn_wme_loadparams(struct bwn_mac *mac,
8062 const struct wmeParams *p, uint16_t shm_offset)
8064 #define SM(_v, _f) (((_v) << _f##_S) & _f)
8065 struct bwn_softc *sc = mac->mac_sc;
8066 uint16_t params[BWN_NR_WMEPARAMS];
8070 slot = BWN_READ_2(mac, BWN_RNG) &
8071 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8073 memset(¶ms, 0, sizeof(params));
8075 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
8076 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
8077 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
8079 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
8080 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8081 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
8082 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8083 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
8084 params[BWN_WMEPARAM_BSLOTS] = slot;
8085 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
8087 for (i = 0; i < N(params); i++) {
8088 if (i == BWN_WMEPARAM_STATUS) {
8089 tmp = bwn_shm_read_2(mac, BWN_SHARED,
8090 shm_offset + (i * 2));
8092 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8095 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8102 bwn_mac_write_bssid(struct bwn_mac *mac)
8104 struct bwn_softc *sc = mac->mac_sc;
8107 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
8109 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
8110 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
8111 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
8112 IEEE80211_ADDR_LEN);
8114 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
8115 tmp = (uint32_t) (mac_bssid[i + 0]);
8116 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
8117 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
8118 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
8119 bwn_ram_write(mac, 0x20 + i, tmp);
8124 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
8125 const uint8_t *macaddr)
8127 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
8134 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
8137 data |= macaddr[1] << 8;
8138 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8140 data |= macaddr[3] << 8;
8141 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8143 data |= macaddr[5] << 8;
8144 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8148 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8149 const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
8151 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
8152 uint8_t per_sta_keys_start = 8;
8154 if (BWN_SEC_NEWAPI(mac))
8155 per_sta_keys_start = 4;
8157 KASSERT(index < mac->mac_max_nr_keys,
8158 ("%s:%d: fail", __func__, __LINE__));
8159 KASSERT(key_len <= BWN_SEC_KEYSIZE,
8160 ("%s:%d: fail", __func__, __LINE__));
8162 if (index >= per_sta_keys_start)
8163 bwn_key_macwrite(mac, index, NULL);
8165 memcpy(buf, key, key_len);
8166 bwn_key_write(mac, index, algorithm, buf);
8167 if (index >= per_sta_keys_start)
8168 bwn_key_macwrite(mac, index, mac_addr);
8170 mac->mac_key[index].algorithm = algorithm;
8174 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8176 struct bwn_softc *sc = mac->mac_sc;
8177 uint32_t addrtmp[2] = { 0, 0 };
8180 if (BWN_SEC_NEWAPI(mac))
8183 KASSERT(index >= start,
8184 ("%s:%d: fail", __func__, __LINE__));
8188 addrtmp[0] = addr[0];
8189 addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8190 addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8191 addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8192 addrtmp[1] = addr[4];
8193 addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8196 if (siba_get_revid(sc->sc_dev) >= 5) {
8197 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8198 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8201 bwn_shm_write_4(mac, BWN_SHARED,
8202 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8203 bwn_shm_write_2(mac, BWN_SHARED,
8204 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8210 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8215 uint16_t kidx, value;
8217 kidx = BWN_SEC_KEY2FW(mac, index);
8218 bwn_shm_write_2(mac, BWN_SHARED,
8219 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8221 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8222 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8224 value |= (uint16_t)(key[i + 1]) << 8;
8225 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8230 bwn_phy_exit(struct bwn_mac *mac)
8233 mac->mac_phy.rf_onoff(mac, 0);
8234 if (mac->mac_phy.exit != NULL)
8235 mac->mac_phy.exit(mac);
8239 bwn_dma_free(struct bwn_mac *mac)
8241 struct bwn_dma *dma;
8243 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8245 dma = &mac->mac_method.dma;
8247 bwn_dma_ringfree(&dma->rx);
8248 bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8249 bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8250 bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8251 bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8252 bwn_dma_ringfree(&dma->mcast);
8256 bwn_core_stop(struct bwn_mac *mac)
8258 struct bwn_softc *sc = mac->mac_sc;
8260 BWN_ASSERT_LOCKED(sc);
8262 if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8265 callout_stop(&sc->sc_rfswitch_ch);
8266 callout_stop(&sc->sc_task_ch);
8267 callout_stop(&sc->sc_watchdog_ch);
8268 sc->sc_watchdog_timer = 0;
8269 BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8270 BWN_READ_4(mac, BWN_INTR_MASK);
8271 bwn_mac_suspend(mac);
8273 mac->mac_status = BWN_MAC_STATUS_INITED;
8277 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8279 struct bwn_mac *up_dev = NULL;
8280 struct bwn_mac *down_dev;
8281 struct bwn_mac *mac;
8285 BWN_ASSERT_LOCKED(sc);
8287 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8288 if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8289 mac->mac_phy.supports_2ghz) {
8292 } else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8293 mac->mac_phy.supports_5ghz) {
8297 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8303 if (up_dev == NULL) {
8304 device_printf(sc->sc_dev, "Could not find a device\n");
8307 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8310 device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8311 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8313 down_dev = sc->sc_curmac;;
8314 status = down_dev->mac_status;
8315 if (status >= BWN_MAC_STATUS_STARTED)
8316 bwn_core_stop(down_dev);
8317 if (status >= BWN_MAC_STATUS_INITED)
8318 bwn_core_exit(down_dev);
8320 if (down_dev != up_dev)
8321 bwn_phy_reset(down_dev);
8323 up_dev->mac_phy.gmode = gmode;
8324 if (status >= BWN_MAC_STATUS_INITED) {
8325 err = bwn_core_init(up_dev);
8327 device_printf(sc->sc_dev,
8328 "fatal: failed to initialize for %s-GHz\n",
8329 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8333 if (status >= BWN_MAC_STATUS_STARTED)
8334 bwn_core_start(up_dev);
8335 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8336 sc->sc_curmac = up_dev;
8340 sc->sc_curmac = NULL;
8345 bwn_rf_turnon(struct bwn_mac *mac)
8348 bwn_mac_suspend(mac);
8349 mac->mac_phy.rf_onoff(mac, 1);
8350 mac->mac_phy.rf_on = 1;
8351 bwn_mac_enable(mac);
8355 bwn_rf_turnoff(struct bwn_mac *mac)
8358 bwn_mac_suspend(mac);
8359 mac->mac_phy.rf_onoff(mac, 0);
8360 mac->mac_phy.rf_on = 0;
8361 bwn_mac_enable(mac);
8365 bwn_phy_reset(struct bwn_mac *mac)
8367 struct bwn_softc *sc = mac->mac_sc;
8369 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8370 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8371 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8373 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8374 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8375 BWN_TGSLOW_PHYRESET);
8380 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8382 struct bwn_vap *bvp = BWN_VAP(vap);
8383 struct ieee80211com *ic= vap->iv_ic;
8384 struct ifnet *ifp = ic->ic_ifp;
8385 enum ieee80211_state ostate = vap->iv_state;
8386 struct bwn_softc *sc = ifp->if_softc;
8387 struct bwn_mac *mac = sc->sc_curmac;
8390 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8391 ieee80211_state_name[vap->iv_state],
8392 ieee80211_state_name[nstate]);
8394 error = bvp->bv_newstate(vap, nstate, arg);
8400 bwn_led_newstate(mac, nstate);
8403 * Clear the BSSID when we stop a STA
8405 if (vap->iv_opmode == IEEE80211_M_STA) {
8406 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8408 * Clear out the BSSID. If we reassociate to
8409 * the same AP, this will reinialize things
8412 if (ic->ic_opmode == IEEE80211_M_STA &&
8413 (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8414 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8415 bwn_set_macaddr(mac);
8420 if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8421 vap->iv_opmode == IEEE80211_M_AHDEMO) {
8422 /* XXX nothing to do? */
8423 } else if (nstate == IEEE80211_S_RUN) {
8424 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8425 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
8426 bwn_set_opmode(mac);
8427 bwn_set_pretbtt(mac);
8428 bwn_spu_setdelay(mac, 0);
8429 bwn_set_macaddr(mac);
8438 bwn_set_pretbtt(struct bwn_mac *mac)
8440 struct bwn_softc *sc = mac->mac_sc;
8441 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8444 if (ic->ic_opmode == IEEE80211_M_IBSS)
8447 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8448 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8449 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8455 struct bwn_mac *mac = arg;
8456 struct bwn_softc *sc = mac->mac_sc;
8459 if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8460 (sc->sc_flags & BWN_FLAG_INVALID))
8461 return (FILTER_STRAY);
8463 reason = BWN_READ_4(mac, BWN_INTR_REASON);
8464 if (reason == 0xffffffff) /* shared IRQ */
8465 return (FILTER_STRAY);
8466 reason &= mac->mac_intr_mask;
8468 return (FILTER_HANDLED);
8470 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
8471 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8472 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8473 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8474 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8475 BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8476 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8477 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8478 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8479 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8480 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8482 /* Disable interrupts. */
8483 BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8485 mac->mac_reason_intr = reason;
8487 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8488 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8490 taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask);
8491 return (FILTER_HANDLED);
8495 bwn_intrtask(void *arg, int npending)
8497 struct bwn_mac *mac = arg;
8498 struct bwn_softc *sc = mac->mac_sc;
8499 struct ifnet *ifp = sc->sc_ifp;
8500 uint32_t merged = 0;
8501 int i, tx = 0, rx = 0;
8504 if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8505 (sc->sc_flags & BWN_FLAG_INVALID)) {
8510 for (i = 0; i < N(mac->mac_reason); i++)
8511 merged |= mac->mac_reason[i];
8513 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8514 device_printf(sc->sc_dev, "MAC trans error\n");
8516 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8517 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8518 mac->mac_phy.txerrors--;
8519 if (mac->mac_phy.txerrors == 0) {
8520 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8521 bwn_restart(mac, "PHY TX errors");
8525 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
8526 if (merged & BWN_DMAINTR_FATALMASK) {
8527 device_printf(sc->sc_dev,
8528 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8529 mac->mac_reason[0], mac->mac_reason[1],
8530 mac->mac_reason[2], mac->mac_reason[3],
8531 mac->mac_reason[4], mac->mac_reason[5]);
8532 bwn_restart(mac, "DMA error");
8536 if (merged & BWN_DMAINTR_NONFATALMASK) {
8537 device_printf(sc->sc_dev,
8538 "DMA error: %#x %#x %#x %#x %#x %#x\n",
8539 mac->mac_reason[0], mac->mac_reason[1],
8540 mac->mac_reason[2], mac->mac_reason[3],
8541 mac->mac_reason[4], mac->mac_reason[5]);
8545 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8546 bwn_intr_ucode_debug(mac);
8547 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8548 bwn_intr_tbtt_indication(mac);
8549 if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8550 bwn_intr_atim_end(mac);
8551 if (mac->mac_reason_intr & BWN_INTR_BEACON)
8552 bwn_intr_beacon(mac);
8553 if (mac->mac_reason_intr & BWN_INTR_PMQ)
8555 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8556 bwn_intr_noise(mac);
8558 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8559 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8560 bwn_dma_rx(mac->mac_method.dma.rx);
8564 rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8566 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8567 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8568 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8569 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8570 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8572 if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8573 bwn_intr_txeof(mac);
8577 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8579 if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8580 int evt = BWN_LED_EVENT_NONE;
8583 if (sc->sc_rx_rate > sc->sc_tx_rate)
8584 evt = BWN_LED_EVENT_RX;
8586 evt = BWN_LED_EVENT_TX;
8588 evt = BWN_LED_EVENT_TX;
8590 evt = BWN_LED_EVENT_RX;
8591 } else if (rx == 0) {
8592 evt = BWN_LED_EVENT_POLL;
8595 if (evt != BWN_LED_EVENT_NONE)
8596 bwn_led_event(mac, evt);
8599 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
8600 if (!IFQ_IS_EMPTY(&ifp->if_snd))
8601 bwn_start_locked(ifp);
8604 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8605 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8611 bwn_restart(struct bwn_mac *mac, const char *msg)
8613 struct bwn_softc *sc = mac->mac_sc;
8614 struct ifnet *ifp = sc->sc_ifp;
8615 struct ieee80211com *ic = ifp->if_l2com;
8617 if (mac->mac_status < BWN_MAC_STATUS_INITED)
8620 device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8621 ieee80211_runtask(ic, &mac->mac_hwreset);
8625 bwn_intr_ucode_debug(struct bwn_mac *mac)
8627 struct bwn_softc *sc = mac->mac_sc;
8630 if (mac->mac_fw.opensource == 0)
8633 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8635 case BWN_DEBUGINTR_PANIC:
8636 bwn_handle_fwpanic(mac);
8638 case BWN_DEBUGINTR_DUMP_SHM:
8639 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8641 case BWN_DEBUGINTR_DUMP_REGS:
8642 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8644 case BWN_DEBUGINTR_MARKER:
8645 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8648 device_printf(sc->sc_dev,
8649 "ucode debug unknown reason: %#x\n", reason);
8652 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8657 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8659 struct bwn_softc *sc = mac->mac_sc;
8660 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8662 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8664 if (ic->ic_opmode == IEEE80211_M_IBSS)
8665 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8669 bwn_intr_atim_end(struct bwn_mac *mac)
8672 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8673 BWN_WRITE_4(mac, BWN_MACCMD,
8674 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8675 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8680 bwn_intr_beacon(struct bwn_mac *mac)
8682 struct bwn_softc *sc = mac->mac_sc;
8683 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8684 uint32_t cmd, beacon0, beacon1;
8686 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8687 ic->ic_opmode == IEEE80211_M_MBSS)
8690 mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8692 cmd = BWN_READ_4(mac, BWN_MACCMD);
8693 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8694 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8696 if (beacon0 && beacon1) {
8697 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8698 mac->mac_intr_mask |= BWN_INTR_BEACON;
8702 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8703 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8704 bwn_load_beacon0(mac);
8705 bwn_load_beacon1(mac);
8706 cmd = BWN_READ_4(mac, BWN_MACCMD);
8707 cmd |= BWN_MACCMD_BEACON0_VALID;
8708 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8711 bwn_load_beacon0(mac);
8712 cmd = BWN_READ_4(mac, BWN_MACCMD);
8713 cmd |= BWN_MACCMD_BEACON0_VALID;
8714 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8715 } else if (!beacon1) {
8716 bwn_load_beacon1(mac);
8717 cmd = BWN_READ_4(mac, BWN_MACCMD);
8718 cmd |= BWN_MACCMD_BEACON1_VALID;
8719 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8725 bwn_intr_pmq(struct bwn_mac *mac)
8730 tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8731 if (!(tmp & 0x00000008))
8734 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8738 bwn_intr_noise(struct bwn_mac *mac)
8740 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8746 if (mac->mac_phy.type != BWN_PHYTYPE_G)
8749 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8750 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8751 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8755 KASSERT(mac->mac_noise.noi_nsamples < 8,
8756 ("%s:%d: fail", __func__, __LINE__));
8757 i = mac->mac_noise.noi_nsamples;
8758 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8759 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8760 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8761 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8762 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8763 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8764 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8765 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8766 mac->mac_noise.noi_nsamples++;
8767 if (mac->mac_noise.noi_nsamples == 8) {
8769 for (i = 0; i < 8; i++) {
8770 for (j = 0; j < 4; j++)
8771 average += mac->mac_noise.noi_samples[i][j];
8773 average = (((average / 32) * 125) + 64) / 128;
8774 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8779 average -= (tmp == 8) ? 72 : 48;
8781 mac->mac_stats.link_noise = average;
8782 mac->mac_noise.noi_running = 0;
8786 bwn_noise_gensample(mac);
8790 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8792 struct bwn_mac *mac = prq->prq_mac;
8793 struct bwn_softc *sc = mac->mac_sc;
8796 BWN_ASSERT_LOCKED(sc);
8798 if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8801 for (i = 0; i < 5000; i++) {
8802 if (bwn_pio_rxeof(prq) == 0)
8806 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8807 return ((i > 0) ? 1 : 0);
8811 bwn_dma_rx(struct bwn_dma_ring *dr)
8815 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8816 curslot = dr->get_curslot(dr);
8817 KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8818 ("%s:%d: fail", __func__, __LINE__));
8820 slot = dr->dr_curslot;
8821 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8822 bwn_dma_rxeof(dr, &slot);
8824 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8825 BUS_DMASYNC_PREWRITE);
8827 dr->set_curslot(dr, slot);
8828 dr->dr_curslot = slot;
8832 bwn_intr_txeof(struct bwn_mac *mac)
8834 struct bwn_txstatus stat;
8835 uint32_t stat0, stat1;
8838 BWN_ASSERT_LOCKED(mac->mac_sc);
8841 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8842 if (!(stat0 & 0x00000001))
8844 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8846 stat.cookie = (stat0 >> 16);
8847 stat.seq = (stat1 & 0x0000ffff);
8848 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8849 tmp = (stat0 & 0x0000ffff);
8850 stat.framecnt = ((tmp & 0xf000) >> 12);
8851 stat.rtscnt = ((tmp & 0x0f00) >> 8);
8852 stat.sreason = ((tmp & 0x001c) >> 2);
8853 stat.pm = (tmp & 0x0080) ? 1 : 0;
8854 stat.im = (tmp & 0x0040) ? 1 : 0;
8855 stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8856 stat.ack = (tmp & 0x0002) ? 1 : 0;
8858 bwn_handle_txeof(mac, &stat);
8863 bwn_hwreset(void *arg, int npending)
8865 struct bwn_mac *mac = arg;
8866 struct bwn_softc *sc = mac->mac_sc;
8872 prev_status = mac->mac_status;
8873 if (prev_status >= BWN_MAC_STATUS_STARTED)
8875 if (prev_status >= BWN_MAC_STATUS_INITED)
8878 if (prev_status >= BWN_MAC_STATUS_INITED) {
8879 error = bwn_core_init(mac);
8883 if (prev_status >= BWN_MAC_STATUS_STARTED)
8884 bwn_core_start(mac);
8887 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8888 sc->sc_curmac = NULL;
8894 bwn_handle_fwpanic(struct bwn_mac *mac)
8896 struct bwn_softc *sc = mac->mac_sc;
8899 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8900 device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8902 if (reason == BWN_FWPANIC_RESTART)
8903 bwn_restart(mac, "ucode panic");
8907 bwn_load_beacon0(struct bwn_mac *mac)
8910 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8914 bwn_load_beacon1(struct bwn_mac *mac)
8917 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8921 bwn_jssi_read(struct bwn_mac *mac)
8925 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8927 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8933 bwn_noise_gensample(struct bwn_mac *mac)
8935 uint32_t jssi = 0x7f7f7f7f;
8937 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8938 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8939 BWN_WRITE_4(mac, BWN_MACCMD,
8940 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8944 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8946 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8948 return (dr->dr_numslots - dr->dr_usedslot);
8952 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8954 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8956 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8957 ("%s:%d: fail", __func__, __LINE__));
8958 if (slot == dr->dr_numslots - 1)
8964 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8966 struct bwn_mac *mac = dr->dr_mac;
8967 struct bwn_softc *sc = mac->mac_sc;
8968 struct bwn_dma *dma = &mac->mac_method.dma;
8969 struct bwn_dmadesc_generic *desc;
8970 struct bwn_dmadesc_meta *meta;
8971 struct bwn_rxhdr4 *rxhdr;
8972 struct ifnet *ifp = sc->sc_ifp;
8979 dr->getdesc(dr, *slot, &desc, &meta);
8981 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8984 if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8989 rxhdr = mtod(m, struct bwn_rxhdr4 *);
8990 len = le16toh(rxhdr->frame_len);
8995 if (bwn_dma_check_redzone(dr, m)) {
8996 device_printf(sc->sc_dev, "redzone error.\n");
8997 bwn_dma_set_redzone(dr, m);
8998 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8999 BUS_DMASYNC_PREWRITE);
9002 if (len > dr->dr_rx_bufsize) {
9005 dr->getdesc(dr, *slot, &desc, &meta);
9006 bwn_dma_set_redzone(dr, meta->mt_m);
9007 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9008 BUS_DMASYNC_PREWRITE);
9009 *slot = bwn_dma_nextslot(dr, *slot);
9011 tmp -= dr->dr_rx_bufsize;
9015 device_printf(sc->sc_dev, "too small buffer "
9016 "(len %u buffer %u dropped %d)\n",
9017 len, dr->dr_rx_bufsize, cnt);
9020 macstat = le32toh(rxhdr->mac_status);
9021 if (macstat & BWN_RX_MAC_FCSERR) {
9022 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9023 device_printf(sc->sc_dev, "RX drop\n");
9028 m->m_pkthdr.rcvif = ifp;
9029 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
9030 m_adj(m, dr->dr_frameoffset);
9032 bwn_rxeof(dr->dr_mac, m, rxhdr);
9036 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
9038 struct bwn_dma_ring *dr;
9039 struct bwn_dmadesc_generic *desc;
9040 struct bwn_dmadesc_meta *meta;
9041 struct bwn_node *bn;
9042 struct bwn_pio_txqueue *tq;
9043 struct bwn_pio_txpkt *tp = NULL;
9044 struct bwn_softc *sc = mac->mac_sc;
9045 struct bwn_stats *stats = &mac->mac_stats;
9046 struct ieee80211_node *ni;
9049 BWN_ASSERT_LOCKED(mac->mac_sc);
9052 device_printf(sc->sc_dev, "TODO: STATUS IM\n");
9054 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
9055 if (status->rtscnt) {
9056 if (status->rtscnt == 0xf)
9062 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
9064 dr = bwn_dma_parse_cookie(mac, status,
9065 status->cookie, &slot);
9067 device_printf(sc->sc_dev,
9068 "failed to parse cookie\n");
9072 dr->getdesc(dr, slot, &desc, &meta);
9073 if (meta->mt_islast) {
9075 bn = (struct bwn_node *)ni;
9076 ieee80211_amrr_tx_complete(&bn->bn_amn,
9080 slot = bwn_dma_nextslot(dr, slot);
9083 bwn_dma_handle_txeof(mac, status);
9086 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9088 device_printf(sc->sc_dev,
9089 "failed to parse cookie\n");
9093 bn = (struct bwn_node *)ni;
9094 ieee80211_amrr_tx_complete(&bn->bn_amn, status->ack, 0);
9096 bwn_pio_handle_txeof(mac, status);
9099 bwn_phy_txpower_check(mac, 0);
9103 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
9105 struct bwn_mac *mac = prq->prq_mac;
9106 struct bwn_softc *sc = mac->mac_sc;
9107 struct bwn_rxhdr4 rxhdr;
9108 struct ifnet *ifp = sc->sc_ifp;
9110 uint32_t ctl32, macstat, v32;
9111 unsigned int i, padding;
9112 uint16_t ctl16, len, v16;
9116 memset(&rxhdr, 0, sizeof(rxhdr));
9118 if (prq->prq_rev >= 8) {
9119 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9120 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
9122 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9123 BWN_PIO8_RXCTL_FRAMEREADY);
9124 for (i = 0; i < 10; i++) {
9125 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9126 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
9131 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9132 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
9134 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
9135 BWN_PIO_RXCTL_FRAMEREADY);
9136 for (i = 0; i < 10; i++) {
9137 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9138 if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
9143 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
9146 if (prq->prq_rev >= 8)
9147 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9148 prq->prq_base + BWN_PIO8_RXDATA);
9150 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9151 prq->prq_base + BWN_PIO_RXDATA);
9152 len = le16toh(rxhdr.frame_len);
9154 device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9158 device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9162 macstat = le32toh(rxhdr.mac_status);
9163 if (macstat & BWN_RX_MAC_FCSERR) {
9164 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9165 device_printf(sc->sc_dev, "%s: FCS error", __func__);
9170 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9171 KASSERT(len + padding <= MCLBYTES, ("too big..\n"));
9172 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
9174 device_printf(sc->sc_dev, "%s: out of memory", __func__);
9177 mp = mtod(m, unsigned char *);
9178 if (prq->prq_rev >= 8) {
9179 siba_read_multi_4(sc->sc_dev, mp + padding, (len & ~3),
9180 prq->prq_base + BWN_PIO8_RXDATA);
9182 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9183 data = &(mp[len + padding - 1]);
9186 *data = (v32 >> 16);
9196 siba_read_multi_2(sc->sc_dev, mp + padding, (len & ~1),
9197 prq->prq_base + BWN_PIO_RXDATA);
9199 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9200 mp[len + padding - 1] = v16;
9204 m->m_pkthdr.rcvif = ifp;
9205 m->m_len = m->m_pkthdr.len = len + padding;
9207 bwn_rxeof(prq->prq_mac, m, &rxhdr);
9211 if (prq->prq_rev >= 8)
9212 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9213 BWN_PIO8_RXCTL_DATAREADY);
9215 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9220 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9221 struct bwn_dmadesc_meta *meta, int init)
9223 struct bwn_mac *mac = dr->dr_mac;
9224 struct bwn_dma *dma = &mac->mac_method.dma;
9225 struct bwn_rxhdr4 *hdr;
9231 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
9236 * If the NIC is up and running, we need to:
9237 * - Clear RX buffer's header.
9238 * - Restore RX descriptor settings.
9245 m->m_len = m->m_pkthdr.len = MCLBYTES;
9247 bwn_dma_set_redzone(dr, m);
9250 * Try to load RX buf into temporary DMA map
9252 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9253 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9258 * See the comment above
9267 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9269 meta->mt_paddr = paddr;
9272 * Swap RX buf's DMA map with the loaded temporary one
9274 map = meta->mt_dmap;
9275 meta->mt_dmap = dr->dr_spare_dmap;
9276 dr->dr_spare_dmap = map;
9280 * Clear RX buf header
9282 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9283 bzero(hdr, sizeof(*hdr));
9284 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9285 BUS_DMASYNC_PREWRITE);
9288 * Setup RX buf descriptor
9290 dr->setdesc(dr, desc, paddr, meta->mt_m->m_len -
9291 sizeof(*hdr), 0, 0, 0);
9296 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9297 bus_size_t mapsz __unused, int error)
9301 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9302 *((bus_addr_t *)arg) = seg->ds_addr;
9307 bwn_hwrate2ieeerate(int rate)
9311 case BWN_CCK_RATE_1MB:
9313 case BWN_CCK_RATE_2MB:
9315 case BWN_CCK_RATE_5MB:
9317 case BWN_CCK_RATE_11MB:
9319 case BWN_OFDM_RATE_6MB:
9321 case BWN_OFDM_RATE_9MB:
9323 case BWN_OFDM_RATE_12MB:
9325 case BWN_OFDM_RATE_18MB:
9327 case BWN_OFDM_RATE_24MB:
9329 case BWN_OFDM_RATE_36MB:
9331 case BWN_OFDM_RATE_48MB:
9333 case BWN_OFDM_RATE_54MB:
9342 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9344 const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9345 struct bwn_plcp6 *plcp;
9346 struct bwn_softc *sc = mac->mac_sc;
9347 struct ieee80211_frame_min *wh;
9348 struct ieee80211_node *ni;
9349 struct ifnet *ifp = sc->sc_ifp;
9350 struct ieee80211com *ic = ifp->if_l2com;
9352 int padding, rate, rssi = 0, noise = 0, type;
9353 uint16_t phytype, phystat0, phystat3, chanstat;
9354 unsigned char *mp = mtod(m, unsigned char *);
9355 static int rx_mac_dec_rpt = 0;
9357 BWN_ASSERT_LOCKED(sc);
9359 phystat0 = le16toh(rxhdr->phy_status0);
9360 phystat3 = le16toh(rxhdr->phy_status3);
9361 macstat = le32toh(rxhdr->mac_status);
9362 chanstat = le16toh(rxhdr->channel);
9363 phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9365 if (macstat & BWN_RX_MAC_FCSERR)
9366 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9367 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9368 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9369 if (macstat & BWN_RX_MAC_DECERR)
9372 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9373 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9374 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9378 plcp = (struct bwn_plcp6 *)(mp + padding);
9379 m_adj(m, sizeof(struct bwn_plcp6) + padding);
9380 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9381 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9385 wh = mtod(m, struct ieee80211_frame_min *);
9387 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9388 device_printf(sc->sc_dev,
9389 "RX decryption attempted (old %d keyidx %#x)\n",
9391 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9393 /* XXX calculating RSSI & noise & antenna */
9395 if (phystat0 & BWN_RX_PHYST0_OFDM)
9396 rate = bwn_plcp_get_ofdmrate(mac, plcp,
9397 phytype == BWN_PHYTYPE_A);
9399 rate = bwn_plcp_get_cckrate(mac, plcp);
9401 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9404 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9407 if (ieee80211_radiotap_active(ic))
9408 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9409 m_adj(m, -IEEE80211_CRC_LEN);
9411 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */
9412 noise = mac->mac_stats.link_noise;
9416 ni = ieee80211_find_rxnode(ic, wh);
9418 type = ieee80211_input(ni, m, rssi, noise);
9419 ieee80211_free_node(ni);
9421 type = ieee80211_input_all(ic, m, rssi, noise);
9426 device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9430 bwn_dma_handle_txeof(struct bwn_mac *mac,
9431 const struct bwn_txstatus *status)
9433 struct bwn_dma *dma = &mac->mac_method.dma;
9434 struct bwn_dma_ring *dr;
9435 struct bwn_dmadesc_generic *desc;
9436 struct bwn_dmadesc_meta *meta;
9437 struct bwn_softc *sc = mac->mac_sc;
9438 struct ieee80211_node *ni;
9439 struct ifnet *ifp = sc->sc_ifp;
9443 BWN_ASSERT_LOCKED(sc);
9445 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9447 device_printf(sc->sc_dev, "failed to parse cookie\n");
9450 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9453 KASSERT(slot >= 0 && slot < dr->dr_numslots,
9454 ("%s:%d: fail", __func__, __LINE__));
9455 dr->getdesc(dr, slot, &desc, &meta);
9457 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
9458 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
9459 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
9460 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9462 if (meta->mt_islast) {
9463 KASSERT(meta->mt_m != NULL,
9464 ("%s:%d: fail", __func__, __LINE__));
9470 * Do any tx complete callback. Note this must
9471 * be done before releasing the node reference.
9473 if (m->m_flags & M_TXCB)
9474 ieee80211_process_callback(ni, m, 0);
9475 ieee80211_free_node(ni);
9481 KASSERT(meta->mt_m == NULL,
9482 ("%s:%d: fail", __func__, __LINE__));
9486 if (meta->mt_islast) {
9490 slot = bwn_dma_nextslot(dr, slot);
9492 sc->sc_watchdog_timer = 0;
9494 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9495 ("%s:%d: fail", __func__, __LINE__));
9496 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9502 bwn_pio_handle_txeof(struct bwn_mac *mac,
9503 const struct bwn_txstatus *status)
9505 struct bwn_pio_txqueue *tq;
9506 struct bwn_pio_txpkt *tp = NULL;
9507 struct bwn_softc *sc = mac->mac_sc;
9508 struct ifnet *ifp = sc->sc_ifp;
9510 BWN_ASSERT_LOCKED(sc);
9512 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9516 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9519 if (tp->tp_ni != NULL) {
9521 * Do any tx complete callback. Note this must
9522 * be done before releasing the node reference.
9524 if (tp->tp_m->m_flags & M_TXCB)
9525 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9526 ieee80211_free_node(tp->tp_ni);
9531 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9535 sc->sc_watchdog_timer = 0;
9537 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9543 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9545 struct bwn_softc *sc = mac->mac_sc;
9546 struct bwn_phy *phy = &mac->mac_phy;
9547 struct ifnet *ifp = sc->sc_ifp;
9548 struct ieee80211com *ic = ifp->if_l2com;
9554 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9556 phy->nexttime = now + 2 * 1000;
9558 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9559 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9562 if (phy->recalc_txpwr != NULL) {
9563 result = phy->recalc_txpwr(mac,
9564 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9565 if (result == BWN_TXPWR_RES_DONE)
9567 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9568 ("%s: fail", __func__));
9569 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9571 ieee80211_runtask(ic, &mac->mac_txpower);
9576 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9579 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9583 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9586 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9590 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9593 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9597 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9600 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9604 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9608 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9610 return (BWN_OFDM_RATE_6MB);
9612 return (BWN_OFDM_RATE_9MB);
9614 return (BWN_OFDM_RATE_12MB);
9616 return (BWN_OFDM_RATE_18MB);
9618 return (BWN_OFDM_RATE_24MB);
9620 return (BWN_OFDM_RATE_36MB);
9622 return (BWN_OFDM_RATE_48MB);
9624 return (BWN_OFDM_RATE_54MB);
9625 /* CCK rates (NB: not IEEE std, device-specific) */
9627 return (BWN_CCK_RATE_1MB);
9629 return (BWN_CCK_RATE_2MB);
9631 return (BWN_CCK_RATE_5MB);
9633 return (BWN_CCK_RATE_11MB);
9636 device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9637 return (BWN_CCK_RATE_1MB);
9641 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9642 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9644 const struct bwn_phy *phy = &mac->mac_phy;
9645 struct bwn_softc *sc = mac->mac_sc;
9646 struct ieee80211_frame *wh;
9647 struct ieee80211_frame *protwh;
9648 struct ieee80211_frame_cts *cts;
9649 struct ieee80211_frame_rts *rts;
9650 const struct ieee80211_txparam *tp;
9651 struct ieee80211vap *vap = ni->ni_vap;
9652 struct ifnet *ifp = sc->sc_ifp;
9653 struct ieee80211com *ic = ifp->if_l2com;
9656 uint32_t macctl = 0;
9657 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9658 uint16_t phyctl = 0;
9659 uint8_t rate, rate_fb;
9661 wh = mtod(m, struct ieee80211_frame *);
9662 memset(txhdr, 0, sizeof(*txhdr));
9664 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9665 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9666 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9671 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9672 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9673 rate = rate_fb = tp->mgmtrate;
9675 rate = rate_fb = tp->mcastrate;
9676 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9677 rate = rate_fb = tp->ucastrate;
9679 rix = ieee80211_amrr_choose(ni, &BWN_NODE(ni)->bn_amn);
9680 rate = ni->ni_txrate;
9683 rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9689 sc->sc_tx_rate = rate;
9691 rate = bwn_ieeerate2hwrate(sc, rate);
9692 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9694 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9695 bwn_plcp_getcck(rate);
9696 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9697 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9699 if ((rate_fb == rate) ||
9700 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9701 (*(u_int16_t *)wh->i_dur == htole16(0)))
9702 txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9704 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9705 m->m_pkthdr.len, rate, isshort);
9707 /* XXX TX encryption */
9708 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9709 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9710 (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9711 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9712 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9713 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9715 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9717 txhdr->chan = phy->chan;
9718 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9720 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9721 rate == BWN_CCK_RATE_11MB))
9722 phyctl |= BWN_TX_PHY_SHORTPRMBL;
9724 /* XXX TX antenna selection */
9726 switch (bwn_antenna_sanitize(mac, 0)) {
9728 phyctl |= BWN_TX_PHY_ANT01AUTO;
9731 phyctl |= BWN_TX_PHY_ANT0;
9734 phyctl |= BWN_TX_PHY_ANT1;
9737 phyctl |= BWN_TX_PHY_ANT2;
9740 phyctl |= BWN_TX_PHY_ANT3;
9743 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9747 macctl |= BWN_TX_MAC_ACK;
9749 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9750 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9751 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9752 macctl |= BWN_TX_MAC_LONGFRAME;
9754 if (ic->ic_flags & IEEE80211_F_USEPROT) {
9755 /* XXX RTS rate is always 1MB??? */
9756 rts_rate = BWN_CCK_RATE_1MB;
9757 rts_rate_fb = bwn_get_fbrate(rts_rate);
9759 protdur = ieee80211_compute_duration(ic->ic_rt,
9760 m->m_pkthdr.len, rate, isshort) +
9761 + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9763 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9764 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9765 (txhdr->body.old.rts_frame) :
9766 (txhdr->body.new.rts_frame));
9767 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9769 KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9770 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9771 mprot->m_pkthdr.len);
9773 macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9774 len = sizeof(struct ieee80211_frame_cts);
9776 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9777 (txhdr->body.old.rts_frame) :
9778 (txhdr->body.new.rts_frame));
9779 protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9781 mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9782 wh->i_addr2, protdur);
9783 KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9784 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9785 mprot->m_pkthdr.len);
9787 macctl |= BWN_TX_MAC_SEND_RTSCTS;
9788 len = sizeof(struct ieee80211_frame_rts);
9790 len += IEEE80211_CRC_LEN;
9791 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9792 &txhdr->body.old.rts_plcp :
9793 &txhdr->body.new.rts_plcp), len, rts_rate);
9794 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9797 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9798 (&txhdr->body.old.rts_frame) :
9799 (&txhdr->body.new.rts_frame));
9800 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9802 if (BWN_ISOFDMRATE(rts_rate)) {
9803 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9804 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9806 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9807 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9809 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9810 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9813 if (BWN_ISOLDFMT(mac))
9814 txhdr->body.old.cookie = htole16(cookie);
9816 txhdr->body.new.cookie = htole16(cookie);
9818 txhdr->macctl = htole32(macctl);
9819 txhdr->phyctl = htole16(phyctl);
9824 if (ieee80211_radiotap_active_vap(vap)) {
9825 sc->sc_tx_th.wt_flags = 0;
9826 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
9827 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9829 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9830 rate == BWN_CCK_RATE_11MB))
9831 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9832 sc->sc_tx_th.wt_rate = rate;
9834 ieee80211_radiotap_tx(vap, m);
9841 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9845 uint8_t *raw = plcp->o.raw;
9847 if (BWN_ISOFDMRATE(rate)) {
9848 d = bwn_plcp_getofdm(rate);
9849 KASSERT(!(octets & 0xf000),
9850 ("%s:%d: fail", __func__, __LINE__));
9852 plcp->o.data = htole32(d);
9854 plen = octets * 16 / rate;
9855 if ((octets * 16 % rate) > 0) {
9857 if ((rate == BWN_CCK_RATE_11MB)
9858 && ((octets * 8 % 11) < 4)) {
9864 plcp->o.data |= htole32(plen << 16);
9865 raw[0] = bwn_plcp_getcck(rate);
9870 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9872 struct bwn_softc *sc = mac->mac_sc;
9877 if (mac->mac_phy.gmode)
9878 mask = siba_sprom_get_ant_bg(sc->sc_dev);
9880 mask = siba_sprom_get_ant_a(sc->sc_dev);
9881 if (!(mask & (1 << (n - 1))))
9887 bwn_get_fbrate(uint8_t bitrate)
9890 case BWN_CCK_RATE_1MB:
9891 return (BWN_CCK_RATE_1MB);
9892 case BWN_CCK_RATE_2MB:
9893 return (BWN_CCK_RATE_1MB);
9894 case BWN_CCK_RATE_5MB:
9895 return (BWN_CCK_RATE_2MB);
9896 case BWN_CCK_RATE_11MB:
9897 return (BWN_CCK_RATE_5MB);
9898 case BWN_OFDM_RATE_6MB:
9899 return (BWN_CCK_RATE_5MB);
9900 case BWN_OFDM_RATE_9MB:
9901 return (BWN_OFDM_RATE_6MB);
9902 case BWN_OFDM_RATE_12MB:
9903 return (BWN_OFDM_RATE_9MB);
9904 case BWN_OFDM_RATE_18MB:
9905 return (BWN_OFDM_RATE_12MB);
9906 case BWN_OFDM_RATE_24MB:
9907 return (BWN_OFDM_RATE_18MB);
9908 case BWN_OFDM_RATE_36MB:
9909 return (BWN_OFDM_RATE_24MB);
9910 case BWN_OFDM_RATE_48MB:
9911 return (BWN_OFDM_RATE_36MB);
9912 case BWN_OFDM_RATE_54MB:
9913 return (BWN_OFDM_RATE_48MB);
9915 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9920 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9921 uint32_t ctl, const void *_data, int len)
9923 struct bwn_softc *sc = mac->mac_sc;
9925 const uint8_t *data = _data;
9927 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9928 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9929 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9931 siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9932 tq->tq_base + BWN_PIO8_TXDATA);
9934 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9935 BWN_PIO8_TXCTL_24_31);
9936 data = &(data[len - 1]);
9939 ctl |= BWN_PIO8_TXCTL_16_23;
9940 value |= (uint32_t)(*data) << 16;
9943 ctl |= BWN_PIO8_TXCTL_8_15;
9944 value |= (uint32_t)(*data) << 8;
9947 value |= (uint32_t)(*data);
9949 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9950 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9957 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9958 uint16_t offset, uint32_t value)
9961 BWN_WRITE_4(mac, tq->tq_base + offset, value);
9965 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9966 uint16_t ctl, const void *_data, int len)
9968 struct bwn_softc *sc = mac->mac_sc;
9969 const uint8_t *data = _data;
9971 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9972 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9974 siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9975 tq->tq_base + BWN_PIO_TXDATA);
9977 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9978 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9979 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9986 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9987 uint16_t ctl, struct mbuf *m0)
9992 struct mbuf *m = m0;
9994 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9995 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9997 for (; m != NULL; m = m->m_next) {
9998 buf = mtod(m, const uint8_t *);
9999 for (i = 0; i < m->m_len; i++) {
10003 data |= (buf[i] << 8);
10004 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
10009 if (m0->m_pkthdr.len % 2) {
10010 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
10011 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
10012 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
10019 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
10022 if (mac->mac_phy.type != BWN_PHYTYPE_G)
10024 BWN_WRITE_2(mac, 0x684, 510 + time);
10025 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
10028 static struct bwn_dma_ring *
10029 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
10032 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
10033 return (mac->mac_method.dma.wme[WME_AC_BE]);
10037 return (mac->mac_method.dma.wme[WME_AC_VO]);
10039 return (mac->mac_method.dma.wme[WME_AC_VI]);
10041 return (mac->mac_method.dma.wme[WME_AC_BE]);
10043 return (mac->mac_method.dma.wme[WME_AC_BK]);
10045 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
10050 bwn_dma_getslot(struct bwn_dma_ring *dr)
10054 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
10056 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
10057 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
10058 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
10060 slot = bwn_dma_nextslot(dr, dr->dr_curslot);
10061 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
10062 dr->dr_curslot = slot;
10069 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
10071 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
10072 unsigned int a, b, c, d;
10076 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
10078 b = (tmp >> 8) & 0xff;
10079 c = (tmp >> 16) & 0xff;
10080 d = (tmp >> 24) & 0xff;
10081 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
10082 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
10084 bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
10085 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
10086 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
10089 a = (a + 32) & 0x3f;
10090 b = (b + 32) & 0x3f;
10091 c = (c + 32) & 0x3f;
10092 d = (d + 32) & 0x3f;
10095 avg = (a + b + c + d + 2) / 4;
10097 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
10098 & BWN_HF_4DB_CCK_POWERBOOST)
10099 avg = (avg >= 13) ? (avg - 13) : 0;
10105 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
10107 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
10108 int rfatt = *rfattp;
10109 int bbatt = *bbattp;
10112 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
10114 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
10116 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
10118 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
10120 if (bbatt > lo->bbatt.max) {
10125 if (bbatt < lo->bbatt.min) {
10130 if (rfatt > lo->rfatt.max) {
10135 if (rfatt < lo->rfatt.min) {
10143 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
10144 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
10148 bwn_phy_lock(struct bwn_mac *mac)
10150 struct bwn_softc *sc = mac->mac_sc;
10151 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10153 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10154 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10156 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10157 bwn_psctl(mac, BWN_PS_AWAKE);
10161 bwn_phy_unlock(struct bwn_mac *mac)
10163 struct bwn_softc *sc = mac->mac_sc;
10164 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10166 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10167 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10169 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10174 bwn_rf_lock(struct bwn_mac *mac)
10177 BWN_WRITE_4(mac, BWN_MACCTL,
10178 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
10179 BWN_READ_4(mac, BWN_MACCTL);
10184 bwn_rf_unlock(struct bwn_mac *mac)
10187 BWN_READ_2(mac, BWN_PHYVER);
10188 BWN_WRITE_4(mac, BWN_MACCTL,
10189 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10192 static struct bwn_pio_txqueue *
10193 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10194 struct bwn_pio_txpkt **pack)
10196 struct bwn_pio *pio = &mac->mac_method.pio;
10197 struct bwn_pio_txqueue *tq = NULL;
10198 unsigned int index;
10200 switch (cookie & 0xf000) {
10202 tq = &pio->wme[WME_AC_BK];
10205 tq = &pio->wme[WME_AC_BE];
10208 tq = &pio->wme[WME_AC_VI];
10211 tq = &pio->wme[WME_AC_VO];
10217 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10220 index = (cookie & 0x0fff);
10221 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10222 if (index >= N(tq->tq_pkts))
10224 *pack = &tq->tq_pkts[index];
10225 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10230 bwn_txpwr(void *arg, int npending)
10232 struct bwn_mac *mac = arg;
10233 struct bwn_softc *sc = mac->mac_sc;
10236 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10237 mac->mac_phy.set_txpwr != NULL)
10238 mac->mac_phy.set_txpwr(mac);
10243 bwn_task_15s(struct bwn_mac *mac)
10247 if (mac->mac_fw.opensource) {
10248 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10250 bwn_restart(mac, "fw watchdog");
10253 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10255 if (mac->mac_phy.task_15s)
10256 mac->mac_phy.task_15s(mac);
10258 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10262 bwn_task_30s(struct bwn_mac *mac)
10265 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10267 mac->mac_noise.noi_running = 1;
10268 mac->mac_noise.noi_nsamples = 0;
10270 bwn_noise_gensample(mac);
10274 bwn_task_60s(struct bwn_mac *mac)
10277 if (mac->mac_phy.task_60s)
10278 mac->mac_phy.task_60s(mac);
10279 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10283 bwn_tasks(void *arg)
10285 struct bwn_mac *mac = arg;
10286 struct bwn_softc *sc = mac->mac_sc;
10288 BWN_ASSERT_LOCKED(sc);
10289 if (mac->mac_status != BWN_MAC_STATUS_STARTED)
10292 if (mac->mac_task_state % 4 == 0)
10294 if (mac->mac_task_state % 2 == 0)
10298 mac->mac_task_state++;
10299 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10303 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10305 struct bwn_softc *sc = mac->mac_sc;
10307 KASSERT(a == 0, ("not support APHY\n"));
10309 switch (plcp->o.raw[0] & 0xf) {
10311 return (BWN_OFDM_RATE_6MB);
10313 return (BWN_OFDM_RATE_9MB);
10315 return (BWN_OFDM_RATE_12MB);
10317 return (BWN_OFDM_RATE_18MB);
10319 return (BWN_OFDM_RATE_24MB);
10321 return (BWN_OFDM_RATE_36MB);
10323 return (BWN_OFDM_RATE_48MB);
10325 return (BWN_OFDM_RATE_54MB);
10327 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10328 plcp->o.raw[0] & 0xf);
10333 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10335 struct bwn_softc *sc = mac->mac_sc;
10337 switch (plcp->o.raw[0]) {
10339 return (BWN_CCK_RATE_1MB);
10341 return (BWN_CCK_RATE_2MB);
10343 return (BWN_CCK_RATE_5MB);
10345 return (BWN_CCK_RATE_11MB);
10347 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10352 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10353 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10354 int rssi, int noise)
10356 struct bwn_softc *sc = mac->mac_sc;
10357 const struct ieee80211_frame_min *wh;
10359 uint16_t low_mactime_now;
10361 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10362 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10364 wh = mtod(m, const struct ieee80211_frame_min *);
10365 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
10366 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10368 bwn_tsf_read(mac, &tsf);
10369 low_mactime_now = tsf;
10370 tsf = tsf & ~0xffffULL;
10371 tsf += le16toh(rxhdr->mac_time);
10372 if (low_mactime_now < le16toh(rxhdr->mac_time))
10375 sc->sc_rx_th.wr_tsf = tsf;
10376 sc->sc_rx_th.wr_rate = rate;
10377 sc->sc_rx_th.wr_antsignal = rssi;
10378 sc->sc_rx_th.wr_antnoise = noise;
10382 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10384 uint32_t low, high;
10386 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10387 ("%s:%d: fail", __func__, __LINE__));
10389 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10390 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10397 bwn_dma_attach(struct bwn_mac *mac)
10399 struct bwn_dma *dma = &mac->mac_method.dma;
10400 struct bwn_softc *sc = mac->mac_sc;
10401 bus_addr_t lowaddr = 0;
10404 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10407 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10409 mac->mac_flags |= BWN_MAC_FLAG_DMA;
10411 dma->dmatype = bwn_dma_gettype(mac);
10412 if (dma->dmatype == BWN_DMA_30BIT)
10413 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10414 else if (dma->dmatype == BWN_DMA_32BIT)
10415 lowaddr = BUS_SPACE_MAXADDR_32BIT;
10417 lowaddr = BUS_SPACE_MAXADDR;
10420 * Create top level DMA tag
10422 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
10423 BWN_ALIGN, 0, /* alignment, bounds */
10424 lowaddr, /* lowaddr */
10425 BUS_SPACE_MAXADDR, /* highaddr */
10426 NULL, NULL, /* filter, filterarg */
10427 MAXBSIZE, /* maxsize */
10428 BUS_SPACE_UNRESTRICTED, /* nsegments */
10429 BUS_SPACE_MAXSIZE, /* maxsegsize */
10431 NULL, NULL, /* lockfunc, lockarg */
10432 &dma->parent_dtag);
10434 device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10439 * Create TX/RX mbuf DMA tag
10441 error = bus_dma_tag_create(dma->parent_dtag,
10449 BUS_SPACE_MAXSIZE_32BIT,
10454 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10457 error = bus_dma_tag_create(dma->parent_dtag,
10465 BUS_SPACE_MAXSIZE_32BIT,
10470 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10474 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10475 if (!dma->wme[WME_AC_BK])
10478 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10479 if (!dma->wme[WME_AC_BE])
10482 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10483 if (!dma->wme[WME_AC_VI])
10486 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10487 if (!dma->wme[WME_AC_VO])
10490 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10493 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10499 fail7: bwn_dma_ringfree(&dma->mcast);
10500 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10501 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10502 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10503 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10504 fail2: bus_dma_tag_destroy(dma->txbuf_dtag);
10505 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag);
10506 fail0: bus_dma_tag_destroy(dma->parent_dtag);
10510 static struct bwn_dma_ring *
10511 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10512 uint16_t cookie, int *slot)
10514 struct bwn_dma *dma = &mac->mac_method.dma;
10515 struct bwn_dma_ring *dr;
10516 struct bwn_softc *sc = mac->mac_sc;
10518 BWN_ASSERT_LOCKED(mac->mac_sc);
10520 switch (cookie & 0xf000) {
10522 dr = dma->wme[WME_AC_BK];
10525 dr = dma->wme[WME_AC_BE];
10528 dr = dma->wme[WME_AC_VI];
10531 dr = dma->wme[WME_AC_VO];
10539 ("invalid cookie value %d", cookie & 0xf000));
10541 *slot = (cookie & 0x0fff);
10542 if (*slot < 0 || *slot >= dr->dr_numslots) {
10544 * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10545 * that it occurs events which have same H/W sequence numbers.
10546 * When it's occurred just prints a WARNING msgs and ignores.
10548 KASSERT(status->seq == dma->lastseq,
10549 ("%s:%d: fail", __func__, __LINE__));
10550 device_printf(sc->sc_dev,
10551 "out of slot ranges (0 < %d < %d)\n", *slot,
10555 dma->lastseq = status->seq;
10560 bwn_dma_stop(struct bwn_mac *mac)
10562 struct bwn_dma *dma;
10564 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10566 dma = &mac->mac_method.dma;
10568 bwn_dma_ringstop(&dma->rx);
10569 bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10570 bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10571 bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10572 bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10573 bwn_dma_ringstop(&dma->mcast);
10577 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10583 bwn_dma_cleanup(*dr);
10587 bwn_pio_stop(struct bwn_mac *mac)
10589 struct bwn_pio *pio;
10591 if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10593 pio = &mac->mac_method.pio;
10595 bwn_destroy_queue_tx(&pio->mcast);
10596 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10597 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10598 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10599 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10603 bwn_led_attach(struct bwn_mac *mac)
10605 struct bwn_softc *sc = mac->mac_sc;
10606 const uint8_t *led_act = NULL;
10607 uint16_t val[BWN_LED_MAX];
10610 sc->sc_led_idle = (2350 * hz) / 1000;
10611 sc->sc_led_blink = 1;
10613 for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10614 if (siba_get_pci_subvendor(sc->sc_dev) ==
10615 bwn_vendor_led_act[i].vid) {
10616 led_act = bwn_vendor_led_act[i].led_act;
10620 if (led_act == NULL)
10621 led_act = bwn_default_led_act;
10623 val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10624 val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10625 val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10626 val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10628 for (i = 0; i < BWN_LED_MAX; ++i) {
10629 struct bwn_led *led = &sc->sc_leds[i];
10631 if (val[i] == 0xff) {
10632 led->led_act = led_act[i];
10634 if (val[i] & BWN_LED_ACT_LOW)
10635 led->led_flags |= BWN_LED_F_ACTLOW;
10636 led->led_act = val[i] & BWN_LED_ACT_MASK;
10638 led->led_mask = (1 << i);
10640 if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10641 led->led_act == BWN_LED_ACT_BLINK_POLL ||
10642 led->led_act == BWN_LED_ACT_BLINK) {
10643 led->led_flags |= BWN_LED_F_BLINK;
10644 if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10645 led->led_flags |= BWN_LED_F_POLLABLE;
10646 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10647 led->led_flags |= BWN_LED_F_SLOW;
10649 if (sc->sc_blink_led == NULL) {
10650 sc->sc_blink_led = led;
10651 if (led->led_flags & BWN_LED_F_SLOW)
10652 BWN_LED_SLOWDOWN(sc->sc_led_idle);
10656 DPRINTF(sc, BWN_DEBUG_LED,
10657 "%dth led, act %d, lowact %d\n", i,
10658 led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10660 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
10663 static __inline uint16_t
10664 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10667 if (led->led_flags & BWN_LED_F_ACTLOW)
10670 val |= led->led_mask;
10672 val &= ~led->led_mask;
10677 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10679 struct bwn_softc *sc = mac->mac_sc;
10680 struct ifnet *ifp = sc->sc_ifp;
10681 struct ieee80211com *ic = ifp->if_l2com;
10685 if (nstate == IEEE80211_S_INIT) {
10686 callout_stop(&sc->sc_led_blink_ch);
10687 sc->sc_led_blinking = 0;
10690 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
10693 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10694 for (i = 0; i < BWN_LED_MAX; ++i) {
10695 struct bwn_led *led = &sc->sc_leds[i];
10698 if (led->led_act == BWN_LED_ACT_UNKN ||
10699 led->led_act == BWN_LED_ACT_NULL)
10702 if ((led->led_flags & BWN_LED_F_BLINK) &&
10703 nstate != IEEE80211_S_INIT)
10706 switch (led->led_act) {
10707 case BWN_LED_ACT_ON: /* Always on */
10710 case BWN_LED_ACT_OFF: /* Always off */
10711 case BWN_LED_ACT_5GHZ: /* TODO: 11A */
10717 case IEEE80211_S_INIT:
10720 case IEEE80211_S_RUN:
10721 if (led->led_act == BWN_LED_ACT_11G &&
10722 ic->ic_curmode != IEEE80211_MODE_11G)
10726 if (led->led_act == BWN_LED_ACT_ASSOC)
10733 val = bwn_led_onoff(led, val, on);
10735 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10739 bwn_led_event(struct bwn_mac *mac, int event)
10741 struct bwn_softc *sc = mac->mac_sc;
10742 struct bwn_led *led = sc->sc_blink_led;
10745 if (event == BWN_LED_EVENT_POLL) {
10746 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10748 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10752 sc->sc_led_ticks = ticks;
10753 if (sc->sc_led_blinking)
10757 case BWN_LED_EVENT_RX:
10758 rate = sc->sc_rx_rate;
10760 case BWN_LED_EVENT_TX:
10761 rate = sc->sc_tx_rate;
10763 case BWN_LED_EVENT_POLL:
10767 panic("unknown LED event %d\n", event);
10770 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10771 bwn_led_duration[rate].off_dur);
10775 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10777 struct bwn_softc *sc = mac->mac_sc;
10778 struct bwn_led *led = sc->sc_blink_led;
10781 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10782 val = bwn_led_onoff(led, val, 1);
10783 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10785 if (led->led_flags & BWN_LED_F_SLOW) {
10786 BWN_LED_SLOWDOWN(on_dur);
10787 BWN_LED_SLOWDOWN(off_dur);
10790 sc->sc_led_blinking = 1;
10791 sc->sc_led_blink_offdur = off_dur;
10793 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10797 bwn_led_blink_next(void *arg)
10799 struct bwn_mac *mac = arg;
10800 struct bwn_softc *sc = mac->mac_sc;
10803 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10804 val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10805 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10807 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10808 bwn_led_blink_end, mac);
10812 bwn_led_blink_end(void *arg)
10814 struct bwn_mac *mac = arg;
10815 struct bwn_softc *sc = mac->mac_sc;
10817 sc->sc_led_blinking = 0;
10821 bwn_suspend(device_t dev)
10823 struct bwn_softc *sc = device_get_softc(dev);
10830 bwn_resume(device_t dev)
10832 struct bwn_softc *sc = device_get_softc(dev);
10833 struct ifnet *ifp = sc->sc_ifp;
10835 if (ifp->if_flags & IFF_UP)
10841 bwn_rfswitch(void *arg)
10843 struct bwn_softc *sc = arg;
10844 struct bwn_mac *mac = sc->sc_curmac;
10845 int cur = 0, prev = 0;
10847 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10848 ("%s: invalid MAC status %d", __func__, mac->mac_status));
10850 if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10851 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10852 & BWN_RF_HWENABLED_HI_MASK))
10855 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10856 & BWN_RF_HWENABLED_LO_MASK)
10860 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10865 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10867 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10869 device_printf(sc->sc_dev,
10870 "status of RF switch is changed to %s\n",
10871 cur ? "ON" : "OFF");
10872 if (cur != mac->mac_phy.rf_on) {
10874 bwn_rf_turnon(mac);
10876 bwn_rf_turnoff(mac);
10880 callout_schedule(&sc->sc_rfswitch_ch, hz);
10884 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10886 struct bwn_phy *phy = &mac->mac_phy;
10887 struct bwn_phy_lp *plp = &phy->phy_lp;
10889 plp->plp_antenna = BWN_ANT_DEFAULT;
10893 bwn_phy_lp_init(struct bwn_mac *mac)
10895 static const struct bwn_stxtable tables[] = {
10896 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10897 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff },
10898 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff },
10899 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10900 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f },
10901 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10902 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 },
10903 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f },
10904 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10905 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 },
10906 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10907 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 },
10908 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f },
10909 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f },
10910 { 2, 11, 0x40, 0, 0x0f }
10912 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10913 struct bwn_softc *sc = mac->mac_sc;
10914 const struct bwn_stxtable *st;
10915 struct ifnet *ifp = sc->sc_ifp;
10916 struct ieee80211com *ic = ifp->if_l2com;
10920 bwn_phy_lp_readsprom(mac); /* XXX bad place */
10921 bwn_phy_lp_bbinit(mac);
10923 /* initialize RF */
10924 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10926 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10929 if (mac->mac_phy.rf_ver == 0x2062)
10930 bwn_phy_lp_b2062_init(mac);
10932 bwn_phy_lp_b2063_init(mac);
10934 /* synchronize stx table. */
10935 for (i = 0; i < N(tables); i++) {
10937 tmp = BWN_RF_READ(mac, st->st_rfaddr);
10938 tmp >>= st->st_rfshift;
10939 tmp <<= st->st_physhift;
10940 BWN_PHY_SETMASK(mac,
10941 BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10942 ~(st->st_mask << st->st_physhift), tmp);
10945 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10946 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10950 if (mac->mac_phy.rev >= 2)
10951 bwn_phy_lp_rxcal_r2(mac);
10952 else if (!plp->plp_rccap) {
10953 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10954 bwn_phy_lp_rccal_r12(mac);
10956 bwn_phy_lp_set_rccap(mac);
10958 error = bwn_phy_lp_switch_channel(mac, 7);
10960 device_printf(sc->sc_dev,
10961 "failed to change channel 7 (%d)\n", error);
10962 bwn_phy_lp_txpctl_init(mac);
10963 bwn_phy_lp_calib(mac);
10968 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10971 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10972 return (BWN_READ_2(mac, BWN_PHYDATA));
10976 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10979 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10980 BWN_WRITE_2(mac, BWN_PHYDATA, value);
10984 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10988 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10989 BWN_WRITE_2(mac, BWN_PHYDATA,
10990 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10994 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10997 KASSERT(reg != 1, ("unaccessible register %d", reg));
10998 if (mac->mac_phy.rev < 2 && reg != 0x4001)
11000 if (mac->mac_phy.rev >= 2)
11002 BWN_WRITE_2(mac, BWN_RFCTL, reg);
11003 return BWN_READ_2(mac, BWN_RFDATALO);
11007 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
11010 KASSERT(reg != 1, ("unaccessible register %d", reg));
11011 BWN_WRITE_2(mac, BWN_RFCTL, reg);
11012 BWN_WRITE_2(mac, BWN_RFDATALO, value);
11016 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
11020 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
11021 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
11022 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
11026 if (mac->mac_phy.rev >= 2) {
11027 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
11028 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
11029 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
11030 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
11031 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
11035 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
11036 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
11037 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
11038 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
11042 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
11044 struct bwn_phy *phy = &mac->mac_phy;
11045 struct bwn_phy_lp *plp = &phy->phy_lp;
11048 if (phy->rf_ver == 0x2063) {
11049 error = bwn_phy_lp_b2063_switch_channel(mac, chan);
11053 error = bwn_phy_lp_b2062_switch_channel(mac, chan);
11056 bwn_phy_lp_set_anafilter(mac, chan);
11057 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
11060 plp->plp_chan = chan;
11061 BWN_WRITE_2(mac, BWN_CHANNEL, chan);
11066 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
11068 struct bwn_softc *sc = mac->mac_sc;
11069 struct ifnet *ifp = sc->sc_ifp;
11070 struct ieee80211com *ic = ifp->if_l2com;
11072 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
11076 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
11078 struct bwn_phy *phy = &mac->mac_phy;
11079 struct bwn_phy_lp *plp = &phy->phy_lp;
11081 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
11084 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
11085 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
11086 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
11087 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
11088 plp->plp_antenna = antenna;
11092 bwn_phy_lp_task_60s(struct bwn_mac *mac)
11095 bwn_phy_lp_calib(mac);
11099 bwn_phy_lp_readsprom(struct bwn_mac *mac)
11101 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11102 struct bwn_softc *sc = mac->mac_sc;
11103 struct ifnet *ifp = sc->sc_ifp;
11104 struct ieee80211com *ic = ifp->if_l2com;
11106 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11107 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
11108 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
11109 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
11110 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
11111 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
11112 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
11116 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
11117 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
11118 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
11119 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
11120 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
11121 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
11122 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
11123 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
11127 bwn_phy_lp_bbinit(struct bwn_mac *mac)
11130 bwn_phy_lp_tblinit(mac);
11131 if (mac->mac_phy.rev >= 2)
11132 bwn_phy_lp_bbinit_r2(mac);
11134 bwn_phy_lp_bbinit_r01(mac);
11138 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
11140 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
11141 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
11142 struct bwn_softc *sc = mac->mac_sc;
11143 struct ifnet *ifp = sc->sc_ifp;
11144 struct ieee80211com *ic = ifp->if_l2com;
11146 bwn_phy_lp_set_txgain(mac,
11147 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
11148 bwn_phy_lp_set_bbmult(mac, 150);
11152 bwn_phy_lp_calib(struct bwn_mac *mac)
11154 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11155 struct bwn_softc *sc = mac->mac_sc;
11156 struct ifnet *ifp = sc->sc_ifp;
11157 struct ieee80211com *ic = ifp->if_l2com;
11158 const struct bwn_rxcompco *rc = NULL;
11159 struct bwn_txgain ogain;
11160 int i, omode, oafeovr, orf, obbmult;
11161 uint8_t mode, fc = 0;
11163 if (plp->plp_chanfullcal != plp->plp_chan) {
11164 plp->plp_chanfullcal = plp->plp_chan;
11168 bwn_mac_suspend(mac);
11170 /* BlueTooth Coexistance Override */
11171 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
11172 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
11174 if (mac->mac_phy.rev >= 2)
11175 bwn_phy_lp_digflt_save(mac);
11176 bwn_phy_lp_get_txpctlmode(mac);
11177 mode = plp->plp_txpctlmode;
11178 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11179 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
11180 bwn_phy_lp_bugfix(mac);
11181 if (mac->mac_phy.rev >= 2 && fc == 1) {
11182 bwn_phy_lp_get_txpctlmode(mac);
11183 omode = plp->plp_txpctlmode;
11184 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11186 ogain = bwn_phy_lp_get_txgain(mac);
11187 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11188 obbmult = bwn_phy_lp_get_bbmult(mac);
11189 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11191 bwn_phy_lp_set_txgain(mac, &ogain);
11192 bwn_phy_lp_set_bbmult(mac, obbmult);
11193 bwn_phy_lp_set_txpctlmode(mac, omode);
11194 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11196 bwn_phy_lp_set_txpctlmode(mac, mode);
11197 if (mac->mac_phy.rev >= 2)
11198 bwn_phy_lp_digflt_restore(mac);
11200 /* do RX IQ Calculation; assumes that noise is true. */
11201 if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11202 for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11203 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11204 rc = &bwn_rxcompco_5354[i];
11206 } else if (mac->mac_phy.rev >= 2)
11207 rc = &bwn_rxcompco_r2;
11209 for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11210 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11211 rc = &bwn_rxcompco_r12[i];
11217 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11218 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11220 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11222 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11223 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11224 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11226 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11227 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11230 bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11231 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11232 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11233 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11234 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11235 bwn_phy_lp_set_deaf(mac, 0);
11236 /* XXX no checking return value? */
11237 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11238 bwn_phy_lp_clear_deaf(mac, 0);
11239 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11240 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11241 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11243 /* disable RX GAIN override. */
11244 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11245 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11246 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11247 if (mac->mac_phy.rev >= 2) {
11248 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11249 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11250 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11251 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11254 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11257 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11258 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11260 bwn_mac_enable(mac);
11264 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11268 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11272 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11273 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11277 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11279 static const struct bwn_b206x_chan *bc = NULL;
11280 struct bwn_softc *sc = mac->mac_sc;
11281 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11283 uint16_t old, scale, tmp16;
11286 for (i = 0; i < N(bwn_b2063_chantable); i++) {
11287 if (bwn_b2063_chantable[i].bc_chan == chan) {
11288 bc = &bwn_b2063_chantable[i];
11295 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11296 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11297 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11298 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11299 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11300 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11301 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11302 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11303 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11304 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11305 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11306 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11308 old = BWN_RF_READ(mac, BWN_B2063_COM15);
11309 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11311 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11312 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11313 freqref = freqxtal * 3;
11314 div = (freqxtal <= 26000000 ? 1 : 2);
11315 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11316 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11317 999999) / 1000000) + 1;
11319 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11320 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11321 0xfff8, timeout >> 2);
11322 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11323 0xff9f,timeout << 5);
11324 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11326 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11327 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11328 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11330 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11331 (timeoutref + 1)) - 1;
11332 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11334 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11336 tmp[0] = ((val[2] * 62500) / freqref) << 4;
11337 tmp[1] = ((val[2] * 62500) % freqref) << 4;
11338 while (tmp[1] >= freqref) {
11342 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11343 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11344 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11345 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11346 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11348 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11349 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11350 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11351 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11353 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11354 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11356 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11358 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11361 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11363 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11364 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11366 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11371 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11372 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11374 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11375 if (freqxtal > 26000000)
11376 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11378 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11381 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11383 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11385 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11387 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11389 /* VCO Calibration */
11390 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11391 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11392 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11394 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11396 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11398 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11400 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11402 BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11407 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11409 struct bwn_softc *sc = mac->mac_sc;
11410 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11411 const struct bwn_b206x_chan *bc = NULL;
11412 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11416 for (i = 0; i < N(bwn_b2062_chantable); i++) {
11417 if (bwn_b2062_chantable[i].bc_chan == chan) {
11418 bc = &bwn_b2062_chantable[i];
11426 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11427 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11428 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11429 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11430 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11431 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11432 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11433 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11434 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11435 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11437 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11438 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11439 bwn_phy_lp_b2062_reset_pllbias(mac);
11440 tmp[0] = freqxtal / 1000;
11441 tmp[1] = plp->plp_div * 1000;
11442 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11443 if (ieee80211_ieee2mhz(chan, 0) < 4000)
11445 tmp[3] = 48 * tmp[0];
11446 tmp[5] = tmp[2] / tmp[3];
11447 tmp[6] = tmp[2] % tmp[3];
11448 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11449 tmp[4] = tmp[6] * 0x100;
11450 tmp[5] = tmp[4] / tmp[3];
11451 tmp[6] = tmp[4] % tmp[3];
11452 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11453 tmp[4] = tmp[6] * 0x100;
11454 tmp[5] = tmp[4] / tmp[3];
11455 tmp[6] = tmp[4] % tmp[3];
11456 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11457 tmp[4] = tmp[6] * 0x100;
11458 tmp[5] = tmp[4] / tmp[3];
11459 tmp[6] = tmp[4] % tmp[3];
11460 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11461 tmp[5] + ((2 * tmp[6]) / tmp[3]));
11462 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11463 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11464 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11465 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11467 bwn_phy_lp_b2062_vco_calib(mac);
11468 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11469 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11470 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11471 bwn_phy_lp_b2062_reset_pllbias(mac);
11472 bwn_phy_lp_b2062_vco_calib(mac);
11473 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11474 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11478 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11483 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11485 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11486 uint16_t tmp = (channel == 14);
11488 if (mac->mac_phy.rev < 2) {
11489 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11490 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11491 bwn_phy_lp_set_rccap(mac);
11495 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11499 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11501 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11502 struct bwn_softc *sc = mac->mac_sc;
11503 struct ifnet *ifp = sc->sc_ifp;
11504 struct ieee80211com *ic = ifp->if_l2com;
11505 uint16_t iso, tmp[3];
11507 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11509 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11510 iso = plp->plp_txisoband_m;
11511 else if (freq <= 5320)
11512 iso = plp->plp_txisoband_l;
11513 else if (freq <= 5700)
11514 iso = plp->plp_txisoband_m;
11516 iso = plp->plp_txisoband_h;
11518 tmp[0] = ((iso - 26) / 12) << 12;
11519 tmp[1] = tmp[0] + 0x1000;
11520 tmp[2] = tmp[0] + 0x2000;
11522 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11523 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11527 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11529 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11531 static const uint16_t addr[] = {
11532 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11533 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11534 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11535 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11536 BWN_PHY_OFDM(0xcf),
11538 static const uint16_t val[] = {
11539 0xde5e, 0xe832, 0xe331, 0x4d26,
11540 0x0026, 0x1420, 0x0020, 0xfe08,
11544 for (i = 0; i < N(addr); i++) {
11545 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11546 BWN_PHY_WRITE(mac, addr[i], val[i]);
11551 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11553 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11554 struct bwn_softc *sc = mac->mac_sc;
11557 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11558 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11559 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11560 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11562 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11563 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11565 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11566 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11569 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11570 device_printf(sc->sc_dev, "unknown command mode\n");
11576 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11578 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11582 bwn_phy_lp_get_txpctlmode(mac);
11583 old = plp->plp_txpctlmode;
11586 plp->plp_txpctlmode = mode;
11588 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11589 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11591 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11592 0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11594 /* disable TX GAIN override */
11595 if (mac->mac_phy.rev < 2)
11596 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11598 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11599 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11601 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11603 plp->plp_txpwridx = -1;
11605 if (mac->mac_phy.rev >= 2) {
11606 if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11607 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11609 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11612 /* writes TX Power Control mode */
11613 switch (plp->plp_txpctlmode) {
11614 case BWN_PHYLP_TXPCTL_OFF:
11615 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11617 case BWN_PHYLP_TXPCTL_ON_HW:
11618 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11620 case BWN_PHYLP_TXPCTL_ON_SW:
11621 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11625 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11627 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11628 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11632 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11634 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11635 struct bwn_softc *sc = mac->mac_sc;
11636 const unsigned int size = 256;
11637 struct bwn_txgain tg;
11638 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11639 uint16_t tssinpt, tssiidx, value[2];
11643 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
11644 M_NOWAIT | M_ZERO);
11645 if (tabs == NULL) {
11646 device_printf(sc->sc_dev, "failed to allocate buffer.\n");
11650 bwn_phy_lp_get_txpctlmode(mac);
11651 mode = plp->plp_txpctlmode;
11652 txpwridx = plp->plp_txpwridx;
11653 tssinpt = plp->plp_tssinpt;
11654 tssiidx = plp->plp_tssiidx;
11656 bwn_tab_read_multi(mac,
11657 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11658 BWN_TAB_4(7, 0x140), size, tabs);
11660 bwn_phy_lp_tblinit(mac);
11661 bwn_phy_lp_bbinit(mac);
11662 bwn_phy_lp_txpctl_init(mac);
11663 bwn_phy_lp_rf_onoff(mac, 1);
11664 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11666 bwn_tab_write_multi(mac,
11667 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11668 BWN_TAB_4(7, 0x140), size, tabs);
11670 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11671 plp->plp_tssinpt = tssinpt;
11672 plp->plp_tssiidx = tssiidx;
11673 bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11674 if (txpwridx != -1) {
11675 /* set TX power by index */
11676 plp->plp_txpwridx = txpwridx;
11677 bwn_phy_lp_get_txpctlmode(mac);
11678 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11679 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11680 if (mac->mac_phy.rev >= 2) {
11681 rxcomp = bwn_tab_read(mac,
11682 BWN_TAB_4(7, txpwridx + 320));
11683 txgain = bwn_tab_read(mac,
11684 BWN_TAB_4(7, txpwridx + 192));
11685 tg.tg_pad = (txgain >> 16) & 0xff;
11686 tg.tg_gm = txgain & 0xff;
11687 tg.tg_pga = (txgain >> 8) & 0xff;
11688 tg.tg_dac = (rxcomp >> 28) & 0xff;
11689 bwn_phy_lp_set_txgain(mac, &tg);
11691 rxcomp = bwn_tab_read(mac,
11692 BWN_TAB_4(10, txpwridx + 320));
11693 txgain = bwn_tab_read(mac,
11694 BWN_TAB_4(10, txpwridx + 192));
11695 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11696 0xf800, (txgain >> 4) & 0x7fff);
11697 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11698 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11700 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11703 value[0] = (rxcomp >> 10) & 0x3ff;
11704 value[1] = rxcomp & 0x3ff;
11705 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11707 coeff = bwn_tab_read(mac,
11708 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11709 BWN_TAB_4(10, txpwridx + 448));
11710 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11711 if (mac->mac_phy.rev >= 2) {
11712 rfpwr = bwn_tab_read(mac,
11713 BWN_TAB_4(7, txpwridx + 576));
11714 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11717 bwn_phy_lp_set_txgain_override(mac);
11719 if (plp->plp_rccap)
11720 bwn_phy_lp_set_rccap(mac);
11721 bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11722 bwn_phy_lp_set_txpctlmode(mac, mode);
11723 free(tabs, M_DEVBUF);
11727 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11729 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11731 static const uint16_t addr[] = {
11732 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11733 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11734 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11735 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11736 BWN_PHY_OFDM(0xcf),
11739 for (i = 0; i < N(addr); i++)
11740 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11744 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11746 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11748 if (mac->mac_phy.rev < 2) {
11749 bwn_phy_lp_tblinit_r01(mac);
11750 bwn_phy_lp_tblinit_txgain(mac);
11751 bwn_phy_lp_set_gaintbl(mac, freq);
11755 bwn_phy_lp_tblinit_r2(mac);
11756 bwn_phy_lp_tblinit_txgain(mac);
11764 struct bwn_smpair {
11771 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11773 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11774 struct bwn_softc *sc = mac->mac_sc;
11775 struct ifnet *ifp = sc->sc_ifp;
11776 struct ieee80211com *ic = ifp->if_l2com;
11777 static const struct bwn_wpair v1[] = {
11778 { BWN_PHY_AFE_DAC_CTL, 0x50 },
11779 { BWN_PHY_AFE_CTL, 0x8800 },
11780 { BWN_PHY_AFE_CTL_OVR, 0 },
11781 { BWN_PHY_AFE_CTL_OVRVAL, 0 },
11782 { BWN_PHY_RF_OVERRIDE_0, 0 },
11783 { BWN_PHY_RF_OVERRIDE_2, 0 },
11784 { BWN_PHY_OFDM(0xf9), 0 },
11785 { BWN_PHY_TR_LOOKUP_1, 0 }
11787 static const struct bwn_smpair v2[] = {
11788 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11789 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11790 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11791 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11792 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11794 static const struct bwn_smpair v3[] = {
11795 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11796 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11797 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11798 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11799 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11800 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11801 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11802 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11803 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11804 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11809 for (i = 0; i < N(v1); i++)
11810 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11811 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11812 for (i = 0; i < N(v2); i++)
11813 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11815 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11816 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11817 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11818 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11819 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11820 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11822 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11824 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11825 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11826 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11827 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11828 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11829 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11830 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11831 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11832 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11833 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11834 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11835 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11836 (siba_get_chiprev(sc->sc_dev) == 0)) {
11837 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11838 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11840 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11841 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11843 for (i = 0; i < N(v3); i++)
11844 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11845 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11846 (siba_get_chiprev(sc->sc_dev) == 0)) {
11847 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11848 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11851 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11852 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11853 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11854 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11855 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11856 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11857 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11859 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11861 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11862 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11863 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11864 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11865 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11866 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11867 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11868 0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11869 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11871 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11872 (siba_get_chiprev(sc->sc_dev) == 0)) {
11873 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11874 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11875 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11878 bwn_phy_lp_digflt_save(mac);
11882 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11884 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11885 struct bwn_softc *sc = mac->mac_sc;
11886 struct ifnet *ifp = sc->sc_ifp;
11887 struct ieee80211com *ic = ifp->if_l2com;
11888 static const struct bwn_smpair v1[] = {
11889 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11890 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11891 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11892 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11893 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11894 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11895 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11897 static const struct bwn_smpair v2[] = {
11898 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11899 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11900 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11901 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11902 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11903 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11904 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11905 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11906 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11907 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11908 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11909 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11910 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11911 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11912 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11913 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11915 static const struct bwn_smpair v3[] = {
11916 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11917 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11918 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11919 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11920 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11921 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11922 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11923 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11925 static const struct bwn_smpair v4[] = {
11926 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11927 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11928 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11929 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11930 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11931 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11932 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11933 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11935 static const struct bwn_smpair v5[] = {
11936 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11937 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11938 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11939 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11940 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11941 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11942 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11943 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11946 uint16_t tmp, tmp2;
11948 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11949 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11950 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11951 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11952 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11953 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11954 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11955 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11956 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11957 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11958 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11959 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11960 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11961 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11962 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11963 for (i = 0; i < N(v1); i++)
11964 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11965 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11966 0xff00, plp->plp_rxpwroffset);
11967 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11968 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11969 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11970 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11971 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11972 if (mac->mac_phy.rev == 0)
11973 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11975 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11977 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11978 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11979 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11981 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11982 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11983 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11984 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11986 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11987 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11988 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11989 0xfff9, (plp->plp_bxarch << 1));
11990 if (mac->mac_phy.rev == 1 &&
11991 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11992 for (i = 0; i < N(v2); i++)
11993 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11995 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11996 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11997 ((mac->mac_phy.rev == 0) &&
11998 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11999 for (i = 0; i < N(v3); i++)
12000 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
12002 } else if (mac->mac_phy.rev == 1 ||
12003 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
12004 for (i = 0; i < N(v4); i++)
12005 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
12008 for (i = 0; i < N(v5); i++)
12009 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
12012 if (mac->mac_phy.rev == 1 &&
12013 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
12014 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
12015 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
12016 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
12017 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
12019 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
12020 (siba_get_chipid(sc->sc_dev) == 0x5354) &&
12021 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
12022 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
12023 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
12024 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
12025 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
12027 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12028 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
12029 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
12030 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
12031 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
12032 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
12033 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
12034 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
12035 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
12037 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
12038 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
12040 if (mac->mac_phy.rev == 1) {
12041 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
12042 tmp2 = (tmp & 0x03e0) >> 5;
12044 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
12045 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
12046 tmp2 = (tmp & 0x1f00) >> 8;
12048 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
12049 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
12050 tmp2 = tmp & 0x00ff;
12052 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
12056 struct bwn_b2062_freq {
12062 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
12064 #define CALC_CTL7(freq, div) \
12065 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
12066 #define CALC_CTL18(freq, div) \
12067 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
12068 #define CALC_CTL19(freq, div) \
12069 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
12070 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12071 struct bwn_softc *sc = mac->mac_sc;
12072 struct ifnet *ifp = sc->sc_ifp;
12073 struct ieee80211com *ic = ifp->if_l2com;
12074 static const struct bwn_b2062_freq freqdata_tab[] = {
12075 { 12000, { 6, 6, 6, 6, 10, 6 } },
12076 { 13000, { 4, 4, 4, 4, 11, 7 } },
12077 { 14400, { 3, 3, 3, 3, 12, 7 } },
12078 { 16200, { 3, 3, 3, 3, 13, 8 } },
12079 { 18000, { 2, 2, 2, 2, 14, 8 } },
12080 { 19200, { 1, 1, 1, 1, 14, 9 } }
12082 static const struct bwn_wpair v1[] = {
12083 { BWN_B2062_N_TXCTL3, 0 },
12084 { BWN_B2062_N_TXCTL4, 0 },
12085 { BWN_B2062_N_TXCTL5, 0 },
12086 { BWN_B2062_N_TXCTL6, 0 },
12087 { BWN_B2062_N_PDNCTL0, 0x40 },
12088 { BWN_B2062_N_PDNCTL0, 0 },
12089 { BWN_B2062_N_CALIB_TS, 0x10 },
12090 { BWN_B2062_N_CALIB_TS, 0 }
12092 const struct bwn_b2062_freq *f = NULL;
12093 uint32_t xtalfreq, ref;
12096 bwn_phy_lp_b2062_tblinit(mac);
12098 for (i = 0; i < N(v1); i++)
12099 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12100 if (mac->mac_phy.rev > 0)
12101 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
12102 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
12103 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12104 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
12106 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
12108 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
12109 ("%s:%d: fail", __func__, __LINE__));
12110 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12111 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
12113 if (xtalfreq <= 30000000) {
12115 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
12118 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
12121 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
12122 CALC_CTL7(xtalfreq, plp->plp_div));
12123 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
12124 CALC_CTL18(xtalfreq, plp->plp_div));
12125 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
12126 CALC_CTL19(xtalfreq, plp->plp_div));
12128 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
12130 for (i = 0; i < N(freqdata_tab); i++) {
12131 if (ref < freqdata_tab[i].freq) {
12132 f = &freqdata_tab[i];
12137 f = &freqdata_tab[N(freqdata_tab) - 1];
12138 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
12139 ((uint16_t)(f->value[1]) << 4) | f->value[0]);
12140 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
12141 ((uint16_t)(f->value[3]) << 4) | f->value[2]);
12142 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
12143 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
12150 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
12153 bwn_phy_lp_b2063_tblinit(mac);
12154 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
12155 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
12156 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
12157 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
12158 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
12159 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
12160 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
12161 if (mac->mac_phy.rev == 2) {
12162 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
12163 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
12164 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
12166 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
12167 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
12172 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
12174 struct bwn_softc *sc = mac->mac_sc;
12175 static const struct bwn_wpair v1[] = {
12176 { BWN_B2063_RX_BB_SP8, 0x0 },
12177 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12178 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12179 { BWN_B2063_RC_CALIB_CTL2, 0x15 },
12180 { BWN_B2063_RC_CALIB_CTL3, 0x70 },
12181 { BWN_B2063_RC_CALIB_CTL4, 0x52 },
12182 { BWN_B2063_RC_CALIB_CTL5, 0x1 },
12183 { BWN_B2063_RC_CALIB_CTL1, 0x7d }
12185 static const struct bwn_wpair v2[] = {
12186 { BWN_B2063_TX_BB_SP3, 0x0 },
12187 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12188 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12189 { BWN_B2063_RC_CALIB_CTL2, 0x55 },
12190 { BWN_B2063_RC_CALIB_CTL3, 0x76 }
12192 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12196 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12198 for (i = 0; i < 2; i++)
12199 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12200 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12201 for (i = 2; i < N(v1); i++)
12202 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12203 for (i = 0; i < 10000; i++) {
12204 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12209 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12210 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12212 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12214 for (i = 0; i < N(v2); i++)
12215 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12216 if (freqxtal == 24000000) {
12217 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12218 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12220 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12221 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12223 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12224 for (i = 0; i < 10000; i++) {
12225 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12229 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12230 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12231 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12235 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12237 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12238 struct bwn_softc *sc = mac->mac_sc;
12239 struct bwn_phy_lp_iq_est ie;
12240 struct bwn_txgain tx_gains;
12241 static const uint32_t pwrtbl[21] = {
12242 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12243 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12244 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12245 0x0004c, 0x0002c, 0x0001a,
12247 uint32_t npwr, ipwr, sqpwr, tmp;
12248 int loopback, i, j, sum, error;
12250 uint8_t txo, bbmult, txpctlmode;
12252 error = bwn_phy_lp_switch_channel(mac, 7);
12254 device_printf(sc->sc_dev,
12255 "failed to change channel to 7 (%d)\n", error);
12256 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12257 bbmult = bwn_phy_lp_get_bbmult(mac);
12259 tx_gains = bwn_phy_lp_get_txgain(mac);
12261 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12262 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12263 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12264 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12265 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12266 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12267 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12269 bwn_phy_lp_get_txpctlmode(mac);
12270 txpctlmode = plp->plp_txpctlmode;
12271 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12274 bwn_phy_lp_set_deaf(mac, 1);
12275 bwn_phy_lp_set_trsw_over(mac, 0, 1);
12276 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12277 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12278 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12279 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12280 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12281 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12282 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12283 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12284 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12285 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12286 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12287 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12288 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12289 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12290 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12291 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12292 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12293 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12294 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12295 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12296 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12297 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12298 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12300 loopback = bwn_phy_lp_loopback(mac);
12301 if (loopback == -1)
12303 bwn_phy_lp_set_rxgain_idx(mac, loopback);
12304 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12305 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12306 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12307 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12310 memset(&ie, 0, sizeof(ie));
12311 for (i = 128; i <= 159; i++) {
12312 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12314 for (j = 5; j <= 25; j++) {
12315 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12316 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12318 sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12319 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12320 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12322 sum += ((ipwr - npwr) * (ipwr - npwr));
12323 if ((i == 128) || (sum < tmp)) {
12324 plp->plp_rccap = i;
12329 bwn_phy_lp_ddfs_turnoff(mac);
12332 bwn_phy_lp_clear_deaf(mac, 1);
12333 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12334 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12336 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12337 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12338 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12339 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12340 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12341 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12342 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12344 bwn_phy_lp_set_bbmult(mac, bbmult);
12346 bwn_phy_lp_set_txgain(mac, &tx_gains);
12347 bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12348 if (plp->plp_rccap)
12349 bwn_phy_lp_set_rccap(mac);
12353 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12355 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12356 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12358 if (mac->mac_phy.rev == 1)
12359 rc_cap = MIN(rc_cap + 5, 15);
12361 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12362 MAX(plp->plp_rccap - 4, 0x80));
12363 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12364 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12365 ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12369 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12376 for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12378 if (r << 1 >= div) {
12380 r = (r << 1) - div;
12389 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12391 struct bwn_softc *sc = mac->mac_sc;
12393 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12395 if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12396 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12397 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12399 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12405 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12408 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12409 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12414 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12416 #define FLAG_A 0x01
12417 #define FLAG_G 0x02
12418 struct bwn_softc *sc = mac->mac_sc;
12419 struct ifnet *ifp = sc->sc_ifp;
12420 struct ieee80211com *ic = ifp->if_l2com;
12421 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12422 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12423 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12424 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12425 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12426 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12427 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12428 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12429 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12430 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12431 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12432 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12433 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12434 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12435 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12436 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12437 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12438 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12439 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12440 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12441 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12442 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12443 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12444 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12445 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12446 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12447 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12448 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12449 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12450 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12451 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12452 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12453 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12454 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12455 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12456 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12457 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12458 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12459 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12460 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12461 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12462 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12463 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12464 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12465 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12466 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12467 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12468 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12470 const struct bwn_b206x_rfinit_entry *br;
12473 for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12474 br = &bwn_b2062_init_tab[i];
12475 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12476 if (br->br_flags & FLAG_G)
12477 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12479 if (br->br_flags & FLAG_A)
12480 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12488 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12490 #define FLAG_A 0x01
12491 #define FLAG_G 0x02
12492 struct bwn_softc *sc = mac->mac_sc;
12493 struct ifnet *ifp = sc->sc_ifp;
12494 struct ieee80211com *ic = ifp->if_l2com;
12495 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12496 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12497 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12498 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12499 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12500 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12501 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12502 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12503 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12504 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12505 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12506 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12507 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12508 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12509 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12510 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12511 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12512 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12513 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12514 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12515 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12516 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12517 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12518 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12519 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12520 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12521 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12522 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12523 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12524 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12525 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12526 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12527 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12528 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12529 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12530 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12531 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12532 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12533 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12534 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12535 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12536 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12537 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12539 const struct bwn_b206x_rfinit_entry *br;
12542 for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12543 br = &bwn_b2063_init_tab[i];
12544 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12545 if (br->br_flags & FLAG_G)
12546 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12548 if (br->br_flags & FLAG_A)
12549 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12557 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12558 int count, void *_data)
12561 uint32_t offset, type;
12562 uint8_t *data = _data;
12564 type = BWN_TAB_GETTYPE(typenoffset);
12565 offset = BWN_TAB_GETOFFSET(typenoffset);
12566 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12568 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12570 for (i = 0; i < count; i++) {
12573 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12576 case BWN_TAB_16BIT:
12577 *((uint16_t *)data) = BWN_PHY_READ(mac,
12578 BWN_PHY_TABLEDATALO);
12581 case BWN_TAB_32BIT:
12582 *((uint32_t *)data) = BWN_PHY_READ(mac,
12583 BWN_PHY_TABLEDATAHI);
12584 *((uint32_t *)data) <<= 16;
12585 *((uint32_t *)data) |= BWN_PHY_READ(mac,
12586 BWN_PHY_TABLEDATALO);
12590 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12596 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12597 int count, const void *_data)
12599 uint32_t offset, type, value;
12600 const uint8_t *data = _data;
12603 type = BWN_TAB_GETTYPE(typenoffset);
12604 offset = BWN_TAB_GETOFFSET(typenoffset);
12605 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12607 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12609 for (i = 0; i < count; i++) {
12614 KASSERT(!(value & ~0xff),
12615 ("%s:%d: fail", __func__, __LINE__));
12616 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12618 case BWN_TAB_16BIT:
12619 value = *((const uint16_t *)data);
12621 KASSERT(!(value & ~0xffff),
12622 ("%s:%d: fail", __func__, __LINE__));
12623 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12625 case BWN_TAB_32BIT:
12626 value = *((const uint32_t *)data);
12628 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12629 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12632 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12637 static struct bwn_txgain
12638 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12640 struct bwn_txgain tg;
12643 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12644 if (mac->mac_phy.rev < 2) {
12645 tmp = BWN_PHY_READ(mac,
12646 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12647 tg.tg_gm = tmp & 0x0007;
12648 tg.tg_pga = (tmp & 0x0078) >> 3;
12649 tg.tg_pad = (tmp & 0x780) >> 7;
12653 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12654 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12655 tg.tg_gm = tmp & 0xff;
12656 tg.tg_pga = (tmp >> 8) & 0xff;
12661 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12664 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12668 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12672 if (mac->mac_phy.rev < 2) {
12673 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12674 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12675 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12676 bwn_phy_lp_set_txgain_override(mac);
12680 pa = bwn_phy_lp_get_pa_gain(mac);
12681 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12682 (tg->tg_pga << 8) | tg->tg_gm);
12683 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12684 tg->tg_pad | (pa << 6));
12685 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12686 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12687 tg->tg_pad | (pa << 8));
12688 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12689 bwn_phy_lp_set_txgain_override(mac);
12693 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12696 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12700 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12702 uint16_t trsw = (tx << 1) | rx;
12704 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12705 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12709 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12711 struct bwn_softc *sc = mac->mac_sc;
12712 struct ifnet *ifp = sc->sc_ifp;
12713 struct ieee80211com *ic = ifp->if_l2com;
12714 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12716 if (mac->mac_phy.rev < 2) {
12718 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12719 ext_lna = (gain & 2) >> 1;
12721 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12722 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12723 0xfbff, ext_lna << 10);
12724 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12725 0xf7ff, ext_lna << 11);
12726 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12728 low_gain = gain & 0xffff;
12729 high_gain = (gain >> 16) & 0xf;
12730 ext_lna = (gain >> 21) & 0x1;
12731 trsw = ~(gain >> 20) & 0x1;
12733 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12734 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12735 0xfdff, ext_lna << 9);
12736 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12737 0xfbff, ext_lna << 10);
12738 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12739 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12740 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12741 tmp = (gain >> 2) & 0x3;
12742 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12744 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12749 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12750 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12751 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12752 if (mac->mac_phy.rev >= 2) {
12753 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12754 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12755 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12756 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12760 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12764 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12766 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12769 plp->plp_crsusr_off = 1;
12771 plp->plp_crssys_off = 1;
12773 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12777 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12779 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12780 struct bwn_softc *sc = mac->mac_sc;
12781 struct ifnet *ifp = sc->sc_ifp;
12782 struct ieee80211com *ic = ifp->if_l2com;
12785 plp->plp_crsusr_off = 0;
12787 plp->plp_crssys_off = 0;
12789 if (plp->plp_crsusr_off || plp->plp_crssys_off)
12792 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12793 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12795 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12798 static unsigned int
12799 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12801 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12802 static uint8_t sqrt_table[256] = {
12803 10, 14, 17, 20, 22, 24, 26, 28,
12804 30, 31, 33, 34, 36, 37, 38, 40,
12805 41, 42, 43, 44, 45, 46, 47, 48,
12806 50, 50, 51, 52, 53, 54, 55, 56,
12807 57, 58, 59, 60, 60, 61, 62, 63,
12808 64, 64, 65, 66, 67, 67, 68, 69,
12809 70, 70, 71, 72, 72, 73, 74, 74,
12810 75, 76, 76, 77, 78, 78, 79, 80,
12811 80, 81, 81, 82, 83, 83, 84, 84,
12812 85, 86, 86, 87, 87, 88, 88, 89,
12813 90, 90, 91, 91, 92, 92, 93, 93,
12814 94, 94, 95, 95, 96, 96, 97, 97,
12815 98, 98, 99, 100, 100, 100, 101, 101,
12816 102, 102, 103, 103, 104, 104, 105, 105,
12817 106, 106, 107, 107, 108, 108, 109, 109,
12818 110, 110, 110, 111, 111, 112, 112, 113,
12819 113, 114, 114, 114, 115, 115, 116, 116,
12820 117, 117, 117, 118, 118, 119, 119, 120,
12821 120, 120, 121, 121, 122, 122, 122, 123,
12822 123, 124, 124, 124, 125, 125, 126, 126,
12823 126, 127, 127, 128, 128, 128, 129, 129,
12824 130, 130, 130, 131, 131, 131, 132, 132,
12825 133, 133, 133, 134, 134, 134, 135, 135,
12826 136, 136, 136, 137, 137, 137, 138, 138,
12827 138, 139, 139, 140, 140, 140, 141, 141,
12828 141, 142, 142, 142, 143, 143, 143, 144,
12829 144, 144, 145, 145, 145, 146, 146, 146,
12830 147, 147, 147, 148, 148, 148, 149, 149,
12831 150, 150, 150, 150, 151, 151, 151, 152,
12832 152, 152, 153, 153, 153, 154, 154, 154,
12833 155, 155, 155, 156, 156, 156, 157, 157,
12834 157, 158, 158, 158, 159, 159, 159, 160
12842 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12846 return (sqrt_table[x - 1] / 10);
12850 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12852 #define CALC_COEFF(_v, _x, _y, _z) do { \
12856 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12858 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12861 #define CALC_COEFF2(_v, _x, _y, _z) do { \
12865 tmp[3] = (_y << (31 - _x)) / (_z >> _t); \
12867 tmp[3] = (_y << (31 - _x)) / (_z << -_t); \
12869 struct bwn_phy_lp_iq_est ie;
12873 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12877 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12878 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12880 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12884 if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12889 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12890 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12892 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12896 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12897 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12904 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12906 static const uint16_t noisescale[] = {
12907 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12908 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12909 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12910 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12911 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12913 static const uint16_t crsgainnft[] = {
12914 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12915 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12916 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12917 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12920 static const uint16_t filterctl[] = {
12921 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12924 static const uint32_t psctl[] = {
12925 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12926 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12927 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12928 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12929 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12930 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12931 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12932 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12934 static const uint16_t ofdmcckgain_r0[] = {
12935 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12936 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12937 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12938 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12941 static const uint16_t ofdmcckgain_r1[] = {
12942 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12943 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12944 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12945 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12948 static const uint16_t gaindelta[] = {
12949 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12952 static const uint32_t txpwrctl[] = {
12953 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12954 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12955 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12956 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12957 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12958 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12959 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12960 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12961 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12962 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12963 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12964 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12965 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
12966 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12967 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12968 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12969 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12970 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12971 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12972 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12973 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12974 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12975 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12976 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12977 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12978 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12979 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12980 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12981 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12982 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12983 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12984 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12985 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12986 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12987 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12988 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12989 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12990 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12991 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12992 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12993 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12994 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12995 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12996 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12997 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12998 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12999 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
13000 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
13001 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
13002 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
13003 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
13004 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
13005 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
13006 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
13007 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
13008 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
13009 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
13010 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
13011 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
13012 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
13013 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
13014 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
13015 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
13016 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
13017 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13018 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13019 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13020 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13021 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13022 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13023 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13024 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13025 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13026 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13027 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13028 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13029 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13030 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13031 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13032 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13033 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13034 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13035 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13036 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13037 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13038 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13039 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13040 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13041 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13042 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
13043 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
13044 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
13045 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
13046 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
13047 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
13048 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
13049 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
13050 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
13051 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
13052 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
13053 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
13054 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
13055 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
13056 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
13057 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
13058 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
13059 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
13060 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
13061 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
13062 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
13063 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
13064 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
13065 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
13066 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
13067 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
13071 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13073 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13074 bwn_tab_sigsq_tbl);
13075 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13076 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
13077 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
13078 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
13079 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13080 bwn_tab_pllfrac_tbl);
13081 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13082 bwn_tabl_iqlocal_tbl);
13083 if (mac->mac_phy.rev == 0) {
13084 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
13086 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
13089 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
13091 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
13094 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
13095 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
13099 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
13101 struct bwn_softc *sc = mac->mac_sc;
13103 static const uint16_t noisescale[] = {
13104 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13105 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13106 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13107 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13108 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13109 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13110 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
13112 static const uint32_t filterctl[] = {
13113 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
13114 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
13116 static const uint32_t psctl[] = {
13117 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
13118 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
13119 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
13120 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
13122 static const uint32_t gainidx[] = {
13123 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13124 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13125 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13126 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
13127 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
13128 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
13129 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
13130 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
13131 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
13132 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
13133 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
13134 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
13135 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
13136 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
13137 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
13138 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13139 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13140 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13141 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
13142 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
13143 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
13144 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
13145 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
13146 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
13147 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
13148 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
13149 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
13150 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
13151 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
13152 0x0000001a, 0x64ca55ad, 0x0000001a
13154 static const uint16_t auxgainidx[] = {
13155 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13156 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
13157 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
13160 static const uint16_t swctl[] = {
13161 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13162 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13163 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13164 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
13165 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13166 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13167 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13168 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
13170 static const uint8_t hf[] = {
13171 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
13172 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
13174 static const uint32_t gainval[] = {
13175 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13176 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13177 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13178 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13179 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13180 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13181 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13182 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13183 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13184 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13185 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13186 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13187 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
13188 0x000000f1, 0x00000000, 0x00000000
13190 static const uint16_t gain[] = {
13191 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13192 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13193 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13194 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13195 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13196 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
13197 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13198 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13199 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13200 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13201 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13202 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13204 static const uint32_t papdeps[] = {
13205 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13206 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13207 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13208 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13209 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13210 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13211 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13212 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13213 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13214 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13215 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13216 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13217 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13219 static const uint32_t papdmult[] = {
13220 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13221 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13222 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13223 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13224 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13225 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13226 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13227 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13228 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13229 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13230 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13231 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13232 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13234 static const uint32_t gainidx_a0[] = {
13235 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13236 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13237 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13238 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13239 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13240 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13241 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13242 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13243 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13244 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13245 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13246 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13247 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13249 static const uint16_t auxgainidx_a0[] = {
13250 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13251 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13252 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13255 static const uint32_t gainval_a0[] = {
13256 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13257 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13258 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13259 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13260 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13261 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13262 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13263 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13264 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13265 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13266 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13267 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13268 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13269 0x000000f7, 0x00000000, 0x00000000
13271 static const uint16_t gain_a0[] = {
13272 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13273 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13274 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13275 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13276 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13277 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
13278 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13279 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13280 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13281 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13282 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13283 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13286 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13288 for (i = 0; i < 704; i++)
13289 bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13291 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13292 bwn_tab_sigsq_tbl);
13293 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13294 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13295 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13296 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13297 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13298 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13299 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13300 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13301 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13302 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13303 bwn_tab_pllfrac_tbl);
13304 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13305 bwn_tabl_iqlocal_tbl);
13306 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13307 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13309 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13310 (siba_get_chiprev(sc->sc_dev) == 0)) {
13311 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13313 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13315 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13317 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13322 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13324 struct bwn_softc *sc = mac->mac_sc;
13325 struct ifnet *ifp = sc->sc_ifp;
13326 struct ieee80211com *ic = ifp->if_l2com;
13327 static struct bwn_txgain_entry txgain_r2[] = {
13328 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13329 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13330 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13331 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13332 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13333 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13334 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13335 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13336 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13337 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13338 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13339 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13340 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13341 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13342 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13343 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13344 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13345 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13346 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13347 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13348 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13349 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13350 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13351 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13352 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13353 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13354 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13355 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13356 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13357 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13358 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13359 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13360 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13361 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13362 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13363 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13364 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13365 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13366 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13367 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13368 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13369 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13370 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13371 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13372 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13373 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13374 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13375 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13376 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13377 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13378 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13379 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13380 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13381 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13382 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13383 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13384 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13385 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13386 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13387 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13388 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13389 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13390 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13391 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13393 static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13394 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13395 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13396 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13397 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13398 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13399 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13400 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13401 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13402 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13403 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13404 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13405 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13406 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13407 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13408 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13409 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13410 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13411 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13412 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13413 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13414 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13415 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13416 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13417 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13418 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13419 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13420 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13421 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13422 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13423 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13424 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13425 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13426 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13427 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13428 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13429 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13430 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13431 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13432 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13433 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13434 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13435 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13436 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13437 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13438 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13439 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13440 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13441 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13442 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13443 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13444 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13445 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13446 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13447 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13448 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13449 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13450 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13451 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13452 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13453 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13454 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13455 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13456 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13457 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13459 static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13460 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13461 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13462 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13463 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13464 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13465 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13466 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13467 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13468 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13469 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13470 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13471 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13472 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13473 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13474 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13475 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13476 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13477 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13478 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13479 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13480 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13481 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13482 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13483 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13484 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13485 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13486 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13487 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13488 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13489 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13490 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13491 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13492 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13493 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13494 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13495 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13496 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13497 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13498 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13499 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13500 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13501 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13502 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13503 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13504 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13505 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13506 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13507 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13508 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13509 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13510 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13511 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13512 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13513 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13514 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13515 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13516 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13517 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13518 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13519 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13520 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13521 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13522 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13523 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13525 static struct bwn_txgain_entry txgain_r0[] = {
13526 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13527 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13528 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13529 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13530 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13531 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13532 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13533 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13534 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13535 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13536 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13537 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13538 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13539 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13540 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13541 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13542 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13543 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13544 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13545 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13546 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13547 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13548 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13549 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13550 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13551 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13552 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13553 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13554 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13555 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13556 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13557 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13558 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13559 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13560 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13561 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13562 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13563 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13564 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13565 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13566 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13567 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13568 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13569 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13570 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13571 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13572 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13573 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13574 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13575 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13576 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13577 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13578 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13579 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13580 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13581 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13582 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13583 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13584 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13585 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13586 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13587 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13588 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13589 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13591 static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13592 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13593 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13594 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13595 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13596 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13597 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13598 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13599 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13600 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13601 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13602 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13603 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13604 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13605 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13606 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13607 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13608 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13609 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13610 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13611 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13612 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13613 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13614 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13615 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13616 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13617 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13618 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13619 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13620 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13621 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13622 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13623 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13624 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13625 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13626 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13627 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13628 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13629 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13630 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13631 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13632 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13633 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13634 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13635 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13636 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13637 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13638 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13639 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13640 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13641 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13642 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13643 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13644 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13645 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13646 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13647 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13648 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13649 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13650 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13651 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13652 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13653 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13654 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13655 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13657 static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13658 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13659 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13660 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13661 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13662 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13663 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13664 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13665 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13666 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13667 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13668 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13669 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13670 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13671 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13672 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13673 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13674 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13675 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13676 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13677 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13678 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13679 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13680 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13681 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13682 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13683 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13684 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13685 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13686 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13687 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13688 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13689 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13690 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13691 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13692 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13693 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13694 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13695 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13696 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13697 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13698 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13699 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13700 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13701 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13702 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13703 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13704 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13705 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13706 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13707 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13708 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13709 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13710 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13711 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13712 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13713 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13714 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13715 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13716 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13717 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13718 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13719 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13720 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13721 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13723 static struct bwn_txgain_entry txgain_r1[] = {
13724 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13725 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13726 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13727 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13728 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13729 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13730 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13731 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13732 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13733 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13734 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13735 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13736 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13737 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13738 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13739 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13740 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13741 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13742 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13743 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13744 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13745 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13746 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13747 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13748 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13749 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13750 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13751 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13752 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13753 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13754 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13755 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13756 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13757 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13758 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13759 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13760 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13761 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13762 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13763 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13764 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13765 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13766 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13767 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13768 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13769 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13770 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13771 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13772 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13773 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13774 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13775 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13776 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13777 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13778 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13779 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13780 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13781 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13782 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13783 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13784 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13785 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13786 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13787 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13788 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13789 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13790 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13791 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13792 { 7, 11, 6, 0, 71 }
13794 static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13795 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13796 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13797 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13798 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13799 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13800 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13801 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13802 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13803 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13804 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13805 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13806 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13807 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13808 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13809 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13810 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13811 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13812 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13813 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13814 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13815 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13816 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13817 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13818 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13819 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13820 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13821 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13822 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13823 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13824 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13825 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13826 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13827 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13828 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13829 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13830 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13831 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13832 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13833 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13834 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13835 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13836 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13837 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13838 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13839 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13840 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13841 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13842 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13843 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13844 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13845 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13846 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13847 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13848 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13849 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13850 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13851 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13852 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13853 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13854 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13855 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13856 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13857 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13858 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13860 static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13861 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13862 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13863 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13864 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13865 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13866 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13867 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13868 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13869 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13870 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13871 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13872 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13873 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13874 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13875 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13876 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13877 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13878 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13879 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13880 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13881 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13882 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13883 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13884 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13885 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13886 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13887 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13888 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13889 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13890 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13891 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13892 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13893 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13894 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13895 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13896 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13897 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13898 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13899 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13900 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13901 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13902 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13903 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13904 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13905 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13906 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13907 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13908 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13909 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13910 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13911 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13912 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13913 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13914 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13915 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13916 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13917 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13918 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13919 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13920 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13921 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13922 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13923 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13924 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13927 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13928 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13929 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13930 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13931 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13934 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13939 if (mac->mac_phy.rev == 0) {
13940 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13941 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13942 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13943 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13944 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13947 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13952 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13953 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13954 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13955 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13956 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13958 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13962 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13964 uint32_t offset, type;
13966 type = BWN_TAB_GETTYPE(typeoffset);
13967 offset = BWN_TAB_GETOFFSET(typeoffset);
13968 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13972 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13973 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13974 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13976 case BWN_TAB_16BIT:
13977 KASSERT(!(value & ~0xffff),
13978 ("%s:%d: fail", __func__, __LINE__));
13979 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13980 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13982 case BWN_TAB_32BIT:
13983 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13984 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13985 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13988 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13993 bwn_phy_lp_loopback(struct bwn_mac *mac)
13995 struct bwn_phy_lp_iq_est ie;
13999 memset(&ie, 0, sizeof(ie));
14001 bwn_phy_lp_set_trsw_over(mac, 1, 1);
14002 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
14003 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
14004 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
14005 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
14006 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
14007 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
14008 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
14009 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
14010 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
14011 for (i = 0; i < 32; i++) {
14012 bwn_phy_lp_set_rxgain_idx(mac, i);
14013 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
14014 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
14016 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
14017 if ((tmp > 4000) && (tmp < 10000)) {
14022 bwn_phy_lp_ddfs_turnoff(mac);
14027 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
14030 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
14034 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
14035 int incr1, int incr2, int scale_idx)
14038 bwn_phy_lp_ddfs_turnoff(mac);
14039 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
14040 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
14041 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
14042 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
14043 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
14044 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
14045 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
14046 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
14047 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
14048 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
14052 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
14053 struct bwn_phy_lp_iq_est *ie)
14057 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
14058 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
14059 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
14060 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
14061 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
14063 for (i = 0; i < 500; i++) {
14064 if (!(BWN_PHY_READ(mac,
14065 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
14069 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
14070 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14074 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
14075 ie->ie_iqprod <<= 16;
14076 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
14077 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
14078 ie->ie_ipwr <<= 16;
14079 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
14080 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
14081 ie->ie_qpwr <<= 16;
14082 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
14084 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14089 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
14091 uint32_t offset, type, value;
14093 type = BWN_TAB_GETTYPE(typeoffset);
14094 offset = BWN_TAB_GETOFFSET(typeoffset);
14095 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
14099 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14100 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
14102 case BWN_TAB_16BIT:
14103 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14104 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14106 case BWN_TAB_32BIT:
14107 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14108 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
14110 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14113 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
14121 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
14124 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
14125 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
14129 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
14133 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
14135 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
14139 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
14142 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
14143 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
14147 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
14150 if (mac->mac_phy.rev < 2)
14151 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
14153 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
14154 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
14156 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
14160 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
14163 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
14167 bwn_nbits(int32_t val)
14172 for (tmp = abs(val); tmp != 0; tmp >>= 1)
14178 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
14179 struct bwn_txgain_entry *table)
14183 for (i = offset; i < count; i++)
14184 bwn_phy_lp_gaintbl_write(mac, i, table[i]);
14188 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
14189 struct bwn_txgain_entry data)
14192 if (mac->mac_phy.rev >= 2)
14193 bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14195 bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14199 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14200 struct bwn_txgain_entry te)
14202 struct bwn_softc *sc = mac->mac_sc;
14203 struct ifnet *ifp = sc->sc_ifp;
14204 struct ieee80211com *ic = ifp->if_l2com;
14207 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14209 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14210 if (mac->mac_phy.rev >= 3) {
14211 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14212 (0x10 << 24) : (0x70 << 24));
14214 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14215 (0x14 << 24) : (0x7f << 24));
14217 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14218 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14219 te.te_bbmult << 20 | te.te_dac << 28);
14223 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14224 struct bwn_txgain_entry te)
14227 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14229 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14230 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) |
14232 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14236 bwn_sysctl_node(struct bwn_softc *sc)
14238 device_t dev = sc->sc_dev;
14239 struct bwn_mac *mac;
14240 struct bwn_stats *stats;
14242 /* XXX assume that count of MAC is only 1. */
14244 if ((mac = sc->sc_curmac) == NULL)
14246 stats = &mac->mac_stats;
14248 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14249 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14250 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14251 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14252 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14253 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14254 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14255 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14256 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14259 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14260 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14261 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14265 static device_method_t bwn_methods[] = {
14266 /* Device interface */
14267 DEVMETHOD(device_probe, bwn_probe),
14268 DEVMETHOD(device_attach, bwn_attach),
14269 DEVMETHOD(device_detach, bwn_detach),
14270 DEVMETHOD(device_suspend, bwn_suspend),
14271 DEVMETHOD(device_resume, bwn_resume),
14274 static driver_t bwn_driver = {
14277 sizeof(struct bwn_softc)
14279 static devclass_t bwn_devclass;
14280 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
14281 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14282 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */
14283 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */
14284 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);