2 * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13 * redistribution must be conditioned upon including a substantially
14 * similar Disclaimer requirement for further binary redistribution.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
34 * The Broadcom Wireless LAN controller driver.
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/module.h>
40 #include <sys/kernel.h>
41 #include <sys/endian.h>
42 #include <sys/errno.h>
43 #include <sys/firmware.h>
45 #include <sys/mutex.h>
46 #include <machine/bus.h>
47 #include <machine/resource.h>
50 #include <sys/socket.h>
51 #include <sys/sockio.h>
53 #include <net/ethernet.h>
55 #include <net/if_arp.h>
56 #include <net/if_dl.h>
57 #include <net/if_llc.h>
58 #include <net/if_media.h>
59 #include <net/if_types.h>
61 #include <dev/pci/pcivar.h>
62 #include <dev/pci/pcireg.h>
63 #include <dev/siba/siba_ids.h>
64 #include <dev/siba/sibareg.h>
65 #include <dev/siba/sibavar.h>
67 #include <net80211/ieee80211_var.h>
68 #include <net80211/ieee80211_radiotap.h>
69 #include <net80211/ieee80211_regdomain.h>
70 #include <net80211/ieee80211_phy.h>
71 #include <net80211/ieee80211_ratectl.h>
73 #include <dev/bwn/if_bwnreg.h>
74 #include <dev/bwn/if_bwnvar.h>
76 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_updateslot(struct ifnet *);
184 static void bwn_update_promisc(struct ifnet *);
185 static void bwn_wme_init(struct bwn_mac *);
186 static int bwn_wme_update(struct ieee80211com *);
187 static void bwn_wme_clear(struct bwn_softc *);
188 static void bwn_wme_load(struct bwn_mac *);
189 static void bwn_wme_loadparams(struct bwn_mac *,
190 const struct wmeParams *, uint16_t);
191 static void bwn_scan_start(struct ieee80211com *);
192 static void bwn_scan_end(struct ieee80211com *);
193 static void bwn_set_channel(struct ieee80211com *);
194 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *,
195 const char [IFNAMSIZ], int, int,
196 int, const uint8_t [IEEE80211_ADDR_LEN],
197 const uint8_t [IEEE80211_ADDR_LEN]);
198 static void bwn_vap_delete(struct ieee80211vap *);
199 static void bwn_stop(struct bwn_softc *, int);
200 static void bwn_stop_locked(struct bwn_softc *, int);
201 static int bwn_core_init(struct bwn_mac *);
202 static void bwn_core_start(struct bwn_mac *);
203 static void bwn_core_exit(struct bwn_mac *);
204 static void bwn_bt_disable(struct bwn_mac *);
205 static int bwn_chip_init(struct bwn_mac *);
206 static uint64_t bwn_hf_read(struct bwn_mac *);
207 static void bwn_hf_write(struct bwn_mac *, uint64_t);
208 static void bwn_set_txretry(struct bwn_mac *, int, int);
209 static void bwn_rate_init(struct bwn_mac *);
210 static void bwn_set_phytxctl(struct bwn_mac *);
211 static void bwn_spu_setdelay(struct bwn_mac *, int);
212 static void bwn_bt_enable(struct bwn_mac *);
213 static void bwn_set_macaddr(struct bwn_mac *);
214 static void bwn_crypt_init(struct bwn_mac *);
215 static void bwn_chip_exit(struct bwn_mac *);
216 static int bwn_fw_fillinfo(struct bwn_mac *);
217 static int bwn_fw_loaducode(struct bwn_mac *);
218 static int bwn_gpio_init(struct bwn_mac *);
219 static int bwn_fw_loadinitvals(struct bwn_mac *);
220 static int bwn_phy_init(struct bwn_mac *);
221 static void bwn_set_txantenna(struct bwn_mac *, int);
222 static void bwn_set_opmode(struct bwn_mac *);
223 static void bwn_rate_write(struct bwn_mac *, uint16_t, int);
224 static uint8_t bwn_plcp_getcck(const uint8_t);
225 static uint8_t bwn_plcp_getofdm(const uint8_t);
226 static void bwn_pio_init(struct bwn_mac *);
227 static uint16_t bwn_pio_idx2base(struct bwn_mac *, int);
228 static void bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *,
230 static void bwn_pio_setupqueue_rx(struct bwn_mac *,
231 struct bwn_pio_rxqueue *, int);
232 static void bwn_destroy_queue_tx(struct bwn_pio_txqueue *);
233 static uint16_t bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *,
235 static void bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *);
236 static int bwn_pio_rx(struct bwn_pio_rxqueue *);
237 static uint8_t bwn_pio_rxeof(struct bwn_pio_rxqueue *);
238 static void bwn_pio_handle_txeof(struct bwn_mac *,
239 const struct bwn_txstatus *);
240 static uint16_t bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t);
241 static uint32_t bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t);
242 static void bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t,
244 static void bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t,
246 static int bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *,
248 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t);
249 static uint32_t bwn_pio_write_multi_4(struct bwn_mac *,
250 struct bwn_pio_txqueue *, uint32_t, const void *, int);
251 static void bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *,
253 static uint16_t bwn_pio_write_multi_2(struct bwn_mac *,
254 struct bwn_pio_txqueue *, uint16_t, const void *, int);
255 static uint16_t bwn_pio_write_mbuf_2(struct bwn_mac *,
256 struct bwn_pio_txqueue *, uint16_t, struct mbuf *);
257 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *,
258 uint16_t, struct bwn_pio_txpkt **);
259 static void bwn_dma_init(struct bwn_mac *);
260 static void bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t);
261 static int bwn_dma_mask2type(uint64_t);
262 static uint64_t bwn_dma_mask(struct bwn_mac *);
263 static uint16_t bwn_dma_base(int, int);
264 static void bwn_dma_ringfree(struct bwn_dma_ring **);
265 static void bwn_dma_32_getdesc(struct bwn_dma_ring *,
266 int, struct bwn_dmadesc_generic **,
267 struct bwn_dmadesc_meta **);
268 static void bwn_dma_32_setdesc(struct bwn_dma_ring *,
269 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
271 static void bwn_dma_32_start_transfer(struct bwn_dma_ring *, int);
272 static void bwn_dma_32_suspend(struct bwn_dma_ring *);
273 static void bwn_dma_32_resume(struct bwn_dma_ring *);
274 static int bwn_dma_32_get_curslot(struct bwn_dma_ring *);
275 static void bwn_dma_32_set_curslot(struct bwn_dma_ring *, int);
276 static void bwn_dma_64_getdesc(struct bwn_dma_ring *,
277 int, struct bwn_dmadesc_generic **,
278 struct bwn_dmadesc_meta **);
279 static void bwn_dma_64_setdesc(struct bwn_dma_ring *,
280 struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
282 static void bwn_dma_64_start_transfer(struct bwn_dma_ring *, int);
283 static void bwn_dma_64_suspend(struct bwn_dma_ring *);
284 static void bwn_dma_64_resume(struct bwn_dma_ring *);
285 static int bwn_dma_64_get_curslot(struct bwn_dma_ring *);
286 static void bwn_dma_64_set_curslot(struct bwn_dma_ring *, int);
287 static int bwn_dma_allocringmemory(struct bwn_dma_ring *);
288 static void bwn_dma_setup(struct bwn_dma_ring *);
289 static void bwn_dma_free_ringmemory(struct bwn_dma_ring *);
290 static void bwn_dma_cleanup(struct bwn_dma_ring *);
291 static void bwn_dma_free_descbufs(struct bwn_dma_ring *);
292 static int bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int);
293 static void bwn_dma_rx(struct bwn_dma_ring *);
294 static int bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int);
295 static void bwn_dma_free_descbuf(struct bwn_dma_ring *,
296 struct bwn_dmadesc_meta *);
297 static void bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *);
298 static int bwn_dma_gettype(struct bwn_mac *);
299 static void bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int);
300 static int bwn_dma_freeslot(struct bwn_dma_ring *);
301 static int bwn_dma_nextslot(struct bwn_dma_ring *, int);
302 static void bwn_dma_rxeof(struct bwn_dma_ring *, int *);
303 static int bwn_dma_newbuf(struct bwn_dma_ring *,
304 struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *,
306 static void bwn_dma_buf_addr(void *, bus_dma_segment_t *, int,
308 static uint8_t bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *);
309 static void bwn_dma_handle_txeof(struct bwn_mac *,
310 const struct bwn_txstatus *);
311 static int bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *,
313 static int bwn_dma_getslot(struct bwn_dma_ring *);
314 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *,
316 static int bwn_dma_attach(struct bwn_mac *);
317 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *,
319 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *,
320 const struct bwn_txstatus *, uint16_t, int *);
321 static void bwn_dma_free(struct bwn_mac *);
322 static void bwn_phy_g_init_sub(struct bwn_mac *);
323 static uint8_t bwn_has_hwpctl(struct bwn_mac *);
324 static void bwn_phy_init_b5(struct bwn_mac *);
325 static void bwn_phy_init_b6(struct bwn_mac *);
326 static void bwn_phy_init_a(struct bwn_mac *);
327 static void bwn_loopback_calcgain(struct bwn_mac *);
328 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *);
329 static void bwn_lo_g_init(struct bwn_mac *);
330 static void bwn_lo_g_adjust(struct bwn_mac *);
331 static void bwn_lo_get_powervector(struct bwn_mac *);
332 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *,
333 const struct bwn_bbatt *, const struct bwn_rfatt *);
334 static void bwn_lo_write(struct bwn_mac *, struct bwn_loctl *);
335 static void bwn_phy_hwpctl_init(struct bwn_mac *);
336 static void bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t);
337 static void bwn_phy_g_set_txpwr_sub(struct bwn_mac *,
338 const struct bwn_bbatt *, const struct bwn_rfatt *,
340 static void bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t);
341 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t);
342 static void bwn_spu_workaround(struct bwn_mac *, uint8_t);
343 static void bwn_wa_init(struct bwn_mac *);
344 static void bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t,
346 static void bwn_dummy_transmission(struct bwn_mac *, int, int);
347 static void bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t,
349 static void bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t,
351 static void bwn_ram_write(struct bwn_mac *, uint16_t, uint32_t);
352 static void bwn_mac_suspend(struct bwn_mac *);
353 static void bwn_mac_enable(struct bwn_mac *);
354 static void bwn_psctl(struct bwn_mac *, uint32_t);
355 static int16_t bwn_nrssi_read(struct bwn_mac *, uint16_t);
356 static void bwn_nrssi_offset(struct bwn_mac *);
357 static void bwn_nrssi_threshold(struct bwn_mac *);
358 static void bwn_nrssi_slope_11g(struct bwn_mac *);
359 static void bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t,
361 static void bwn_set_original_gains(struct bwn_mac *);
362 static void bwn_hwpctl_early_init(struct bwn_mac *);
363 static void bwn_hwpctl_init_gphy(struct bwn_mac *);
364 static uint16_t bwn_phy_g_chan2freq(uint8_t);
365 static int bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype);
366 static int bwn_fw_get(struct bwn_mac *, enum bwn_fwtype,
367 const char *, struct bwn_fwfile *);
368 static void bwn_release_firmware(struct bwn_mac *);
369 static void bwn_do_release_fw(struct bwn_fwfile *);
370 static uint16_t bwn_fwcaps_read(struct bwn_mac *);
371 static int bwn_fwinitvals_write(struct bwn_mac *,
372 const struct bwn_fwinitvals *, size_t, size_t);
373 static int bwn_switch_channel(struct bwn_mac *, int);
374 static uint16_t bwn_ant2phy(int);
375 static void bwn_mac_write_bssid(struct bwn_mac *);
376 static void bwn_mac_setfilter(struct bwn_mac *, uint16_t,
378 static void bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t,
379 const uint8_t *, size_t, const uint8_t *);
380 static void bwn_key_macwrite(struct bwn_mac *, uint8_t,
382 static void bwn_key_write(struct bwn_mac *, uint8_t, uint8_t,
384 static void bwn_phy_exit(struct bwn_mac *);
385 static void bwn_core_stop(struct bwn_mac *);
386 static int bwn_switch_band(struct bwn_softc *,
387 struct ieee80211_channel *);
388 static void bwn_phy_reset(struct bwn_mac *);
389 static int bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
390 static void bwn_set_pretbtt(struct bwn_mac *);
391 static int bwn_intr(void *);
392 static void bwn_intrtask(void *, int);
393 static void bwn_restart(struct bwn_mac *, const char *);
394 static void bwn_intr_ucode_debug(struct bwn_mac *);
395 static void bwn_intr_tbtt_indication(struct bwn_mac *);
396 static void bwn_intr_atim_end(struct bwn_mac *);
397 static void bwn_intr_beacon(struct bwn_mac *);
398 static void bwn_intr_pmq(struct bwn_mac *);
399 static void bwn_intr_noise(struct bwn_mac *);
400 static void bwn_intr_txeof(struct bwn_mac *);
401 static void bwn_hwreset(void *, int);
402 static void bwn_handle_fwpanic(struct bwn_mac *);
403 static void bwn_load_beacon0(struct bwn_mac *);
404 static void bwn_load_beacon1(struct bwn_mac *);
405 static uint32_t bwn_jssi_read(struct bwn_mac *);
406 static void bwn_noise_gensample(struct bwn_mac *);
407 static void bwn_handle_txeof(struct bwn_mac *,
408 const struct bwn_txstatus *);
409 static void bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *);
410 static void bwn_phy_txpower_check(struct bwn_mac *, uint32_t);
411 static void bwn_start_locked(struct ifnet *);
412 static int bwn_tx_start(struct bwn_softc *, struct ieee80211_node *,
414 static int bwn_tx_isfull(struct bwn_softc *, struct mbuf *);
415 static int bwn_set_txhdr(struct bwn_mac *,
416 struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *,
418 static void bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t,
420 static uint8_t bwn_antenna_sanitize(struct bwn_mac *, uint8_t);
421 static uint8_t bwn_get_fbrate(uint8_t);
422 static int bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t);
423 static void bwn_phy_g_setatt(struct bwn_mac *, int *, int *);
424 static void bwn_phy_lock(struct bwn_mac *);
425 static void bwn_phy_unlock(struct bwn_mac *);
426 static void bwn_rf_lock(struct bwn_mac *);
427 static void bwn_rf_unlock(struct bwn_mac *);
428 static void bwn_txpwr(void *, int);
429 static void bwn_tasks(void *);
430 static void bwn_task_15s(struct bwn_mac *);
431 static void bwn_task_30s(struct bwn_mac *);
432 static void bwn_task_60s(struct bwn_mac *);
433 static int bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *,
435 static int bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *);
436 static void bwn_rx_radiotap(struct bwn_mac *, struct mbuf *,
437 const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int,
439 static void bwn_tsf_read(struct bwn_mac *, uint64_t *);
440 static void bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t);
441 static void bwn_set_slot_time(struct bwn_mac *, uint16_t);
442 static void bwn_watchdog(void *);
443 static void bwn_dma_stop(struct bwn_mac *);
444 static void bwn_pio_stop(struct bwn_mac *);
445 static void bwn_dma_ringstop(struct bwn_dma_ring **);
446 static void bwn_led_attach(struct bwn_mac *);
447 static void bwn_led_newstate(struct bwn_mac *, enum ieee80211_state);
448 static void bwn_led_event(struct bwn_mac *, int);
449 static void bwn_led_blink_start(struct bwn_mac *, int, int);
450 static void bwn_led_blink_next(void *);
451 static void bwn_led_blink_end(void *);
452 static void bwn_rfswitch(void *);
453 static void bwn_rf_turnon(struct bwn_mac *);
454 static void bwn_rf_turnoff(struct bwn_mac *);
455 static void bwn_phy_lp_init_pre(struct bwn_mac *);
456 static int bwn_phy_lp_init(struct bwn_mac *);
457 static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t);
458 static void bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t);
459 static void bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t,
461 static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t);
462 static void bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t);
463 static void bwn_phy_lp_rf_onoff(struct bwn_mac *, int);
464 static int bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t);
465 static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *);
466 static void bwn_phy_lp_set_antenna(struct bwn_mac *, int);
467 static void bwn_phy_lp_task_60s(struct bwn_mac *);
468 static void bwn_phy_lp_readsprom(struct bwn_mac *);
469 static void bwn_phy_lp_bbinit(struct bwn_mac *);
470 static void bwn_phy_lp_txpctl_init(struct bwn_mac *);
471 static void bwn_phy_lp_calib(struct bwn_mac *);
472 static void bwn_phy_lp_switch_analog(struct bwn_mac *, int);
473 static int bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t);
474 static int bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t);
475 static void bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t);
476 static void bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t);
477 static void bwn_phy_lp_digflt_save(struct bwn_mac *);
478 static void bwn_phy_lp_get_txpctlmode(struct bwn_mac *);
479 static void bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t);
480 static void bwn_phy_lp_bugfix(struct bwn_mac *);
481 static void bwn_phy_lp_digflt_restore(struct bwn_mac *);
482 static void bwn_phy_lp_tblinit(struct bwn_mac *);
483 static void bwn_phy_lp_bbinit_r2(struct bwn_mac *);
484 static void bwn_phy_lp_bbinit_r01(struct bwn_mac *);
485 static void bwn_phy_lp_b2062_init(struct bwn_mac *);
486 static void bwn_phy_lp_b2063_init(struct bwn_mac *);
487 static void bwn_phy_lp_rxcal_r2(struct bwn_mac *);
488 static void bwn_phy_lp_rccal_r12(struct bwn_mac *);
489 static void bwn_phy_lp_set_rccap(struct bwn_mac *);
490 static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t);
491 static void bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *);
492 static void bwn_phy_lp_b2062_vco_calib(struct bwn_mac *);
493 static void bwn_tab_write_multi(struct bwn_mac *, uint32_t, int,
495 static void bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *);
496 static struct bwn_txgain
497 bwn_phy_lp_get_txgain(struct bwn_mac *);
498 static uint8_t bwn_phy_lp_get_bbmult(struct bwn_mac *);
499 static void bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *);
500 static void bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t);
501 static void bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t);
502 static void bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t);
503 static void bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t);
504 static int bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t);
505 static void bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t);
506 static void bwn_phy_lp_tblinit_r01(struct bwn_mac *);
507 static void bwn_phy_lp_tblinit_r2(struct bwn_mac *);
508 static void bwn_phy_lp_tblinit_txgain(struct bwn_mac *);
509 static void bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t);
510 static void bwn_phy_lp_b2062_tblinit(struct bwn_mac *);
511 static void bwn_phy_lp_b2063_tblinit(struct bwn_mac *);
512 static int bwn_phy_lp_loopback(struct bwn_mac *);
513 static void bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t);
514 static void bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int,
516 static uint8_t bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t,
517 struct bwn_phy_lp_iq_est *);
518 static void bwn_phy_lp_ddfs_turnoff(struct bwn_mac *);
519 static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t);
520 static void bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t);
521 static void bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t);
522 static void bwn_phy_lp_set_txgain_override(struct bwn_mac *);
523 static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *);
524 static uint8_t bwn_nbits(int32_t);
525 static void bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int,
526 struct bwn_txgain_entry *);
527 static void bwn_phy_lp_gaintbl_write(struct bwn_mac *, int,
528 struct bwn_txgain_entry);
529 static void bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int,
530 struct bwn_txgain_entry);
531 static void bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int,
532 struct bwn_txgain_entry);
533 static void bwn_sysctl_node(struct bwn_softc *);
535 static struct resource_spec bwn_res_spec_legacy[] = {
536 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE },
540 static struct resource_spec bwn_res_spec_msi[] = {
541 { SYS_RES_IRQ, 1, RF_ACTIVE },
545 static const struct bwn_channelinfo bwn_chantable_bg = {
547 { 2412, 1, 30 }, { 2417, 2, 30 }, { 2422, 3, 30 },
548 { 2427, 4, 30 }, { 2432, 5, 30 }, { 2437, 6, 30 },
549 { 2442, 7, 30 }, { 2447, 8, 30 }, { 2452, 9, 30 },
550 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 },
551 { 2472, 13, 30 }, { 2484, 14, 30 } },
555 static const struct bwn_channelinfo bwn_chantable_a = {
557 { 5170, 34, 30 }, { 5180, 36, 30 }, { 5190, 38, 30 },
558 { 5200, 40, 30 }, { 5210, 42, 30 }, { 5220, 44, 30 },
559 { 5230, 46, 30 }, { 5240, 48, 30 }, { 5260, 52, 30 },
560 { 5280, 56, 30 }, { 5300, 60, 30 }, { 5320, 64, 30 },
561 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 },
562 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 },
563 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 },
564 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 },
565 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 },
566 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 },
567 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 },
568 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 },
573 static const struct bwn_channelinfo bwn_chantable_n = {
575 { 5160, 32, 30 }, { 5170, 34, 30 }, { 5180, 36, 30 },
576 { 5190, 38, 30 }, { 5200, 40, 30 }, { 5210, 42, 30 },
577 { 5220, 44, 30 }, { 5230, 46, 30 }, { 5240, 48, 30 },
578 { 5250, 50, 30 }, { 5260, 52, 30 }, { 5270, 54, 30 },
579 { 5280, 56, 30 }, { 5290, 58, 30 }, { 5300, 60, 30 },
580 { 5310, 62, 30 }, { 5320, 64, 30 }, { 5330, 66, 30 },
581 { 5340, 68, 30 }, { 5350, 70, 30 }, { 5360, 72, 30 },
582 { 5370, 74, 30 }, { 5380, 76, 30 }, { 5390, 78, 30 },
583 { 5400, 80, 30 }, { 5410, 82, 30 }, { 5420, 84, 30 },
584 { 5430, 86, 30 }, { 5440, 88, 30 }, { 5450, 90, 30 },
585 { 5460, 92, 30 }, { 5470, 94, 30 }, { 5480, 96, 30 },
586 { 5490, 98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 },
587 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 },
588 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 },
589 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 },
590 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 },
591 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 },
592 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 },
593 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 },
594 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 },
595 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 },
596 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 },
597 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 },
598 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 },
599 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 },
600 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 },
601 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 },
602 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 },
603 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 },
604 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 },
605 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 },
606 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 },
607 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
608 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
609 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
610 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
611 { 6130, 226, 30 }, { 6140, 228, 30 } },
615 static const uint8_t bwn_b2063_chantable_data[33][12] = {
616 { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
617 { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
618 { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
619 { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
620 { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
621 { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 },
622 { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 },
623 { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 },
624 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 },
625 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 },
626 { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 },
627 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 },
628 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 },
629 { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 },
630 { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
631 { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
632 { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 },
633 { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 },
634 { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 },
635 { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
636 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
637 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
638 { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
639 { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
640 { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 },
641 { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
642 { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
643 { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
644 { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
645 { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
646 { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
647 { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
648 { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }
651 static const struct bwn_b206x_chan bwn_b2063_chantable[] = {
652 { 1, 2412, bwn_b2063_chantable_data[0] },
653 { 2, 2417, bwn_b2063_chantable_data[0] },
654 { 3, 2422, bwn_b2063_chantable_data[0] },
655 { 4, 2427, bwn_b2063_chantable_data[1] },
656 { 5, 2432, bwn_b2063_chantable_data[1] },
657 { 6, 2437, bwn_b2063_chantable_data[1] },
658 { 7, 2442, bwn_b2063_chantable_data[1] },
659 { 8, 2447, bwn_b2063_chantable_data[1] },
660 { 9, 2452, bwn_b2063_chantable_data[2] },
661 { 10, 2457, bwn_b2063_chantable_data[2] },
662 { 11, 2462, bwn_b2063_chantable_data[3] },
663 { 12, 2467, bwn_b2063_chantable_data[3] },
664 { 13, 2472, bwn_b2063_chantable_data[3] },
665 { 14, 2484, bwn_b2063_chantable_data[4] },
666 { 34, 5170, bwn_b2063_chantable_data[5] },
667 { 36, 5180, bwn_b2063_chantable_data[6] },
668 { 38, 5190, bwn_b2063_chantable_data[7] },
669 { 40, 5200, bwn_b2063_chantable_data[8] },
670 { 42, 5210, bwn_b2063_chantable_data[9] },
671 { 44, 5220, bwn_b2063_chantable_data[10] },
672 { 46, 5230, bwn_b2063_chantable_data[11] },
673 { 48, 5240, bwn_b2063_chantable_data[12] },
674 { 52, 5260, bwn_b2063_chantable_data[13] },
675 { 56, 5280, bwn_b2063_chantable_data[14] },
676 { 60, 5300, bwn_b2063_chantable_data[14] },
677 { 64, 5320, bwn_b2063_chantable_data[15] },
678 { 100, 5500, bwn_b2063_chantable_data[16] },
679 { 104, 5520, bwn_b2063_chantable_data[17] },
680 { 108, 5540, bwn_b2063_chantable_data[18] },
681 { 112, 5560, bwn_b2063_chantable_data[19] },
682 { 116, 5580, bwn_b2063_chantable_data[20] },
683 { 120, 5600, bwn_b2063_chantable_data[21] },
684 { 124, 5620, bwn_b2063_chantable_data[21] },
685 { 128, 5640, bwn_b2063_chantable_data[22] },
686 { 132, 5660, bwn_b2063_chantable_data[22] },
687 { 136, 5680, bwn_b2063_chantable_data[22] },
688 { 140, 5700, bwn_b2063_chantable_data[23] },
689 { 149, 5745, bwn_b2063_chantable_data[23] },
690 { 153, 5765, bwn_b2063_chantable_data[23] },
691 { 157, 5785, bwn_b2063_chantable_data[23] },
692 { 161, 5805, bwn_b2063_chantable_data[23] },
693 { 165, 5825, bwn_b2063_chantable_data[23] },
694 { 184, 4920, bwn_b2063_chantable_data[24] },
695 { 188, 4940, bwn_b2063_chantable_data[25] },
696 { 192, 4960, bwn_b2063_chantable_data[26] },
697 { 196, 4980, bwn_b2063_chantable_data[27] },
698 { 200, 5000, bwn_b2063_chantable_data[28] },
699 { 204, 5020, bwn_b2063_chantable_data[29] },
700 { 208, 5040, bwn_b2063_chantable_data[30] },
701 { 212, 5060, bwn_b2063_chantable_data[31] },
702 { 216, 5080, bwn_b2063_chantable_data[32] }
705 static const uint8_t bwn_b2062_chantable_data[22][12] = {
706 { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 },
707 { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
708 { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
709 { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
710 { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
711 { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
712 { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
713 { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
714 { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
715 { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
716 { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
717 { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
718 { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
719 { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
720 { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
721 { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
722 { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
723 { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
724 { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
725 { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
726 { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
727 { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }
730 static const struct bwn_b206x_chan bwn_b2062_chantable[] = {
731 { 1, 2412, bwn_b2062_chantable_data[0] },
732 { 2, 2417, bwn_b2062_chantable_data[0] },
733 { 3, 2422, bwn_b2062_chantable_data[0] },
734 { 4, 2427, bwn_b2062_chantable_data[0] },
735 { 5, 2432, bwn_b2062_chantable_data[0] },
736 { 6, 2437, bwn_b2062_chantable_data[0] },
737 { 7, 2442, bwn_b2062_chantable_data[0] },
738 { 8, 2447, bwn_b2062_chantable_data[0] },
739 { 9, 2452, bwn_b2062_chantable_data[0] },
740 { 10, 2457, bwn_b2062_chantable_data[0] },
741 { 11, 2462, bwn_b2062_chantable_data[0] },
742 { 12, 2467, bwn_b2062_chantable_data[0] },
743 { 13, 2472, bwn_b2062_chantable_data[0] },
744 { 14, 2484, bwn_b2062_chantable_data[0] },
745 { 34, 5170, bwn_b2062_chantable_data[1] },
746 { 38, 5190, bwn_b2062_chantable_data[2] },
747 { 42, 5210, bwn_b2062_chantable_data[2] },
748 { 46, 5230, bwn_b2062_chantable_data[3] },
749 { 36, 5180, bwn_b2062_chantable_data[4] },
750 { 40, 5200, bwn_b2062_chantable_data[5] },
751 { 44, 5220, bwn_b2062_chantable_data[6] },
752 { 48, 5240, bwn_b2062_chantable_data[3] },
753 { 52, 5260, bwn_b2062_chantable_data[3] },
754 { 56, 5280, bwn_b2062_chantable_data[3] },
755 { 60, 5300, bwn_b2062_chantable_data[7] },
756 { 64, 5320, bwn_b2062_chantable_data[8] },
757 { 100, 5500, bwn_b2062_chantable_data[9] },
758 { 104, 5520, bwn_b2062_chantable_data[10] },
759 { 108, 5540, bwn_b2062_chantable_data[10] },
760 { 112, 5560, bwn_b2062_chantable_data[10] },
761 { 116, 5580, bwn_b2062_chantable_data[11] },
762 { 120, 5600, bwn_b2062_chantable_data[12] },
763 { 124, 5620, bwn_b2062_chantable_data[12] },
764 { 128, 5640, bwn_b2062_chantable_data[12] },
765 { 132, 5660, bwn_b2062_chantable_data[12] },
766 { 136, 5680, bwn_b2062_chantable_data[12] },
767 { 140, 5700, bwn_b2062_chantable_data[12] },
768 { 149, 5745, bwn_b2062_chantable_data[12] },
769 { 153, 5765, bwn_b2062_chantable_data[12] },
770 { 157, 5785, bwn_b2062_chantable_data[12] },
771 { 161, 5805, bwn_b2062_chantable_data[12] },
772 { 165, 5825, bwn_b2062_chantable_data[12] },
773 { 184, 4920, bwn_b2062_chantable_data[13] },
774 { 188, 4940, bwn_b2062_chantable_data[14] },
775 { 192, 4960, bwn_b2062_chantable_data[15] },
776 { 196, 4980, bwn_b2062_chantable_data[16] },
777 { 200, 5000, bwn_b2062_chantable_data[17] },
778 { 204, 5020, bwn_b2062_chantable_data[18] },
779 { 208, 5040, bwn_b2062_chantable_data[19] },
780 { 212, 5060, bwn_b2062_chantable_data[20] },
781 { 216, 5080, bwn_b2062_chantable_data[21] }
785 static const struct bwn_rxcompco bwn_rxcompco_5354[] = {
786 { 1, -66, 15 }, { 2, -66, 15 }, { 3, -66, 15 }, { 4, -66, 15 },
787 { 5, -66, 15 }, { 6, -66, 15 }, { 7, -66, 14 }, { 8, -66, 14 },
788 { 9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 },
789 { 13, -66, 13 }, { 14, -66, 13 },
793 static const struct bwn_rxcompco bwn_rxcompco_r12[] = {
794 { 1, -64, 13 }, { 2, -64, 13 }, { 3, -64, 13 }, { 4, -64, 13 },
795 { 5, -64, 12 }, { 6, -64, 12 }, { 7, -64, 12 }, { 8, -64, 12 },
796 { 9, -64, 12 }, { 10, -64, 11 }, { 11, -64, 11 }, { 12, -64, 11 },
797 { 13, -64, 11 }, { 14, -64, 10 }, { 34, -62, 24 }, { 38, -62, 24 },
798 { 42, -62, 24 }, { 46, -62, 23 }, { 36, -62, 24 }, { 40, -62, 24 },
799 { 44, -62, 23 }, { 48, -62, 23 }, { 52, -62, 23 }, { 56, -62, 22 },
800 { 60, -62, 22 }, { 64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 },
801 { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 },
802 { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 },
803 { 140, -62, 10 }, { 149, -61, 9 }, { 153, -61, 9 }, { 157, -61, 9 },
804 { 161, -61, 8 }, { 165, -61, 8 }, { 184, -62, 25 }, { 188, -62, 25 },
805 { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 },
806 { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 },
809 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 };
811 static const uint8_t bwn_tab_sigsq_tbl[] = {
812 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd,
813 0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
814 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00,
815 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
816 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
817 0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
820 static const uint8_t bwn_tab_pllfrac_tbl[] = {
821 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80,
822 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
825 static const uint16_t bwn_tabl_iqlocal_tbl[] = {
826 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002,
827 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
828 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
829 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
830 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006,
831 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
832 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
833 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
834 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
835 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
836 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
837 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
840 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
841 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
842 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
843 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
844 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
845 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
847 #define VENDOR_LED_ACT(vendor) \
849 .vid = PCI_VENDOR_##vendor, \
850 .led_act = { BWN_VENDOR_LED_ACT_##vendor } \
853 static const struct {
855 uint8_t led_act[BWN_LED_MAX];
856 } bwn_vendor_led_act[] = {
857 VENDOR_LED_ACT(COMPAQ),
858 VENDOR_LED_ACT(ASUSTEK)
861 static const uint8_t bwn_default_led_act[BWN_LED_MAX] =
862 { BWN_VENDOR_LED_ACT_DEFAULT };
864 #undef VENDOR_LED_ACT
866 static const struct {
869 } bwn_led_duration[109] = {
885 static const uint16_t bwn_wme_shm_offsets[] = {
886 [0] = BWN_WME_BESTEFFORT,
887 [1] = BWN_WME_BACKGROUND,
892 static const struct siba_devid bwn_devs[] = {
893 SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"),
894 SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"),
895 SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"),
896 SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"),
897 SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"),
898 SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"),
899 SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"),
900 SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"),
901 SIBA_DEV(BROADCOM, 80211, 16, "Revision 16")
905 bwn_probe(device_t dev)
909 for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) {
910 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor &&
911 siba_get_device(dev) == bwn_devs[i].sd_device &&
912 siba_get_revid(dev) == bwn_devs[i].sd_rev)
913 return (BUS_PROBE_DEFAULT);
920 bwn_attach(device_t dev)
923 struct bwn_softc *sc = device_get_softc(dev);
924 int error, i, msic, reg;
928 sc->sc_debug = bwn_debug;
931 if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
932 error = bwn_attach_pre(sc);
935 bwn_sprom_bugfixes(dev);
936 sc->sc_flags |= BWN_FLAG_ATTACHED;
939 if (!TAILQ_EMPTY(&sc->sc_maclist)) {
940 if (siba_get_pci_device(dev) != 0x4313 &&
941 siba_get_pci_device(dev) != 0x431a &&
942 siba_get_pci_device(dev) != 0x4321) {
943 device_printf(sc->sc_dev,
944 "skip 802.11 cores\n");
949 mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF,
954 mac->mac_status = BWN_MAC_STATUS_UNINIT;
956 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
958 TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac);
959 TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac);
960 TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac);
962 error = bwn_attach_core(mac);
967 device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) "
968 "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
969 siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev),
970 mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev,
971 mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver,
972 mac->mac_phy.rf_rev);
973 if (mac->mac_flags & BWN_MAC_FLAG_DMA)
974 device_printf(sc->sc_dev, "DMA (%d bits)\n",
975 mac->mac_method.dma.dmatype);
977 device_printf(sc->sc_dev, "PIO\n");
980 * setup PCI resources and interrupt.
982 if (pci_find_extcap(dev, PCIY_EXPRESS, ®) == 0) {
983 msic = pci_msi_count(dev);
985 device_printf(sc->sc_dev, "MSI count : %d\n", msic);
989 mac->mac_intr_spec = bwn_res_spec_legacy;
990 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) {
991 if (pci_alloc_msi(dev, &msic) == 0) {
992 device_printf(sc->sc_dev,
993 "Using %d MSI messages\n", msic);
994 mac->mac_intr_spec = bwn_res_spec_msi;
999 error = bus_alloc_resources(dev, mac->mac_intr_spec,
1002 device_printf(sc->sc_dev,
1003 "couldn't allocate IRQ resources (%d)\n", error);
1007 if (mac->mac_msi == 0)
1008 error = bus_setup_intr(dev, mac->mac_res_irq[0],
1009 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1010 &mac->mac_intrhand[0]);
1012 for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1013 error = bus_setup_intr(dev, mac->mac_res_irq[i],
1014 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1015 &mac->mac_intrhand[i]);
1017 device_printf(sc->sc_dev,
1018 "couldn't setup interrupt (%d)\n", error);
1024 TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list);
1027 * calls attach-post routine
1029 if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0)
1030 bwn_attach_post(sc);
1034 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0)
1035 pci_release_msi(dev);
1037 free(mac, M_DEVBUF);
1042 bwn_is_valid_ether_addr(uint8_t *addr)
1044 char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
1046 if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN)))
1053 bwn_attach_post(struct bwn_softc *sc)
1055 struct ieee80211com *ic;
1056 struct ifnet *ifp = sc->sc_ifp;
1060 /* XXX not right but it's not used anywhere important */
1061 ic->ic_phytype = IEEE80211_T_OFDM;
1062 ic->ic_opmode = IEEE80211_M_STA;
1064 IEEE80211_C_STA /* station mode supported */
1065 | IEEE80211_C_MONITOR /* monitor mode */
1066 | IEEE80211_C_AHDEMO /* adhoc demo mode */
1067 | IEEE80211_C_SHPREAMBLE /* short preamble supported */
1068 | IEEE80211_C_SHSLOT /* short slot time supported */
1069 | IEEE80211_C_WME /* WME/WMM supported */
1070 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */
1071 | IEEE80211_C_BGSCAN /* capable of bg scanning */
1072 | IEEE80211_C_TXPMGT /* capable of txpow mgt */
1075 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */
1077 /* call MI attach routine. */
1078 ieee80211_ifattach(ic,
1079 bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
1080 siba_sprom_get_mac_80211a(sc->sc_dev) :
1081 siba_sprom_get_mac_80211bg(sc->sc_dev));
1083 ic->ic_headroom = sizeof(struct bwn_txhdr);
1085 /* override default methods */
1086 ic->ic_raw_xmit = bwn_raw_xmit;
1087 ic->ic_updateslot = bwn_updateslot;
1088 ic->ic_update_promisc = bwn_update_promisc;
1089 ic->ic_wme.wme_update = bwn_wme_update;
1091 ic->ic_scan_start = bwn_scan_start;
1092 ic->ic_scan_end = bwn_scan_end;
1093 ic->ic_set_channel = bwn_set_channel;
1095 ic->ic_vap_create = bwn_vap_create;
1096 ic->ic_vap_delete = bwn_vap_delete;
1098 ieee80211_radiotap_attach(ic,
1099 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
1100 BWN_TX_RADIOTAP_PRESENT,
1101 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
1102 BWN_RX_RADIOTAP_PRESENT);
1104 bwn_sysctl_node(sc);
1107 ieee80211_announce(ic);
1112 bwn_phy_detach(struct bwn_mac *mac)
1115 if (mac->mac_phy.detach != NULL)
1116 mac->mac_phy.detach(mac);
1120 bwn_detach(device_t dev)
1122 struct bwn_softc *sc = device_get_softc(dev);
1123 struct bwn_mac *mac = sc->sc_curmac;
1124 struct ifnet *ifp = sc->sc_ifp;
1125 struct ieee80211com *ic = ifp->if_l2com;
1128 sc->sc_flags |= BWN_FLAG_INVALID;
1130 if (device_is_attached(sc->sc_dev)) {
1133 callout_drain(&sc->sc_led_blink_ch);
1134 callout_drain(&sc->sc_rfswitch_ch);
1135 callout_drain(&sc->sc_task_ch);
1136 callout_drain(&sc->sc_watchdog_ch);
1137 bwn_phy_detach(mac);
1139 ieee80211_draintask(ic, &mac->mac_hwreset);
1140 ieee80211_draintask(ic, &mac->mac_txpower);
1141 ieee80211_ifdetach(ic);
1145 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
1146 taskqueue_free(sc->sc_tq);
1148 for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1149 if (mac->mac_intrhand[i] != NULL) {
1150 bus_teardown_intr(dev, mac->mac_res_irq[i],
1151 mac->mac_intrhand[i]);
1152 mac->mac_intrhand[i] = NULL;
1155 bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq);
1156 if (mac->mac_msi != 0)
1157 pci_release_msi(dev);
1159 BWN_LOCK_DESTROY(sc);
1164 bwn_attach_pre(struct bwn_softc *sc)
1170 TAILQ_INIT(&sc->sc_maclist);
1171 callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0);
1172 callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0);
1173 callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0);
1175 sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT,
1176 taskqueue_thread_enqueue, &sc->sc_tq);
1177 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
1178 "%s taskq", device_get_nameunit(sc->sc_dev));
1180 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
1182 device_printf(sc->sc_dev, "can not if_alloc()\n");
1187 /* set these up early for if_printf use */
1188 if_initname(ifp, device_get_name(sc->sc_dev),
1189 device_get_unit(sc->sc_dev));
1192 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1193 ifp->if_init = bwn_init;
1194 ifp->if_ioctl = bwn_ioctl;
1195 ifp->if_start = bwn_start;
1196 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
1197 ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
1198 IFQ_SET_READY(&ifp->if_snd);
1202 fail: BWN_LOCK_DESTROY(sc);
1207 bwn_sprom_bugfixes(device_t dev)
1209 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \
1210 ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \
1211 (siba_get_pci_device(dev) == _device) && \
1212 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \
1213 (siba_get_pci_subdevice(dev) == _subdevice))
1215 if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
1216 siba_get_pci_subdevice(dev) == 0x4e &&
1217 siba_get_pci_revid(dev) > 0x40)
1218 siba_sprom_set_bf_lo(dev,
1219 siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
1220 if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
1221 siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
1222 siba_sprom_set_bf_lo(dev,
1223 siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
1224 if (siba_get_type(dev) == SIBA_TYPE_PCI) {
1225 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1226 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1227 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1228 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1229 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1230 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1231 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1232 siba_sprom_set_bf_lo(dev,
1233 siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
1239 bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1241 #define IS_RUNNING(ifp) \
1242 ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
1243 struct bwn_softc *sc = ifp->if_softc;
1244 struct ieee80211com *ic = ifp->if_l2com;
1245 struct ifreq *ifr = (struct ifreq *)data;
1246 int error = 0, startall;
1251 if (IS_RUNNING(ifp)) {
1252 bwn_update_promisc(ifp);
1253 } else if (ifp->if_flags & IFF_UP) {
1254 if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
1261 ieee80211_start_all(ic);
1264 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1267 error = ether_ioctl(ifp, cmd, data);
1277 bwn_start(struct ifnet *ifp)
1279 struct bwn_softc *sc = ifp->if_softc;
1282 bwn_start_locked(ifp);
1287 bwn_start_locked(struct ifnet *ifp)
1289 struct bwn_softc *sc = ifp->if_softc;
1290 struct bwn_mac *mac = sc->sc_curmac;
1291 struct ieee80211_frame *wh;
1292 struct ieee80211_node *ni;
1293 struct ieee80211_key *k;
1296 BWN_ASSERT_LOCKED(sc);
1298 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL ||
1299 mac->mac_status < BWN_MAC_STATUS_STARTED)
1303 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */
1307 if (bwn_tx_isfull(sc, m))
1309 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1311 device_printf(sc->sc_dev, "unexpected NULL ni\n");
1316 KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
1317 wh = mtod(m, struct ieee80211_frame *);
1318 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1319 k = ieee80211_crypto_encap(ni, m);
1321 ieee80211_free_node(ni);
1327 wh = NULL; /* Catch any invalid use */
1329 if (bwn_tx_start(sc, ni, m) != 0) {
1331 ieee80211_free_node(ni);
1336 sc->sc_watchdog_timer = 5;
1341 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1343 struct bwn_dma_ring *dr;
1344 struct bwn_mac *mac = sc->sc_curmac;
1345 struct bwn_pio_txqueue *tq;
1346 struct ifnet *ifp = sc->sc_ifp;
1347 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1349 BWN_ASSERT_LOCKED(sc);
1351 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1352 dr = bwn_dma_select(mac, M_WME_GETAC(m));
1353 if (dr->dr_stop == 1 ||
1354 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1359 tq = bwn_pio_select(mac, M_WME_GETAC(m));
1360 if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1361 pktlen > (tq->tq_size - tq->tq_used)) {
1368 IFQ_DRV_PREPEND(&ifp->if_snd, m);
1369 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1374 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1376 struct bwn_mac *mac = sc->sc_curmac;
1379 BWN_ASSERT_LOCKED(sc);
1381 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1386 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1387 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1396 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1398 struct bwn_pio_txpkt *tp;
1399 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1400 struct bwn_softc *sc = mac->mac_sc;
1401 struct bwn_txhdr txhdr;
1407 BWN_ASSERT_LOCKED(sc);
1409 /* XXX TODO send packets after DTIM */
1411 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1412 tp = TAILQ_FIRST(&tq->tq_pktlist);
1416 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1418 device_printf(sc->sc_dev, "tx fail\n");
1422 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1423 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1426 if (siba_get_revid(sc->sc_dev) >= 8) {
1428 * XXX please removes m_defrag(9)
1430 m_new = m_defrag(m, M_DONTWAIT);
1431 if (m_new == NULL) {
1432 device_printf(sc->sc_dev,
1433 "%s: can't defrag TX buffer\n",
1437 if (m_new->m_next != NULL)
1438 device_printf(sc->sc_dev,
1439 "TODO: fragmented packets for PIO\n");
1443 ctl32 = bwn_pio_write_multi_4(mac, tq,
1444 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1445 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1446 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1448 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1449 mtod(m_new, const void *), m_new->m_pkthdr.len);
1450 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1451 ctl32 | BWN_PIO8_TXCTL_EOF);
1453 ctl16 = bwn_pio_write_multi_2(mac, tq,
1454 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1455 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1456 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1457 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1458 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1459 ctl16 | BWN_PIO_TXCTL_EOF);
1465 static struct bwn_pio_txqueue *
1466 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1469 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1470 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1474 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1476 return (&mac->mac_method.pio.wme[WME_AC_BK]);
1478 return (&mac->mac_method.pio.wme[WME_AC_VI]);
1480 return (&mac->mac_method.pio.wme[WME_AC_VO]);
1482 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1487 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1489 #define BWN_GET_TXHDRCACHE(slot) \
1490 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)])
1491 struct bwn_dma *dma = &mac->mac_method.dma;
1492 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1493 struct bwn_dmadesc_generic *desc;
1494 struct bwn_dmadesc_meta *mt;
1495 struct bwn_softc *sc = mac->mac_sc;
1496 struct ifnet *ifp = sc->sc_ifp;
1497 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1498 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1500 BWN_ASSERT_LOCKED(sc);
1501 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1503 /* XXX send after DTIM */
1505 slot = bwn_dma_getslot(dr);
1506 dr->getdesc(dr, slot, &desc, &mt);
1507 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1508 ("%s:%d: fail", __func__, __LINE__));
1510 error = bwn_set_txhdr(dr->dr_mac, ni, m,
1511 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1512 BWN_DMA_COOKIE(dr, slot));
1515 error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap,
1516 BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr,
1517 &mt->mt_paddr, BUS_DMA_NOWAIT);
1519 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1523 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1524 BUS_DMASYNC_PREWRITE);
1525 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1526 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1527 BUS_DMASYNC_PREWRITE);
1529 slot = bwn_dma_getslot(dr);
1530 dr->getdesc(dr, slot, &desc, &mt);
1531 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1532 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1536 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1537 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1538 if (error && error != EFBIG) {
1539 if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
1543 if (error) { /* error == EFBIG */
1546 m_new = m_defrag(m, M_DONTWAIT);
1547 if (m_new == NULL) {
1548 if_printf(ifp, "%s: can't defrag TX buffer\n",
1557 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1558 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1560 if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
1565 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1566 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1567 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1568 BUS_DMASYNC_PREWRITE);
1570 /* XXX send after DTIM */
1572 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1575 dr->dr_curslot = backup[0];
1576 dr->dr_usedslot = backup[1];
1578 #undef BWN_GET_TXHDRCACHE
1582 bwn_watchdog(void *arg)
1584 struct bwn_softc *sc = arg;
1585 struct ifnet *ifp = sc->sc_ifp;
1587 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1588 if_printf(ifp, "device timeout\n");
1591 callout_schedule(&sc->sc_watchdog_ch, hz);
1595 bwn_attach_core(struct bwn_mac *mac)
1597 struct bwn_softc *sc = mac->mac_sc;
1598 int error, have_bg = 0, have_a = 0;
1601 KASSERT(siba_get_revid(sc->sc_dev) >= 5,
1602 ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
1604 siba_powerup(sc->sc_dev, 0);
1606 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
1608 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1609 error = bwn_phy_getinfo(mac, high);
1613 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1614 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1615 if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
1616 siba_get_pci_device(sc->sc_dev) != 0x4319 &&
1617 siba_get_pci_device(sc->sc_dev) != 0x4324) {
1618 have_a = have_bg = 0;
1619 if (mac->mac_phy.type == BWN_PHYTYPE_A)
1621 else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1622 mac->mac_phy.type == BWN_PHYTYPE_N ||
1623 mac->mac_phy.type == BWN_PHYTYPE_LP)
1626 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1627 mac->mac_phy.type));
1629 /* XXX turns off PHY A because it's not supported */
1630 if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1631 mac->mac_phy.type != BWN_PHYTYPE_N) {
1636 if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1637 mac->mac_phy.attach = bwn_phy_g_attach;
1638 mac->mac_phy.detach = bwn_phy_g_detach;
1639 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1640 mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1641 mac->mac_phy.init = bwn_phy_g_init;
1642 mac->mac_phy.exit = bwn_phy_g_exit;
1643 mac->mac_phy.phy_read = bwn_phy_g_read;
1644 mac->mac_phy.phy_write = bwn_phy_g_write;
1645 mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1646 mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1647 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1648 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1649 mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1650 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1651 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1652 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1653 mac->mac_phy.set_im = bwn_phy_g_im;
1654 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1655 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1656 mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1657 mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1658 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1659 mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1660 mac->mac_phy.init = bwn_phy_lp_init;
1661 mac->mac_phy.phy_read = bwn_phy_lp_read;
1662 mac->mac_phy.phy_write = bwn_phy_lp_write;
1663 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1664 mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1665 mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1666 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1667 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1668 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1669 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1670 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1671 mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1673 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1679 mac->mac_phy.gmode = have_bg;
1680 if (mac->mac_phy.attach != NULL) {
1681 error = mac->mac_phy.attach(mac);
1683 device_printf(sc->sc_dev, "failed\n");
1688 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1690 error = bwn_chiptest(mac);
1693 error = bwn_setup_channels(mac, have_bg, have_a);
1695 device_printf(sc->sc_dev, "failed to setup channels\n");
1699 if (sc->sc_curmac == NULL)
1700 sc->sc_curmac = mac;
1702 error = bwn_dma_attach(mac);
1704 device_printf(sc->sc_dev, "failed to initialize DMA\n");
1708 mac->mac_phy.switch_analog(mac, 0);
1710 siba_dev_down(sc->sc_dev, 0);
1712 siba_powerdown(sc->sc_dev);
1717 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1719 struct bwn_softc *sc = mac->mac_sc;
1722 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1724 siba_dev_up(sc->sc_dev, flags);
1727 low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1728 ~BWN_TGSLOW_PHYRESET;
1729 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
1730 siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1732 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1733 siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1736 if (mac->mac_phy.switch_analog != NULL)
1737 mac->mac_phy.switch_analog(mac, 1);
1739 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1740 if (flags & BWN_TGSLOW_SUPPORT_G)
1741 ctl |= BWN_MACCTL_GMODE;
1742 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1746 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1748 struct bwn_phy *phy = &mac->mac_phy;
1749 struct bwn_softc *sc = mac->mac_sc;
1753 tmp = BWN_READ_2(mac, BWN_PHYVER);
1754 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1756 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1757 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1758 phy->rev = (tmp & BWN_PHYVER_VERSION);
1759 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1760 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1761 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1762 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1763 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1764 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1768 if (siba_get_chipid(sc->sc_dev) == 0x4317) {
1769 if (siba_get_chiprev(sc->sc_dev) == 0)
1771 else if (siba_get_chiprev(sc->sc_dev) == 1)
1776 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1777 tmp = BWN_READ_2(mac, BWN_RFDATALO);
1778 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1779 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1781 phy->rf_rev = (tmp & 0xf0000000) >> 28;
1782 phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1783 phy->rf_manuf = (tmp & 0x00000fff);
1784 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */
1786 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1787 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1788 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1789 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1790 (phy->type == BWN_PHYTYPE_N &&
1791 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1792 (phy->type == BWN_PHYTYPE_LP &&
1793 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1798 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1800 phy->type, phy->rev, phy->analog);
1803 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1805 phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1810 bwn_chiptest(struct bwn_mac *mac)
1812 #define TESTVAL0 0x55aaaa55
1813 #define TESTVAL1 0xaa5555aa
1814 struct bwn_softc *sc = mac->mac_sc;
1819 backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1821 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1822 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1824 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1825 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1828 bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1830 if ((siba_get_revid(sc->sc_dev) >= 3) &&
1831 (siba_get_revid(sc->sc_dev) <= 10)) {
1832 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1833 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1834 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1836 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1839 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1841 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1842 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1849 device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1853 #define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1854 #define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1857 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1859 struct bwn_softc *sc = mac->mac_sc;
1860 struct ifnet *ifp = sc->sc_ifp;
1861 struct ieee80211com *ic = ifp->if_l2com;
1863 memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1867 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1868 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1869 if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1871 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1872 &ic->ic_nchans, &bwn_chantable_n,
1873 IEEE80211_CHAN_HTA);
1876 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1877 &ic->ic_nchans, &bwn_chantable_a,
1881 mac->mac_phy.supports_2ghz = have_bg;
1882 mac->mac_phy.supports_5ghz = have_a;
1884 return (ic->ic_nchans == 0 ? ENXIO : 0);
1888 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1892 BWN_ASSERT_LOCKED(mac->mac_sc);
1894 if (way == BWN_SHARED) {
1895 KASSERT((offset & 0x0001) == 0,
1896 ("%s:%d warn", __func__, __LINE__));
1897 if (offset & 0x0003) {
1898 bwn_shm_ctlword(mac, way, offset >> 2);
1899 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1901 bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1902 ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1907 bwn_shm_ctlword(mac, way, offset);
1908 ret = BWN_READ_4(mac, BWN_SHM_DATA);
1914 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1918 BWN_ASSERT_LOCKED(mac->mac_sc);
1920 if (way == BWN_SHARED) {
1921 KASSERT((offset & 0x0001) == 0,
1922 ("%s:%d warn", __func__, __LINE__));
1923 if (offset & 0x0003) {
1924 bwn_shm_ctlword(mac, way, offset >> 2);
1925 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1930 bwn_shm_ctlword(mac, way, offset);
1931 ret = BWN_READ_2(mac, BWN_SHM_DATA);
1938 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1946 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1950 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1953 BWN_ASSERT_LOCKED(mac->mac_sc);
1955 if (way == BWN_SHARED) {
1956 KASSERT((offset & 0x0001) == 0,
1957 ("%s:%d warn", __func__, __LINE__));
1958 if (offset & 0x0003) {
1959 bwn_shm_ctlword(mac, way, offset >> 2);
1960 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1961 (value >> 16) & 0xffff);
1962 bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1963 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1968 bwn_shm_ctlword(mac, way, offset);
1969 BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1973 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1976 BWN_ASSERT_LOCKED(mac->mac_sc);
1978 if (way == BWN_SHARED) {
1979 KASSERT((offset & 0x0001) == 0,
1980 ("%s:%d warn", __func__, __LINE__));
1981 if (offset & 0x0003) {
1982 bwn_shm_ctlword(mac, way, offset >> 2);
1983 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1988 bwn_shm_ctlword(mac, way, offset);
1989 BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1993 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
1998 c->ic_flags = flags;
2001 c->ic_maxpower = 2 * txpow;
2002 c->ic_maxregpower = txpow;
2006 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
2007 const struct bwn_channelinfo *ci, int flags)
2009 struct ieee80211_channel *c;
2012 c = &chans[*nchans];
2014 for (i = 0; i < ci->nchannels; i++) {
2015 const struct bwn_channel *hc;
2017 hc = &ci->channels[i];
2018 if (*nchans >= maxchans)
2020 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
2022 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
2023 /* g channel have a separate b-only entry */
2024 if (*nchans >= maxchans)
2027 c[-1].ic_flags = IEEE80211_CHAN_B;
2030 if (flags == IEEE80211_CHAN_HTG) {
2031 /* HT g channel have a separate g-only entry */
2032 if (*nchans >= maxchans)
2034 c[-1].ic_flags = IEEE80211_CHAN_G;
2036 c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2037 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */
2040 if (flags == IEEE80211_CHAN_HTA) {
2041 /* HT a channel have a separate a-only entry */
2042 if (*nchans >= maxchans)
2044 c[-1].ic_flags = IEEE80211_CHAN_A;
2046 c[0].ic_flags &= ~IEEE80211_CHAN_HT;
2047 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */
2054 bwn_phy_g_attach(struct bwn_mac *mac)
2056 struct bwn_softc *sc = mac->mac_sc;
2057 struct bwn_phy *phy = &mac->mac_phy;
2058 struct bwn_phy_g *pg = &phy->phy_g;
2060 int16_t pab0, pab1, pab2;
2061 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2064 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
2065 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
2066 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
2067 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
2069 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
2070 device_printf(sc->sc_dev, "not supported anymore\n");
2073 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2075 pg->pg_idletssi = 52;
2076 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2080 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2081 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
2082 if (pg->pg_tssi2dbm == NULL) {
2083 device_printf(sc->sc_dev, "failed to allocate buffer\n");
2086 for (i = 0; i < 64; i++) {
2087 int32_t m1, m2, f, q, delta;
2090 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2091 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2096 device_printf(sc->sc_dev,
2097 "failed to generate tssi2dBm\n");
2098 free(pg->pg_tssi2dbm, M_DEVBUF);
2101 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2106 } while (delta >= 2);
2108 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2112 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2117 bwn_phy_g_detach(struct bwn_mac *mac)
2119 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2121 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2122 free(pg->pg_tssi2dbm, M_DEVBUF);
2123 pg->pg_tssi2dbm = NULL;
2129 bwn_phy_g_init_pre(struct bwn_mac *mac)
2131 struct bwn_phy *phy = &mac->mac_phy;
2132 struct bwn_phy_g *pg = &phy->phy_g;
2137 tssi2dbm = pg->pg_tssi2dbm;
2138 idletssi = pg->pg_idletssi;
2140 memset(pg, 0, sizeof(*pg));
2142 pg->pg_tssi2dbm = tssi2dbm;
2143 pg->pg_idletssi = idletssi;
2145 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2147 for (i = 0; i < N(pg->pg_nrssi); i++)
2148 pg->pg_nrssi[i] = -1000;
2149 for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2150 pg->pg_nrssi_lt[i] = i;
2151 pg->pg_lofcal = 0xffff;
2152 pg->pg_initval = 0xffff;
2153 pg->pg_immode = BWN_IMMODE_NONE;
2154 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2155 pg->pg_avgtssi = 0xff;
2157 pg->pg_loctl.tx_bias = 0xff;
2158 TAILQ_INIT(&pg->pg_loctl.calib_list);
2162 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2164 struct bwn_phy *phy = &mac->mac_phy;
2165 struct bwn_phy_g *pg = &phy->phy_g;
2166 struct bwn_softc *sc = mac->mac_sc;
2167 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2168 static const struct bwn_rfatt rfatt0[] = {
2169 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
2170 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2173 static const struct bwn_rfatt rfatt1[] = {
2174 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2177 static const struct bwn_rfatt rfatt2[] = {
2178 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2181 static const struct bwn_bbatt bbatt_0[] = {
2182 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2185 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2187 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2188 pg->pg_bbatt.att = 0;
2190 pg->pg_bbatt.att = 2;
2192 /* prepare Radio Attenuation */
2193 pg->pg_rfatt.padmix = 0;
2195 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
2196 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
2197 if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
2198 pg->pg_rfatt.att = 2;
2200 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
2201 pg->pg_rfatt.att = 3;
2206 if (phy->type == BWN_PHYTYPE_A) {
2207 pg->pg_rfatt.att = 0x60;
2211 switch (phy->rf_ver) {
2213 switch (phy->rf_rev) {
2215 pg->pg_rfatt.att = 5;
2218 if (phy->type == BWN_PHYTYPE_G) {
2219 if (siba_get_pci_subvendor(sc->sc_dev) ==
2220 SIBA_BOARDVENDOR_BCM &&
2221 siba_get_pci_subdevice(sc->sc_dev) ==
2222 SIBA_BOARD_BCM4309G &&
2223 siba_get_pci_revid(sc->sc_dev) >= 30)
2224 pg->pg_rfatt.att = 3;
2225 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2226 SIBA_BOARDVENDOR_BCM &&
2227 siba_get_pci_subdevice(sc->sc_dev) ==
2229 pg->pg_rfatt.att = 3;
2231 pg->pg_rfatt.att = 1;
2233 if (siba_get_pci_subvendor(sc->sc_dev) ==
2234 SIBA_BOARDVENDOR_BCM &&
2235 siba_get_pci_subdevice(sc->sc_dev) ==
2236 SIBA_BOARD_BCM4309G &&
2237 siba_get_pci_revid(sc->sc_dev) >= 30)
2238 pg->pg_rfatt.att = 7;
2240 pg->pg_rfatt.att = 6;
2244 if (phy->type == BWN_PHYTYPE_G) {
2245 if (siba_get_pci_subvendor(sc->sc_dev) ==
2246 SIBA_BOARDVENDOR_BCM &&
2247 siba_get_pci_subdevice(sc->sc_dev) ==
2248 SIBA_BOARD_BCM4309G &&
2249 siba_get_pci_revid(sc->sc_dev) >= 30)
2250 pg->pg_rfatt.att = 3;
2251 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2252 SIBA_BOARDVENDOR_BCM &&
2253 siba_get_pci_subdevice(sc->sc_dev) ==
2255 pg->pg_rfatt.att = 5;
2256 else if (siba_get_chipid(sc->sc_dev) == 0x4320)
2257 pg->pg_rfatt.att = 4;
2259 pg->pg_rfatt.att = 3;
2261 pg->pg_rfatt.att = 6;
2264 pg->pg_rfatt.att = 5;
2268 pg->pg_rfatt.att = 1;
2272 pg->pg_rfatt.att = 5;
2275 pg->pg_rfatt.att = 0xa;
2276 pg->pg_rfatt.padmix = 1;
2280 pg->pg_rfatt.att = 5;
2285 switch (phy->rf_rev) {
2287 pg->pg_rfatt.att = 6;
2292 pg->pg_rfatt.att = 5;
2294 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2296 if (!bwn_has_hwpctl(mac)) {
2297 lo->rfatt.array = rfatt0;
2298 lo->rfatt.len = N(rfatt0);
2303 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2304 lo->rfatt.array = rfatt1;
2305 lo->rfatt.len = N(rfatt1);
2310 lo->rfatt.array = rfatt2;
2311 lo->rfatt.len = N(rfatt2);
2315 lo->bbatt.array = bbatt_0;
2316 lo->bbatt.len = N(bbatt_0);
2320 BWN_READ_4(mac, BWN_MACCTL);
2321 if (phy->rev == 1) {
2323 bwn_reset_core(mac, 0);
2324 bwn_phy_g_init_sub(mac);
2326 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2332 bwn_phy_g_txctl(struct bwn_mac *mac)
2334 struct bwn_phy *phy = &mac->mac_phy;
2336 if (phy->rf_ver != 0x2050)
2338 if (phy->rf_rev == 1)
2339 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2340 if (phy->rf_rev < 6)
2341 return (BWN_TXCTL_PA2DB);
2342 if (phy->rf_rev == 8)
2343 return (BWN_TXCTL_TXMIX);
2348 bwn_phy_g_init(struct bwn_mac *mac)
2351 bwn_phy_g_init_sub(mac);
2356 bwn_phy_g_exit(struct bwn_mac *mac)
2358 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2359 struct bwn_lo_calib *cal, *tmp;
2363 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2364 TAILQ_REMOVE(&lo->calib_list, cal, list);
2365 free(cal, M_DEVBUF);
2370 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2373 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2374 return (BWN_READ_2(mac, BWN_PHYDATA));
2378 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2381 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2382 BWN_WRITE_2(mac, BWN_PHYDATA, value);
2386 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2389 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2390 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2391 return (BWN_READ_2(mac, BWN_RFDATALO));
2395 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2398 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2399 BWN_WRITE_2(mac, BWN_RFCTL, reg);
2400 BWN_WRITE_2(mac, BWN_RFDATALO, value);
2404 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2407 return (mac->mac_phy.rev >= 6);
2411 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2413 struct bwn_phy *phy = &mac->mac_phy;
2414 struct bwn_phy_g *pg = &phy->phy_g;
2415 unsigned int channel;
2416 uint16_t rfover, rfoverval;
2422 BWN_PHY_WRITE(mac, 0x15, 0x8000);
2423 BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2424 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2425 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2426 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2427 pg->pg_radioctx_over);
2428 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2429 pg->pg_radioctx_overval);
2430 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2432 channel = phy->chan;
2433 bwn_phy_g_switch_chan(mac, 6, 1);
2434 bwn_phy_g_switch_chan(mac, channel, 0);
2438 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2439 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2440 pg->pg_radioctx_over = rfover;
2441 pg->pg_radioctx_overval = rfoverval;
2442 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2443 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2444 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2448 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2451 if ((newchan < 1) || (newchan > 14))
2453 bwn_phy_g_switch_chan(mac, newchan, 0);
2459 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2466 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2468 struct bwn_phy *phy = &mac->mac_phy;
2473 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2476 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2477 bwn_hf_write(mac, hf);
2479 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2480 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2481 ((autodiv ? BWN_ANTAUTO1 : antenna)
2482 << BWN_PHY_BBANDCFG_RXANT_SHIFT));
2485 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2486 if (antenna == BWN_ANTAUTO1)
2487 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2489 tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2490 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2492 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2494 tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2496 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2497 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2498 if (phy->rev >= 2) {
2499 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2500 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2501 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2502 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2505 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2507 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2508 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2512 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2514 hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2515 bwn_hf_write(mac, hf);
2519 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2521 struct bwn_phy *phy = &mac->mac_phy;
2522 struct bwn_phy_g *pg = &phy->phy_g;
2524 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2525 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2527 if (phy->rev == 0 || !phy->gmode)
2530 pg->pg_aci_wlan_automatic = 0;
2535 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2537 struct bwn_phy *phy = &mac->mac_phy;
2538 struct bwn_phy_g *pg = &phy->phy_g;
2539 struct bwn_softc *sc = mac->mac_sc;
2546 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2548 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2549 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2550 if (cck < 0 && ofdm < 0) {
2551 if (ignore_tssi == 0)
2552 return (BWN_TXPWR_RES_DONE);
2556 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2557 if (pg->pg_avgtssi != 0xff)
2558 tssi = (tssi + pg->pg_avgtssi) / 2;
2559 pg->pg_avgtssi = tssi;
2560 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2562 max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2563 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2566 device_printf(sc->sc_dev, "invalid max TX-power value\n");
2568 siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2571 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2572 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2573 tssi, 0x00), 0x3f)]);
2575 return (BWN_TXPWR_RES_DONE);
2577 rfatt = -((power + 7) / 8);
2578 bbatt = (-(power / 2)) - (4 * rfatt);
2579 if ((rfatt == 0) && (bbatt == 0))
2580 return (BWN_TXPWR_RES_DONE);
2581 pg->pg_bbatt_delta = bbatt;
2582 pg->pg_rfatt_delta = rfatt;
2583 return (BWN_TXPWR_RES_NEED_ADJUST);
2587 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2589 struct bwn_phy *phy = &mac->mac_phy;
2590 struct bwn_phy_g *pg = &phy->phy_g;
2591 struct bwn_softc *sc = mac->mac_sc;
2595 bwn_mac_suspend(mac);
2597 BWN_ASSERT_LOCKED(sc);
2599 bbatt = pg->pg_bbatt.att;
2600 bbatt += pg->pg_bbatt_delta;
2601 rfatt = pg->pg_rfatt.att;
2602 rfatt += pg->pg_rfatt_delta;
2604 bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2605 txctl = pg->pg_txctl;
2606 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2609 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2612 } else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2614 bbatt += 4 * (rfatt - 2);
2617 } else if (rfatt > 4 && txctl) {
2628 pg->pg_txctl = txctl;
2629 bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2630 pg->pg_rfatt.att = rfatt;
2631 pg->pg_bbatt.att = bbatt;
2633 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2637 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2640 bwn_phy_unlock(mac);
2642 bwn_mac_enable(mac);
2646 bwn_phy_g_task_15s(struct bwn_mac *mac)
2648 struct bwn_phy *phy = &mac->mac_phy;
2649 struct bwn_phy_g *pg = &phy->phy_g;
2650 struct bwn_softc *sc = mac->mac_sc;
2651 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2652 unsigned long expire, now;
2653 struct bwn_lo_calib *cal, *tmp;
2654 uint8_t expired = 0;
2656 bwn_mac_suspend(mac);
2662 if (bwn_has_hwpctl(mac)) {
2663 expire = now - BWN_LO_PWRVEC_EXPIRE;
2664 if (time_before(lo->pwr_vec_read_time, expire)) {
2665 bwn_lo_get_powervector(mac);
2666 bwn_phy_g_dc_lookup_init(mac, 0);
2671 expire = now - BWN_LO_CALIB_EXPIRE;
2672 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2673 if (!time_before(cal->calib_time, expire))
2675 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2676 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2677 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2681 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2682 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2683 cal->ctl.i, cal->ctl.q);
2685 TAILQ_REMOVE(&lo->calib_list, cal, list);
2686 free(cal, M_DEVBUF);
2688 if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2689 cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2692 device_printf(sc->sc_dev,
2693 "failed to recalibrate LO\n");
2696 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2697 bwn_lo_write(mac, &cal->ctl);
2701 bwn_mac_enable(mac);
2705 bwn_phy_g_task_60s(struct bwn_mac *mac)
2707 struct bwn_phy *phy = &mac->mac_phy;
2708 struct bwn_softc *sc = mac->mac_sc;
2709 uint8_t old = phy->chan;
2711 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2714 bwn_mac_suspend(mac);
2715 bwn_nrssi_slope_11g(mac);
2716 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2717 bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2718 bwn_switch_channel(mac, old);
2720 bwn_mac_enable(mac);
2724 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2727 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2731 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2732 const struct ieee80211_bpf_params *params)
2734 struct ieee80211com *ic = ni->ni_ic;
2735 struct ifnet *ifp = ic->ic_ifp;
2736 struct bwn_softc *sc = ifp->if_softc;
2737 struct bwn_mac *mac = sc->sc_curmac;
2739 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
2740 mac->mac_status < BWN_MAC_STATUS_STARTED) {
2741 ieee80211_free_node(ni);
2747 if (bwn_tx_isfull(sc, m)) {
2748 ieee80211_free_node(ni);
2755 if (bwn_tx_start(sc, ni, m) != 0) {
2757 ieee80211_free_node(ni);
2760 sc->sc_watchdog_timer = 5;
2766 * Callback from the 802.11 layer to update the slot time
2767 * based on the current setting. We use it to notify the
2768 * firmware of ERP changes and the f/w takes care of things
2769 * like slot time and preamble.
2772 bwn_updateslot(struct ifnet *ifp)
2774 struct bwn_softc *sc = ifp->if_softc;
2775 struct ieee80211com *ic = ifp->if_l2com;
2776 struct bwn_mac *mac;
2779 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
2780 mac = (struct bwn_mac *)sc->sc_curmac;
2781 bwn_set_slot_time(mac,
2782 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2788 * Callback from the 802.11 layer after a promiscuous mode change.
2789 * Note this interface does not check the operating mode as this
2790 * is an internal callback and we are expected to honor the current
2791 * state (e.g. this is used for setting the interface in promiscuous
2792 * mode when operating in hostap mode to do ACS).
2795 bwn_update_promisc(struct ifnet *ifp)
2797 struct bwn_softc *sc = ifp->if_softc;
2798 struct bwn_mac *mac = sc->sc_curmac;
2801 mac = sc->sc_curmac;
2802 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2803 if (ifp->if_flags & IFF_PROMISC)
2804 sc->sc_filters |= BWN_MACCTL_PROMISC;
2806 sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2807 bwn_set_opmode(mac);
2813 * Callback from the 802.11 layer to update WME parameters.
2816 bwn_wme_update(struct ieee80211com *ic)
2818 struct bwn_softc *sc = ic->ic_ifp->if_softc;
2819 struct bwn_mac *mac = sc->sc_curmac;
2820 struct wmeParams *wmep;
2824 mac = sc->sc_curmac;
2825 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2826 bwn_mac_suspend(mac);
2827 for (i = 0; i < N(sc->sc_wmeParams); i++) {
2828 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2829 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2831 bwn_mac_enable(mac);
2838 bwn_scan_start(struct ieee80211com *ic)
2840 struct ifnet *ifp = ic->ic_ifp;
2841 struct bwn_softc *sc = ifp->if_softc;
2842 struct bwn_mac *mac;
2845 mac = sc->sc_curmac;
2846 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2847 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2848 bwn_set_opmode(mac);
2849 /* disable CFP update during scan */
2850 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2856 bwn_scan_end(struct ieee80211com *ic)
2858 struct ifnet *ifp = ic->ic_ifp;
2859 struct bwn_softc *sc = ifp->if_softc;
2860 struct bwn_mac *mac;
2863 mac = sc->sc_curmac;
2864 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2865 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2866 bwn_set_opmode(mac);
2867 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2873 bwn_set_channel(struct ieee80211com *ic)
2875 struct ifnet *ifp = ic->ic_ifp;
2876 struct bwn_softc *sc = ifp->if_softc;
2877 struct bwn_mac *mac = sc->sc_curmac;
2878 struct bwn_phy *phy = &mac->mac_phy;
2883 error = bwn_switch_band(sc, ic->ic_curchan);
2886 bwn_mac_suspend(mac);
2887 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2888 chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2889 if (chan != phy->chan)
2890 bwn_switch_channel(mac, chan);
2892 /* TX power level */
2893 if (ic->ic_curchan->ic_maxpower != 0 &&
2894 ic->ic_curchan->ic_maxpower != phy->txpower) {
2895 phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2896 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2897 BWN_TXPWR_IGNORE_TSSI);
2900 bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2901 if (phy->set_antenna)
2902 phy->set_antenna(mac, BWN_ANT_DEFAULT);
2904 if (sc->sc_rf_enabled != phy->rf_on) {
2905 if (sc->sc_rf_enabled) {
2907 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2908 device_printf(sc->sc_dev,
2909 "please turns on the RF switch\n");
2911 bwn_rf_turnoff(mac);
2914 bwn_mac_enable(mac);
2918 * Setup radio tap channel freq and flags
2920 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2921 htole16(ic->ic_curchan->ic_freq);
2922 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2923 htole16(ic->ic_curchan->ic_flags & 0xffff);
2928 static struct ieee80211vap *
2929 bwn_vap_create(struct ieee80211com *ic,
2930 const char name[IFNAMSIZ], int unit, int opmode, int flags,
2931 const uint8_t bssid[IEEE80211_ADDR_LEN],
2932 const uint8_t mac0[IEEE80211_ADDR_LEN])
2934 struct ifnet *ifp = ic->ic_ifp;
2935 struct bwn_softc *sc = ifp->if_softc;
2936 struct ieee80211vap *vap;
2937 struct bwn_vap *bvp;
2938 uint8_t mac[IEEE80211_ADDR_LEN];
2940 IEEE80211_ADDR_COPY(mac, mac0);
2942 case IEEE80211_M_HOSTAP:
2943 case IEEE80211_M_MBSS:
2944 case IEEE80211_M_STA:
2945 case IEEE80211_M_WDS:
2946 case IEEE80211_M_MONITOR:
2947 case IEEE80211_M_IBSS:
2948 case IEEE80211_M_AHDEMO:
2954 IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
2956 bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap),
2957 M_80211_VAP, M_NOWAIT | M_ZERO);
2959 device_printf(sc->sc_dev, "failed to allocate a buffer\n");
2963 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
2964 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
2965 /* override with driver methods */
2966 bvp->bv_newstate = vap->iv_newstate;
2967 vap->iv_newstate = bwn_newstate;
2969 /* override max aid so sta's cannot assoc when we're out of sta id's */
2970 vap->iv_max_aid = BWN_STAID_MAX;
2972 ieee80211_ratectl_init(vap);
2974 /* complete setup */
2975 ieee80211_vap_attach(vap, ieee80211_media_change,
2976 ieee80211_media_status);
2981 bwn_vap_delete(struct ieee80211vap *vap)
2983 struct bwn_vap *bvp = BWN_VAP(vap);
2985 ieee80211_ratectl_deinit(vap);
2986 ieee80211_vap_detach(vap);
2987 free(bvp, M_80211_VAP);
2993 struct bwn_softc *sc = arg;
2994 struct ifnet *ifp = sc->sc_ifp;
2995 struct ieee80211com *ic = ifp->if_l2com;
2998 DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
2999 __func__, ifp->if_flags);
3002 error = bwn_init_locked(sc);
3006 ieee80211_start_all(ic); /* start all vap's */
3010 bwn_init_locked(struct bwn_softc *sc)
3012 struct bwn_mac *mac;
3013 struct ifnet *ifp = sc->sc_ifp;
3016 BWN_ASSERT_LOCKED(sc);
3018 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
3019 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
3022 sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
3023 sc->sc_rf_enabled = 1;
3025 mac = sc->sc_curmac;
3026 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
3027 error = bwn_core_init(mac);
3031 if (mac->mac_status == BWN_MAC_STATUS_INITED)
3032 bwn_core_start(mac);
3034 bwn_set_opmode(mac);
3035 bwn_set_pretbtt(mac);
3036 bwn_spu_setdelay(mac, 0);
3037 bwn_set_macaddr(mac);
3039 ifp->if_drv_flags |= IFF_DRV_RUNNING;
3040 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
3041 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
3047 bwn_stop(struct bwn_softc *sc, int statechg)
3051 bwn_stop_locked(sc, statechg);
3056 bwn_stop_locked(struct bwn_softc *sc, int statechg)
3058 struct bwn_mac *mac = sc->sc_curmac;
3059 struct ifnet *ifp = sc->sc_ifp;
3061 BWN_ASSERT_LOCKED(sc);
3063 if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
3064 /* XXX FIXME opmode not based on VAP */
3065 bwn_set_opmode(mac);
3066 bwn_set_macaddr(mac);
3069 if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
3072 callout_stop(&sc->sc_led_blink_ch);
3073 sc->sc_led_blinking = 0;
3076 sc->sc_rf_enabled = 0;
3078 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
3082 bwn_wme_clear(struct bwn_softc *sc)
3084 #define MS(_v, _f) (((_v) & _f) >> _f##_S)
3085 struct wmeParams *p;
3088 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
3089 ("%s:%d: fail", __func__, __LINE__));
3091 for (i = 0; i < N(sc->sc_wmeParams); i++) {
3092 p = &(sc->sc_wmeParams[i]);
3094 switch (bwn_wme_shm_offsets[i]) {
3096 p->wmep_txopLimit = 0;
3098 /* XXX FIXME: log2(cwmin) */
3099 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3100 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3103 p->wmep_txopLimit = 0;
3105 /* XXX FIXME: log2(cwmin) */
3106 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3107 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3109 case BWN_WME_BESTEFFORT:
3110 p->wmep_txopLimit = 0;
3112 /* XXX FIXME: log2(cwmin) */
3113 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3114 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3116 case BWN_WME_BACKGROUND:
3117 p->wmep_txopLimit = 0;
3119 /* XXX FIXME: log2(cwmin) */
3120 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3121 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3124 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3130 bwn_core_init(struct bwn_mac *mac)
3132 struct bwn_softc *sc = mac->mac_sc;
3136 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3137 ("%s:%d: fail", __func__, __LINE__));
3139 siba_powerup(sc->sc_dev, 0);
3140 if (!siba_dev_isup(sc->sc_dev))
3142 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3144 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3145 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3146 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3147 BWN_GETTIME(mac->mac_phy.nexttime);
3148 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3149 bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3150 mac->mac_stats.link_noise = -95;
3151 mac->mac_reason_intr = 0;
3152 bzero(mac->mac_reason, sizeof(mac->mac_reason));
3153 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3155 if (sc->sc_debug & BWN_DEBUG_XMIT)
3156 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3158 mac->mac_suspended = 1;
3159 mac->mac_task_state = 0;
3160 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3162 mac->mac_phy.init_pre(mac);
3164 siba_pcicore_intr(sc->sc_dev);
3166 siba_fix_imcfglobug(sc->sc_dev);
3167 bwn_bt_disable(mac);
3168 if (mac->mac_phy.prepare_hw) {
3169 error = mac->mac_phy.prepare_hw(mac);
3173 error = bwn_chip_init(mac);
3176 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3177 siba_get_revid(sc->sc_dev));
3178 hf = bwn_hf_read(mac);
3179 if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3180 hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3181 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3182 hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3183 if (mac->mac_phy.rev == 1)
3184 hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3186 if (mac->mac_phy.rf_ver == 0x2050) {
3187 if (mac->mac_phy.rf_rev < 6)
3188 hf |= BWN_HF_FORCE_VCO_RECALC;
3189 if (mac->mac_phy.rf_rev == 6)
3190 hf |= BWN_HF_4318_TSSI;
3192 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3193 hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3194 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3195 (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3196 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3197 hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3198 bwn_hf_write(mac, hf);
3200 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3201 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3202 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3203 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3206 bwn_set_phytxctl(mac);
3208 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3209 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3210 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3212 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3219 bwn_spu_setdelay(mac, 1);
3222 siba_powerup(sc->sc_dev,
3223 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3224 bwn_set_macaddr(mac);
3225 bwn_crypt_init(mac);
3227 /* XXX LED initializatin */
3229 mac->mac_status = BWN_MAC_STATUS_INITED;
3236 siba_powerdown(sc->sc_dev);
3237 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3238 ("%s:%d: fail", __func__, __LINE__));
3243 bwn_core_start(struct bwn_mac *mac)
3245 struct bwn_softc *sc = mac->mac_sc;
3248 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3249 ("%s:%d: fail", __func__, __LINE__));
3251 if (siba_get_revid(sc->sc_dev) < 5)
3255 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3256 if (!(tmp & 0x00000001))
3258 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3261 bwn_mac_enable(mac);
3262 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3263 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3265 mac->mac_status = BWN_MAC_STATUS_STARTED;
3269 bwn_core_exit(struct bwn_mac *mac)
3271 struct bwn_softc *sc = mac->mac_sc;
3274 BWN_ASSERT_LOCKED(mac->mac_sc);
3276 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3277 ("%s:%d: fail", __func__, __LINE__));
3279 if (mac->mac_status != BWN_MAC_STATUS_INITED)
3281 mac->mac_status = BWN_MAC_STATUS_UNINIT;
3283 macctl = BWN_READ_4(mac, BWN_MACCTL);
3284 macctl &= ~BWN_MACCTL_MCODE_RUN;
3285 macctl |= BWN_MACCTL_MCODE_JMP0;
3286 BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3291 mac->mac_phy.switch_analog(mac, 0);
3292 siba_dev_down(sc->sc_dev, 0);
3293 siba_powerdown(sc->sc_dev);
3297 bwn_bt_disable(struct bwn_mac *mac)
3299 struct bwn_softc *sc = mac->mac_sc;
3302 /* XXX do nothing yet */
3306 bwn_chip_init(struct bwn_mac *mac)
3308 struct bwn_softc *sc = mac->mac_sc;
3309 struct bwn_phy *phy = &mac->mac_phy;
3313 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3315 macctl |= BWN_MACCTL_GMODE;
3316 BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3318 error = bwn_fw_fillinfo(mac);
3321 error = bwn_fw_loaducode(mac);
3325 error = bwn_gpio_init(mac);
3329 error = bwn_fw_loadinitvals(mac);
3331 siba_gpio_set(sc->sc_dev, 0);
3334 phy->switch_analog(mac, 1);
3335 error = bwn_phy_init(mac);
3337 siba_gpio_set(sc->sc_dev, 0);
3341 phy->set_im(mac, BWN_IMMODE_NONE);
3342 if (phy->set_antenna)
3343 phy->set_antenna(mac, BWN_ANT_DEFAULT);
3344 bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3346 if (phy->type == BWN_PHYTYPE_B)
3347 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3348 BWN_WRITE_4(mac, 0x0100, 0x01000000);
3349 if (siba_get_revid(sc->sc_dev) < 5)
3350 BWN_WRITE_4(mac, 0x010c, 0x01000000);
3352 BWN_WRITE_4(mac, BWN_MACCTL,
3353 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3354 BWN_WRITE_4(mac, BWN_MACCTL,
3355 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3356 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3358 bwn_set_opmode(mac);
3359 if (siba_get_revid(sc->sc_dev) < 3) {
3360 BWN_WRITE_2(mac, 0x060e, 0x0000);
3361 BWN_WRITE_2(mac, 0x0610, 0x8000);
3362 BWN_WRITE_2(mac, 0x0604, 0x0000);
3363 BWN_WRITE_2(mac, 0x0606, 0x0200);
3365 BWN_WRITE_4(mac, 0x0188, 0x80000000);
3366 BWN_WRITE_4(mac, 0x018c, 0x02000000);
3368 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3369 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
3370 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3371 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3372 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3373 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3374 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3375 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3376 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3377 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3381 /* read hostflags */
3383 bwn_hf_read(struct bwn_mac *mac)
3387 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3389 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3391 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3396 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3399 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3400 (value & 0x00000000ffffull));
3401 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3402 (value & 0x0000ffff0000ull) >> 16);
3403 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3404 (value & 0xffff00000000ULL) >> 32);
3408 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3411 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3412 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3416 bwn_rate_init(struct bwn_mac *mac)
3419 switch (mac->mac_phy.type) {
3422 case BWN_PHYTYPE_LP:
3424 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3425 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3426 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3427 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3428 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3429 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3430 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3431 if (mac->mac_phy.type == BWN_PHYTYPE_A)
3435 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3436 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3437 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3438 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3441 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3446 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3452 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3455 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3457 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3458 bwn_shm_read_2(mac, BWN_SHARED, offset));
3462 bwn_plcp_getcck(const uint8_t bitrate)
3466 case BWN_CCK_RATE_1MB:
3468 case BWN_CCK_RATE_2MB:
3470 case BWN_CCK_RATE_5MB:
3472 case BWN_CCK_RATE_11MB:
3475 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3480 bwn_plcp_getofdm(const uint8_t bitrate)
3484 case BWN_OFDM_RATE_6MB:
3486 case BWN_OFDM_RATE_9MB:
3488 case BWN_OFDM_RATE_12MB:
3490 case BWN_OFDM_RATE_18MB:
3492 case BWN_OFDM_RATE_24MB:
3494 case BWN_OFDM_RATE_36MB:
3496 case BWN_OFDM_RATE_48MB:
3498 case BWN_OFDM_RATE_54MB:
3501 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3506 bwn_set_phytxctl(struct bwn_mac *mac)
3510 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3512 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3513 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3514 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3518 bwn_pio_init(struct bwn_mac *mac)
3520 struct bwn_pio *pio = &mac->mac_method.pio;
3522 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3523 & ~BWN_MACCTL_BIGENDIAN);
3524 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3526 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3527 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3528 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3529 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3530 bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3531 bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3535 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3538 struct bwn_pio_txpkt *tp;
3539 struct bwn_softc *sc = mac->mac_sc;
3542 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3543 tq->tq_index = index;
3545 tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3546 if (siba_get_revid(sc->sc_dev) >= 8)
3549 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3553 TAILQ_INIT(&tq->tq_pktlist);
3554 for (i = 0; i < N(tq->tq_pkts); i++) {
3555 tp = &(tq->tq_pkts[i]);
3558 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3563 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3565 struct bwn_softc *sc = mac->mac_sc;
3566 static const uint16_t bases[] = {
3576 static const uint16_t bases_rev11[] = {
3585 if (siba_get_revid(sc->sc_dev) >= 11) {
3586 if (index >= N(bases_rev11))
3587 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3588 return (bases_rev11[index]);
3590 if (index >= N(bases))
3591 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3592 return (bases[index]);
3596 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3599 struct bwn_softc *sc = mac->mac_sc;
3602 prq->prq_rev = siba_get_revid(sc->sc_dev);
3603 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3604 bwn_dma_rxdirectfifo(mac, index, 1);
3608 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3612 bwn_pio_cancel_tx_packets(tq);
3616 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3619 bwn_destroy_pioqueue_tx(pio);
3623 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3627 return (BWN_READ_2(mac, tq->tq_base + offset));
3631 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3637 type = bwn_dma_mask2type(bwn_dma_mask(mac));
3638 base = bwn_dma_base(type, idx);
3639 if (type == BWN_DMA_64BIT) {
3640 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3641 ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3643 ctl |= BWN_DMA64_RXDIRECTFIFO;
3644 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3646 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3647 ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3649 ctl |= BWN_DMA32_RXDIRECTFIFO;
3650 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3655 bwn_dma_mask(struct bwn_mac *mac)
3660 tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3661 if (tmp & SIBA_TGSHIGH_DMA64)
3662 return (BWN_DMA_BIT_MASK(64));
3663 base = bwn_dma_base(0, 0);
3664 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3665 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3666 if (tmp & BWN_DMA32_TXADDREXT_MASK)
3667 return (BWN_DMA_BIT_MASK(32));
3669 return (BWN_DMA_BIT_MASK(30));
3673 bwn_dma_mask2type(uint64_t dmamask)
3676 if (dmamask == BWN_DMA_BIT_MASK(30))
3677 return (BWN_DMA_30BIT);
3678 if (dmamask == BWN_DMA_BIT_MASK(32))
3679 return (BWN_DMA_32BIT);
3680 if (dmamask == BWN_DMA_BIT_MASK(64))
3681 return (BWN_DMA_64BIT);
3682 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3683 return (BWN_DMA_30BIT);
3687 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3689 struct bwn_pio_txpkt *tp;
3692 for (i = 0; i < N(tq->tq_pkts); i++) {
3693 tp = &(tq->tq_pkts[i]);
3702 bwn_dma_base(int type, int controller_idx)
3704 static const uint16_t map64[] = {
3712 static const uint16_t map32[] = {
3721 if (type == BWN_DMA_64BIT) {
3722 KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3723 ("%s:%d: fail", __func__, __LINE__));
3724 return (map64[controller_idx]);
3726 KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3727 ("%s:%d: fail", __func__, __LINE__));
3728 return (map32[controller_idx]);
3732 bwn_dma_init(struct bwn_mac *mac)
3734 struct bwn_dma *dma = &mac->mac_method.dma;
3736 /* setup TX DMA channels. */
3737 bwn_dma_setup(dma->wme[WME_AC_BK]);
3738 bwn_dma_setup(dma->wme[WME_AC_BE]);
3739 bwn_dma_setup(dma->wme[WME_AC_VI]);
3740 bwn_dma_setup(dma->wme[WME_AC_VO]);
3741 bwn_dma_setup(dma->mcast);
3742 /* setup RX DMA channel. */
3743 bwn_dma_setup(dma->rx);
3746 static struct bwn_dma_ring *
3747 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3748 int for_tx, int type)
3750 struct bwn_dma *dma = &mac->mac_method.dma;
3751 struct bwn_dma_ring *dr;
3752 struct bwn_dmadesc_generic *desc;
3753 struct bwn_dmadesc_meta *mt;
3754 struct bwn_softc *sc = mac->mac_sc;
3757 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO);
3760 dr->dr_numslots = BWN_RXRING_SLOTS;
3762 dr->dr_numslots = BWN_TXRING_SLOTS;
3764 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3765 M_DEVBUF, M_NOWAIT | M_ZERO);
3766 if (dr->dr_meta == NULL)
3771 dr->dr_base = bwn_dma_base(type, controller_index);
3772 dr->dr_index = controller_index;
3773 if (type == BWN_DMA_64BIT) {
3774 dr->getdesc = bwn_dma_64_getdesc;
3775 dr->setdesc = bwn_dma_64_setdesc;
3776 dr->start_transfer = bwn_dma_64_start_transfer;
3777 dr->suspend = bwn_dma_64_suspend;
3778 dr->resume = bwn_dma_64_resume;
3779 dr->get_curslot = bwn_dma_64_get_curslot;
3780 dr->set_curslot = bwn_dma_64_set_curslot;
3782 dr->getdesc = bwn_dma_32_getdesc;
3783 dr->setdesc = bwn_dma_32_setdesc;
3784 dr->start_transfer = bwn_dma_32_start_transfer;
3785 dr->suspend = bwn_dma_32_suspend;
3786 dr->resume = bwn_dma_32_resume;
3787 dr->get_curslot = bwn_dma_32_get_curslot;
3788 dr->set_curslot = bwn_dma_32_set_curslot;
3792 dr->dr_curslot = -1;
3794 if (dr->dr_index == 0) {
3795 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3796 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3798 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3801 error = bwn_dma_allocringmemory(dr);
3807 * Assumption: BWN_TXRING_SLOTS can be divided by
3808 * BWN_TX_SLOTS_PER_FRAME
3810 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3811 ("%s:%d: fail", __func__, __LINE__));
3813 dr->dr_txhdr_cache =
3814 malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3815 BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO);
3816 KASSERT(dr->dr_txhdr_cache != NULL,
3817 ("%s:%d: fail", __func__, __LINE__));
3820 * Create TX ring DMA stuffs
3822 error = bus_dma_tag_create(dma->parent_dtag,
3829 BUS_SPACE_MAXSIZE_32BIT,
3832 &dr->dr_txring_dtag);
3834 device_printf(sc->sc_dev,
3835 "can't create TX ring DMA tag: TODO frees\n");
3839 for (i = 0; i < dr->dr_numslots; i += 2) {
3840 dr->getdesc(dr, i, &desc, &mt);
3842 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3846 error = bus_dmamap_create(dr->dr_txring_dtag, 0,
3849 device_printf(sc->sc_dev,
3850 "can't create RX buf DMA map\n");
3854 dr->getdesc(dr, i + 1, &desc, &mt);
3856 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3860 error = bus_dmamap_create(dma->txbuf_dtag, 0,
3863 device_printf(sc->sc_dev,
3864 "can't create RX buf DMA map\n");
3869 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3870 &dr->dr_spare_dmap);
3872 device_printf(sc->sc_dev,
3873 "can't create RX buf DMA map\n");
3874 goto out; /* XXX wrong! */
3877 for (i = 0; i < dr->dr_numslots; i++) {
3878 dr->getdesc(dr, i, &desc, &mt);
3880 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3883 device_printf(sc->sc_dev,
3884 "can't create RX buf DMA map\n");
3885 goto out; /* XXX wrong! */
3887 error = bwn_dma_newbuf(dr, desc, mt, 1);
3889 device_printf(sc->sc_dev,
3890 "failed to allocate RX buf\n");
3891 goto out; /* XXX wrong! */
3895 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3896 BUS_DMASYNC_PREWRITE);
3898 dr->dr_usedslot = dr->dr_numslots;
3905 free(dr->dr_txhdr_cache, M_DEVBUF);
3907 free(dr->dr_meta, M_DEVBUF);
3914 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3920 bwn_dma_free_descbufs(*dr);
3921 bwn_dma_free_ringmemory(*dr);
3923 free((*dr)->dr_txhdr_cache, M_DEVBUF);
3924 free((*dr)->dr_meta, M_DEVBUF);
3925 free(*dr, M_DEVBUF);
3931 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3932 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3934 struct bwn_dmadesc32 *desc;
3936 *meta = &(dr->dr_meta[slot]);
3937 desc = dr->dr_ring_descbase;
3938 desc = &(desc[slot]);
3940 *gdesc = (struct bwn_dmadesc_generic *)desc;
3944 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3945 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3946 int start, int end, int irq)
3948 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3949 struct bwn_softc *sc = dr->dr_mac->mac_sc;
3950 uint32_t addr, addrext, ctl;
3953 slot = (int)(&(desc->dma.dma32) - descbase);
3954 KASSERT(slot >= 0 && slot < dr->dr_numslots,
3955 ("%s:%d: fail", __func__, __LINE__));
3957 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
3958 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
3959 addr |= siba_dma_translation(sc->sc_dev);
3960 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3961 if (slot == dr->dr_numslots - 1)
3962 ctl |= BWN_DMA32_DCTL_DTABLEEND;
3964 ctl |= BWN_DMA32_DCTL_FRAMESTART;
3966 ctl |= BWN_DMA32_DCTL_FRAMEEND;
3968 ctl |= BWN_DMA32_DCTL_IRQ;
3969 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3970 & BWN_DMA32_DCTL_ADDREXT_MASK;
3972 desc->dma.dma32.control = htole32(ctl);
3973 desc->dma.dma32.address = htole32(addr);
3977 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3980 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3981 (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3985 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3988 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3989 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3993 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3996 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3997 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
4001 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
4005 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
4006 val &= BWN_DMA32_RXDPTR;
4008 return (val / sizeof(struct bwn_dmadesc32));
4012 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
4015 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
4016 (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
4020 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
4021 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
4023 struct bwn_dmadesc64 *desc;
4025 *meta = &(dr->dr_meta[slot]);
4026 desc = dr->dr_ring_descbase;
4027 desc = &(desc[slot]);
4029 *gdesc = (struct bwn_dmadesc_generic *)desc;
4033 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
4034 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
4035 int start, int end, int irq)
4037 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
4038 struct bwn_softc *sc = dr->dr_mac->mac_sc;
4040 uint32_t ctl0 = 0, ctl1 = 0;
4041 uint32_t addrlo, addrhi;
4044 slot = (int)(&(desc->dma.dma64) - descbase);
4045 KASSERT(slot >= 0 && slot < dr->dr_numslots,
4046 ("%s:%d: fail", __func__, __LINE__));
4048 addrlo = (uint32_t) (dmaaddr & 0xffffffff);
4049 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
4050 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
4052 addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
4053 if (slot == dr->dr_numslots - 1)
4054 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
4056 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
4058 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
4060 ctl0 |= BWN_DMA64_DCTL0_IRQ;
4061 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
4062 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
4063 & BWN_DMA64_DCTL1_ADDREXT_MASK;
4065 desc->dma.dma64.control0 = htole32(ctl0);
4066 desc->dma.dma64.control1 = htole32(ctl1);
4067 desc->dma.dma64.address_low = htole32(addrlo);
4068 desc->dma.dma64.address_high = htole32(addrhi);
4072 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
4075 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
4076 (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4080 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
4083 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4084 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
4088 bwn_dma_64_resume(struct bwn_dma_ring *dr)
4091 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
4092 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
4096 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
4100 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
4101 val &= BWN_DMA64_RXSTATDPTR;
4103 return (val / sizeof(struct bwn_dmadesc64));
4107 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4110 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4111 (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4115 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4117 struct bwn_mac *mac = dr->dr_mac;
4118 struct bwn_dma *dma = &mac->mac_method.dma;
4119 struct bwn_softc *sc = mac->mac_sc;
4122 error = bus_dma_tag_create(dma->parent_dtag,
4127 BWN_DMA_RINGMEMSIZE,
4129 BUS_SPACE_MAXSIZE_32BIT,
4134 device_printf(sc->sc_dev,
4135 "can't create TX ring DMA tag: TODO frees\n");
4139 error = bus_dmamem_alloc(dr->dr_ring_dtag,
4140 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4143 device_printf(sc->sc_dev,
4144 "can't allocate DMA mem: TODO frees\n");
4147 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4148 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4149 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
4151 device_printf(sc->sc_dev,
4152 "can't load DMA mem: TODO free\n");
4160 bwn_dma_setup(struct bwn_dma_ring *dr)
4162 struct bwn_softc *sc = dr->dr_mac->mac_sc;
4164 uint32_t addrext, ring32, value;
4165 uint32_t trans = siba_dma_translation(sc->sc_dev);
4168 dr->dr_curslot = -1;
4170 if (dr->dr_type == BWN_DMA_64BIT) {
4171 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4172 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4174 value = BWN_DMA64_TXENABLE;
4175 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4176 & BWN_DMA64_TXADDREXT_MASK;
4177 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4178 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4179 (ring64 & 0xffffffff));
4180 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4182 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4184 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4185 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4186 value = BWN_DMA32_TXENABLE;
4187 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4188 & BWN_DMA32_TXADDREXT_MASK;
4189 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4190 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4191 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4199 dr->dr_usedslot = dr->dr_numslots;
4201 if (dr->dr_type == BWN_DMA_64BIT) {
4202 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4203 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4204 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4205 value |= BWN_DMA64_RXENABLE;
4206 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4207 & BWN_DMA64_RXADDREXT_MASK;
4208 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4209 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4210 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4211 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4213 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4214 sizeof(struct bwn_dmadesc64));
4216 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4217 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4218 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4219 value |= BWN_DMA32_RXENABLE;
4220 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4221 & BWN_DMA32_RXADDREXT_MASK;
4222 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4223 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4224 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4225 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4226 sizeof(struct bwn_dmadesc32));
4231 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4234 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4235 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4240 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4244 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4245 if (dr->dr_type == BWN_DMA_64BIT) {
4246 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4247 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4249 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4251 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4252 if (dr->dr_type == BWN_DMA_64BIT) {
4253 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4254 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4256 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4261 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4263 struct bwn_dmadesc_generic *desc;
4264 struct bwn_dmadesc_meta *meta;
4265 struct bwn_mac *mac = dr->dr_mac;
4266 struct bwn_dma *dma = &mac->mac_method.dma;
4267 struct bwn_softc *sc = mac->mac_sc;
4270 if (!dr->dr_usedslot)
4272 for (i = 0; i < dr->dr_numslots; i++) {
4273 dr->getdesc(dr, i, &desc, &meta);
4275 if (meta->mt_m == NULL) {
4277 device_printf(sc->sc_dev, "%s: not TX?\n",
4282 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
4283 bus_dmamap_unload(dr->dr_txring_dtag,
4285 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
4286 bus_dmamap_unload(dma->txbuf_dtag,
4289 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4290 bwn_dma_free_descbuf(dr, meta);
4295 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4298 struct bwn_softc *sc = mac->mac_sc;
4303 for (i = 0; i < 10; i++) {
4304 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4306 value = BWN_READ_4(mac, base + offset);
4307 if (type == BWN_DMA_64BIT) {
4308 value &= BWN_DMA64_TXSTAT;
4309 if (value == BWN_DMA64_TXSTAT_DISABLED ||
4310 value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4311 value == BWN_DMA64_TXSTAT_STOPPED)
4314 value &= BWN_DMA32_TXSTATE;
4315 if (value == BWN_DMA32_TXSTAT_DISABLED ||
4316 value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4317 value == BWN_DMA32_TXSTAT_STOPPED)
4322 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4323 BWN_WRITE_4(mac, base + offset, 0);
4324 for (i = 0; i < 10; i++) {
4325 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4327 value = BWN_READ_4(mac, base + offset);
4328 if (type == BWN_DMA_64BIT) {
4329 value &= BWN_DMA64_TXSTAT;
4330 if (value == BWN_DMA64_TXSTAT_DISABLED) {
4335 value &= BWN_DMA32_TXSTATE;
4336 if (value == BWN_DMA32_TXSTAT_DISABLED) {
4344 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4353 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4356 struct bwn_softc *sc = mac->mac_sc;
4361 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4362 BWN_WRITE_4(mac, base + offset, 0);
4363 for (i = 0; i < 10; i++) {
4364 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4366 value = BWN_READ_4(mac, base + offset);
4367 if (type == BWN_DMA_64BIT) {
4368 value &= BWN_DMA64_RXSTAT;
4369 if (value == BWN_DMA64_RXSTAT_DISABLED) {
4374 value &= BWN_DMA32_RXSTATE;
4375 if (value == BWN_DMA32_RXSTAT_DISABLED) {
4383 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4391 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4392 struct bwn_dmadesc_meta *meta)
4395 if (meta->mt_m != NULL) {
4396 m_freem(meta->mt_m);
4399 if (meta->mt_ni != NULL) {
4400 ieee80211_free_node(meta->mt_ni);
4406 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4408 struct bwn_rxhdr4 *rxhdr;
4409 unsigned char *frame;
4411 rxhdr = mtod(m, struct bwn_rxhdr4 *);
4412 rxhdr->frame_len = 0;
4414 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4415 sizeof(struct bwn_plcp6) + 2,
4416 ("%s:%d: fail", __func__, __LINE__));
4417 frame = mtod(m, char *) + dr->dr_frameoffset;
4418 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4422 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4424 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4426 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4431 bwn_wme_init(struct bwn_mac *mac)
4436 /* enable WME support. */
4437 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4438 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4439 BWN_IFSCTL_USE_EDCF);
4443 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4445 struct bwn_softc *sc = mac->mac_sc;
4446 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
4447 uint16_t delay; /* microsec */
4449 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4450 if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4452 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4453 delay = max(delay, (uint16_t)2400);
4455 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4459 bwn_bt_enable(struct bwn_mac *mac)
4461 struct bwn_softc *sc = mac->mac_sc;
4464 if (bwn_bluetooth == 0)
4466 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4468 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4471 hf = bwn_hf_read(mac);
4472 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4473 hf |= BWN_HF_BT_COEXISTALT;
4475 hf |= BWN_HF_BT_COEXIST;
4476 bwn_hf_write(mac, hf);
4480 bwn_set_macaddr(struct bwn_mac *mac)
4483 bwn_mac_write_bssid(mac);
4484 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
4488 bwn_clear_keys(struct bwn_mac *mac)
4492 for (i = 0; i < mac->mac_max_nr_keys; i++) {
4493 KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4494 ("%s:%d: fail", __func__, __LINE__));
4496 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4497 NULL, BWN_SEC_KEYSIZE, NULL);
4498 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4499 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4500 NULL, BWN_SEC_KEYSIZE, NULL);
4502 mac->mac_key[i].keyconf = NULL;
4507 bwn_crypt_init(struct bwn_mac *mac)
4509 struct bwn_softc *sc = mac->mac_sc;
4511 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4512 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4513 ("%s:%d: fail", __func__, __LINE__));
4514 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4516 if (siba_get_revid(sc->sc_dev) >= 5)
4517 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4518 bwn_clear_keys(mac);
4522 bwn_chip_exit(struct bwn_mac *mac)
4524 struct bwn_softc *sc = mac->mac_sc;
4527 siba_gpio_set(sc->sc_dev, 0);
4531 bwn_fw_fillinfo(struct bwn_mac *mac)
4535 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4538 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4545 bwn_gpio_init(struct bwn_mac *mac)
4547 struct bwn_softc *sc = mac->mac_sc;
4548 uint32_t mask = 0x1f, set = 0xf, value;
4550 BWN_WRITE_4(mac, BWN_MACCTL,
4551 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4552 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4553 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4555 if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4559 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4560 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4561 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4565 if (siba_get_revid(sc->sc_dev) >= 2)
4568 value = siba_gpio_get(sc->sc_dev);
4571 siba_gpio_set(sc->sc_dev, (value & mask) | set);
4577 bwn_fw_loadinitvals(struct bwn_mac *mac)
4579 #define GETFWOFFSET(fwp, offset) \
4580 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4581 const size_t hdr_len = sizeof(struct bwn_fwhdr);
4582 const struct bwn_fwhdr *hdr;
4583 struct bwn_fw *fw = &mac->mac_fw;
4586 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4587 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4588 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4591 if (fw->initvals_band.fw) {
4592 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4593 error = bwn_fwinitvals_write(mac,
4594 GETFWOFFSET(fw->initvals_band, hdr_len),
4596 fw->initvals_band.fw->datasize - hdr_len);
4603 bwn_phy_init(struct bwn_mac *mac)
4605 struct bwn_softc *sc = mac->mac_sc;
4608 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4609 mac->mac_phy.rf_onoff(mac, 1);
4610 error = mac->mac_phy.init(mac);
4612 device_printf(sc->sc_dev, "PHY init failed\n");
4615 error = bwn_switch_channel(mac,
4616 mac->mac_phy.get_default_chan(mac));
4618 device_printf(sc->sc_dev,
4619 "failed to switch default channel\n");
4624 if (mac->mac_phy.exit)
4625 mac->mac_phy.exit(mac);
4627 mac->mac_phy.rf_onoff(mac, 0);
4633 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4638 ant = bwn_ant2phy(antenna);
4641 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4642 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4643 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4644 /* For Probe Resposes */
4645 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4646 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4647 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4651 bwn_set_opmode(struct bwn_mac *mac)
4653 struct bwn_softc *sc = mac->mac_sc;
4654 struct ifnet *ifp = sc->sc_ifp;
4655 struct ieee80211com *ic = ifp->if_l2com;
4657 uint16_t cfp_pretbtt;
4659 ctl = BWN_READ_4(mac, BWN_MACCTL);
4660 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4661 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4662 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4663 ctl |= BWN_MACCTL_STA;
4665 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4666 ic->ic_opmode == IEEE80211_M_MBSS)
4667 ctl |= BWN_MACCTL_HOSTAP;
4668 else if (ic->ic_opmode == IEEE80211_M_IBSS)
4669 ctl &= ~BWN_MACCTL_STA;
4670 ctl |= sc->sc_filters;
4672 if (siba_get_revid(sc->sc_dev) <= 4)
4673 ctl |= BWN_MACCTL_PROMISC;
4675 BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4678 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4679 if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4680 siba_get_chiprev(sc->sc_dev) == 3)
4685 BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4689 bwn_dma_gettype(struct bwn_mac *mac)
4694 tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4695 if (tmp & SIBA_TGSHIGH_DMA64)
4696 return (BWN_DMA_64BIT);
4697 base = bwn_dma_base(0, 0);
4698 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4699 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4700 if (tmp & BWN_DMA32_TXADDREXT_MASK)
4701 return (BWN_DMA_32BIT);
4703 return (BWN_DMA_30BIT);
4707 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4710 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4711 *((bus_addr_t *)arg) = seg->ds_addr;
4716 bwn_phy_g_init_sub(struct bwn_mac *mac)
4718 struct bwn_phy *phy = &mac->mac_phy;
4719 struct bwn_phy_g *pg = &phy->phy_g;
4720 struct bwn_softc *sc = mac->mac_sc;
4724 bwn_phy_init_b5(mac);
4726 bwn_phy_init_b6(mac);
4728 if (phy->rev >= 2 || phy->gmode)
4729 bwn_phy_init_a(mac);
4731 if (phy->rev >= 2) {
4732 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4733 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4735 if (phy->rev == 2) {
4736 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4737 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4740 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4741 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4743 if (phy->gmode || phy->rev >= 2) {
4744 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4745 tmp &= BWN_PHYVER_VERSION;
4746 if (tmp == 3 || tmp == 5) {
4747 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4748 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4751 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4755 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4756 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4757 if (phy->rf_rev == 8) {
4758 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4759 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4761 if (BWN_HAS_LOOPBACK(phy))
4762 bwn_loopback_calcgain(mac);
4764 if (phy->rf_rev != 8) {
4765 if (pg->pg_initval == 0xffff)
4766 pg->pg_initval = bwn_rf_init_bcm2050(mac);
4768 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4771 if (BWN_HAS_TXMAG(phy)) {
4772 BWN_RF_WRITE(mac, 0x52,
4773 (BWN_RF_READ(mac, 0x52) & 0xff00)
4774 | pg->pg_loctl.tx_bias |
4775 pg->pg_loctl.tx_magn);
4777 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4779 if (phy->rev >= 6) {
4780 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4781 (pg->pg_loctl.tx_bias << 12));
4783 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4784 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4786 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4788 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4790 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4791 if (phy->gmode || phy->rev >= 2) {
4792 bwn_lo_g_adjust(mac);
4793 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4796 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4797 for (i = 0; i < 64; i++) {
4798 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4799 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4800 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4803 bwn_nrssi_threshold(mac);
4804 } else if (phy->gmode || phy->rev >= 2) {
4805 if (pg->pg_nrssi[0] == -1000) {
4806 KASSERT(pg->pg_nrssi[1] == -1000,
4807 ("%s:%d: fail", __func__, __LINE__));
4808 bwn_nrssi_slope_11g(mac);
4810 bwn_nrssi_threshold(mac);
4812 if (phy->rf_rev == 8)
4813 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4814 bwn_phy_hwpctl_init(mac);
4815 if ((siba_get_chipid(sc->sc_dev) == 0x4306
4816 && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4817 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4818 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4823 bwn_has_hwpctl(struct bwn_mac *mac)
4826 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4828 return (mac->mac_phy.use_hwpctl(mac));
4832 bwn_phy_init_b5(struct bwn_mac *mac)
4834 struct bwn_phy *phy = &mac->mac_phy;
4835 struct bwn_phy_g *pg = &phy->phy_g;
4836 struct bwn_softc *sc = mac->mac_sc;
4837 uint16_t offset, value;
4838 uint8_t old_channel;
4840 if (phy->analog == 1)
4841 BWN_RF_SET(mac, 0x007a, 0x0050);
4842 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4843 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4845 for (offset = 0x00a8; offset < 0x00c7; offset++) {
4846 BWN_PHY_WRITE(mac, offset, value);
4850 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4851 if (phy->rf_ver == 0x2050)
4852 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4854 if (phy->gmode || phy->rev >= 2) {
4855 if (phy->rf_ver == 0x2050) {
4856 BWN_RF_SET(mac, 0x007a, 0x0020);
4857 BWN_RF_SET(mac, 0x0051, 0x0004);
4859 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4861 BWN_PHY_SET(mac, 0x0802, 0x0100);
4862 BWN_PHY_SET(mac, 0x042b, 0x2000);
4864 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4866 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4867 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4868 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4871 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4872 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4874 if (phy->analog == 1) {
4875 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4876 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4877 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4878 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4879 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4881 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4882 BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4883 BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4885 if (phy->analog == 1)
4886 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4888 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4890 if (phy->analog == 0)
4891 BWN_WRITE_2(mac, 0x03e4, 0x3000);
4893 old_channel = phy->chan;
4894 bwn_phy_g_switch_chan(mac, 7, 0);
4896 if (phy->rf_ver != 0x2050) {
4897 BWN_RF_WRITE(mac, 0x0075, 0x0080);
4898 BWN_RF_WRITE(mac, 0x0079, 0x0081);
4901 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4902 BWN_RF_WRITE(mac, 0x0050, 0x0023);
4904 if (phy->rf_ver == 0x2050) {
4905 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4906 BWN_RF_WRITE(mac, 0x005a, 0x0070);
4909 BWN_RF_WRITE(mac, 0x005b, 0x007b);
4910 BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4911 BWN_RF_SET(mac, 0x007a, 0x0007);
4913 bwn_phy_g_switch_chan(mac, old_channel, 0);
4914 BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4915 BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4916 BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4918 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4921 if (phy->rf_ver == 0x2050)
4922 BWN_RF_WRITE(mac, 0x005d, 0x000d);
4924 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4928 bwn_loopback_calcgain(struct bwn_mac *mac)
4930 struct bwn_phy *phy = &mac->mac_phy;
4931 struct bwn_phy_g *pg = &phy->phy_g;
4932 struct bwn_softc *sc = mac->mac_sc;
4933 uint16_t backup_phy[16] = { 0 };
4934 uint16_t backup_radio[3];
4935 uint16_t backup_bband;
4936 uint16_t i, j, loop_i_max;
4938 uint16_t loop1_outer_done, loop1_inner_done;
4940 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4941 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4942 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4943 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4944 if (phy->rev != 1) {
4945 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4946 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4948 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4949 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4950 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4951 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4952 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4953 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4954 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4955 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4956 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4957 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4958 backup_bband = pg->pg_bbatt.att;
4959 backup_radio[0] = BWN_RF_READ(mac, 0x52);
4960 backup_radio[1] = BWN_RF_READ(mac, 0x43);
4961 backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4963 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4964 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4965 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4966 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4967 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4968 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4969 if (phy->rev != 1) {
4970 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4971 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4972 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4973 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4975 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4976 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4977 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4978 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4980 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4981 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4982 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4984 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4985 if (phy->rev != 1) {
4986 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4987 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4989 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4991 if (phy->rf_rev == 8)
4992 BWN_RF_WRITE(mac, 0x43, 0x000f);
4994 BWN_RF_WRITE(mac, 0x52, 0);
4995 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4997 bwn_phy_g_set_bbatt(mac, 11);
5000 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5002 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5003 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5005 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
5006 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
5008 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
5009 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
5011 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
5012 if (phy->rev >= 7) {
5013 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
5014 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
5017 BWN_RF_MASK(mac, 0x7a, 0x00f7);
5020 loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
5021 for (i = 0; i < loop_i_max; i++) {
5022 for (j = 0; j < 16; j++) {
5023 BWN_RF_WRITE(mac, 0x43, i);
5024 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
5026 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5027 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5029 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5034 loop1_outer_done = i;
5035 loop1_inner_done = j;
5037 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
5039 for (j = j - 8; j < 16; j++) {
5040 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
5041 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
5042 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
5045 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
5052 if (phy->rev != 1) {
5053 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
5054 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
5056 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
5057 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
5058 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
5059 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
5060 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
5061 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
5062 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
5063 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
5064 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
5066 bwn_phy_g_set_bbatt(mac, backup_bband);
5068 BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
5069 BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
5070 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
5072 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
5074 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
5075 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
5076 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
5077 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
5079 pg->pg_max_lb_gain =
5080 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
5081 pg->pg_trsw_rx_gain = trsw_rx * 2;
5085 bwn_rf_init_bcm2050(struct bwn_mac *mac)
5087 struct bwn_phy *phy = &mac->mac_phy;
5088 uint32_t tmp1 = 0, tmp2 = 0;
5089 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
5090 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
5091 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
5092 static const uint8_t rcc_table[] = {
5093 0x02, 0x03, 0x01, 0x0f,
5094 0x06, 0x07, 0x05, 0x0f,
5095 0x0a, 0x0b, 0x09, 0x0f,
5096 0x0e, 0x0f, 0x0d, 0x0f,
5099 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
5100 rfoverval = rfover = cck3 = 0;
5101 radio0 = BWN_RF_READ(mac, 0x43);
5102 radio1 = BWN_RF_READ(mac, 0x51);
5103 radio2 = BWN_RF_READ(mac, 0x52);
5104 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5105 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5106 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5107 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5109 if (phy->type == BWN_PHYTYPE_B) {
5110 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5111 reg0 = BWN_READ_2(mac, 0x3ec);
5113 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5114 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5115 } else if (phy->gmode || phy->rev >= 2) {
5116 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5117 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5118 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5119 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5120 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5121 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5123 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5124 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5125 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5126 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5127 if (BWN_HAS_LOOPBACK(phy)) {
5128 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5129 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5131 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5133 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5134 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5137 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5138 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5140 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5141 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5143 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5145 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5146 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5147 reg1 = BWN_READ_2(mac, 0x3e6);
5148 reg2 = BWN_READ_2(mac, 0x3f4);
5150 if (phy->analog == 0)
5151 BWN_WRITE_2(mac, 0x03e6, 0x0122);
5153 if (phy->analog >= 2)
5154 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5155 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5156 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5159 reg = BWN_RF_READ(mac, 0x60);
5160 index = (reg & 0x001e) >> 1;
5161 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5163 if (phy->type == BWN_PHYTYPE_B)
5164 BWN_RF_WRITE(mac, 0x78, 0x26);
5165 if (phy->gmode || phy->rev >= 2) {
5166 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5167 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5170 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5171 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5172 if (phy->gmode || phy->rev >= 2) {
5173 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5174 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5177 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5178 BWN_RF_SET(mac, 0x51, 0x0004);
5179 if (phy->rf_rev == 8)
5180 BWN_RF_WRITE(mac, 0x43, 0x1f);
5182 BWN_RF_WRITE(mac, 0x52, 0);
5183 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5185 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5187 for (i = 0; i < 16; i++) {
5188 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5189 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5190 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5191 if (phy->gmode || phy->rev >= 2) {
5192 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5193 bwn_rf_2050_rfoverval(mac,
5194 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5196 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5198 if (phy->gmode || phy->rev >= 2) {
5199 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5200 bwn_rf_2050_rfoverval(mac,
5201 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5203 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5205 if (phy->gmode || phy->rev >= 2) {
5206 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5207 bwn_rf_2050_rfoverval(mac,
5208 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5210 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5212 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5213 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5214 if (phy->gmode || phy->rev >= 2) {
5215 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5216 bwn_rf_2050_rfoverval(mac,
5217 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5219 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5223 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5227 for (i = 0; i < 16; i++) {
5228 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5229 BWN_RF_WRITE(mac, 0x78, radio78);
5231 for (j = 0; j < 16; j++) {
5232 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5233 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5234 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5235 if (phy->gmode || phy->rev >= 2) {
5236 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5237 bwn_rf_2050_rfoverval(mac,
5238 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5240 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5242 if (phy->gmode || phy->rev >= 2) {
5243 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5244 bwn_rf_2050_rfoverval(mac,
5245 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5247 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5249 if (phy->gmode || phy->rev >= 2) {
5250 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5251 bwn_rf_2050_rfoverval(mac,
5252 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5254 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5256 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5257 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5258 if (phy->gmode || phy->rev >= 2) {
5259 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5260 bwn_rf_2050_rfoverval(mac,
5261 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5263 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5271 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5272 BWN_RF_WRITE(mac, 0x51, radio1);
5273 BWN_RF_WRITE(mac, 0x52, radio2);
5274 BWN_RF_WRITE(mac, 0x43, radio0);
5275 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5276 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5277 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5278 BWN_WRITE_2(mac, 0x3e6, reg1);
5279 if (phy->analog != 0)
5280 BWN_WRITE_2(mac, 0x3f4, reg2);
5281 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5282 bwn_spu_workaround(mac, phy->chan);
5283 if (phy->type == BWN_PHYTYPE_B) {
5284 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5285 BWN_WRITE_2(mac, 0x3ec, reg0);
5286 } else if (phy->gmode) {
5287 BWN_WRITE_2(mac, BWN_PHY_RADIO,
5288 BWN_READ_2(mac, BWN_PHY_RADIO)
5290 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5291 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5292 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5293 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5295 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5296 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5297 if (BWN_HAS_LOOPBACK(phy)) {
5298 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5299 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5303 return ((i > 15) ? radio78 : rcc);
5307 bwn_phy_init_b6(struct bwn_mac *mac)
5309 struct bwn_phy *phy = &mac->mac_phy;
5310 struct bwn_phy_g *pg = &phy->phy_g;
5311 struct bwn_softc *sc = mac->mac_sc;
5312 uint16_t offset, val;
5313 uint8_t old_channel;
5315 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5316 ("%s:%d: fail", __func__, __LINE__));
5318 BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5319 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5320 if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5321 BWN_RF_WRITE(mac, 0x51, 0x37);
5322 BWN_RF_WRITE(mac, 0x52, 0x70);
5323 BWN_RF_WRITE(mac, 0x53, 0xb3);
5324 BWN_RF_WRITE(mac, 0x54, 0x9b);
5325 BWN_RF_WRITE(mac, 0x5a, 0x88);
5326 BWN_RF_WRITE(mac, 0x5b, 0x88);
5327 BWN_RF_WRITE(mac, 0x5d, 0x88);
5328 BWN_RF_WRITE(mac, 0x5e, 0x88);
5329 BWN_RF_WRITE(mac, 0x7d, 0x88);
5331 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5333 if (phy->rf_rev == 8) {
5334 BWN_RF_WRITE(mac, 0x51, 0);
5335 BWN_RF_WRITE(mac, 0x52, 0x40);
5336 BWN_RF_WRITE(mac, 0x53, 0xb7);
5337 BWN_RF_WRITE(mac, 0x54, 0x98);
5338 BWN_RF_WRITE(mac, 0x5a, 0x88);
5339 BWN_RF_WRITE(mac, 0x5b, 0x6b);
5340 BWN_RF_WRITE(mac, 0x5c, 0x0f);
5341 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5342 BWN_RF_WRITE(mac, 0x5d, 0xfa);
5343 BWN_RF_WRITE(mac, 0x5e, 0xd8);
5345 BWN_RF_WRITE(mac, 0x5d, 0xf5);
5346 BWN_RF_WRITE(mac, 0x5e, 0xb8);
5348 BWN_RF_WRITE(mac, 0x0073, 0x0003);
5349 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5350 BWN_RF_WRITE(mac, 0x007c, 0x0001);
5351 BWN_RF_WRITE(mac, 0x007e, 0x0008);
5353 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5354 BWN_PHY_WRITE(mac, offset, val);
5357 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5358 BWN_PHY_WRITE(mac, offset, val);
5361 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5362 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5365 if (phy->type == BWN_PHYTYPE_G) {
5366 BWN_RF_SET(mac, 0x007a, 0x0020);
5367 BWN_RF_SET(mac, 0x0051, 0x0004);
5368 BWN_PHY_SET(mac, 0x0802, 0x0100);
5369 BWN_PHY_SET(mac, 0x042b, 0x2000);
5370 BWN_PHY_WRITE(mac, 0x5b, 0);
5371 BWN_PHY_WRITE(mac, 0x5c, 0);
5374 old_channel = phy->chan;
5375 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5377 BWN_RF_WRITE(mac, 0x0050, 0x0020);
5378 BWN_RF_WRITE(mac, 0x0050, 0x0023);
5380 if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5381 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5382 BWN_RF_WRITE(mac, 0x50, 0x20);
5384 if (phy->rf_rev <= 2) {
5385 BWN_RF_WRITE(mac, 0x7c, 0x20);
5386 BWN_RF_WRITE(mac, 0x5a, 0x70);
5387 BWN_RF_WRITE(mac, 0x5b, 0x7b);
5388 BWN_RF_WRITE(mac, 0x5c, 0xb0);
5390 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5392 bwn_phy_g_switch_chan(mac, old_channel, 0);
5394 BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5395 if (phy->rf_rev >= 6)
5396 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5398 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5399 BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5400 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5402 if (phy->rf_rev <= 5)
5403 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5404 if (phy->rf_rev <= 2)
5405 BWN_RF_WRITE(mac, 0x005d, 0x000d);
5407 if (phy->analog == 4) {
5408 BWN_WRITE_2(mac, 0x3e4, 9);
5409 BWN_PHY_MASK(mac, 0x61, 0x0fff);
5411 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5412 if (phy->type == BWN_PHYTYPE_B)
5413 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5414 else if (phy->type == BWN_PHYTYPE_G)
5415 BWN_WRITE_2(mac, 0x03e6, 0x0);
5419 bwn_phy_init_a(struct bwn_mac *mac)
5421 struct bwn_phy *phy = &mac->mac_phy;
5422 struct bwn_softc *sc = mac->mac_sc;
5424 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5425 ("%s:%d: fail", __func__, __LINE__));
5427 if (phy->rev >= 6) {
5428 if (phy->type == BWN_PHYTYPE_A)
5429 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5430 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5431 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5433 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5438 if (phy->type == BWN_PHYTYPE_G &&
5439 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5440 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5444 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5448 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5449 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5453 bwn_wa_agc(struct bwn_mac *mac)
5455 struct bwn_phy *phy = &mac->mac_phy;
5457 if (phy->rev == 1) {
5458 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5459 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5460 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5461 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5462 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5463 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5464 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5465 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5466 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5468 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5469 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5470 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5471 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5474 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5476 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5477 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5478 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5479 BWN_RF_SET(mac, 0x7a, 0x0008);
5480 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5481 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5482 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5483 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5485 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5486 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5487 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5488 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5489 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5490 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5491 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5492 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5493 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5494 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5495 if (phy->rev == 1) {
5496 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5497 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5499 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5500 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5501 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5502 if (phy->rev >= 6) {
5503 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5504 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5505 (uint16_t)~0xf000, 0x3000);
5508 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5509 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5510 if (phy->rev == 1) {
5511 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5512 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5513 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5514 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5515 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5516 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5517 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5518 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5520 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5521 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5522 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5523 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5525 if (phy->rev >= 6) {
5526 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5527 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5529 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5533 bwn_wa_grev1(struct bwn_mac *mac)
5535 struct bwn_phy *phy = &mac->mac_phy;
5537 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5538 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5539 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5541 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5543 /* init CRSTHRES and ANTDWELL */
5544 if (phy->rev == 1) {
5545 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5546 } else if (phy->rev == 2) {
5547 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5548 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5549 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5551 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5552 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5553 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5554 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5556 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5557 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5558 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5560 /* XXX support PHY-A??? */
5561 for (i = 0; i < N(bwn_tab_finefreqg); i++)
5562 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5563 bwn_tab_finefreqg[i]);
5565 /* XXX support PHY-A??? */
5567 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5568 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5569 bwn_tab_noise_g1[i]);
5571 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5572 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5573 bwn_tab_noise_g2[i]);
5576 for (i = 0; i < N(bwn_tab_rotor); i++)
5577 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5580 /* XXX support PHY-A??? */
5581 if (phy->rev >= 6) {
5582 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5584 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5586 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5588 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5590 for (i = 0; i < N(bwn_tab_retard); i++)
5591 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5594 if (phy->rev == 1) {
5595 for (i = 0; i < 16; i++)
5596 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5599 for (i = 0; i < 32; i++)
5600 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5607 bwn_wa_grev26789(struct bwn_mac *mac)
5609 struct bwn_phy *phy = &mac->mac_phy;
5611 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5614 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5616 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5618 /* init CRSTHRES and ANTDWELL */
5620 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5621 else if (phy->rev == 2) {
5622 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5623 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5624 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5626 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5627 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5628 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5629 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5632 for (i = 0; i < 64; i++)
5633 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5635 /* XXX support PHY-A??? */
5637 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5638 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5639 bwn_tab_noise_g1[i]);
5641 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5642 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5643 bwn_tab_noise_g2[i]);
5645 /* XXX support PHY-A??? */
5646 if (phy->rev >= 6) {
5647 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5649 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5651 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5653 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5655 for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5656 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5657 bwn_tab_sigmasqr2[i]);
5659 if (phy->rev == 1) {
5660 for (i = 0; i < 16; i++)
5661 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5664 for (i = 0; i < 32; i++)
5665 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5670 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5672 if (phy->type == BWN_PHYTYPE_A)
5673 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5675 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5677 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5678 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5679 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5682 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5683 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5687 bwn_wa_init(struct bwn_mac *mac)
5689 struct bwn_phy *phy = &mac->mac_phy;
5690 struct bwn_softc *sc = mac->mac_sc;
5692 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5703 bwn_wa_grev26789(mac);
5706 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5709 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5710 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5711 siba_get_pci_revid(sc->sc_dev) != 0x17) {
5713 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5715 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5718 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5719 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5720 if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5723 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5724 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5726 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5728 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5730 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5732 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5734 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5739 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5740 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5741 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5744 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5745 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5749 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5752 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5755 addr = table + offset;
5756 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5757 (addr - 1 != pg->pg_ofdmtab_addr)) {
5758 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5759 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5761 pg->pg_ofdmtab_addr = addr;
5762 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5766 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5769 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5772 addr = table + offset;
5773 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5774 (addr - 1 != pg->pg_ofdmtab_addr)) {
5775 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5776 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5778 pg->pg_ofdmtab_addr = addr;
5780 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5781 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5785 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5789 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5790 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5794 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5796 struct bwn_phy *phy = &mac->mac_phy;
5797 struct bwn_softc *sc = mac->mac_sc;
5798 unsigned int i, max_loop;
5800 uint32_t buffer[5] = {
5801 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5806 buffer[0] = 0x000201cc;
5809 buffer[0] = 0x000b846e;
5812 BWN_ASSERT_LOCKED(mac->mac_sc);
5814 for (i = 0; i < 5; i++)
5815 bwn_ram_write(mac, i * 4, buffer[i]);
5817 BWN_WRITE_2(mac, 0x0568, 0x0000);
5818 BWN_WRITE_2(mac, 0x07c0,
5819 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5820 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5821 BWN_WRITE_2(mac, 0x050c, value);
5822 if (phy->type == BWN_PHYTYPE_LP)
5823 BWN_WRITE_2(mac, 0x0514, 0x1a02);
5824 BWN_WRITE_2(mac, 0x0508, 0x0000);
5825 BWN_WRITE_2(mac, 0x050a, 0x0000);
5826 BWN_WRITE_2(mac, 0x054c, 0x0000);
5827 BWN_WRITE_2(mac, 0x056a, 0x0014);
5828 BWN_WRITE_2(mac, 0x0568, 0x0826);
5829 BWN_WRITE_2(mac, 0x0500, 0x0000);
5830 if (phy->type == BWN_PHYTYPE_LP)
5831 BWN_WRITE_2(mac, 0x0502, 0x0050);
5833 BWN_WRITE_2(mac, 0x0502, 0x0030);
5835 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5836 BWN_RF_WRITE(mac, 0x0051, 0x0017);
5837 for (i = 0x00; i < max_loop; i++) {
5838 value = BWN_READ_2(mac, 0x050e);
5843 for (i = 0x00; i < 0x0a; i++) {
5844 value = BWN_READ_2(mac, 0x050e);
5849 for (i = 0x00; i < 0x19; i++) {
5850 value = BWN_READ_2(mac, 0x0690);
5851 if (!(value & 0x0100))
5855 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5856 BWN_RF_WRITE(mac, 0x0051, 0x0037);
5860 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5864 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5866 macctl = BWN_READ_4(mac, BWN_MACCTL);
5867 if (macctl & BWN_MACCTL_BIGENDIAN)
5868 printf("TODO: need swap\n");
5870 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5871 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5872 BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5876 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5880 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5881 ("%s:%d: fail", __func__, __LINE__));
5883 value = (uint8_t) (ctl->q);
5884 value |= ((uint8_t) (ctl->i)) << 8;
5885 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5889 bwn_lo_calcfeed(struct bwn_mac *mac,
5890 uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5892 struct bwn_phy *phy = &mac->mac_phy;
5893 struct bwn_softc *sc = mac->mac_sc;
5895 uint16_t feedthrough;
5898 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5899 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5901 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5902 ("%s:%d: fail", __func__, __LINE__));
5903 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5904 ("%s:%d: fail", __func__, __LINE__));
5906 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5908 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5909 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5911 rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5913 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5914 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5916 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5917 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5919 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5920 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5922 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5924 pga |= BWN_PHY_PGACTL_UNKNOWN;
5925 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5927 pga |= BWN_PHY_PGACTL_LOWBANDW;
5928 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5930 pga |= BWN_PHY_PGACTL_LPF;
5931 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5934 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5936 return (feedthrough);
5940 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5941 uint16_t *value, uint16_t *pad_mix_gain)
5943 struct bwn_phy *phy = &mac->mac_phy;
5944 uint16_t reg, v, padmix;
5946 if (phy->type == BWN_PHYTYPE_B) {
5948 if (phy->rf_rev <= 5) {
5956 if (phy->rev >= 2 && phy->rf_rev == 8) {
5969 *pad_mix_gain = padmix;
5975 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5977 struct bwn_phy *phy = &mac->mac_phy;
5978 struct bwn_phy_g *pg = &phy->phy_g;
5979 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5981 uint16_t trsw_rx, pga;
5982 uint16_t rf_pctl_reg;
5984 static const uint8_t tx_bias_values[] = {
5985 0x09, 0x08, 0x0a, 0x01, 0x00,
5986 0x02, 0x05, 0x04, 0x06,
5988 static const uint8_t tx_magn_values[] = {
5992 if (!BWN_HAS_LOOPBACK(phy)) {
6000 lb_gain = pg->pg_max_lb_gain / 2;
6003 pga = abs(10 - lb_gain) / 6;
6004 pga = MIN(MAX(pga, 0), 15);
6011 if ((phy->rev >= 2) &&
6012 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
6015 if ((10 - lb_gain) < cmp_val)
6016 tmp = (10 - lb_gain);
6024 rf_pctl_reg = cmp_val;
6029 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
6030 bwn_phy_g_set_bbatt(mac, 2);
6032 reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
6034 BWN_RF_MASK(mac, reg, mask);
6036 if (BWN_HAS_TXMAG(phy)) {
6039 int min_feedth = 0xffff;
6040 uint8_t tx_magn, tx_bias;
6042 for (i = 0; i < N(tx_magn_values); i++) {
6043 tx_magn = tx_magn_values[i];
6044 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
6045 for (j = 0; j < N(tx_bias_values); j++) {
6046 tx_bias = tx_bias_values[j];
6047 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
6048 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
6050 if (feedthrough < min_feedth) {
6051 lo->tx_bias = tx_bias;
6052 lo->tx_magn = tx_magn;
6053 min_feedth = feedthrough;
6055 if (lo->tx_bias == 0)
6058 BWN_RF_WRITE(mac, 0x52,
6059 (BWN_RF_READ(mac, 0x52)
6060 & 0xff00) | lo->tx_bias | lo->
6066 BWN_RF_MASK(mac, 0x52, 0xfff0);
6069 BWN_GETTIME(lo->txctl_measured_time);
6073 bwn_lo_get_powervector(struct bwn_mac *mac)
6075 struct bwn_phy *phy = &mac->mac_phy;
6076 struct bwn_phy_g *pg = &phy->phy_g;
6077 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6080 uint64_t power_vector = 0;
6082 for (i = 0; i < 8; i += 2) {
6083 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
6084 power_vector |= (tmp << (i * 8));
6085 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
6088 lo->power_vector = power_vector;
6090 BWN_GETTIME(lo->pwr_vec_read_time);
6094 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
6097 struct bwn_phy *phy = &mac->mac_phy;
6098 struct bwn_phy_g *pg = &phy->phy_g;
6101 if (max_rx_gain < 0)
6104 if (BWN_HAS_LOOPBACK(phy)) {
6109 trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6110 if (max_rx_gain >= trsw_rx_gain) {
6111 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6115 trsw_rx_gain = max_rx_gain;
6116 if (trsw_rx_gain < 9) {
6117 pg->pg_lna_lod_gain = 0;
6119 pg->pg_lna_lod_gain = 1;
6122 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6123 pg->pg_pga_gain = trsw_rx_gain / 3;
6124 if (pg->pg_pga_gain >= 5) {
6125 pg->pg_pga_gain -= 5;
6126 pg->pg_lna_gain = 2;
6128 pg->pg_lna_gain = 0;
6130 pg->pg_lna_gain = 0;
6131 pg->pg_trsw_rx_gain = 0x20;
6132 if (max_rx_gain >= 0x14) {
6133 pg->pg_lna_lod_gain = 1;
6134 pg->pg_pga_gain = 2;
6135 } else if (max_rx_gain >= 0x12) {
6136 pg->pg_lna_lod_gain = 1;
6137 pg->pg_pga_gain = 1;
6138 } else if (max_rx_gain >= 0xf) {
6139 pg->pg_lna_lod_gain = 1;
6140 pg->pg_pga_gain = 0;
6142 pg->pg_lna_lod_gain = 0;
6143 pg->pg_pga_gain = 0;
6147 tmp = BWN_RF_READ(mac, 0x7a);
6148 if (pg->pg_lna_lod_gain == 0)
6152 BWN_RF_WRITE(mac, 0x7a, tmp);
6156 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6158 struct bwn_phy *phy = &mac->mac_phy;
6159 struct bwn_phy_g *pg = &phy->phy_g;
6160 struct bwn_softc *sc = mac->mac_sc;
6161 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6165 if (bwn_has_hwpctl(mac)) {
6166 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6167 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6168 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6169 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6170 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6172 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6173 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6174 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6175 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6177 if (phy->type == BWN_PHYTYPE_B &&
6178 phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6179 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6180 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6182 if (phy->rev >= 2) {
6183 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6184 sav->phy_analogoverval =
6185 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6186 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6187 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6188 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6189 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6190 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6192 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6193 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6194 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6195 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6196 if (phy->type == BWN_PHYTYPE_G) {
6197 if ((phy->rev >= 7) &&
6198 (siba_sprom_get_bf_lo(sc->sc_dev) &
6200 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6202 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6205 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6207 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6209 sav->reg0 = BWN_READ_2(mac, 0x3f4);
6210 sav->reg1 = BWN_READ_2(mac, 0x3e2);
6211 sav->rf0 = BWN_RF_READ(mac, 0x43);
6212 sav->rf1 = BWN_RF_READ(mac, 0x7a);
6213 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6214 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6215 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6216 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6218 if (!BWN_HAS_TXMAG(phy)) {
6219 sav->rf2 = BWN_RF_READ(mac, 0x52);
6222 if (phy->type == BWN_PHYTYPE_B) {
6223 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6224 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6225 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6226 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6228 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6231 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6235 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6236 BWN_PHY_WRITE(mac, tmp, 0x007f);
6238 tmp = sav->phy_syncctl;
6239 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6241 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6243 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6244 if (phy->type == BWN_PHYTYPE_G ||
6245 (phy->type == BWN_PHYTYPE_B &&
6246 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6247 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6249 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6251 bwn_dummy_transmission(mac, 0, 1);
6252 bwn_phy_g_switch_chan(mac, 6, 0);
6253 BWN_RF_READ(mac, 0x51);
6254 if (phy->type == BWN_PHYTYPE_G)
6255 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6258 if (time_before(lo->txctl_measured_time,
6259 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6260 bwn_lo_measure_txctl_values(mac);
6262 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6263 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6265 if (phy->type == BWN_PHYTYPE_B)
6266 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6268 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6273 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6275 struct bwn_phy *phy = &mac->mac_phy;
6276 struct bwn_phy_g *pg = &phy->phy_g;
6279 if (phy->rev >= 2) {
6280 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6281 tmp = (pg->pg_pga_gain << 8);
6282 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6284 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6286 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6288 tmp = (pg->pg_pga_gain | 0xefa0);
6289 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6291 if (phy->type == BWN_PHYTYPE_G) {
6293 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6295 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6297 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6299 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6301 BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6302 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6303 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6304 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6305 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6306 BWN_RF_WRITE(mac, 0x43, sav->rf0);
6307 BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6308 if (!BWN_HAS_TXMAG(phy)) {
6310 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6312 BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6313 if (phy->type == BWN_PHYTYPE_B &&
6314 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6315 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6316 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6318 if (phy->rev >= 2) {
6319 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6320 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6321 sav->phy_analogoverval);
6322 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6323 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6324 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6325 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6326 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6328 if (bwn_has_hwpctl(mac)) {
6329 tmp = (sav->phy_lomask & 0xbfff);
6330 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6331 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6332 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6333 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6334 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6336 bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6340 bwn_lo_probe_loctl(struct bwn_mac *mac,
6341 struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6343 struct bwn_phy *phy = &mac->mac_phy;
6344 struct bwn_phy_g *pg = &phy->phy_g;
6345 struct bwn_loctl orig, test;
6346 struct bwn_loctl prev = { -100, -100 };
6347 static const struct bwn_loctl modifiers[] = {
6348 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,},
6349 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,}
6351 int begin, end, lower = 0, i;
6354 if (d->curstate == 0) {
6357 } else if (d->curstate % 2 == 0) {
6358 begin = d->curstate - 1;
6359 end = d->curstate + 1;
6361 begin = d->curstate - 2;
6362 end = d->curstate + 2;
6369 memcpy(&orig, probe, sizeof(struct bwn_loctl));
6373 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6374 memcpy(&test, &orig, sizeof(struct bwn_loctl));
6375 test.i += modifiers[i - 1].i * d->multipler;
6376 test.q += modifiers[i - 1].q * d->multipler;
6377 if ((test.i != prev.i || test.q != prev.q) &&
6378 (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6379 bwn_lo_write(mac, &test);
6380 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6381 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6382 if (feedth < d->feedth) {
6383 memcpy(probe, &test,
6384 sizeof(struct bwn_loctl));
6387 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6391 memcpy(&prev, &test, sizeof(prev));
6405 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6407 struct bwn_phy *phy = &mac->mac_phy;
6408 struct bwn_phy_g *pg = &phy->phy_g;
6409 struct bwn_lo_g_sm d;
6410 struct bwn_loctl probe;
6411 int lower, repeat, cnt = 0;
6416 if (BWN_HAS_LOOPBACK(phy))
6419 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6420 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6423 bwn_lo_write(mac, &d.loctl);
6424 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6425 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6426 if (feedth < 0x258) {
6427 if (feedth >= 0x12c)
6431 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6432 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6437 KASSERT(d.curstate >= 0 && d.curstate <= 8,
6438 ("%s:%d: fail", __func__, __LINE__));
6439 memcpy(&probe, &d.loctl,
6440 sizeof(struct bwn_loctl));
6441 lower = bwn_lo_probe_loctl(mac, &probe, &d);
6444 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6446 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6448 } while (d.nmeasure < 24);
6449 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6451 if (BWN_HAS_LOOPBACK(phy)) {
6452 if (d.feedth > 0x1194)
6454 else if (d.feedth < 0x5dc)
6457 if (d.feedth <= 0x5dc) {
6462 } else if (cnt == 2)
6465 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6466 } while (++cnt < repeat);
6469 static struct bwn_lo_calib *
6470 bwn_lo_calibset(struct bwn_mac *mac,
6471 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6473 struct bwn_phy *phy = &mac->mac_phy;
6474 struct bwn_phy_g *pg = &phy->phy_g;
6475 struct bwn_loctl loctl = { 0, 0 };
6476 struct bwn_lo_calib *cal;
6477 struct bwn_lo_g_value sval = { 0 };
6479 uint16_t pad, reg, value;
6481 sval.old_channel = phy->chan;
6482 bwn_mac_suspend(mac);
6483 bwn_lo_save(mac, &sval);
6485 reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6486 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6487 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6489 rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6492 if (BWN_HAS_LOOPBACK(phy))
6493 rxgain += pg->pg_max_lb_gain;
6494 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6495 bwn_phy_g_set_bbatt(mac, bbatt->att);
6496 bwn_lo_probe_sm(mac, &loctl, &rxgain);
6498 bwn_lo_restore(mac, &sval);
6499 bwn_mac_enable(mac);
6501 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
6503 device_printf(mac->mac_sc->sc_dev, "out of memory\n");
6506 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6507 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6508 memcpy(&cal->ctl, &loctl, sizeof(loctl));
6510 BWN_GETTIME(cal->calib_time);
6515 static struct bwn_lo_calib *
6516 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6517 const struct bwn_rfatt *rfatt)
6519 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6520 struct bwn_lo_calib *c;
6522 TAILQ_FOREACH(c, &lo->calib_list, list) {
6523 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6525 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6530 c = bwn_lo_calibset(mac, bbatt, rfatt);
6533 TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6539 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6541 struct bwn_phy *phy = &mac->mac_phy;
6542 struct bwn_phy_g *pg = &phy->phy_g;
6543 struct bwn_softc *sc = mac->mac_sc;
6544 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6545 const struct bwn_rfatt *rfatt;
6546 const struct bwn_bbatt *bbatt;
6549 int rf_offset, bb_offset;
6550 uint8_t changed = 0;
6552 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6553 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6554 ("%s:%d: fail", __func__, __LINE__));
6556 pvector = lo->power_vector;
6557 if (!update && !pvector)
6560 bwn_mac_suspend(mac);
6562 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6563 struct bwn_lo_calib *cal;
6567 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6569 bb_offset = i / lo->rfatt.len;
6570 rf_offset = i % lo->rfatt.len;
6571 bbatt = &(lo->bbatt.array[bb_offset]);
6572 rfatt = &(lo->rfatt.array[rf_offset]);
6574 cal = bwn_lo_calibset(mac, bbatt, rfatt);
6576 device_printf(sc->sc_dev, "LO: Could not "
6577 "calibrate DC table entry\n");
6580 val = (uint8_t)(cal->ctl.q);
6581 val |= ((uint8_t)(cal->ctl.i)) << 4;
6582 free(cal, M_DEVBUF);
6586 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6587 | ((val & 0x00ff) << 8);
6589 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6594 for (i = 0; i < BWN_DC_LT_SIZE; i++)
6595 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6597 bwn_mac_enable(mac);
6601 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6606 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6611 bwn_lo_g_adjust(struct bwn_mac *mac)
6613 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6614 struct bwn_lo_calib *cal;
6615 struct bwn_rfatt rf;
6617 memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6618 bwn_lo_fixup_rfatt(&rf);
6620 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6623 bwn_lo_write(mac, &cal->ctl);
6627 bwn_lo_g_init(struct bwn_mac *mac)
6630 if (!bwn_has_hwpctl(mac))
6633 bwn_lo_get_powervector(mac);
6634 bwn_phy_g_dc_lookup_init(mac, 1);
6638 bwn_mac_suspend(struct bwn_mac *mac)
6640 struct bwn_softc *sc = mac->mac_sc;
6644 KASSERT(mac->mac_suspended >= 0,
6645 ("%s:%d: fail", __func__, __LINE__));
6647 if (mac->mac_suspended == 0) {
6648 bwn_psctl(mac, BWN_PS_AWAKE);
6649 BWN_WRITE_4(mac, BWN_MACCTL,
6650 BWN_READ_4(mac, BWN_MACCTL)
6652 BWN_READ_4(mac, BWN_MACCTL);
6653 for (i = 35; i; i--) {
6654 tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6655 if (tmp & BWN_INTR_MAC_SUSPENDED)
6659 for (i = 40; i; i--) {
6660 tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6661 if (tmp & BWN_INTR_MAC_SUSPENDED)
6665 device_printf(sc->sc_dev, "MAC suspend failed\n");
6668 mac->mac_suspended++;
6672 bwn_mac_enable(struct bwn_mac *mac)
6674 struct bwn_softc *sc = mac->mac_sc;
6677 state = bwn_shm_read_2(mac, BWN_SHARED,
6678 BWN_SHARED_UCODESTAT);
6679 if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6680 state != BWN_SHARED_UCODESTAT_SLEEP)
6681 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6683 mac->mac_suspended--;
6684 KASSERT(mac->mac_suspended >= 0,
6685 ("%s:%d: fail", __func__, __LINE__));
6686 if (mac->mac_suspended == 0) {
6687 BWN_WRITE_4(mac, BWN_MACCTL,
6688 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6689 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6690 BWN_READ_4(mac, BWN_MACCTL);
6691 BWN_READ_4(mac, BWN_INTR_REASON);
6697 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6699 struct bwn_softc *sc = mac->mac_sc;
6703 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6704 ("%s:%d: fail", __func__, __LINE__));
6705 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6706 ("%s:%d: fail", __func__, __LINE__));
6708 /* XXX forcibly awake and hwps-off */
6710 BWN_WRITE_4(mac, BWN_MACCTL,
6711 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6713 BWN_READ_4(mac, BWN_MACCTL);
6714 if (siba_get_revid(sc->sc_dev) >= 5) {
6715 for (i = 0; i < 100; i++) {
6716 ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6717 BWN_SHARED_UCODESTAT);
6718 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6726 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6729 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6730 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6734 bwn_nrssi_threshold(struct bwn_mac *mac)
6736 struct bwn_phy *phy = &mac->mac_phy;
6737 struct bwn_phy_g *pg = &phy->phy_g;
6738 struct bwn_softc *sc = mac->mac_sc;
6743 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6745 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6746 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6754 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6755 a += (pg->pg_nrssi[0] << 6);
6756 a += (a < 32) ? 31 : 32;
6758 a = MIN(MAX(a, -31), 31);
6760 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6761 b += (pg->pg_nrssi[0] << 6);
6767 b = MIN(MAX(b, -31), 31);
6769 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6770 tmpu16 |= ((uint32_t)b & 0x0000003f);
6771 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6772 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6776 tmp16 = bwn_nrssi_read(mac, 0x20);
6779 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6783 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6785 #define SAVE_RF_MAX 3
6786 #define SAVE_PHY_COMM_MAX 4
6787 #define SAVE_PHY3_MAX 8
6788 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6789 { 0x7a, 0x52, 0x43 };
6790 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6791 { 0x15, 0x5a, 0x59, 0x58 };
6792 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6793 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6794 0x0801, 0x0060, 0x0014, 0x0478
6796 struct bwn_phy *phy = &mac->mac_phy;
6797 struct bwn_phy_g *pg = &phy->phy_g;
6798 int32_t i, tmp32, phy3_idx = 0;
6799 uint16_t delta, tmp;
6800 uint16_t save_rf[SAVE_RF_MAX];
6801 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6802 uint16_t save_phy3[SAVE_PHY3_MAX];
6803 uint16_t ant_div, phy0, chan_ex;
6804 int16_t nrssi0, nrssi1;
6806 KASSERT(phy->type == BWN_PHYTYPE_G,
6807 ("%s:%d: fail", __func__, __LINE__));
6809 if (phy->rf_rev >= 9)
6811 if (phy->rf_rev == 8)
6812 bwn_nrssi_offset(mac);
6814 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6815 BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6818 * Save RF/PHY registers for later restoration
6820 ant_div = BWN_READ_2(mac, 0x03e2);
6821 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6822 for (i = 0; i < SAVE_RF_MAX; ++i)
6823 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6824 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6825 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6827 phy0 = BWN_READ_2(mac, BWN_PHY0);
6828 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6829 if (phy->rev >= 3) {
6830 for (i = 0; i < SAVE_PHY3_MAX; ++i)
6831 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6832 BWN_PHY_WRITE(mac, 0x002e, 0);
6833 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6838 BWN_PHY_SET(mac, 0x0478, 0x0100);
6839 BWN_PHY_SET(mac, 0x0801, 0x0040);
6843 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6846 BWN_PHY_SET(mac, 0x0060, 0x0040);
6847 BWN_PHY_SET(mac, 0x0014, 0x0200);
6852 BWN_RF_SET(mac, 0x007a, 0x0070);
6853 bwn_set_all_gains(mac, 0, 8, 0);
6854 BWN_RF_MASK(mac, 0x007a, 0x00f7);
6855 if (phy->rev >= 2) {
6856 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6857 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6859 BWN_RF_SET(mac, 0x007a, 0x0080);
6862 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6863 if (nrssi0 >= 0x0020)
6869 BWN_RF_MASK(mac, 0x007a, 0x007f);
6871 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6873 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6874 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6875 BWN_RF_SET(mac, 0x007a, 0x000f);
6876 BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6877 if (phy->rev >= 2) {
6878 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6879 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6882 bwn_set_all_gains(mac, 3, 0, 1);
6883 if (phy->rf_rev == 8) {
6884 BWN_RF_WRITE(mac, 0x0043, 0x001f);
6886 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6887 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6888 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6889 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6891 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6892 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6893 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6895 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6898 * Install calculated narrow RSSI values
6900 if (nrssi1 >= 0x0020)
6902 if (nrssi0 == nrssi1)
6903 pg->pg_nrssi_slope = 0x00010000;
6905 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6907 pg->pg_nrssi[0] = nrssi1;
6908 pg->pg_nrssi[1] = nrssi0;
6912 * Restore saved RF/PHY registers
6914 if (phy->rev >= 3) {
6915 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6916 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6917 save_phy3[phy3_idx]);
6920 if (phy->rev >= 2) {
6921 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6922 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6925 for (i = 0; i < SAVE_RF_MAX; ++i)
6926 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6928 BWN_WRITE_2(mac, 0x03e2, ant_div);
6929 BWN_WRITE_2(mac, 0x03e6, phy0);
6930 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6932 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6933 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6935 bwn_spu_workaround(mac, phy->chan);
6936 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6937 bwn_set_original_gains(mac);
6938 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6939 if (phy->rev >= 3) {
6940 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6941 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6942 save_phy3[phy3_idx]);
6946 delta = 0x1f - pg->pg_nrssi[0];
6947 for (i = 0; i < 64; i++) {
6948 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6949 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6950 pg->pg_nrssi_lt[i] = tmp32;
6953 bwn_nrssi_threshold(mac);
6955 #undef SAVE_PHY_COMM_MAX
6956 #undef SAVE_PHY3_MAX
6960 bwn_nrssi_offset(struct bwn_mac *mac)
6962 #define SAVE_RF_MAX 2
6963 #define SAVE_PHY_COMM_MAX 10
6964 #define SAVE_PHY6_MAX 8
6965 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6967 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6968 0x0001, 0x0811, 0x0812, 0x0814,
6969 0x0815, 0x005a, 0x0059, 0x0058,
6972 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6973 0x002e, 0x002f, 0x080f, 0x0810,
6974 0x0801, 0x0060, 0x0014, 0x0478
6976 struct bwn_phy *phy = &mac->mac_phy;
6977 int i, phy6_idx = 0;
6978 uint16_t save_rf[SAVE_RF_MAX];
6979 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6980 uint16_t save_phy6[SAVE_PHY6_MAX];
6982 uint16_t saved = 0xffff;
6984 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6985 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6986 for (i = 0; i < SAVE_RF_MAX; ++i)
6987 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6989 BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6990 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6991 BWN_PHY_SET(mac, 0x0811, 0x000c);
6992 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6993 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6994 if (phy->rev >= 6) {
6995 for (i = 0; i < SAVE_PHY6_MAX; ++i)
6996 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6998 BWN_PHY_WRITE(mac, 0x002e, 0);
6999 BWN_PHY_WRITE(mac, 0x002f, 0);
7000 BWN_PHY_WRITE(mac, 0x080f, 0);
7001 BWN_PHY_WRITE(mac, 0x0810, 0);
7002 BWN_PHY_SET(mac, 0x0478, 0x0100);
7003 BWN_PHY_SET(mac, 0x0801, 0x0040);
7004 BWN_PHY_SET(mac, 0x0060, 0x0040);
7005 BWN_PHY_SET(mac, 0x0014, 0x0200);
7007 BWN_RF_SET(mac, 0x007a, 0x0070);
7008 BWN_RF_SET(mac, 0x007a, 0x0080);
7011 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7015 for (i = 7; i >= 4; i--) {
7016 BWN_RF_WRITE(mac, 0x007b, i);
7018 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
7022 if (nrssi < 31 && saved == 0xffff)
7025 if (saved == 0xffff)
7028 BWN_RF_MASK(mac, 0x007a, 0x007f);
7029 if (phy->rev != 1) {
7030 BWN_PHY_SET(mac, 0x0814, 0x0001);
7031 BWN_PHY_MASK(mac, 0x0815, 0xfffe);
7033 BWN_PHY_SET(mac, 0x0811, 0x000c);
7034 BWN_PHY_SET(mac, 0x0812, 0x000c);
7035 BWN_PHY_SET(mac, 0x0811, 0x0030);
7036 BWN_PHY_SET(mac, 0x0812, 0x0030);
7037 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
7038 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
7039 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
7041 BWN_PHY_WRITE(mac, 0x0003, 0x0122);
7043 BWN_PHY_SET(mac, 0x000a, 0x2000);
7044 if (phy->rev != 1) {
7045 BWN_PHY_SET(mac, 0x0814, 0x0004);
7046 BWN_PHY_MASK(mac, 0x0815, 0xfffb);
7048 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
7049 BWN_RF_SET(mac, 0x007a, 0x000f);
7050 bwn_set_all_gains(mac, 3, 0, 1);
7051 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
7053 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
7057 for (i = 0; i < 4; i++) {
7058 BWN_RF_WRITE(mac, 0x007b, i);
7060 nrssi = (int16_t)((BWN_PHY_READ(mac,
7061 0x047f) >> 8) & 0x003f);
7064 if (nrssi > -31 && saved == 0xffff)
7067 if (saved == 0xffff)
7072 BWN_RF_WRITE(mac, 0x007b, saved);
7075 * Restore saved RF/PHY registers
7077 if (phy->rev >= 6) {
7078 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
7079 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7080 save_phy6[phy6_idx]);
7083 if (phy->rev != 1) {
7084 for (i = 3; i < 5; i++)
7085 BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
7088 for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
7089 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
7091 for (i = SAVE_RF_MAX - 1; i >= 0; --i)
7092 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
7094 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
7095 BWN_PHY_SET(mac, 0x0429, 0x8000);
7096 bwn_set_original_gains(mac);
7097 if (phy->rev >= 6) {
7098 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
7099 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
7100 save_phy6[phy6_idx]);
7104 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7105 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7106 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7110 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7113 struct bwn_phy *phy = &mac->mac_phy;
7115 uint16_t start = 0x08, end = 0x18;
7119 if (phy->rev <= 1) {
7124 table = BWN_OFDMTAB_GAINX;
7126 table = BWN_OFDMTAB_GAINX_R1;
7127 for (i = 0; i < 4; i++)
7128 bwn_ofdmtab_write_2(mac, table, i, first);
7130 for (i = start; i < end; i++)
7131 bwn_ofdmtab_write_2(mac, table, i, second);
7134 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7135 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7136 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7137 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7139 bwn_dummy_transmission(mac, 0, 1);
7143 bwn_set_original_gains(struct bwn_mac *mac)
7145 struct bwn_phy *phy = &mac->mac_phy;
7148 uint16_t start = 0x0008, end = 0x0018;
7150 if (phy->rev <= 1) {
7155 table = BWN_OFDMTAB_GAINX;
7157 table = BWN_OFDMTAB_GAINX_R1;
7158 for (i = 0; i < 4; i++) {
7160 tmp |= (i & 0x0001) << 1;
7161 tmp |= (i & 0x0002) >> 1;
7163 bwn_ofdmtab_write_2(mac, table, i, tmp);
7166 for (i = start; i < end; i++)
7167 bwn_ofdmtab_write_2(mac, table, i, i - start);
7169 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7170 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7171 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7172 bwn_dummy_transmission(mac, 0, 1);
7176 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7178 struct bwn_phy *phy = &mac->mac_phy;
7179 struct bwn_phy_g *pg = &phy->phy_g;
7180 struct bwn_rfatt old_rfatt, rfatt;
7181 struct bwn_bbatt old_bbatt, bbatt;
7182 struct bwn_softc *sc = mac->mac_sc;
7183 uint8_t old_txctl = 0;
7185 KASSERT(phy->type == BWN_PHYTYPE_G,
7186 ("%s:%d: fail", __func__, __LINE__));
7188 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7189 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7192 BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7194 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7198 bwn_hwpctl_early_init(mac);
7199 if (pg->pg_curtssi == 0) {
7200 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7201 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7203 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7204 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7205 old_txctl = pg->pg_txctl;
7208 if (phy->rf_rev == 8) {
7215 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7217 bwn_dummy_transmission(mac, 0, 1);
7218 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7219 if (phy->rf_ver == 0x2050 && phy->analog == 0)
7220 BWN_RF_MASK(mac, 0x0076, 0xff7b);
7222 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7223 &old_rfatt, old_txctl);
7225 bwn_hwpctl_init_gphy(mac);
7228 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7229 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7230 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7231 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7235 bwn_hwpctl_early_init(struct bwn_mac *mac)
7237 struct bwn_phy *phy = &mac->mac_phy;
7239 if (!bwn_has_hwpctl(mac)) {
7240 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7244 BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7245 BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7246 BWN_PHY_SET(mac, 0x047c, 0x0002);
7247 BWN_PHY_SET(mac, 0x047a, 0xf000);
7248 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7249 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7250 BWN_PHY_SET(mac, 0x005d, 0x8000);
7251 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7252 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7253 BWN_PHY_SET(mac, 0x0036, 0x0400);
7255 BWN_PHY_SET(mac, 0x0036, 0x0200);
7256 BWN_PHY_SET(mac, 0x0036, 0x0400);
7257 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7258 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7259 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7260 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7261 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7266 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7268 struct bwn_phy *phy = &mac->mac_phy;
7269 struct bwn_phy_g *pg = &phy->phy_g;
7270 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7272 uint16_t nr_written = 0, tmp, value;
7275 if (!bwn_has_hwpctl(mac)) {
7276 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7280 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7281 (pg->pg_idletssi - pg->pg_curtssi));
7282 BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7283 (pg->pg_idletssi - pg->pg_curtssi));
7285 for (i = 0; i < 32; i++)
7286 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7287 for (i = 32; i < 64; i++)
7288 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7289 for (i = 0; i < 64; i += 2) {
7290 value = (uint16_t) pg->pg_tssi2dbm[i];
7291 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7292 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7295 for (rf = 0; rf < lo->rfatt.len; rf++) {
7296 for (bb = 0; bb < lo->bbatt.len; bb++) {
7297 if (nr_written >= 0x40)
7299 tmp = lo->bbatt.array[bb].att;
7301 if (phy->rf_rev == 8)
7305 tmp |= lo->rfatt.array[rf].att;
7306 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7311 BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7312 BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7314 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7315 BWN_PHY_SET(mac, 0x0478, 0x0800);
7316 BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7317 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7319 bwn_phy_g_dc_lookup_init(mac, 1);
7320 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7324 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7326 struct bwn_softc *sc = mac->mac_sc;
7329 bwn_spu_workaround(mac, channel);
7331 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7333 if (channel == 14) {
7334 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7336 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7339 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7340 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7341 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7345 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7346 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7350 bwn_phy_g_chan2freq(uint8_t channel)
7352 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7354 KASSERT(channel >= 1 && channel <= 14,
7355 ("%s:%d: fail", __func__, __LINE__));
7357 return (bwn_phy_g_rf_channels[channel - 1]);
7361 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7362 const struct bwn_rfatt *rfatt, uint8_t txctl)
7364 struct bwn_phy *phy = &mac->mac_phy;
7365 struct bwn_phy_g *pg = &phy->phy_g;
7366 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7368 uint16_t tx_bias, tx_magn;
7372 tx_bias = lo->tx_bias;
7373 tx_magn = lo->tx_magn;
7374 if (tx_bias == 0xff)
7377 pg->pg_txctl = txctl;
7378 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7379 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7380 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7381 bwn_phy_g_set_bbatt(mac, bb);
7382 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7383 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7384 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7386 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7387 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7389 if (BWN_HAS_TXMAG(phy))
7390 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7392 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7393 bwn_lo_g_adjust(mac);
7397 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7400 struct bwn_phy *phy = &mac->mac_phy;
7402 if (phy->analog == 0) {
7403 BWN_WRITE_2(mac, BWN_PHY0,
7404 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7407 if (phy->analog > 1) {
7408 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7411 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7415 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7417 struct bwn_phy *phy = &mac->mac_phy;
7418 struct bwn_phy_g *pg = &phy->phy_g;
7419 struct bwn_softc *sc = mac->mac_sc;
7424 if (phy->gmode == 0)
7427 if (BWN_HAS_LOOPBACK(phy)) {
7428 max_lb_gain = pg->pg_max_lb_gain;
7429 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7430 if (max_lb_gain >= 0x46) {
7432 max_lb_gain -= 0x46;
7433 } else if (max_lb_gain >= 0x3a) {
7435 max_lb_gain -= 0x3a;
7436 } else if (max_lb_gain >= 0x2e) {
7438 max_lb_gain -= 0x2e;
7441 max_lb_gain -= 0x10;
7444 for (i = 0; i < 16; i++) {
7445 max_lb_gain -= (i * 6);
7446 if (max_lb_gain < 6)
7450 if ((phy->rev < 7) ||
7451 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7452 if (reg == BWN_PHY_RFOVER) {
7454 } else if (reg == BWN_PHY_RFOVERVAL) {
7457 case BWN_LPD(0, 1, 1):
7459 case BWN_LPD(0, 0, 1):
7460 case BWN_LPD(1, 0, 1):
7461 return (0x0092 | extlna);
7462 case BWN_LPD(1, 0, 0):
7463 return (0x0093 | extlna);
7466 ("%s:%d: fail", __func__, __LINE__));
7468 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7470 if (reg == BWN_PHY_RFOVER)
7472 if (reg == BWN_PHY_RFOVERVAL) {
7477 case BWN_LPD(0, 1, 1):
7479 case BWN_LPD(0, 0, 1):
7480 return (0x8092 | extlna);
7481 case BWN_LPD(1, 0, 1):
7482 return (0x2092 | extlna);
7483 case BWN_LPD(1, 0, 0):
7484 return (0x2093 | extlna);
7487 ("%s:%d: fail", __func__, __LINE__));
7489 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7494 if ((phy->rev < 7) ||
7495 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7496 if (reg == BWN_PHY_RFOVER) {
7498 } else if (reg == BWN_PHY_RFOVERVAL) {
7500 case BWN_LPD(0, 1, 1):
7502 case BWN_LPD(0, 0, 1):
7504 case BWN_LPD(1, 0, 1):
7506 case BWN_LPD(1, 0, 0):
7510 ("%s:%d: fail", __func__, __LINE__));
7512 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7514 if (reg == BWN_PHY_RFOVER) {
7516 } else if (reg == BWN_PHY_RFOVERVAL) {
7518 case BWN_LPD(0, 1, 1):
7520 case BWN_LPD(0, 0, 1):
7522 case BWN_LPD(1, 0, 1):
7524 case BWN_LPD(1, 0, 0):
7528 ("%s:%d: fail", __func__, __LINE__));
7530 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7536 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7539 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7541 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7542 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7544 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7548 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7550 struct bwn_softc *sc = mac->mac_sc;
7551 struct bwn_fw *fw = &mac->mac_fw;
7552 const uint8_t rev = siba_get_revid(sc->sc_dev);
7553 const char *filename;
7558 if (rev >= 5 && rev <= 10)
7559 filename = "ucode5";
7560 else if (rev >= 11 && rev <= 12)
7561 filename = "ucode11";
7563 filename = "ucode13";
7565 filename = "ucode14";
7567 filename = "ucode15";
7569 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7570 bwn_release_firmware(mac);
7571 return (EOPNOTSUPP);
7573 error = bwn_fw_get(mac, type, filename, &fw->ucode);
7575 bwn_release_firmware(mac);
7580 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7581 if (rev >= 5 && rev <= 10) {
7582 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7583 if (error == ENOENT)
7586 bwn_release_firmware(mac);
7589 } else if (rev < 11) {
7590 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7591 return (EOPNOTSUPP);
7595 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7596 switch (mac->mac_phy.type) {
7598 if (rev < 5 || rev > 10)
7600 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7601 filename = "a0g1initvals5";
7603 filename = "a0g0initvals5";
7606 if (rev >= 5 && rev <= 10)
7607 filename = "b0g0initvals5";
7609 filename = "b0g0initvals13";
7613 case BWN_PHYTYPE_LP:
7615 filename = "lp0initvals13";
7617 filename = "lp0initvals14";
7619 filename = "lp0initvals15";
7624 if (rev >= 11 && rev <= 12)
7625 filename = "n0initvals11";
7632 error = bwn_fw_get(mac, type, filename, &fw->initvals);
7634 bwn_release_firmware(mac);
7638 /* bandswitch initvals */
7639 switch (mac->mac_phy.type) {
7641 if (rev >= 5 && rev <= 10) {
7642 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7643 filename = "a0g1bsinitvals5";
7645 filename = "a0g0bsinitvals5";
7646 } else if (rev >= 11)
7652 if (rev >= 5 && rev <= 10)
7653 filename = "b0g0bsinitvals5";
7659 case BWN_PHYTYPE_LP:
7661 filename = "lp0bsinitvals13";
7663 filename = "lp0bsinitvals14";
7665 filename = "lp0bsinitvals15";
7670 if (rev >= 11 && rev <= 12)
7671 filename = "n0bsinitvals11";
7678 error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7680 bwn_release_firmware(mac);
7685 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7686 bwn_release_firmware(mac);
7687 return (EOPNOTSUPP);
7691 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7692 const char *name, struct bwn_fwfile *bfw)
7694 const struct bwn_fwhdr *hdr;
7695 struct bwn_softc *sc = mac->mac_sc;
7696 const struct firmware *fw;
7700 bwn_do_release_fw(bfw);
7703 if (bfw->filename != NULL) {
7704 if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7706 bwn_do_release_fw(bfw);
7709 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7710 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7711 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7712 /* XXX Sleeping on "fwload" with the non-sleepable locks held */
7713 fw = firmware_get(namebuf);
7715 device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7719 if (fw->datasize < sizeof(struct bwn_fwhdr))
7721 hdr = (const struct bwn_fwhdr *)(fw->data);
7722 switch (hdr->type) {
7723 case BWN_FWTYPE_UCODE:
7724 case BWN_FWTYPE_PCM:
7725 if (be32toh(hdr->size) !=
7726 (fw->datasize - sizeof(struct bwn_fwhdr)))
7736 bfw->filename = name;
7741 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7743 firmware_put(fw, FIRMWARE_UNLOAD);
7748 bwn_release_firmware(struct bwn_mac *mac)
7751 bwn_do_release_fw(&mac->mac_fw.ucode);
7752 bwn_do_release_fw(&mac->mac_fw.pcm);
7753 bwn_do_release_fw(&mac->mac_fw.initvals);
7754 bwn_do_release_fw(&mac->mac_fw.initvals_band);
7758 bwn_do_release_fw(struct bwn_fwfile *bfw)
7761 if (bfw->fw != NULL)
7762 firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7764 bfw->filename = NULL;
7768 bwn_fw_loaducode(struct bwn_mac *mac)
7770 #define GETFWOFFSET(fwp, offset) \
7771 ((const uint32_t *)((const char *)fwp.fw->data + offset))
7772 #define GETFWSIZE(fwp, offset) \
7773 ((fwp.fw->datasize - offset) / sizeof(uint32_t))
7774 struct bwn_softc *sc = mac->mac_sc;
7775 const uint32_t *data;
7778 uint16_t date, fwcaps, time;
7781 ctl = BWN_READ_4(mac, BWN_MACCTL);
7782 ctl |= BWN_MACCTL_MCODE_JMP0;
7783 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7785 BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7786 for (i = 0; i < 64; i++)
7787 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7788 for (i = 0; i < 4096; i += 2)
7789 bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7791 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7792 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7793 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7795 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7799 if (mac->mac_fw.pcm.fw) {
7800 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7801 bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7802 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7803 bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7804 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7805 sizeof(struct bwn_fwhdr)); i++) {
7806 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7811 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7812 BWN_WRITE_4(mac, BWN_MACCTL,
7813 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7814 BWN_MACCTL_MCODE_RUN);
7816 for (i = 0; i < 21; i++) {
7817 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7820 device_printf(sc->sc_dev, "ucode timeout\n");
7826 BWN_READ_4(mac, BWN_INTR_REASON);
7828 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7829 if (mac->mac_fw.rev <= 0x128) {
7830 device_printf(sc->sc_dev, "the firmware is too old\n");
7834 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7835 BWN_SHARED_UCODE_PATCH);
7836 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7837 mac->mac_fw.opensource = (date == 0xffff);
7839 mac->mac_flags |= BWN_MAC_FLAG_WME;
7840 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7842 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7843 if (mac->mac_fw.opensource == 0) {
7844 device_printf(sc->sc_dev,
7845 "firmware version (rev %u patch %u date %#x time %#x)\n",
7846 mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7847 if (mac->mac_fw.no_pcmfile)
7848 device_printf(sc->sc_dev,
7849 "no HW crypto acceleration due to pcm5\n");
7851 mac->mac_fw.patch = time;
7852 fwcaps = bwn_fwcaps_read(mac);
7853 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7854 device_printf(sc->sc_dev,
7855 "disabling HW crypto acceleration\n");
7856 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7858 if (!(fwcaps & BWN_FWCAPS_WME)) {
7859 device_printf(sc->sc_dev, "disabling WME support\n");
7860 mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7864 if (BWN_ISOLDFMT(mac))
7865 device_printf(sc->sc_dev, "using old firmware image\n");
7870 BWN_WRITE_4(mac, BWN_MACCTL,
7871 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7872 BWN_MACCTL_MCODE_JMP0);
7879 /* OpenFirmware only */
7881 bwn_fwcaps_read(struct bwn_mac *mac)
7884 KASSERT(mac->mac_fw.opensource == 1,
7885 ("%s:%d: fail", __func__, __LINE__));
7886 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7890 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7891 size_t count, size_t array_size)
7893 #define GET_NEXTIV16(iv) \
7894 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \
7895 sizeof(uint16_t) + sizeof(uint16_t)))
7896 #define GET_NEXTIV32(iv) \
7897 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \
7898 sizeof(uint16_t) + sizeof(uint32_t)))
7899 struct bwn_softc *sc = mac->mac_sc;
7900 const struct bwn_fwinitvals *iv;
7905 KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7906 ("%s:%d: fail", __func__, __LINE__));
7908 for (i = 0; i < count; i++) {
7909 if (array_size < sizeof(iv->offset_size))
7911 array_size -= sizeof(iv->offset_size);
7912 offset = be16toh(iv->offset_size);
7913 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7914 offset &= BWN_FWINITVALS_OFFSET_MASK;
7915 if (offset >= 0x1000)
7918 if (array_size < sizeof(iv->data.d32))
7920 array_size -= sizeof(iv->data.d32);
7921 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7922 iv = GET_NEXTIV32(iv);
7925 if (array_size < sizeof(iv->data.d16))
7927 array_size -= sizeof(iv->data.d16);
7928 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7930 iv = GET_NEXTIV16(iv);
7933 if (array_size != 0)
7937 device_printf(sc->sc_dev, "initvals: invalid format\n");
7944 bwn_switch_channel(struct bwn_mac *mac, int chan)
7946 struct bwn_phy *phy = &(mac->mac_phy);
7947 struct bwn_softc *sc = mac->mac_sc;
7948 struct ifnet *ifp = sc->sc_ifp;
7949 struct ieee80211com *ic = ifp->if_l2com;
7950 uint16_t channelcookie, savedcookie;
7954 chan = phy->get_default_chan(mac);
7956 channelcookie = chan;
7957 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
7958 channelcookie |= 0x100;
7959 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
7960 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
7961 error = phy->switch_channel(mac, chan);
7965 mac->mac_phy.chan = chan;
7969 device_printf(sc->sc_dev, "failed to switch channel\n");
7970 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
7975 bwn_ant2phy(int antenna)
7980 return (BWN_TX_PHY_ANT0);
7982 return (BWN_TX_PHY_ANT1);
7984 return (BWN_TX_PHY_ANT2);
7986 return (BWN_TX_PHY_ANT3);
7988 return (BWN_TX_PHY_ANT01AUTO);
7990 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7995 bwn_wme_load(struct bwn_mac *mac)
7997 struct bwn_softc *sc = mac->mac_sc;
8000 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
8001 ("%s:%d: fail", __func__, __LINE__));
8003 bwn_mac_suspend(mac);
8004 for (i = 0; i < N(sc->sc_wmeParams); i++)
8005 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
8006 bwn_wme_shm_offsets[i]);
8007 bwn_mac_enable(mac);
8011 bwn_wme_loadparams(struct bwn_mac *mac,
8012 const struct wmeParams *p, uint16_t shm_offset)
8014 #define SM(_v, _f) (((_v) << _f##_S) & _f)
8015 struct bwn_softc *sc = mac->mac_sc;
8016 uint16_t params[BWN_NR_WMEPARAMS];
8020 slot = BWN_READ_2(mac, BWN_RNG) &
8021 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8023 memset(¶ms, 0, sizeof(params));
8025 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
8026 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
8027 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
8029 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
8030 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8031 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
8032 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
8033 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
8034 params[BWN_WMEPARAM_BSLOTS] = slot;
8035 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
8037 for (i = 0; i < N(params); i++) {
8038 if (i == BWN_WMEPARAM_STATUS) {
8039 tmp = bwn_shm_read_2(mac, BWN_SHARED,
8040 shm_offset + (i * 2));
8042 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8045 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
8052 bwn_mac_write_bssid(struct bwn_mac *mac)
8054 struct bwn_softc *sc = mac->mac_sc;
8057 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
8059 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
8060 memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
8061 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
8062 IEEE80211_ADDR_LEN);
8064 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
8065 tmp = (uint32_t) (mac_bssid[i + 0]);
8066 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
8067 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
8068 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
8069 bwn_ram_write(mac, 0x20 + i, tmp);
8074 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
8075 const uint8_t *macaddr)
8077 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
8084 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
8087 data |= macaddr[1] << 8;
8088 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8090 data |= macaddr[3] << 8;
8091 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8093 data |= macaddr[5] << 8;
8094 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
8098 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8099 const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
8101 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
8102 uint8_t per_sta_keys_start = 8;
8104 if (BWN_SEC_NEWAPI(mac))
8105 per_sta_keys_start = 4;
8107 KASSERT(index < mac->mac_max_nr_keys,
8108 ("%s:%d: fail", __func__, __LINE__));
8109 KASSERT(key_len <= BWN_SEC_KEYSIZE,
8110 ("%s:%d: fail", __func__, __LINE__));
8112 if (index >= per_sta_keys_start)
8113 bwn_key_macwrite(mac, index, NULL);
8115 memcpy(buf, key, key_len);
8116 bwn_key_write(mac, index, algorithm, buf);
8117 if (index >= per_sta_keys_start)
8118 bwn_key_macwrite(mac, index, mac_addr);
8120 mac->mac_key[index].algorithm = algorithm;
8124 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8126 struct bwn_softc *sc = mac->mac_sc;
8127 uint32_t addrtmp[2] = { 0, 0 };
8130 if (BWN_SEC_NEWAPI(mac))
8133 KASSERT(index >= start,
8134 ("%s:%d: fail", __func__, __LINE__));
8138 addrtmp[0] = addr[0];
8139 addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8140 addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8141 addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8142 addrtmp[1] = addr[4];
8143 addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8146 if (siba_get_revid(sc->sc_dev) >= 5) {
8147 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8148 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8151 bwn_shm_write_4(mac, BWN_SHARED,
8152 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8153 bwn_shm_write_2(mac, BWN_SHARED,
8154 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8160 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8165 uint16_t kidx, value;
8167 kidx = BWN_SEC_KEY2FW(mac, index);
8168 bwn_shm_write_2(mac, BWN_SHARED,
8169 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8171 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8172 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8174 value |= (uint16_t)(key[i + 1]) << 8;
8175 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8180 bwn_phy_exit(struct bwn_mac *mac)
8183 mac->mac_phy.rf_onoff(mac, 0);
8184 if (mac->mac_phy.exit != NULL)
8185 mac->mac_phy.exit(mac);
8189 bwn_dma_free(struct bwn_mac *mac)
8191 struct bwn_dma *dma;
8193 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8195 dma = &mac->mac_method.dma;
8197 bwn_dma_ringfree(&dma->rx);
8198 bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8199 bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8200 bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8201 bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8202 bwn_dma_ringfree(&dma->mcast);
8206 bwn_core_stop(struct bwn_mac *mac)
8208 struct bwn_softc *sc = mac->mac_sc;
8210 BWN_ASSERT_LOCKED(sc);
8212 if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8215 callout_stop(&sc->sc_rfswitch_ch);
8216 callout_stop(&sc->sc_task_ch);
8217 callout_stop(&sc->sc_watchdog_ch);
8218 sc->sc_watchdog_timer = 0;
8219 BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8220 BWN_READ_4(mac, BWN_INTR_MASK);
8221 bwn_mac_suspend(mac);
8223 mac->mac_status = BWN_MAC_STATUS_INITED;
8227 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8229 struct bwn_mac *up_dev = NULL;
8230 struct bwn_mac *down_dev;
8231 struct bwn_mac *mac;
8235 BWN_ASSERT_LOCKED(sc);
8237 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8238 if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8239 mac->mac_phy.supports_2ghz) {
8242 } else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8243 mac->mac_phy.supports_5ghz) {
8247 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8253 if (up_dev == NULL) {
8254 device_printf(sc->sc_dev, "Could not find a device\n");
8257 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8260 device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8261 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8263 down_dev = sc->sc_curmac;;
8264 status = down_dev->mac_status;
8265 if (status >= BWN_MAC_STATUS_STARTED)
8266 bwn_core_stop(down_dev);
8267 if (status >= BWN_MAC_STATUS_INITED)
8268 bwn_core_exit(down_dev);
8270 if (down_dev != up_dev)
8271 bwn_phy_reset(down_dev);
8273 up_dev->mac_phy.gmode = gmode;
8274 if (status >= BWN_MAC_STATUS_INITED) {
8275 err = bwn_core_init(up_dev);
8277 device_printf(sc->sc_dev,
8278 "fatal: failed to initialize for %s-GHz\n",
8279 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8283 if (status >= BWN_MAC_STATUS_STARTED)
8284 bwn_core_start(up_dev);
8285 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8286 sc->sc_curmac = up_dev;
8290 sc->sc_curmac = NULL;
8295 bwn_rf_turnon(struct bwn_mac *mac)
8298 bwn_mac_suspend(mac);
8299 mac->mac_phy.rf_onoff(mac, 1);
8300 mac->mac_phy.rf_on = 1;
8301 bwn_mac_enable(mac);
8305 bwn_rf_turnoff(struct bwn_mac *mac)
8308 bwn_mac_suspend(mac);
8309 mac->mac_phy.rf_onoff(mac, 0);
8310 mac->mac_phy.rf_on = 0;
8311 bwn_mac_enable(mac);
8315 bwn_phy_reset(struct bwn_mac *mac)
8317 struct bwn_softc *sc = mac->mac_sc;
8319 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8320 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8321 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8323 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8324 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8325 BWN_TGSLOW_PHYRESET);
8330 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8332 const struct ieee80211_txparam *tp;
8333 struct bwn_vap *bvp = BWN_VAP(vap);
8334 struct ieee80211com *ic= vap->iv_ic;
8335 struct ifnet *ifp = ic->ic_ifp;
8336 enum ieee80211_state ostate = vap->iv_state;
8337 struct bwn_softc *sc = ifp->if_softc;
8338 struct bwn_mac *mac = sc->sc_curmac;
8341 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8342 ieee80211_state_name[vap->iv_state],
8343 ieee80211_state_name[nstate]);
8345 error = bvp->bv_newstate(vap, nstate, arg);
8351 bwn_led_newstate(mac, nstate);
8354 * Clear the BSSID when we stop a STA
8356 if (vap->iv_opmode == IEEE80211_M_STA) {
8357 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8359 * Clear out the BSSID. If we reassociate to
8360 * the same AP, this will reinialize things
8363 if (ic->ic_opmode == IEEE80211_M_STA &&
8364 (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8365 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8366 bwn_set_macaddr(mac);
8371 if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8372 vap->iv_opmode == IEEE80211_M_AHDEMO) {
8373 /* XXX nothing to do? */
8374 } else if (nstate == IEEE80211_S_RUN) {
8375 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8376 memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
8377 bwn_set_opmode(mac);
8378 bwn_set_pretbtt(mac);
8379 bwn_spu_setdelay(mac, 0);
8380 bwn_set_macaddr(mac);
8382 /* Initializes ratectl for a node. */
8383 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
8384 if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
8385 ieee80211_ratectl_node_init(vap->iv_bss);
8394 bwn_set_pretbtt(struct bwn_mac *mac)
8396 struct bwn_softc *sc = mac->mac_sc;
8397 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8400 if (ic->ic_opmode == IEEE80211_M_IBSS)
8403 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8404 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8405 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8411 struct bwn_mac *mac = arg;
8412 struct bwn_softc *sc = mac->mac_sc;
8415 if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8416 (sc->sc_flags & BWN_FLAG_INVALID))
8417 return (FILTER_STRAY);
8419 reason = BWN_READ_4(mac, BWN_INTR_REASON);
8420 if (reason == 0xffffffff) /* shared IRQ */
8421 return (FILTER_STRAY);
8422 reason &= mac->mac_intr_mask;
8424 return (FILTER_HANDLED);
8426 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
8427 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8428 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8429 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8430 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8431 BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8432 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8433 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8434 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8435 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8436 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8438 /* Disable interrupts. */
8439 BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8441 mac->mac_reason_intr = reason;
8443 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8444 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8446 taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask);
8447 return (FILTER_HANDLED);
8451 bwn_intrtask(void *arg, int npending)
8453 struct bwn_mac *mac = arg;
8454 struct bwn_softc *sc = mac->mac_sc;
8455 struct ifnet *ifp = sc->sc_ifp;
8456 uint32_t merged = 0;
8457 int i, tx = 0, rx = 0;
8460 if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8461 (sc->sc_flags & BWN_FLAG_INVALID)) {
8466 for (i = 0; i < N(mac->mac_reason); i++)
8467 merged |= mac->mac_reason[i];
8469 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8470 device_printf(sc->sc_dev, "MAC trans error\n");
8472 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8473 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8474 mac->mac_phy.txerrors--;
8475 if (mac->mac_phy.txerrors == 0) {
8476 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8477 bwn_restart(mac, "PHY TX errors");
8481 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
8482 if (merged & BWN_DMAINTR_FATALMASK) {
8483 device_printf(sc->sc_dev,
8484 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8485 mac->mac_reason[0], mac->mac_reason[1],
8486 mac->mac_reason[2], mac->mac_reason[3],
8487 mac->mac_reason[4], mac->mac_reason[5]);
8488 bwn_restart(mac, "DMA error");
8492 if (merged & BWN_DMAINTR_NONFATALMASK) {
8493 device_printf(sc->sc_dev,
8494 "DMA error: %#x %#x %#x %#x %#x %#x\n",
8495 mac->mac_reason[0], mac->mac_reason[1],
8496 mac->mac_reason[2], mac->mac_reason[3],
8497 mac->mac_reason[4], mac->mac_reason[5]);
8501 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8502 bwn_intr_ucode_debug(mac);
8503 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8504 bwn_intr_tbtt_indication(mac);
8505 if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8506 bwn_intr_atim_end(mac);
8507 if (mac->mac_reason_intr & BWN_INTR_BEACON)
8508 bwn_intr_beacon(mac);
8509 if (mac->mac_reason_intr & BWN_INTR_PMQ)
8511 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8512 bwn_intr_noise(mac);
8514 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8515 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8516 bwn_dma_rx(mac->mac_method.dma.rx);
8520 rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8522 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8523 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8524 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8525 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8526 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8528 if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8529 bwn_intr_txeof(mac);
8533 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8535 if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8536 int evt = BWN_LED_EVENT_NONE;
8539 if (sc->sc_rx_rate > sc->sc_tx_rate)
8540 evt = BWN_LED_EVENT_RX;
8542 evt = BWN_LED_EVENT_TX;
8544 evt = BWN_LED_EVENT_TX;
8546 evt = BWN_LED_EVENT_RX;
8547 } else if (rx == 0) {
8548 evt = BWN_LED_EVENT_POLL;
8551 if (evt != BWN_LED_EVENT_NONE)
8552 bwn_led_event(mac, evt);
8555 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
8556 if (!IFQ_IS_EMPTY(&ifp->if_snd))
8557 bwn_start_locked(ifp);
8560 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8561 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8567 bwn_restart(struct bwn_mac *mac, const char *msg)
8569 struct bwn_softc *sc = mac->mac_sc;
8570 struct ifnet *ifp = sc->sc_ifp;
8571 struct ieee80211com *ic = ifp->if_l2com;
8573 if (mac->mac_status < BWN_MAC_STATUS_INITED)
8576 device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8577 ieee80211_runtask(ic, &mac->mac_hwreset);
8581 bwn_intr_ucode_debug(struct bwn_mac *mac)
8583 struct bwn_softc *sc = mac->mac_sc;
8586 if (mac->mac_fw.opensource == 0)
8589 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8591 case BWN_DEBUGINTR_PANIC:
8592 bwn_handle_fwpanic(mac);
8594 case BWN_DEBUGINTR_DUMP_SHM:
8595 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8597 case BWN_DEBUGINTR_DUMP_REGS:
8598 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8600 case BWN_DEBUGINTR_MARKER:
8601 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8604 device_printf(sc->sc_dev,
8605 "ucode debug unknown reason: %#x\n", reason);
8608 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8613 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8615 struct bwn_softc *sc = mac->mac_sc;
8616 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8618 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8620 if (ic->ic_opmode == IEEE80211_M_IBSS)
8621 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8625 bwn_intr_atim_end(struct bwn_mac *mac)
8628 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8629 BWN_WRITE_4(mac, BWN_MACCMD,
8630 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8631 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8636 bwn_intr_beacon(struct bwn_mac *mac)
8638 struct bwn_softc *sc = mac->mac_sc;
8639 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
8640 uint32_t cmd, beacon0, beacon1;
8642 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8643 ic->ic_opmode == IEEE80211_M_MBSS)
8646 mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8648 cmd = BWN_READ_4(mac, BWN_MACCMD);
8649 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8650 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8652 if (beacon0 && beacon1) {
8653 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8654 mac->mac_intr_mask |= BWN_INTR_BEACON;
8658 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8659 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8660 bwn_load_beacon0(mac);
8661 bwn_load_beacon1(mac);
8662 cmd = BWN_READ_4(mac, BWN_MACCMD);
8663 cmd |= BWN_MACCMD_BEACON0_VALID;
8664 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8667 bwn_load_beacon0(mac);
8668 cmd = BWN_READ_4(mac, BWN_MACCMD);
8669 cmd |= BWN_MACCMD_BEACON0_VALID;
8670 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8671 } else if (!beacon1) {
8672 bwn_load_beacon1(mac);
8673 cmd = BWN_READ_4(mac, BWN_MACCMD);
8674 cmd |= BWN_MACCMD_BEACON1_VALID;
8675 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8681 bwn_intr_pmq(struct bwn_mac *mac)
8686 tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8687 if (!(tmp & 0x00000008))
8690 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8694 bwn_intr_noise(struct bwn_mac *mac)
8696 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8702 if (mac->mac_phy.type != BWN_PHYTYPE_G)
8705 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8706 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8707 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8711 KASSERT(mac->mac_noise.noi_nsamples < 8,
8712 ("%s:%d: fail", __func__, __LINE__));
8713 i = mac->mac_noise.noi_nsamples;
8714 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8715 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8716 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8717 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8718 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8719 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8720 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8721 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8722 mac->mac_noise.noi_nsamples++;
8723 if (mac->mac_noise.noi_nsamples == 8) {
8725 for (i = 0; i < 8; i++) {
8726 for (j = 0; j < 4; j++)
8727 average += mac->mac_noise.noi_samples[i][j];
8729 average = (((average / 32) * 125) + 64) / 128;
8730 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8735 average -= (tmp == 8) ? 72 : 48;
8737 mac->mac_stats.link_noise = average;
8738 mac->mac_noise.noi_running = 0;
8742 bwn_noise_gensample(mac);
8746 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8748 struct bwn_mac *mac = prq->prq_mac;
8749 struct bwn_softc *sc = mac->mac_sc;
8752 BWN_ASSERT_LOCKED(sc);
8754 if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8757 for (i = 0; i < 5000; i++) {
8758 if (bwn_pio_rxeof(prq) == 0)
8762 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8763 return ((i > 0) ? 1 : 0);
8767 bwn_dma_rx(struct bwn_dma_ring *dr)
8771 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8772 curslot = dr->get_curslot(dr);
8773 KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8774 ("%s:%d: fail", __func__, __LINE__));
8776 slot = dr->dr_curslot;
8777 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8778 bwn_dma_rxeof(dr, &slot);
8780 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8781 BUS_DMASYNC_PREWRITE);
8783 dr->set_curslot(dr, slot);
8784 dr->dr_curslot = slot;
8788 bwn_intr_txeof(struct bwn_mac *mac)
8790 struct bwn_txstatus stat;
8791 uint32_t stat0, stat1;
8794 BWN_ASSERT_LOCKED(mac->mac_sc);
8797 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8798 if (!(stat0 & 0x00000001))
8800 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8802 stat.cookie = (stat0 >> 16);
8803 stat.seq = (stat1 & 0x0000ffff);
8804 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8805 tmp = (stat0 & 0x0000ffff);
8806 stat.framecnt = ((tmp & 0xf000) >> 12);
8807 stat.rtscnt = ((tmp & 0x0f00) >> 8);
8808 stat.sreason = ((tmp & 0x001c) >> 2);
8809 stat.pm = (tmp & 0x0080) ? 1 : 0;
8810 stat.im = (tmp & 0x0040) ? 1 : 0;
8811 stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8812 stat.ack = (tmp & 0x0002) ? 1 : 0;
8814 bwn_handle_txeof(mac, &stat);
8819 bwn_hwreset(void *arg, int npending)
8821 struct bwn_mac *mac = arg;
8822 struct bwn_softc *sc = mac->mac_sc;
8828 prev_status = mac->mac_status;
8829 if (prev_status >= BWN_MAC_STATUS_STARTED)
8831 if (prev_status >= BWN_MAC_STATUS_INITED)
8834 if (prev_status >= BWN_MAC_STATUS_INITED) {
8835 error = bwn_core_init(mac);
8839 if (prev_status >= BWN_MAC_STATUS_STARTED)
8840 bwn_core_start(mac);
8843 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8844 sc->sc_curmac = NULL;
8850 bwn_handle_fwpanic(struct bwn_mac *mac)
8852 struct bwn_softc *sc = mac->mac_sc;
8855 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8856 device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8858 if (reason == BWN_FWPANIC_RESTART)
8859 bwn_restart(mac, "ucode panic");
8863 bwn_load_beacon0(struct bwn_mac *mac)
8866 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8870 bwn_load_beacon1(struct bwn_mac *mac)
8873 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8877 bwn_jssi_read(struct bwn_mac *mac)
8881 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8883 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8889 bwn_noise_gensample(struct bwn_mac *mac)
8891 uint32_t jssi = 0x7f7f7f7f;
8893 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8894 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8895 BWN_WRITE_4(mac, BWN_MACCMD,
8896 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8900 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8902 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8904 return (dr->dr_numslots - dr->dr_usedslot);
8908 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8910 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8912 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8913 ("%s:%d: fail", __func__, __LINE__));
8914 if (slot == dr->dr_numslots - 1)
8920 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8922 struct bwn_mac *mac = dr->dr_mac;
8923 struct bwn_softc *sc = mac->mac_sc;
8924 struct bwn_dma *dma = &mac->mac_method.dma;
8925 struct bwn_dmadesc_generic *desc;
8926 struct bwn_dmadesc_meta *meta;
8927 struct bwn_rxhdr4 *rxhdr;
8928 struct ifnet *ifp = sc->sc_ifp;
8935 dr->getdesc(dr, *slot, &desc, &meta);
8937 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8940 if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8945 rxhdr = mtod(m, struct bwn_rxhdr4 *);
8946 len = le16toh(rxhdr->frame_len);
8951 if (bwn_dma_check_redzone(dr, m)) {
8952 device_printf(sc->sc_dev, "redzone error.\n");
8953 bwn_dma_set_redzone(dr, m);
8954 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8955 BUS_DMASYNC_PREWRITE);
8958 if (len > dr->dr_rx_bufsize) {
8961 dr->getdesc(dr, *slot, &desc, &meta);
8962 bwn_dma_set_redzone(dr, meta->mt_m);
8963 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8964 BUS_DMASYNC_PREWRITE);
8965 *slot = bwn_dma_nextslot(dr, *slot);
8967 tmp -= dr->dr_rx_bufsize;
8971 device_printf(sc->sc_dev, "too small buffer "
8972 "(len %u buffer %u dropped %d)\n",
8973 len, dr->dr_rx_bufsize, cnt);
8976 macstat = le32toh(rxhdr->mac_status);
8977 if (macstat & BWN_RX_MAC_FCSERR) {
8978 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8979 device_printf(sc->sc_dev, "RX drop\n");
8984 m->m_pkthdr.rcvif = ifp;
8985 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8986 m_adj(m, dr->dr_frameoffset);
8988 bwn_rxeof(dr->dr_mac, m, rxhdr);
8992 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8994 struct bwn_dma_ring *dr;
8995 struct bwn_dmadesc_generic *desc;
8996 struct bwn_dmadesc_meta *meta;
8997 struct bwn_pio_txqueue *tq;
8998 struct bwn_pio_txpkt *tp = NULL;
8999 struct bwn_softc *sc = mac->mac_sc;
9000 struct bwn_stats *stats = &mac->mac_stats;
9001 struct ieee80211_node *ni;
9002 struct ieee80211vap *vap;
9003 int retrycnt = 0, slot;
9005 BWN_ASSERT_LOCKED(mac->mac_sc);
9008 device_printf(sc->sc_dev, "TODO: STATUS IM\n");
9010 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
9011 if (status->rtscnt) {
9012 if (status->rtscnt == 0xf)
9018 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
9020 dr = bwn_dma_parse_cookie(mac, status,
9021 status->cookie, &slot);
9023 device_printf(sc->sc_dev,
9024 "failed to parse cookie\n");
9028 dr->getdesc(dr, slot, &desc, &meta);
9029 if (meta->mt_islast) {
9032 ieee80211_ratectl_tx_complete(vap, ni,
9034 IEEE80211_RATECTL_TX_SUCCESS :
9035 IEEE80211_RATECTL_TX_FAILURE,
9039 slot = bwn_dma_nextslot(dr, slot);
9042 bwn_dma_handle_txeof(mac, status);
9045 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9047 device_printf(sc->sc_dev,
9048 "failed to parse cookie\n");
9053 ieee80211_ratectl_tx_complete(vap, ni,
9055 IEEE80211_RATECTL_TX_SUCCESS :
9056 IEEE80211_RATECTL_TX_FAILURE,
9059 bwn_pio_handle_txeof(mac, status);
9062 bwn_phy_txpower_check(mac, 0);
9066 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
9068 struct bwn_mac *mac = prq->prq_mac;
9069 struct bwn_softc *sc = mac->mac_sc;
9070 struct bwn_rxhdr4 rxhdr;
9071 struct ifnet *ifp = sc->sc_ifp;
9073 uint32_t ctl32, macstat, v32;
9074 unsigned int i, padding;
9075 uint16_t ctl16, len, totlen, v16;
9079 memset(&rxhdr, 0, sizeof(rxhdr));
9081 if (prq->prq_rev >= 8) {
9082 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9083 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
9085 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9086 BWN_PIO8_RXCTL_FRAMEREADY);
9087 for (i = 0; i < 10; i++) {
9088 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
9089 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
9094 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9095 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
9097 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
9098 BWN_PIO_RXCTL_FRAMEREADY);
9099 for (i = 0; i < 10; i++) {
9100 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
9101 if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
9106 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
9109 if (prq->prq_rev >= 8)
9110 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9111 prq->prq_base + BWN_PIO8_RXDATA);
9113 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
9114 prq->prq_base + BWN_PIO_RXDATA);
9115 len = le16toh(rxhdr.frame_len);
9117 device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9121 device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9125 macstat = le32toh(rxhdr.mac_status);
9126 if (macstat & BWN_RX_MAC_FCSERR) {
9127 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9128 device_printf(sc->sc_dev, "%s: FCS error", __func__);
9133 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9134 totlen = len + padding;
9135 KASSERT(totlen <= MCLBYTES, ("too big..\n"));
9136 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
9138 device_printf(sc->sc_dev, "%s: out of memory", __func__);
9141 mp = mtod(m, unsigned char *);
9142 if (prq->prq_rev >= 8) {
9143 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3),
9144 prq->prq_base + BWN_PIO8_RXDATA);
9146 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9147 data = &(mp[totlen - 1]);
9148 switch (totlen & 3) {
9150 *data = (v32 >> 16);
9160 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1),
9161 prq->prq_base + BWN_PIO_RXDATA);
9163 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9164 mp[totlen - 1] = v16;
9168 m->m_pkthdr.rcvif = ifp;
9169 m->m_len = m->m_pkthdr.len = totlen;
9171 bwn_rxeof(prq->prq_mac, m, &rxhdr);
9175 if (prq->prq_rev >= 8)
9176 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9177 BWN_PIO8_RXCTL_DATAREADY);
9179 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9184 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9185 struct bwn_dmadesc_meta *meta, int init)
9187 struct bwn_mac *mac = dr->dr_mac;
9188 struct bwn_dma *dma = &mac->mac_method.dma;
9189 struct bwn_rxhdr4 *hdr;
9195 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
9200 * If the NIC is up and running, we need to:
9201 * - Clear RX buffer's header.
9202 * - Restore RX descriptor settings.
9209 m->m_len = m->m_pkthdr.len = MCLBYTES;
9211 bwn_dma_set_redzone(dr, m);
9214 * Try to load RX buf into temporary DMA map
9216 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9217 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9222 * See the comment above
9231 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9233 meta->mt_paddr = paddr;
9236 * Swap RX buf's DMA map with the loaded temporary one
9238 map = meta->mt_dmap;
9239 meta->mt_dmap = dr->dr_spare_dmap;
9240 dr->dr_spare_dmap = map;
9244 * Clear RX buf header
9246 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9247 bzero(hdr, sizeof(*hdr));
9248 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9249 BUS_DMASYNC_PREWRITE);
9252 * Setup RX buf descriptor
9254 dr->setdesc(dr, desc, paddr, meta->mt_m->m_len -
9255 sizeof(*hdr), 0, 0, 0);
9260 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9261 bus_size_t mapsz __unused, int error)
9265 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9266 *((bus_addr_t *)arg) = seg->ds_addr;
9271 bwn_hwrate2ieeerate(int rate)
9275 case BWN_CCK_RATE_1MB:
9277 case BWN_CCK_RATE_2MB:
9279 case BWN_CCK_RATE_5MB:
9281 case BWN_CCK_RATE_11MB:
9283 case BWN_OFDM_RATE_6MB:
9285 case BWN_OFDM_RATE_9MB:
9287 case BWN_OFDM_RATE_12MB:
9289 case BWN_OFDM_RATE_18MB:
9291 case BWN_OFDM_RATE_24MB:
9293 case BWN_OFDM_RATE_36MB:
9295 case BWN_OFDM_RATE_48MB:
9297 case BWN_OFDM_RATE_54MB:
9306 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9308 const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9309 struct bwn_plcp6 *plcp;
9310 struct bwn_softc *sc = mac->mac_sc;
9311 struct ieee80211_frame_min *wh;
9312 struct ieee80211_node *ni;
9313 struct ifnet *ifp = sc->sc_ifp;
9314 struct ieee80211com *ic = ifp->if_l2com;
9316 int padding, rate, rssi = 0, noise = 0, type;
9317 uint16_t phytype, phystat0, phystat3, chanstat;
9318 unsigned char *mp = mtod(m, unsigned char *);
9319 static int rx_mac_dec_rpt = 0;
9321 BWN_ASSERT_LOCKED(sc);
9323 phystat0 = le16toh(rxhdr->phy_status0);
9324 phystat3 = le16toh(rxhdr->phy_status3);
9325 macstat = le32toh(rxhdr->mac_status);
9326 chanstat = le16toh(rxhdr->channel);
9327 phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9329 if (macstat & BWN_RX_MAC_FCSERR)
9330 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9331 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9332 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9333 if (macstat & BWN_RX_MAC_DECERR)
9336 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9337 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9338 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9342 plcp = (struct bwn_plcp6 *)(mp + padding);
9343 m_adj(m, sizeof(struct bwn_plcp6) + padding);
9344 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9345 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9349 wh = mtod(m, struct ieee80211_frame_min *);
9351 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9352 device_printf(sc->sc_dev,
9353 "RX decryption attempted (old %d keyidx %#x)\n",
9355 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9357 /* XXX calculating RSSI & noise & antenna */
9359 if (phystat0 & BWN_RX_PHYST0_OFDM)
9360 rate = bwn_plcp_get_ofdmrate(mac, plcp,
9361 phytype == BWN_PHYTYPE_A);
9363 rate = bwn_plcp_get_cckrate(mac, plcp);
9365 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9368 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9371 if (ieee80211_radiotap_active(ic))
9372 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9373 m_adj(m, -IEEE80211_CRC_LEN);
9375 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */
9376 noise = mac->mac_stats.link_noise;
9382 ni = ieee80211_find_rxnode(ic, wh);
9384 type = ieee80211_input(ni, m, rssi, noise);
9385 ieee80211_free_node(ni);
9387 type = ieee80211_input_all(ic, m, rssi, noise);
9392 device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9396 bwn_dma_handle_txeof(struct bwn_mac *mac,
9397 const struct bwn_txstatus *status)
9399 struct bwn_dma *dma = &mac->mac_method.dma;
9400 struct bwn_dma_ring *dr;
9401 struct bwn_dmadesc_generic *desc;
9402 struct bwn_dmadesc_meta *meta;
9403 struct bwn_softc *sc = mac->mac_sc;
9404 struct ieee80211_node *ni;
9405 struct ifnet *ifp = sc->sc_ifp;
9409 BWN_ASSERT_LOCKED(sc);
9411 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9413 device_printf(sc->sc_dev, "failed to parse cookie\n");
9416 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9419 KASSERT(slot >= 0 && slot < dr->dr_numslots,
9420 ("%s:%d: fail", __func__, __LINE__));
9421 dr->getdesc(dr, slot, &desc, &meta);
9423 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
9424 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
9425 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
9426 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9428 if (meta->mt_islast) {
9429 KASSERT(meta->mt_m != NULL,
9430 ("%s:%d: fail", __func__, __LINE__));
9436 * Do any tx complete callback. Note this must
9437 * be done before releasing the node reference.
9439 if (m->m_flags & M_TXCB)
9440 ieee80211_process_callback(ni, m, 0);
9441 ieee80211_free_node(ni);
9447 KASSERT(meta->mt_m == NULL,
9448 ("%s:%d: fail", __func__, __LINE__));
9452 if (meta->mt_islast) {
9456 slot = bwn_dma_nextslot(dr, slot);
9458 sc->sc_watchdog_timer = 0;
9460 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9461 ("%s:%d: fail", __func__, __LINE__));
9462 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9468 bwn_pio_handle_txeof(struct bwn_mac *mac,
9469 const struct bwn_txstatus *status)
9471 struct bwn_pio_txqueue *tq;
9472 struct bwn_pio_txpkt *tp = NULL;
9473 struct bwn_softc *sc = mac->mac_sc;
9474 struct ifnet *ifp = sc->sc_ifp;
9476 BWN_ASSERT_LOCKED(sc);
9478 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9482 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9485 if (tp->tp_ni != NULL) {
9487 * Do any tx complete callback. Note this must
9488 * be done before releasing the node reference.
9490 if (tp->tp_m->m_flags & M_TXCB)
9491 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9492 ieee80211_free_node(tp->tp_ni);
9497 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9501 sc->sc_watchdog_timer = 0;
9503 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
9509 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9511 struct bwn_softc *sc = mac->mac_sc;
9512 struct bwn_phy *phy = &mac->mac_phy;
9513 struct ifnet *ifp = sc->sc_ifp;
9514 struct ieee80211com *ic = ifp->if_l2com;
9520 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9522 phy->nexttime = now + 2 * 1000;
9524 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9525 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9528 if (phy->recalc_txpwr != NULL) {
9529 result = phy->recalc_txpwr(mac,
9530 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9531 if (result == BWN_TXPWR_RES_DONE)
9533 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9534 ("%s: fail", __func__));
9535 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9537 ieee80211_runtask(ic, &mac->mac_txpower);
9542 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9545 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9549 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9552 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9556 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9559 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9563 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9566 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9570 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9574 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9576 return (BWN_OFDM_RATE_6MB);
9578 return (BWN_OFDM_RATE_9MB);
9580 return (BWN_OFDM_RATE_12MB);
9582 return (BWN_OFDM_RATE_18MB);
9584 return (BWN_OFDM_RATE_24MB);
9586 return (BWN_OFDM_RATE_36MB);
9588 return (BWN_OFDM_RATE_48MB);
9590 return (BWN_OFDM_RATE_54MB);
9591 /* CCK rates (NB: not IEEE std, device-specific) */
9593 return (BWN_CCK_RATE_1MB);
9595 return (BWN_CCK_RATE_2MB);
9597 return (BWN_CCK_RATE_5MB);
9599 return (BWN_CCK_RATE_11MB);
9602 device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9603 return (BWN_CCK_RATE_1MB);
9607 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9608 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9610 const struct bwn_phy *phy = &mac->mac_phy;
9611 struct bwn_softc *sc = mac->mac_sc;
9612 struct ieee80211_frame *wh;
9613 struct ieee80211_frame *protwh;
9614 struct ieee80211_frame_cts *cts;
9615 struct ieee80211_frame_rts *rts;
9616 const struct ieee80211_txparam *tp;
9617 struct ieee80211vap *vap = ni->ni_vap;
9618 struct ifnet *ifp = sc->sc_ifp;
9619 struct ieee80211com *ic = ifp->if_l2com;
9622 uint32_t macctl = 0;
9623 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9624 uint16_t phyctl = 0;
9625 uint8_t rate, rate_fb;
9627 wh = mtod(m, struct ieee80211_frame *);
9628 memset(txhdr, 0, sizeof(*txhdr));
9630 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9631 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9632 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9637 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9638 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9639 rate = rate_fb = tp->mgmtrate;
9641 rate = rate_fb = tp->mcastrate;
9642 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9643 rate = rate_fb = tp->ucastrate;
9645 rix = ieee80211_ratectl_rate(ni, NULL, 0);
9646 rate = ni->ni_txrate;
9649 rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9655 sc->sc_tx_rate = rate;
9657 rate = bwn_ieeerate2hwrate(sc, rate);
9658 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9660 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9661 bwn_plcp_getcck(rate);
9662 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9663 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9665 if ((rate_fb == rate) ||
9666 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9667 (*(u_int16_t *)wh->i_dur == htole16(0)))
9668 txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9670 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9671 m->m_pkthdr.len, rate, isshort);
9673 /* XXX TX encryption */
9674 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9675 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9676 (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9677 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9678 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9679 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9681 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9683 txhdr->chan = phy->chan;
9684 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9686 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9687 rate == BWN_CCK_RATE_11MB))
9688 phyctl |= BWN_TX_PHY_SHORTPRMBL;
9690 /* XXX TX antenna selection */
9692 switch (bwn_antenna_sanitize(mac, 0)) {
9694 phyctl |= BWN_TX_PHY_ANT01AUTO;
9697 phyctl |= BWN_TX_PHY_ANT0;
9700 phyctl |= BWN_TX_PHY_ANT1;
9703 phyctl |= BWN_TX_PHY_ANT2;
9706 phyctl |= BWN_TX_PHY_ANT3;
9709 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9713 macctl |= BWN_TX_MAC_ACK;
9715 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9716 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9717 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9718 macctl |= BWN_TX_MAC_LONGFRAME;
9720 if (ic->ic_flags & IEEE80211_F_USEPROT) {
9721 /* XXX RTS rate is always 1MB??? */
9722 rts_rate = BWN_CCK_RATE_1MB;
9723 rts_rate_fb = bwn_get_fbrate(rts_rate);
9725 protdur = ieee80211_compute_duration(ic->ic_rt,
9726 m->m_pkthdr.len, rate, isshort) +
9727 + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9729 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9730 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9731 (txhdr->body.old.rts_frame) :
9732 (txhdr->body.new.rts_frame));
9733 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9735 KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9736 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9737 mprot->m_pkthdr.len);
9739 macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9740 len = sizeof(struct ieee80211_frame_cts);
9742 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9743 (txhdr->body.old.rts_frame) :
9744 (txhdr->body.new.rts_frame));
9745 protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9747 mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9748 wh->i_addr2, protdur);
9749 KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9750 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9751 mprot->m_pkthdr.len);
9753 macctl |= BWN_TX_MAC_SEND_RTSCTS;
9754 len = sizeof(struct ieee80211_frame_rts);
9756 len += IEEE80211_CRC_LEN;
9757 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9758 &txhdr->body.old.rts_plcp :
9759 &txhdr->body.new.rts_plcp), len, rts_rate);
9760 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9763 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9764 (&txhdr->body.old.rts_frame) :
9765 (&txhdr->body.new.rts_frame));
9766 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9768 if (BWN_ISOFDMRATE(rts_rate)) {
9769 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9770 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9772 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9773 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9775 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9776 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9779 if (BWN_ISOLDFMT(mac))
9780 txhdr->body.old.cookie = htole16(cookie);
9782 txhdr->body.new.cookie = htole16(cookie);
9784 txhdr->macctl = htole32(macctl);
9785 txhdr->phyctl = htole16(phyctl);
9790 if (ieee80211_radiotap_active_vap(vap)) {
9791 sc->sc_tx_th.wt_flags = 0;
9792 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
9793 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9795 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9796 rate == BWN_CCK_RATE_11MB))
9797 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9798 sc->sc_tx_th.wt_rate = rate;
9800 ieee80211_radiotap_tx(vap, m);
9807 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9811 uint8_t *raw = plcp->o.raw;
9813 if (BWN_ISOFDMRATE(rate)) {
9814 d = bwn_plcp_getofdm(rate);
9815 KASSERT(!(octets & 0xf000),
9816 ("%s:%d: fail", __func__, __LINE__));
9818 plcp->o.data = htole32(d);
9820 plen = octets * 16 / rate;
9821 if ((octets * 16 % rate) > 0) {
9823 if ((rate == BWN_CCK_RATE_11MB)
9824 && ((octets * 8 % 11) < 4)) {
9830 plcp->o.data |= htole32(plen << 16);
9831 raw[0] = bwn_plcp_getcck(rate);
9836 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9838 struct bwn_softc *sc = mac->mac_sc;
9843 if (mac->mac_phy.gmode)
9844 mask = siba_sprom_get_ant_bg(sc->sc_dev);
9846 mask = siba_sprom_get_ant_a(sc->sc_dev);
9847 if (!(mask & (1 << (n - 1))))
9853 bwn_get_fbrate(uint8_t bitrate)
9856 case BWN_CCK_RATE_1MB:
9857 return (BWN_CCK_RATE_1MB);
9858 case BWN_CCK_RATE_2MB:
9859 return (BWN_CCK_RATE_1MB);
9860 case BWN_CCK_RATE_5MB:
9861 return (BWN_CCK_RATE_2MB);
9862 case BWN_CCK_RATE_11MB:
9863 return (BWN_CCK_RATE_5MB);
9864 case BWN_OFDM_RATE_6MB:
9865 return (BWN_CCK_RATE_5MB);
9866 case BWN_OFDM_RATE_9MB:
9867 return (BWN_OFDM_RATE_6MB);
9868 case BWN_OFDM_RATE_12MB:
9869 return (BWN_OFDM_RATE_9MB);
9870 case BWN_OFDM_RATE_18MB:
9871 return (BWN_OFDM_RATE_12MB);
9872 case BWN_OFDM_RATE_24MB:
9873 return (BWN_OFDM_RATE_18MB);
9874 case BWN_OFDM_RATE_36MB:
9875 return (BWN_OFDM_RATE_24MB);
9876 case BWN_OFDM_RATE_48MB:
9877 return (BWN_OFDM_RATE_36MB);
9878 case BWN_OFDM_RATE_54MB:
9879 return (BWN_OFDM_RATE_48MB);
9881 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9886 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9887 uint32_t ctl, const void *_data, int len)
9889 struct bwn_softc *sc = mac->mac_sc;
9891 const uint8_t *data = _data;
9893 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9894 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9895 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9897 siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9898 tq->tq_base + BWN_PIO8_TXDATA);
9900 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9901 BWN_PIO8_TXCTL_24_31);
9902 data = &(data[len - 1]);
9905 ctl |= BWN_PIO8_TXCTL_16_23;
9906 value |= (uint32_t)(*data) << 16;
9909 ctl |= BWN_PIO8_TXCTL_8_15;
9910 value |= (uint32_t)(*data) << 8;
9913 value |= (uint32_t)(*data);
9915 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9916 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9923 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9924 uint16_t offset, uint32_t value)
9927 BWN_WRITE_4(mac, tq->tq_base + offset, value);
9931 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9932 uint16_t ctl, const void *_data, int len)
9934 struct bwn_softc *sc = mac->mac_sc;
9935 const uint8_t *data = _data;
9937 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9938 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9940 siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9941 tq->tq_base + BWN_PIO_TXDATA);
9943 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9944 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9945 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9952 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9953 uint16_t ctl, struct mbuf *m0)
9958 struct mbuf *m = m0;
9960 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9961 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9963 for (; m != NULL; m = m->m_next) {
9964 buf = mtod(m, const uint8_t *);
9965 for (i = 0; i < m->m_len; i++) {
9969 data |= (buf[i] << 8);
9970 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9975 if (m0->m_pkthdr.len % 2) {
9976 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9977 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9978 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9985 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9988 if (mac->mac_phy.type != BWN_PHYTYPE_G)
9990 BWN_WRITE_2(mac, 0x684, 510 + time);
9991 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9994 static struct bwn_dma_ring *
9995 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9998 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9999 return (mac->mac_method.dma.wme[WME_AC_BE]);
10003 return (mac->mac_method.dma.wme[WME_AC_VO]);
10005 return (mac->mac_method.dma.wme[WME_AC_VI]);
10007 return (mac->mac_method.dma.wme[WME_AC_BE]);
10009 return (mac->mac_method.dma.wme[WME_AC_BK]);
10011 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
10016 bwn_dma_getslot(struct bwn_dma_ring *dr)
10020 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
10022 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
10023 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
10024 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
10026 slot = bwn_dma_nextslot(dr, dr->dr_curslot);
10027 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
10028 dr->dr_curslot = slot;
10035 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
10037 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
10038 unsigned int a, b, c, d;
10042 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
10044 b = (tmp >> 8) & 0xff;
10045 c = (tmp >> 16) & 0xff;
10046 d = (tmp >> 24) & 0xff;
10047 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
10048 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
10050 bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
10051 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
10052 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
10055 a = (a + 32) & 0x3f;
10056 b = (b + 32) & 0x3f;
10057 c = (c + 32) & 0x3f;
10058 d = (d + 32) & 0x3f;
10061 avg = (a + b + c + d + 2) / 4;
10063 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
10064 & BWN_HF_4DB_CCK_POWERBOOST)
10065 avg = (avg >= 13) ? (avg - 13) : 0;
10071 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
10073 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
10074 int rfatt = *rfattp;
10075 int bbatt = *bbattp;
10078 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
10080 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
10082 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
10084 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
10086 if (bbatt > lo->bbatt.max) {
10091 if (bbatt < lo->bbatt.min) {
10096 if (rfatt > lo->rfatt.max) {
10101 if (rfatt < lo->rfatt.min) {
10109 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
10110 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
10114 bwn_phy_lock(struct bwn_mac *mac)
10116 struct bwn_softc *sc = mac->mac_sc;
10117 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10119 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10120 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10122 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10123 bwn_psctl(mac, BWN_PS_AWAKE);
10127 bwn_phy_unlock(struct bwn_mac *mac)
10129 struct bwn_softc *sc = mac->mac_sc;
10130 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
10132 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
10133 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
10135 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
10140 bwn_rf_lock(struct bwn_mac *mac)
10143 BWN_WRITE_4(mac, BWN_MACCTL,
10144 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
10145 BWN_READ_4(mac, BWN_MACCTL);
10150 bwn_rf_unlock(struct bwn_mac *mac)
10153 BWN_READ_2(mac, BWN_PHYVER);
10154 BWN_WRITE_4(mac, BWN_MACCTL,
10155 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10158 static struct bwn_pio_txqueue *
10159 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10160 struct bwn_pio_txpkt **pack)
10162 struct bwn_pio *pio = &mac->mac_method.pio;
10163 struct bwn_pio_txqueue *tq = NULL;
10164 unsigned int index;
10166 switch (cookie & 0xf000) {
10168 tq = &pio->wme[WME_AC_BK];
10171 tq = &pio->wme[WME_AC_BE];
10174 tq = &pio->wme[WME_AC_VI];
10177 tq = &pio->wme[WME_AC_VO];
10183 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10186 index = (cookie & 0x0fff);
10187 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10188 if (index >= N(tq->tq_pkts))
10190 *pack = &tq->tq_pkts[index];
10191 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10196 bwn_txpwr(void *arg, int npending)
10198 struct bwn_mac *mac = arg;
10199 struct bwn_softc *sc = mac->mac_sc;
10202 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10203 mac->mac_phy.set_txpwr != NULL)
10204 mac->mac_phy.set_txpwr(mac);
10209 bwn_task_15s(struct bwn_mac *mac)
10213 if (mac->mac_fw.opensource) {
10214 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10216 bwn_restart(mac, "fw watchdog");
10219 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10221 if (mac->mac_phy.task_15s)
10222 mac->mac_phy.task_15s(mac);
10224 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10228 bwn_task_30s(struct bwn_mac *mac)
10231 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10233 mac->mac_noise.noi_running = 1;
10234 mac->mac_noise.noi_nsamples = 0;
10236 bwn_noise_gensample(mac);
10240 bwn_task_60s(struct bwn_mac *mac)
10243 if (mac->mac_phy.task_60s)
10244 mac->mac_phy.task_60s(mac);
10245 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10249 bwn_tasks(void *arg)
10251 struct bwn_mac *mac = arg;
10252 struct bwn_softc *sc = mac->mac_sc;
10254 BWN_ASSERT_LOCKED(sc);
10255 if (mac->mac_status != BWN_MAC_STATUS_STARTED)
10258 if (mac->mac_task_state % 4 == 0)
10260 if (mac->mac_task_state % 2 == 0)
10264 mac->mac_task_state++;
10265 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10269 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10271 struct bwn_softc *sc = mac->mac_sc;
10273 KASSERT(a == 0, ("not support APHY\n"));
10275 switch (plcp->o.raw[0] & 0xf) {
10277 return (BWN_OFDM_RATE_6MB);
10279 return (BWN_OFDM_RATE_9MB);
10281 return (BWN_OFDM_RATE_12MB);
10283 return (BWN_OFDM_RATE_18MB);
10285 return (BWN_OFDM_RATE_24MB);
10287 return (BWN_OFDM_RATE_36MB);
10289 return (BWN_OFDM_RATE_48MB);
10291 return (BWN_OFDM_RATE_54MB);
10293 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10294 plcp->o.raw[0] & 0xf);
10299 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10301 struct bwn_softc *sc = mac->mac_sc;
10303 switch (plcp->o.raw[0]) {
10305 return (BWN_CCK_RATE_1MB);
10307 return (BWN_CCK_RATE_2MB);
10309 return (BWN_CCK_RATE_5MB);
10311 return (BWN_CCK_RATE_11MB);
10313 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10318 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10319 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10320 int rssi, int noise)
10322 struct bwn_softc *sc = mac->mac_sc;
10323 const struct ieee80211_frame_min *wh;
10325 uint16_t low_mactime_now;
10327 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10328 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10330 wh = mtod(m, const struct ieee80211_frame_min *);
10331 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
10332 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10334 bwn_tsf_read(mac, &tsf);
10335 low_mactime_now = tsf;
10336 tsf = tsf & ~0xffffULL;
10337 tsf += le16toh(rxhdr->mac_time);
10338 if (low_mactime_now < le16toh(rxhdr->mac_time))
10341 sc->sc_rx_th.wr_tsf = tsf;
10342 sc->sc_rx_th.wr_rate = rate;
10343 sc->sc_rx_th.wr_antsignal = rssi;
10344 sc->sc_rx_th.wr_antnoise = noise;
10348 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10350 uint32_t low, high;
10352 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10353 ("%s:%d: fail", __func__, __LINE__));
10355 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10356 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10363 bwn_dma_attach(struct bwn_mac *mac)
10365 struct bwn_dma *dma = &mac->mac_method.dma;
10366 struct bwn_softc *sc = mac->mac_sc;
10367 bus_addr_t lowaddr = 0;
10370 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10373 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10375 mac->mac_flags |= BWN_MAC_FLAG_DMA;
10377 dma->dmatype = bwn_dma_gettype(mac);
10378 if (dma->dmatype == BWN_DMA_30BIT)
10379 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10380 else if (dma->dmatype == BWN_DMA_32BIT)
10381 lowaddr = BUS_SPACE_MAXADDR_32BIT;
10383 lowaddr = BUS_SPACE_MAXADDR;
10386 * Create top level DMA tag
10388 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
10389 BWN_ALIGN, 0, /* alignment, bounds */
10390 lowaddr, /* lowaddr */
10391 BUS_SPACE_MAXADDR, /* highaddr */
10392 NULL, NULL, /* filter, filterarg */
10393 MAXBSIZE, /* maxsize */
10394 BUS_SPACE_UNRESTRICTED, /* nsegments */
10395 BUS_SPACE_MAXSIZE, /* maxsegsize */
10397 NULL, NULL, /* lockfunc, lockarg */
10398 &dma->parent_dtag);
10400 device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10405 * Create TX/RX mbuf DMA tag
10407 error = bus_dma_tag_create(dma->parent_dtag,
10415 BUS_SPACE_MAXSIZE_32BIT,
10420 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10423 error = bus_dma_tag_create(dma->parent_dtag,
10431 BUS_SPACE_MAXSIZE_32BIT,
10436 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10440 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10441 if (!dma->wme[WME_AC_BK])
10444 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10445 if (!dma->wme[WME_AC_BE])
10448 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10449 if (!dma->wme[WME_AC_VI])
10452 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10453 if (!dma->wme[WME_AC_VO])
10456 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10459 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10465 fail7: bwn_dma_ringfree(&dma->mcast);
10466 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10467 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10468 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10469 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10470 fail2: bus_dma_tag_destroy(dma->txbuf_dtag);
10471 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag);
10472 fail0: bus_dma_tag_destroy(dma->parent_dtag);
10476 static struct bwn_dma_ring *
10477 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10478 uint16_t cookie, int *slot)
10480 struct bwn_dma *dma = &mac->mac_method.dma;
10481 struct bwn_dma_ring *dr;
10482 struct bwn_softc *sc = mac->mac_sc;
10484 BWN_ASSERT_LOCKED(mac->mac_sc);
10486 switch (cookie & 0xf000) {
10488 dr = dma->wme[WME_AC_BK];
10491 dr = dma->wme[WME_AC_BE];
10494 dr = dma->wme[WME_AC_VI];
10497 dr = dma->wme[WME_AC_VO];
10505 ("invalid cookie value %d", cookie & 0xf000));
10507 *slot = (cookie & 0x0fff);
10508 if (*slot < 0 || *slot >= dr->dr_numslots) {
10510 * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10511 * that it occurs events which have same H/W sequence numbers.
10512 * When it's occurred just prints a WARNING msgs and ignores.
10514 KASSERT(status->seq == dma->lastseq,
10515 ("%s:%d: fail", __func__, __LINE__));
10516 device_printf(sc->sc_dev,
10517 "out of slot ranges (0 < %d < %d)\n", *slot,
10521 dma->lastseq = status->seq;
10526 bwn_dma_stop(struct bwn_mac *mac)
10528 struct bwn_dma *dma;
10530 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10532 dma = &mac->mac_method.dma;
10534 bwn_dma_ringstop(&dma->rx);
10535 bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10536 bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10537 bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10538 bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10539 bwn_dma_ringstop(&dma->mcast);
10543 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10549 bwn_dma_cleanup(*dr);
10553 bwn_pio_stop(struct bwn_mac *mac)
10555 struct bwn_pio *pio;
10557 if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10559 pio = &mac->mac_method.pio;
10561 bwn_destroy_queue_tx(&pio->mcast);
10562 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10563 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10564 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10565 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10569 bwn_led_attach(struct bwn_mac *mac)
10571 struct bwn_softc *sc = mac->mac_sc;
10572 const uint8_t *led_act = NULL;
10573 uint16_t val[BWN_LED_MAX];
10576 sc->sc_led_idle = (2350 * hz) / 1000;
10577 sc->sc_led_blink = 1;
10579 for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10580 if (siba_get_pci_subvendor(sc->sc_dev) ==
10581 bwn_vendor_led_act[i].vid) {
10582 led_act = bwn_vendor_led_act[i].led_act;
10586 if (led_act == NULL)
10587 led_act = bwn_default_led_act;
10589 val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10590 val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10591 val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10592 val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10594 for (i = 0; i < BWN_LED_MAX; ++i) {
10595 struct bwn_led *led = &sc->sc_leds[i];
10597 if (val[i] == 0xff) {
10598 led->led_act = led_act[i];
10600 if (val[i] & BWN_LED_ACT_LOW)
10601 led->led_flags |= BWN_LED_F_ACTLOW;
10602 led->led_act = val[i] & BWN_LED_ACT_MASK;
10604 led->led_mask = (1 << i);
10606 if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10607 led->led_act == BWN_LED_ACT_BLINK_POLL ||
10608 led->led_act == BWN_LED_ACT_BLINK) {
10609 led->led_flags |= BWN_LED_F_BLINK;
10610 if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10611 led->led_flags |= BWN_LED_F_POLLABLE;
10612 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10613 led->led_flags |= BWN_LED_F_SLOW;
10615 if (sc->sc_blink_led == NULL) {
10616 sc->sc_blink_led = led;
10617 if (led->led_flags & BWN_LED_F_SLOW)
10618 BWN_LED_SLOWDOWN(sc->sc_led_idle);
10622 DPRINTF(sc, BWN_DEBUG_LED,
10623 "%dth led, act %d, lowact %d\n", i,
10624 led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10626 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
10629 static __inline uint16_t
10630 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10633 if (led->led_flags & BWN_LED_F_ACTLOW)
10636 val |= led->led_mask;
10638 val &= ~led->led_mask;
10643 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10645 struct bwn_softc *sc = mac->mac_sc;
10646 struct ifnet *ifp = sc->sc_ifp;
10647 struct ieee80211com *ic = ifp->if_l2com;
10651 if (nstate == IEEE80211_S_INIT) {
10652 callout_stop(&sc->sc_led_blink_ch);
10653 sc->sc_led_blinking = 0;
10656 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
10659 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10660 for (i = 0; i < BWN_LED_MAX; ++i) {
10661 struct bwn_led *led = &sc->sc_leds[i];
10664 if (led->led_act == BWN_LED_ACT_UNKN ||
10665 led->led_act == BWN_LED_ACT_NULL)
10668 if ((led->led_flags & BWN_LED_F_BLINK) &&
10669 nstate != IEEE80211_S_INIT)
10672 switch (led->led_act) {
10673 case BWN_LED_ACT_ON: /* Always on */
10676 case BWN_LED_ACT_OFF: /* Always off */
10677 case BWN_LED_ACT_5GHZ: /* TODO: 11A */
10683 case IEEE80211_S_INIT:
10686 case IEEE80211_S_RUN:
10687 if (led->led_act == BWN_LED_ACT_11G &&
10688 ic->ic_curmode != IEEE80211_MODE_11G)
10692 if (led->led_act == BWN_LED_ACT_ASSOC)
10699 val = bwn_led_onoff(led, val, on);
10701 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10705 bwn_led_event(struct bwn_mac *mac, int event)
10707 struct bwn_softc *sc = mac->mac_sc;
10708 struct bwn_led *led = sc->sc_blink_led;
10711 if (event == BWN_LED_EVENT_POLL) {
10712 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10714 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10718 sc->sc_led_ticks = ticks;
10719 if (sc->sc_led_blinking)
10723 case BWN_LED_EVENT_RX:
10724 rate = sc->sc_rx_rate;
10726 case BWN_LED_EVENT_TX:
10727 rate = sc->sc_tx_rate;
10729 case BWN_LED_EVENT_POLL:
10733 panic("unknown LED event %d\n", event);
10736 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10737 bwn_led_duration[rate].off_dur);
10741 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10743 struct bwn_softc *sc = mac->mac_sc;
10744 struct bwn_led *led = sc->sc_blink_led;
10747 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10748 val = bwn_led_onoff(led, val, 1);
10749 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10751 if (led->led_flags & BWN_LED_F_SLOW) {
10752 BWN_LED_SLOWDOWN(on_dur);
10753 BWN_LED_SLOWDOWN(off_dur);
10756 sc->sc_led_blinking = 1;
10757 sc->sc_led_blink_offdur = off_dur;
10759 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10763 bwn_led_blink_next(void *arg)
10765 struct bwn_mac *mac = arg;
10766 struct bwn_softc *sc = mac->mac_sc;
10769 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10770 val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10771 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10773 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10774 bwn_led_blink_end, mac);
10778 bwn_led_blink_end(void *arg)
10780 struct bwn_mac *mac = arg;
10781 struct bwn_softc *sc = mac->mac_sc;
10783 sc->sc_led_blinking = 0;
10787 bwn_suspend(device_t dev)
10789 struct bwn_softc *sc = device_get_softc(dev);
10796 bwn_resume(device_t dev)
10798 struct bwn_softc *sc = device_get_softc(dev);
10799 struct ifnet *ifp = sc->sc_ifp;
10801 if (ifp->if_flags & IFF_UP)
10807 bwn_rfswitch(void *arg)
10809 struct bwn_softc *sc = arg;
10810 struct bwn_mac *mac = sc->sc_curmac;
10811 int cur = 0, prev = 0;
10813 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10814 ("%s: invalid MAC status %d", __func__, mac->mac_status));
10816 if (mac->mac_phy.rf_rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10817 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10818 & BWN_RF_HWENABLED_HI_MASK))
10821 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10822 & BWN_RF_HWENABLED_LO_MASK)
10826 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10831 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10833 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10835 device_printf(sc->sc_dev,
10836 "status of RF switch is changed to %s\n",
10837 cur ? "ON" : "OFF");
10838 if (cur != mac->mac_phy.rf_on) {
10840 bwn_rf_turnon(mac);
10842 bwn_rf_turnoff(mac);
10846 callout_schedule(&sc->sc_rfswitch_ch, hz);
10850 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10852 struct bwn_phy *phy = &mac->mac_phy;
10853 struct bwn_phy_lp *plp = &phy->phy_lp;
10855 plp->plp_antenna = BWN_ANT_DEFAULT;
10859 bwn_phy_lp_init(struct bwn_mac *mac)
10861 static const struct bwn_stxtable tables[] = {
10862 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10863 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff },
10864 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff },
10865 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10866 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f },
10867 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10868 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 },
10869 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f },
10870 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10871 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 },
10872 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10873 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 },
10874 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f },
10875 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f },
10876 { 2, 11, 0x40, 0, 0x0f }
10878 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10879 struct bwn_softc *sc = mac->mac_sc;
10880 const struct bwn_stxtable *st;
10881 struct ifnet *ifp = sc->sc_ifp;
10882 struct ieee80211com *ic = ifp->if_l2com;
10886 bwn_phy_lp_readsprom(mac); /* XXX bad place */
10887 bwn_phy_lp_bbinit(mac);
10889 /* initialize RF */
10890 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10892 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10895 if (mac->mac_phy.rf_ver == 0x2062)
10896 bwn_phy_lp_b2062_init(mac);
10898 bwn_phy_lp_b2063_init(mac);
10900 /* synchronize stx table. */
10901 for (i = 0; i < N(tables); i++) {
10903 tmp = BWN_RF_READ(mac, st->st_rfaddr);
10904 tmp >>= st->st_rfshift;
10905 tmp <<= st->st_physhift;
10906 BWN_PHY_SETMASK(mac,
10907 BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10908 ~(st->st_mask << st->st_physhift), tmp);
10911 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10912 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10916 if (mac->mac_phy.rev >= 2)
10917 bwn_phy_lp_rxcal_r2(mac);
10918 else if (!plp->plp_rccap) {
10919 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10920 bwn_phy_lp_rccal_r12(mac);
10922 bwn_phy_lp_set_rccap(mac);
10924 error = bwn_phy_lp_switch_channel(mac, 7);
10926 device_printf(sc->sc_dev,
10927 "failed to change channel 7 (%d)\n", error);
10928 bwn_phy_lp_txpctl_init(mac);
10929 bwn_phy_lp_calib(mac);
10934 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10937 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10938 return (BWN_READ_2(mac, BWN_PHYDATA));
10942 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10945 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10946 BWN_WRITE_2(mac, BWN_PHYDATA, value);
10950 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10954 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10955 BWN_WRITE_2(mac, BWN_PHYDATA,
10956 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10960 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10963 KASSERT(reg != 1, ("unaccessible register %d", reg));
10964 if (mac->mac_phy.rev < 2 && reg != 0x4001)
10966 if (mac->mac_phy.rev >= 2)
10968 BWN_WRITE_2(mac, BWN_RFCTL, reg);
10969 return BWN_READ_2(mac, BWN_RFDATALO);
10973 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10976 KASSERT(reg != 1, ("unaccessible register %d", reg));
10977 BWN_WRITE_2(mac, BWN_RFCTL, reg);
10978 BWN_WRITE_2(mac, BWN_RFDATALO, value);
10982 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10986 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10987 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10988 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10992 if (mac->mac_phy.rev >= 2) {
10993 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10994 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10995 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10996 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10997 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
11001 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
11002 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
11003 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
11004 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
11008 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
11010 struct bwn_phy *phy = &mac->mac_phy;
11011 struct bwn_phy_lp *plp = &phy->phy_lp;
11014 if (phy->rf_ver == 0x2063) {
11015 error = bwn_phy_lp_b2063_switch_channel(mac, chan);
11019 error = bwn_phy_lp_b2062_switch_channel(mac, chan);
11022 bwn_phy_lp_set_anafilter(mac, chan);
11023 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
11026 plp->plp_chan = chan;
11027 BWN_WRITE_2(mac, BWN_CHANNEL, chan);
11032 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
11034 struct bwn_softc *sc = mac->mac_sc;
11035 struct ifnet *ifp = sc->sc_ifp;
11036 struct ieee80211com *ic = ifp->if_l2com;
11038 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
11042 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
11044 struct bwn_phy *phy = &mac->mac_phy;
11045 struct bwn_phy_lp *plp = &phy->phy_lp;
11047 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
11050 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
11051 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
11052 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
11053 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
11054 plp->plp_antenna = antenna;
11058 bwn_phy_lp_task_60s(struct bwn_mac *mac)
11061 bwn_phy_lp_calib(mac);
11065 bwn_phy_lp_readsprom(struct bwn_mac *mac)
11067 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11068 struct bwn_softc *sc = mac->mac_sc;
11069 struct ifnet *ifp = sc->sc_ifp;
11070 struct ieee80211com *ic = ifp->if_l2com;
11072 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11073 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
11074 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
11075 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
11076 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
11077 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
11078 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
11082 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
11083 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
11084 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
11085 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
11086 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
11087 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
11088 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
11089 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
11093 bwn_phy_lp_bbinit(struct bwn_mac *mac)
11096 bwn_phy_lp_tblinit(mac);
11097 if (mac->mac_phy.rev >= 2)
11098 bwn_phy_lp_bbinit_r2(mac);
11100 bwn_phy_lp_bbinit_r01(mac);
11104 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
11106 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
11107 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
11108 struct bwn_softc *sc = mac->mac_sc;
11109 struct ifnet *ifp = sc->sc_ifp;
11110 struct ieee80211com *ic = ifp->if_l2com;
11112 bwn_phy_lp_set_txgain(mac,
11113 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
11114 bwn_phy_lp_set_bbmult(mac, 150);
11118 bwn_phy_lp_calib(struct bwn_mac *mac)
11120 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11121 struct bwn_softc *sc = mac->mac_sc;
11122 struct ifnet *ifp = sc->sc_ifp;
11123 struct ieee80211com *ic = ifp->if_l2com;
11124 const struct bwn_rxcompco *rc = NULL;
11125 struct bwn_txgain ogain;
11126 int i, omode, oafeovr, orf, obbmult;
11127 uint8_t mode, fc = 0;
11129 if (plp->plp_chanfullcal != plp->plp_chan) {
11130 plp->plp_chanfullcal = plp->plp_chan;
11134 bwn_mac_suspend(mac);
11136 /* BlueTooth Coexistance Override */
11137 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
11138 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
11140 if (mac->mac_phy.rev >= 2)
11141 bwn_phy_lp_digflt_save(mac);
11142 bwn_phy_lp_get_txpctlmode(mac);
11143 mode = plp->plp_txpctlmode;
11144 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11145 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
11146 bwn_phy_lp_bugfix(mac);
11147 if (mac->mac_phy.rev >= 2 && fc == 1) {
11148 bwn_phy_lp_get_txpctlmode(mac);
11149 omode = plp->plp_txpctlmode;
11150 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11152 ogain = bwn_phy_lp_get_txgain(mac);
11153 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11154 obbmult = bwn_phy_lp_get_bbmult(mac);
11155 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11157 bwn_phy_lp_set_txgain(mac, &ogain);
11158 bwn_phy_lp_set_bbmult(mac, obbmult);
11159 bwn_phy_lp_set_txpctlmode(mac, omode);
11160 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11162 bwn_phy_lp_set_txpctlmode(mac, mode);
11163 if (mac->mac_phy.rev >= 2)
11164 bwn_phy_lp_digflt_restore(mac);
11166 /* do RX IQ Calculation; assumes that noise is true. */
11167 if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11168 for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11169 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11170 rc = &bwn_rxcompco_5354[i];
11172 } else if (mac->mac_phy.rev >= 2)
11173 rc = &bwn_rxcompco_r2;
11175 for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11176 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11177 rc = &bwn_rxcompco_r12[i];
11183 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11184 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11186 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11188 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11189 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11190 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11192 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11193 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11196 bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11197 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11198 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11199 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11200 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11201 bwn_phy_lp_set_deaf(mac, 0);
11202 /* XXX no checking return value? */
11203 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11204 bwn_phy_lp_clear_deaf(mac, 0);
11205 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11206 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11207 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11209 /* disable RX GAIN override. */
11210 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11211 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11212 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11213 if (mac->mac_phy.rev >= 2) {
11214 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11215 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11216 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11217 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11220 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11223 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11224 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11226 bwn_mac_enable(mac);
11230 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11234 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11238 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11239 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11243 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11245 static const struct bwn_b206x_chan *bc = NULL;
11246 struct bwn_softc *sc = mac->mac_sc;
11247 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11249 uint16_t old, scale, tmp16;
11252 for (i = 0; i < N(bwn_b2063_chantable); i++) {
11253 if (bwn_b2063_chantable[i].bc_chan == chan) {
11254 bc = &bwn_b2063_chantable[i];
11261 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11262 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11263 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11264 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11265 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11266 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11267 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11268 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11269 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11270 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11271 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11272 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11274 old = BWN_RF_READ(mac, BWN_B2063_COM15);
11275 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11277 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11278 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11279 freqref = freqxtal * 3;
11280 div = (freqxtal <= 26000000 ? 1 : 2);
11281 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11282 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11283 999999) / 1000000) + 1;
11285 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11286 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11287 0xfff8, timeout >> 2);
11288 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11289 0xff9f,timeout << 5);
11290 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11292 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11293 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11294 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11296 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11297 (timeoutref + 1)) - 1;
11298 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11300 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11302 tmp[0] = ((val[2] * 62500) / freqref) << 4;
11303 tmp[1] = ((val[2] * 62500) % freqref) << 4;
11304 while (tmp[1] >= freqref) {
11308 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11309 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11310 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11311 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11312 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11314 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11315 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11316 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11317 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11319 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11320 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11322 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11324 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11327 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11329 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11330 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11332 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11337 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11338 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11340 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11341 if (freqxtal > 26000000)
11342 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11344 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11347 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11349 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11351 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11353 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11355 /* VCO Calibration */
11356 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11357 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11358 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11360 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11362 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11364 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11366 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11368 BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11373 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11375 struct bwn_softc *sc = mac->mac_sc;
11376 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11377 const struct bwn_b206x_chan *bc = NULL;
11378 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11382 for (i = 0; i < N(bwn_b2062_chantable); i++) {
11383 if (bwn_b2062_chantable[i].bc_chan == chan) {
11384 bc = &bwn_b2062_chantable[i];
11392 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11393 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11394 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11395 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11396 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11397 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11398 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11399 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11400 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11401 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11403 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11404 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11405 bwn_phy_lp_b2062_reset_pllbias(mac);
11406 tmp[0] = freqxtal / 1000;
11407 tmp[1] = plp->plp_div * 1000;
11408 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11409 if (ieee80211_ieee2mhz(chan, 0) < 4000)
11411 tmp[3] = 48 * tmp[0];
11412 tmp[5] = tmp[2] / tmp[3];
11413 tmp[6] = tmp[2] % tmp[3];
11414 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11415 tmp[4] = tmp[6] * 0x100;
11416 tmp[5] = tmp[4] / tmp[3];
11417 tmp[6] = tmp[4] % tmp[3];
11418 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11419 tmp[4] = tmp[6] * 0x100;
11420 tmp[5] = tmp[4] / tmp[3];
11421 tmp[6] = tmp[4] % tmp[3];
11422 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11423 tmp[4] = tmp[6] * 0x100;
11424 tmp[5] = tmp[4] / tmp[3];
11425 tmp[6] = tmp[4] % tmp[3];
11426 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11427 tmp[5] + ((2 * tmp[6]) / tmp[3]));
11428 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11429 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11430 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11431 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11433 bwn_phy_lp_b2062_vco_calib(mac);
11434 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11435 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11436 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11437 bwn_phy_lp_b2062_reset_pllbias(mac);
11438 bwn_phy_lp_b2062_vco_calib(mac);
11439 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11440 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11444 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11449 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11451 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11452 uint16_t tmp = (channel == 14);
11454 if (mac->mac_phy.rev < 2) {
11455 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11456 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11457 bwn_phy_lp_set_rccap(mac);
11461 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11465 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11467 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11468 struct bwn_softc *sc = mac->mac_sc;
11469 struct ifnet *ifp = sc->sc_ifp;
11470 struct ieee80211com *ic = ifp->if_l2com;
11471 uint16_t iso, tmp[3];
11473 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11475 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11476 iso = plp->plp_txisoband_m;
11477 else if (freq <= 5320)
11478 iso = plp->plp_txisoband_l;
11479 else if (freq <= 5700)
11480 iso = plp->plp_txisoband_m;
11482 iso = plp->plp_txisoband_h;
11484 tmp[0] = ((iso - 26) / 12) << 12;
11485 tmp[1] = tmp[0] + 0x1000;
11486 tmp[2] = tmp[0] + 0x2000;
11488 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11489 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11493 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11495 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11497 static const uint16_t addr[] = {
11498 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11499 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11500 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11501 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11502 BWN_PHY_OFDM(0xcf),
11504 static const uint16_t val[] = {
11505 0xde5e, 0xe832, 0xe331, 0x4d26,
11506 0x0026, 0x1420, 0x0020, 0xfe08,
11510 for (i = 0; i < N(addr); i++) {
11511 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11512 BWN_PHY_WRITE(mac, addr[i], val[i]);
11517 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11519 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11520 struct bwn_softc *sc = mac->mac_sc;
11523 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11524 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11525 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11526 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11528 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11529 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11531 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11532 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11535 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11536 device_printf(sc->sc_dev, "unknown command mode\n");
11542 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11544 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11548 bwn_phy_lp_get_txpctlmode(mac);
11549 old = plp->plp_txpctlmode;
11552 plp->plp_txpctlmode = mode;
11554 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11555 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11557 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11558 0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11560 /* disable TX GAIN override */
11561 if (mac->mac_phy.rev < 2)
11562 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11564 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11565 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11567 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11569 plp->plp_txpwridx = -1;
11571 if (mac->mac_phy.rev >= 2) {
11572 if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11573 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11575 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11578 /* writes TX Power Control mode */
11579 switch (plp->plp_txpctlmode) {
11580 case BWN_PHYLP_TXPCTL_OFF:
11581 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11583 case BWN_PHYLP_TXPCTL_ON_HW:
11584 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11586 case BWN_PHYLP_TXPCTL_ON_SW:
11587 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11591 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11593 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11594 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11598 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11600 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11601 struct bwn_softc *sc = mac->mac_sc;
11602 const unsigned int size = 256;
11603 struct bwn_txgain tg;
11604 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11605 uint16_t tssinpt, tssiidx, value[2];
11609 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
11610 M_NOWAIT | M_ZERO);
11611 if (tabs == NULL) {
11612 device_printf(sc->sc_dev, "failed to allocate buffer.\n");
11616 bwn_phy_lp_get_txpctlmode(mac);
11617 mode = plp->plp_txpctlmode;
11618 txpwridx = plp->plp_txpwridx;
11619 tssinpt = plp->plp_tssinpt;
11620 tssiidx = plp->plp_tssiidx;
11622 bwn_tab_read_multi(mac,
11623 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11624 BWN_TAB_4(7, 0x140), size, tabs);
11626 bwn_phy_lp_tblinit(mac);
11627 bwn_phy_lp_bbinit(mac);
11628 bwn_phy_lp_txpctl_init(mac);
11629 bwn_phy_lp_rf_onoff(mac, 1);
11630 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11632 bwn_tab_write_multi(mac,
11633 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11634 BWN_TAB_4(7, 0x140), size, tabs);
11636 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11637 plp->plp_tssinpt = tssinpt;
11638 plp->plp_tssiidx = tssiidx;
11639 bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11640 if (txpwridx != -1) {
11641 /* set TX power by index */
11642 plp->plp_txpwridx = txpwridx;
11643 bwn_phy_lp_get_txpctlmode(mac);
11644 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11645 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11646 if (mac->mac_phy.rev >= 2) {
11647 rxcomp = bwn_tab_read(mac,
11648 BWN_TAB_4(7, txpwridx + 320));
11649 txgain = bwn_tab_read(mac,
11650 BWN_TAB_4(7, txpwridx + 192));
11651 tg.tg_pad = (txgain >> 16) & 0xff;
11652 tg.tg_gm = txgain & 0xff;
11653 tg.tg_pga = (txgain >> 8) & 0xff;
11654 tg.tg_dac = (rxcomp >> 28) & 0xff;
11655 bwn_phy_lp_set_txgain(mac, &tg);
11657 rxcomp = bwn_tab_read(mac,
11658 BWN_TAB_4(10, txpwridx + 320));
11659 txgain = bwn_tab_read(mac,
11660 BWN_TAB_4(10, txpwridx + 192));
11661 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11662 0xf800, (txgain >> 4) & 0x7fff);
11663 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11664 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11666 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11669 value[0] = (rxcomp >> 10) & 0x3ff;
11670 value[1] = rxcomp & 0x3ff;
11671 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11673 coeff = bwn_tab_read(mac,
11674 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11675 BWN_TAB_4(10, txpwridx + 448));
11676 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11677 if (mac->mac_phy.rev >= 2) {
11678 rfpwr = bwn_tab_read(mac,
11679 BWN_TAB_4(7, txpwridx + 576));
11680 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11683 bwn_phy_lp_set_txgain_override(mac);
11685 if (plp->plp_rccap)
11686 bwn_phy_lp_set_rccap(mac);
11687 bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11688 bwn_phy_lp_set_txpctlmode(mac, mode);
11689 free(tabs, M_DEVBUF);
11693 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11695 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11697 static const uint16_t addr[] = {
11698 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11699 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11700 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11701 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11702 BWN_PHY_OFDM(0xcf),
11705 for (i = 0; i < N(addr); i++)
11706 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11710 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11712 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11714 if (mac->mac_phy.rev < 2) {
11715 bwn_phy_lp_tblinit_r01(mac);
11716 bwn_phy_lp_tblinit_txgain(mac);
11717 bwn_phy_lp_set_gaintbl(mac, freq);
11721 bwn_phy_lp_tblinit_r2(mac);
11722 bwn_phy_lp_tblinit_txgain(mac);
11730 struct bwn_smpair {
11737 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11739 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11740 struct bwn_softc *sc = mac->mac_sc;
11741 struct ifnet *ifp = sc->sc_ifp;
11742 struct ieee80211com *ic = ifp->if_l2com;
11743 static const struct bwn_wpair v1[] = {
11744 { BWN_PHY_AFE_DAC_CTL, 0x50 },
11745 { BWN_PHY_AFE_CTL, 0x8800 },
11746 { BWN_PHY_AFE_CTL_OVR, 0 },
11747 { BWN_PHY_AFE_CTL_OVRVAL, 0 },
11748 { BWN_PHY_RF_OVERRIDE_0, 0 },
11749 { BWN_PHY_RF_OVERRIDE_2, 0 },
11750 { BWN_PHY_OFDM(0xf9), 0 },
11751 { BWN_PHY_TR_LOOKUP_1, 0 }
11753 static const struct bwn_smpair v2[] = {
11754 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11755 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11756 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11757 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11758 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11760 static const struct bwn_smpair v3[] = {
11761 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11762 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11763 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11764 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11765 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11766 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11767 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11768 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11769 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11770 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11775 for (i = 0; i < N(v1); i++)
11776 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11777 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11778 for (i = 0; i < N(v2); i++)
11779 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11781 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11782 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11783 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11784 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11785 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11786 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11788 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11790 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11791 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11792 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11793 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11794 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11795 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11796 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11797 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11798 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11799 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11800 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11801 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11802 (siba_get_chiprev(sc->sc_dev) == 0)) {
11803 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11804 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11806 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11807 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11809 for (i = 0; i < N(v3); i++)
11810 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11811 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11812 (siba_get_chiprev(sc->sc_dev) == 0)) {
11813 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11814 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11817 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11818 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11819 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11820 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11821 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11822 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11823 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11825 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11827 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11828 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11829 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11830 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11831 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11832 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11833 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11834 0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11835 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11837 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11838 (siba_get_chiprev(sc->sc_dev) == 0)) {
11839 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11840 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11841 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11844 bwn_phy_lp_digflt_save(mac);
11848 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11850 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11851 struct bwn_softc *sc = mac->mac_sc;
11852 struct ifnet *ifp = sc->sc_ifp;
11853 struct ieee80211com *ic = ifp->if_l2com;
11854 static const struct bwn_smpair v1[] = {
11855 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11856 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11857 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11858 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11859 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11860 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11861 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11863 static const struct bwn_smpair v2[] = {
11864 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11865 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11866 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11867 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11868 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11869 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11870 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11871 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11872 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11873 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11874 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11875 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11876 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11877 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11878 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11879 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11881 static const struct bwn_smpair v3[] = {
11882 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11883 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11884 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11885 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11886 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11887 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11888 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11889 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11891 static const struct bwn_smpair v4[] = {
11892 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11893 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11894 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11895 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11896 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11897 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11898 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11899 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11901 static const struct bwn_smpair v5[] = {
11902 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11903 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11904 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11905 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11906 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11907 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11908 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11909 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11912 uint16_t tmp, tmp2;
11914 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11915 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11916 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11917 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11918 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11919 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11920 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11921 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11922 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11923 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11924 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11925 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11926 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11927 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11928 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11929 for (i = 0; i < N(v1); i++)
11930 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11931 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11932 0xff00, plp->plp_rxpwroffset);
11933 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11934 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11935 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11936 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11937 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11938 if (mac->mac_phy.rev == 0)
11939 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11941 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11943 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11944 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11945 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11947 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11948 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11949 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11950 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11952 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11953 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11954 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11955 0xfff9, (plp->plp_bxarch << 1));
11956 if (mac->mac_phy.rev == 1 &&
11957 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11958 for (i = 0; i < N(v2); i++)
11959 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11961 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11962 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11963 ((mac->mac_phy.rev == 0) &&
11964 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11965 for (i = 0; i < N(v3); i++)
11966 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11968 } else if (mac->mac_phy.rev == 1 ||
11969 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11970 for (i = 0; i < N(v4); i++)
11971 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11974 for (i = 0; i < N(v5); i++)
11975 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11978 if (mac->mac_phy.rev == 1 &&
11979 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11980 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11981 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11982 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11983 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11985 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11986 (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11987 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11988 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11989 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11990 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11991 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11993 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11994 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11995 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11996 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11997 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11998 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11999 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
12000 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
12001 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
12003 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
12004 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
12006 if (mac->mac_phy.rev == 1) {
12007 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
12008 tmp2 = (tmp & 0x03e0) >> 5;
12010 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
12011 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
12012 tmp2 = (tmp & 0x1f00) >> 8;
12014 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
12015 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
12016 tmp2 = tmp & 0x00ff;
12018 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
12022 struct bwn_b2062_freq {
12028 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
12030 #define CALC_CTL7(freq, div) \
12031 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
12032 #define CALC_CTL18(freq, div) \
12033 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
12034 #define CALC_CTL19(freq, div) \
12035 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
12036 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12037 struct bwn_softc *sc = mac->mac_sc;
12038 struct ifnet *ifp = sc->sc_ifp;
12039 struct ieee80211com *ic = ifp->if_l2com;
12040 static const struct bwn_b2062_freq freqdata_tab[] = {
12041 { 12000, { 6, 6, 6, 6, 10, 6 } },
12042 { 13000, { 4, 4, 4, 4, 11, 7 } },
12043 { 14400, { 3, 3, 3, 3, 12, 7 } },
12044 { 16200, { 3, 3, 3, 3, 13, 8 } },
12045 { 18000, { 2, 2, 2, 2, 14, 8 } },
12046 { 19200, { 1, 1, 1, 1, 14, 9 } }
12048 static const struct bwn_wpair v1[] = {
12049 { BWN_B2062_N_TXCTL3, 0 },
12050 { BWN_B2062_N_TXCTL4, 0 },
12051 { BWN_B2062_N_TXCTL5, 0 },
12052 { BWN_B2062_N_TXCTL6, 0 },
12053 { BWN_B2062_N_PDNCTL0, 0x40 },
12054 { BWN_B2062_N_PDNCTL0, 0 },
12055 { BWN_B2062_N_CALIB_TS, 0x10 },
12056 { BWN_B2062_N_CALIB_TS, 0 }
12058 const struct bwn_b2062_freq *f = NULL;
12059 uint32_t xtalfreq, ref;
12062 bwn_phy_lp_b2062_tblinit(mac);
12064 for (i = 0; i < N(v1); i++)
12065 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12066 if (mac->mac_phy.rev > 0)
12067 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
12068 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
12069 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12070 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
12072 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
12074 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
12075 ("%s:%d: fail", __func__, __LINE__));
12076 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12077 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
12079 if (xtalfreq <= 30000000) {
12081 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
12084 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
12087 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
12088 CALC_CTL7(xtalfreq, plp->plp_div));
12089 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
12090 CALC_CTL18(xtalfreq, plp->plp_div));
12091 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
12092 CALC_CTL19(xtalfreq, plp->plp_div));
12094 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
12096 for (i = 0; i < N(freqdata_tab); i++) {
12097 if (ref < freqdata_tab[i].freq) {
12098 f = &freqdata_tab[i];
12103 f = &freqdata_tab[N(freqdata_tab) - 1];
12104 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
12105 ((uint16_t)(f->value[1]) << 4) | f->value[0]);
12106 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
12107 ((uint16_t)(f->value[3]) << 4) | f->value[2]);
12108 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
12109 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
12116 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
12119 bwn_phy_lp_b2063_tblinit(mac);
12120 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
12121 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
12122 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
12123 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
12124 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
12125 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
12126 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
12127 if (mac->mac_phy.rev == 2) {
12128 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
12129 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
12130 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
12132 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
12133 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
12138 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
12140 struct bwn_softc *sc = mac->mac_sc;
12141 static const struct bwn_wpair v1[] = {
12142 { BWN_B2063_RX_BB_SP8, 0x0 },
12143 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12144 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12145 { BWN_B2063_RC_CALIB_CTL2, 0x15 },
12146 { BWN_B2063_RC_CALIB_CTL3, 0x70 },
12147 { BWN_B2063_RC_CALIB_CTL4, 0x52 },
12148 { BWN_B2063_RC_CALIB_CTL5, 0x1 },
12149 { BWN_B2063_RC_CALIB_CTL1, 0x7d }
12151 static const struct bwn_wpair v2[] = {
12152 { BWN_B2063_TX_BB_SP3, 0x0 },
12153 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12154 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12155 { BWN_B2063_RC_CALIB_CTL2, 0x55 },
12156 { BWN_B2063_RC_CALIB_CTL3, 0x76 }
12158 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12162 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12164 for (i = 0; i < 2; i++)
12165 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12166 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12167 for (i = 2; i < N(v1); i++)
12168 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12169 for (i = 0; i < 10000; i++) {
12170 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12175 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12176 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12178 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12180 for (i = 0; i < N(v2); i++)
12181 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12182 if (freqxtal == 24000000) {
12183 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12184 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12186 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12187 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12189 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12190 for (i = 0; i < 10000; i++) {
12191 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12195 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12196 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12197 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12201 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12203 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12204 struct bwn_softc *sc = mac->mac_sc;
12205 struct bwn_phy_lp_iq_est ie;
12206 struct bwn_txgain tx_gains;
12207 static const uint32_t pwrtbl[21] = {
12208 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12209 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12210 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12211 0x0004c, 0x0002c, 0x0001a,
12213 uint32_t npwr, ipwr, sqpwr, tmp;
12214 int loopback, i, j, sum, error;
12216 uint8_t txo, bbmult, txpctlmode;
12218 error = bwn_phy_lp_switch_channel(mac, 7);
12220 device_printf(sc->sc_dev,
12221 "failed to change channel to 7 (%d)\n", error);
12222 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12223 bbmult = bwn_phy_lp_get_bbmult(mac);
12225 tx_gains = bwn_phy_lp_get_txgain(mac);
12227 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12228 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12229 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12230 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12231 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12232 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12233 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12235 bwn_phy_lp_get_txpctlmode(mac);
12236 txpctlmode = plp->plp_txpctlmode;
12237 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12240 bwn_phy_lp_set_deaf(mac, 1);
12241 bwn_phy_lp_set_trsw_over(mac, 0, 1);
12242 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12243 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12244 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12245 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12246 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12247 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12248 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12249 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12250 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12251 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12252 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12253 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12254 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12255 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12256 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12257 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12258 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12259 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12260 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12261 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12262 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12263 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12264 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12266 loopback = bwn_phy_lp_loopback(mac);
12267 if (loopback == -1)
12269 bwn_phy_lp_set_rxgain_idx(mac, loopback);
12270 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12271 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12272 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12273 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12276 memset(&ie, 0, sizeof(ie));
12277 for (i = 128; i <= 159; i++) {
12278 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12280 for (j = 5; j <= 25; j++) {
12281 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12282 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12284 sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12285 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12286 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12288 sum += ((ipwr - npwr) * (ipwr - npwr));
12289 if ((i == 128) || (sum < tmp)) {
12290 plp->plp_rccap = i;
12295 bwn_phy_lp_ddfs_turnoff(mac);
12298 bwn_phy_lp_clear_deaf(mac, 1);
12299 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12300 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12302 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12303 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12304 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12305 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12306 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12307 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12308 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12310 bwn_phy_lp_set_bbmult(mac, bbmult);
12312 bwn_phy_lp_set_txgain(mac, &tx_gains);
12313 bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12314 if (plp->plp_rccap)
12315 bwn_phy_lp_set_rccap(mac);
12319 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12321 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12322 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12324 if (mac->mac_phy.rev == 1)
12325 rc_cap = MIN(rc_cap + 5, 15);
12327 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12328 MAX(plp->plp_rccap - 4, 0x80));
12329 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12330 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12331 ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12335 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12342 for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12344 if (r << 1 >= div) {
12346 r = (r << 1) - div;
12355 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12357 struct bwn_softc *sc = mac->mac_sc;
12359 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12361 if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12362 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12363 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12365 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12371 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12374 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12375 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12380 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12382 #define FLAG_A 0x01
12383 #define FLAG_G 0x02
12384 struct bwn_softc *sc = mac->mac_sc;
12385 struct ifnet *ifp = sc->sc_ifp;
12386 struct ieee80211com *ic = ifp->if_l2com;
12387 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12388 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12389 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12390 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12391 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12392 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12393 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12394 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12395 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12396 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12397 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12398 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12399 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12400 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12401 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12402 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12403 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12404 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12405 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12406 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12407 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12408 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12409 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12410 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12411 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12412 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12413 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12414 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12415 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12416 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12417 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12418 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12419 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12420 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12421 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12422 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12423 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12424 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12425 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12426 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12427 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12428 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12429 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12430 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12431 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12432 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12433 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12434 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12436 const struct bwn_b206x_rfinit_entry *br;
12439 for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12440 br = &bwn_b2062_init_tab[i];
12441 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12442 if (br->br_flags & FLAG_G)
12443 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12445 if (br->br_flags & FLAG_A)
12446 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12454 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12456 #define FLAG_A 0x01
12457 #define FLAG_G 0x02
12458 struct bwn_softc *sc = mac->mac_sc;
12459 struct ifnet *ifp = sc->sc_ifp;
12460 struct ieee80211com *ic = ifp->if_l2com;
12461 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12462 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12463 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12464 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12465 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12466 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12467 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12468 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12469 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12470 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12471 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12472 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12473 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12474 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12475 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12476 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12477 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12478 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12479 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12480 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12481 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12482 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12483 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12484 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12485 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12486 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12487 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12488 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12489 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12490 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12491 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12492 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12493 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12494 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12495 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12496 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12497 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12498 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12499 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12500 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12501 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12502 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12503 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12505 const struct bwn_b206x_rfinit_entry *br;
12508 for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12509 br = &bwn_b2063_init_tab[i];
12510 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12511 if (br->br_flags & FLAG_G)
12512 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12514 if (br->br_flags & FLAG_A)
12515 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12523 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12524 int count, void *_data)
12527 uint32_t offset, type;
12528 uint8_t *data = _data;
12530 type = BWN_TAB_GETTYPE(typenoffset);
12531 offset = BWN_TAB_GETOFFSET(typenoffset);
12532 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12534 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12536 for (i = 0; i < count; i++) {
12539 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12542 case BWN_TAB_16BIT:
12543 *((uint16_t *)data) = BWN_PHY_READ(mac,
12544 BWN_PHY_TABLEDATALO);
12547 case BWN_TAB_32BIT:
12548 *((uint32_t *)data) = BWN_PHY_READ(mac,
12549 BWN_PHY_TABLEDATAHI);
12550 *((uint32_t *)data) <<= 16;
12551 *((uint32_t *)data) |= BWN_PHY_READ(mac,
12552 BWN_PHY_TABLEDATALO);
12556 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12562 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12563 int count, const void *_data)
12565 uint32_t offset, type, value;
12566 const uint8_t *data = _data;
12569 type = BWN_TAB_GETTYPE(typenoffset);
12570 offset = BWN_TAB_GETOFFSET(typenoffset);
12571 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12573 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12575 for (i = 0; i < count; i++) {
12580 KASSERT(!(value & ~0xff),
12581 ("%s:%d: fail", __func__, __LINE__));
12582 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12584 case BWN_TAB_16BIT:
12585 value = *((const uint16_t *)data);
12587 KASSERT(!(value & ~0xffff),
12588 ("%s:%d: fail", __func__, __LINE__));
12589 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12591 case BWN_TAB_32BIT:
12592 value = *((const uint32_t *)data);
12594 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12595 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12598 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12603 static struct bwn_txgain
12604 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12606 struct bwn_txgain tg;
12609 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12610 if (mac->mac_phy.rev < 2) {
12611 tmp = BWN_PHY_READ(mac,
12612 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12613 tg.tg_gm = tmp & 0x0007;
12614 tg.tg_pga = (tmp & 0x0078) >> 3;
12615 tg.tg_pad = (tmp & 0x780) >> 7;
12619 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12620 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12621 tg.tg_gm = tmp & 0xff;
12622 tg.tg_pga = (tmp >> 8) & 0xff;
12627 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12630 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12634 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12638 if (mac->mac_phy.rev < 2) {
12639 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12640 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12641 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12642 bwn_phy_lp_set_txgain_override(mac);
12646 pa = bwn_phy_lp_get_pa_gain(mac);
12647 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12648 (tg->tg_pga << 8) | tg->tg_gm);
12649 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12650 tg->tg_pad | (pa << 6));
12651 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12652 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12653 tg->tg_pad | (pa << 8));
12654 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12655 bwn_phy_lp_set_txgain_override(mac);
12659 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12662 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12666 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12668 uint16_t trsw = (tx << 1) | rx;
12670 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12671 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12675 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12677 struct bwn_softc *sc = mac->mac_sc;
12678 struct ifnet *ifp = sc->sc_ifp;
12679 struct ieee80211com *ic = ifp->if_l2com;
12680 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12682 if (mac->mac_phy.rev < 2) {
12684 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12685 ext_lna = (gain & 2) >> 1;
12687 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12688 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12689 0xfbff, ext_lna << 10);
12690 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12691 0xf7ff, ext_lna << 11);
12692 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12694 low_gain = gain & 0xffff;
12695 high_gain = (gain >> 16) & 0xf;
12696 ext_lna = (gain >> 21) & 0x1;
12697 trsw = ~(gain >> 20) & 0x1;
12699 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12700 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12701 0xfdff, ext_lna << 9);
12702 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12703 0xfbff, ext_lna << 10);
12704 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12705 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12706 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12707 tmp = (gain >> 2) & 0x3;
12708 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12710 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12715 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12716 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12717 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12718 if (mac->mac_phy.rev >= 2) {
12719 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12720 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12721 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12722 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12726 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12730 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12732 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12735 plp->plp_crsusr_off = 1;
12737 plp->plp_crssys_off = 1;
12739 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12743 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12745 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12746 struct bwn_softc *sc = mac->mac_sc;
12747 struct ifnet *ifp = sc->sc_ifp;
12748 struct ieee80211com *ic = ifp->if_l2com;
12751 plp->plp_crsusr_off = 0;
12753 plp->plp_crssys_off = 0;
12755 if (plp->plp_crsusr_off || plp->plp_crssys_off)
12758 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12759 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12761 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12764 static unsigned int
12765 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12767 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12768 static uint8_t sqrt_table[256] = {
12769 10, 14, 17, 20, 22, 24, 26, 28,
12770 30, 31, 33, 34, 36, 37, 38, 40,
12771 41, 42, 43, 44, 45, 46, 47, 48,
12772 50, 50, 51, 52, 53, 54, 55, 56,
12773 57, 58, 59, 60, 60, 61, 62, 63,
12774 64, 64, 65, 66, 67, 67, 68, 69,
12775 70, 70, 71, 72, 72, 73, 74, 74,
12776 75, 76, 76, 77, 78, 78, 79, 80,
12777 80, 81, 81, 82, 83, 83, 84, 84,
12778 85, 86, 86, 87, 87, 88, 88, 89,
12779 90, 90, 91, 91, 92, 92, 93, 93,
12780 94, 94, 95, 95, 96, 96, 97, 97,
12781 98, 98, 99, 100, 100, 100, 101, 101,
12782 102, 102, 103, 103, 104, 104, 105, 105,
12783 106, 106, 107, 107, 108, 108, 109, 109,
12784 110, 110, 110, 111, 111, 112, 112, 113,
12785 113, 114, 114, 114, 115, 115, 116, 116,
12786 117, 117, 117, 118, 118, 119, 119, 120,
12787 120, 120, 121, 121, 122, 122, 122, 123,
12788 123, 124, 124, 124, 125, 125, 126, 126,
12789 126, 127, 127, 128, 128, 128, 129, 129,
12790 130, 130, 130, 131, 131, 131, 132, 132,
12791 133, 133, 133, 134, 134, 134, 135, 135,
12792 136, 136, 136, 137, 137, 137, 138, 138,
12793 138, 139, 139, 140, 140, 140, 141, 141,
12794 141, 142, 142, 142, 143, 143, 143, 144,
12795 144, 144, 145, 145, 145, 146, 146, 146,
12796 147, 147, 147, 148, 148, 148, 149, 149,
12797 150, 150, 150, 150, 151, 151, 151, 152,
12798 152, 152, 153, 153, 153, 154, 154, 154,
12799 155, 155, 155, 156, 156, 156, 157, 157,
12800 157, 158, 158, 158, 159, 159, 159, 160
12808 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12812 return (sqrt_table[x - 1] / 10);
12816 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12818 #define CALC_COEFF(_v, _x, _y, _z) do { \
12822 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12824 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12827 #define CALC_COEFF2(_v, _x, _y, _z) do { \
12831 _v = (_y << (31 - _x)) / (_z >> _t); \
12833 _v = (_y << (31 - _x)) / (_z << -_t); \
12835 struct bwn_phy_lp_iq_est ie;
12839 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12843 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12844 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12846 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12850 if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12855 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12856 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12858 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12862 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12863 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12870 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12872 static const uint16_t noisescale[] = {
12873 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12874 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12875 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12876 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12877 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12879 static const uint16_t crsgainnft[] = {
12880 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12881 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12882 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12883 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12886 static const uint16_t filterctl[] = {
12887 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12890 static const uint32_t psctl[] = {
12891 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12892 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12893 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12894 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12895 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12896 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12897 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12898 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12900 static const uint16_t ofdmcckgain_r0[] = {
12901 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12902 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12903 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12904 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12907 static const uint16_t ofdmcckgain_r1[] = {
12908 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12909 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12910 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12911 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12914 static const uint16_t gaindelta[] = {
12915 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12918 static const uint32_t txpwrctl[] = {
12919 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12920 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12921 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12922 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12923 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12924 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12925 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12926 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12927 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12928 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12929 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12930 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12931 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
12932 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12933 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12934 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12935 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12936 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12937 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12938 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12939 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12940 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12941 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12942 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12943 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12944 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12945 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12946 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12947 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12948 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12949 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12950 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12951 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12952 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12953 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12954 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12955 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12956 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12957 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12958 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12959 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12960 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12961 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12962 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12963 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12964 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12965 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12966 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12967 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12968 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12969 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12970 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12971 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12972 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12973 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12974 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12975 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12976 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12977 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12978 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12979 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12980 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12981 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12982 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12983 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12984 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12985 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12986 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12987 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12988 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12989 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12990 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12991 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12992 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12993 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12994 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12995 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12996 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12997 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12998 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12999 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13000 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13001 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13002 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13003 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13004 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13005 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13006 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
13007 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
13008 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
13009 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
13010 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
13011 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
13012 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
13013 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
13014 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
13015 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
13016 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
13017 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
13018 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
13019 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
13020 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
13021 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
13022 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
13023 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
13024 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
13025 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
13026 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
13027 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
13028 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
13029 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
13030 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
13031 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
13032 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
13033 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
13037 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13039 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13040 bwn_tab_sigsq_tbl);
13041 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13042 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
13043 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
13044 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
13045 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13046 bwn_tab_pllfrac_tbl);
13047 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13048 bwn_tabl_iqlocal_tbl);
13049 if (mac->mac_phy.rev == 0) {
13050 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
13052 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
13055 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
13057 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
13060 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
13061 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
13065 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
13067 struct bwn_softc *sc = mac->mac_sc;
13069 static const uint16_t noisescale[] = {
13070 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13071 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13072 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13073 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13074 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13075 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
13076 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
13078 static const uint32_t filterctl[] = {
13079 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
13080 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
13082 static const uint32_t psctl[] = {
13083 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
13084 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
13085 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
13086 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
13088 static const uint32_t gainidx[] = {
13089 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13090 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13091 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13092 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
13093 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
13094 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
13095 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
13096 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
13097 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
13098 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
13099 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
13100 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
13101 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
13102 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
13103 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
13104 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13105 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13106 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13107 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
13108 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
13109 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
13110 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
13111 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
13112 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
13113 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
13114 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
13115 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
13116 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
13117 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
13118 0x0000001a, 0x64ca55ad, 0x0000001a
13120 static const uint16_t auxgainidx[] = {
13121 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13122 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
13123 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
13126 static const uint16_t swctl[] = {
13127 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13128 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13129 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13130 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
13131 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13132 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
13133 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
13134 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
13136 static const uint8_t hf[] = {
13137 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
13138 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
13140 static const uint32_t gainval[] = {
13141 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13142 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13143 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13144 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13145 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13146 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13147 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13148 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13149 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13150 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13151 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13152 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13153 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
13154 0x000000f1, 0x00000000, 0x00000000
13156 static const uint16_t gain[] = {
13157 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13158 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13159 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13160 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13161 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13162 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
13163 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13164 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13165 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13166 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13167 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13168 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13170 static const uint32_t papdeps[] = {
13171 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13172 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13173 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13174 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13175 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13176 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13177 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13178 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13179 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13180 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13181 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13182 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13183 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13185 static const uint32_t papdmult[] = {
13186 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13187 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13188 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13189 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13190 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13191 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13192 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13193 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13194 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13195 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13196 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13197 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13198 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13200 static const uint32_t gainidx_a0[] = {
13201 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13202 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13203 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13204 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13205 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13206 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13207 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13208 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13209 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13210 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13211 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13212 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13213 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13215 static const uint16_t auxgainidx_a0[] = {
13216 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13217 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13218 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13221 static const uint32_t gainval_a0[] = {
13222 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13223 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13224 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13225 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13226 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13227 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13228 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13229 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13230 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13231 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13232 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13233 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13234 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13235 0x000000f7, 0x00000000, 0x00000000
13237 static const uint16_t gain_a0[] = {
13238 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13239 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13240 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13241 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13242 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13243 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
13244 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13245 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13246 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13247 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13248 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13249 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13252 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13254 for (i = 0; i < 704; i++)
13255 bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13257 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13258 bwn_tab_sigsq_tbl);
13259 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13260 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13261 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13262 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13263 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13264 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13265 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13266 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13267 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13268 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13269 bwn_tab_pllfrac_tbl);
13270 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13271 bwn_tabl_iqlocal_tbl);
13272 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13273 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13275 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13276 (siba_get_chiprev(sc->sc_dev) == 0)) {
13277 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13279 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13281 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13283 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13288 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13290 struct bwn_softc *sc = mac->mac_sc;
13291 struct ifnet *ifp = sc->sc_ifp;
13292 struct ieee80211com *ic = ifp->if_l2com;
13293 static struct bwn_txgain_entry txgain_r2[] = {
13294 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13295 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13296 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13297 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13298 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13299 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13300 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13301 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13302 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13303 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13304 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13305 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13306 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13307 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13308 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13309 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13310 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13311 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13312 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13313 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13314 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13315 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13316 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13317 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13318 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13319 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13320 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13321 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13322 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13323 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13324 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13325 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13326 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13327 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13328 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13329 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13330 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13331 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13332 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13333 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13334 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13335 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13336 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13337 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13338 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13339 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13340 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13341 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13342 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13343 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13344 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13345 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13346 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13347 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13348 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13349 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13350 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13351 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13352 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13353 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13354 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13355 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13356 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13357 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13359 static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13360 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13361 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13362 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13363 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13364 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13365 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13366 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13367 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13368 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13369 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13370 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13371 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13372 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13373 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13374 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13375 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13376 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13377 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13378 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13379 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13380 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13381 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13382 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13383 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13384 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13385 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13386 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13387 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13388 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13389 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13390 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13391 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13392 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13393 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13394 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13395 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13396 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13397 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13398 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13399 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13400 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13401 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13402 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13403 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13404 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13405 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13406 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13407 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13408 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13409 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13410 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13411 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13412 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13413 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13414 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13415 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13416 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13417 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13418 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13419 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13420 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13421 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13422 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13423 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13425 static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13426 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13427 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13428 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13429 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13430 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13431 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13432 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13433 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13434 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13435 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13436 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13437 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13438 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13439 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13440 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13441 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13442 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13443 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13444 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13445 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13446 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13447 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13448 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13449 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13450 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13451 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13452 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13453 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13454 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13455 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13456 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13457 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13458 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13459 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13460 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13461 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13462 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13463 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13464 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13465 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13466 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13467 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13468 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13469 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13470 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13471 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13472 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13473 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13474 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13475 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13476 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13477 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13478 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13479 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13480 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13481 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13482 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13483 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13484 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13485 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13486 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13487 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13488 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13489 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13491 static struct bwn_txgain_entry txgain_r0[] = {
13492 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13493 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13494 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13495 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13496 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13497 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13498 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13499 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13500 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13501 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13502 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13503 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13504 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13505 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13506 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13507 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13508 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13509 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13510 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13511 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13512 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13513 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13514 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13515 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13516 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13517 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13518 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13519 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13520 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13521 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13522 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13523 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13524 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13525 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13526 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13527 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13528 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13529 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13530 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13531 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13532 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13533 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13534 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13535 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13536 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13537 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13538 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13539 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13540 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13541 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13542 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13543 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13544 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13545 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13546 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13547 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13548 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13549 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13550 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13551 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13552 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13553 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13554 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13555 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13557 static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13558 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13559 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13560 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13561 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13562 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13563 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13564 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13565 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13566 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13567 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13568 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13569 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13570 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13571 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13572 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13573 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13574 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13575 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13576 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13577 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13578 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13579 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13580 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13581 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13582 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13583 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13584 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13585 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13586 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13587 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13588 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13589 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13590 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13591 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13592 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13593 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13594 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13595 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13596 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13597 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13598 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13599 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13600 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13601 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13602 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13603 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13604 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13605 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13606 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13607 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13608 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13609 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13610 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13611 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13612 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13613 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13614 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13615 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13616 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13617 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13618 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13619 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13620 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13621 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13623 static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13624 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13625 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13626 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13627 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13628 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13629 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13630 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13631 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13632 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13633 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13634 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13635 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13636 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13637 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13638 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13639 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13640 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13641 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13642 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13643 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13644 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13645 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13646 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13647 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13648 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13649 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13650 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13651 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13652 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13653 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13654 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13655 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13656 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13657 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13658 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13659 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13660 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13661 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13662 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13663 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13664 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13665 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13666 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13667 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13668 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13669 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13670 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13671 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13672 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13673 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13674 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13675 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13676 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13677 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13678 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13679 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13680 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13681 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13682 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13683 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13684 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13685 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13686 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13687 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13689 static struct bwn_txgain_entry txgain_r1[] = {
13690 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13691 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13692 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13693 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13694 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13695 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13696 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13697 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13698 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13699 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13700 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13701 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13702 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13703 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13704 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13705 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13706 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13707 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13708 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13709 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13710 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13711 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13712 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13713 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13714 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13715 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13716 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13717 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13718 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13719 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13720 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13721 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13722 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13723 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13724 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13725 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13726 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13727 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13728 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13729 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13730 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13731 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13732 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13733 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13734 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13735 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13736 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13737 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13738 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13739 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13740 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13741 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13742 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13743 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13744 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13745 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13746 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13747 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13748 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13749 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13750 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13751 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13752 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13753 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13754 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13755 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13756 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13757 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13758 { 7, 11, 6, 0, 71 }
13760 static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13761 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13762 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13763 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13764 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13765 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13766 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13767 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13768 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13769 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13770 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13771 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13772 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13773 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13774 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13775 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13776 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13777 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13778 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13779 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13780 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13781 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13782 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13783 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13784 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13785 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13786 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13787 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13788 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13789 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13790 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13791 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13792 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13793 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13794 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13795 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13796 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13797 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13798 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13799 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13800 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13801 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13802 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13803 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13804 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13805 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13806 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13807 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13808 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13809 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13810 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13811 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13812 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13813 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13814 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13815 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13816 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13817 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13818 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13819 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13820 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13821 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13822 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13823 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13824 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13826 static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13827 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13828 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13829 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13830 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13831 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13832 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13833 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13834 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13835 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13836 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13837 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13838 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13839 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13840 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13841 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13842 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13843 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13844 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13845 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13846 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13847 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13848 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13849 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13850 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13851 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13852 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13853 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13854 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13855 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13856 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13857 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13858 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13859 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13860 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13861 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13862 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13863 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13864 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13865 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13866 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13867 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13868 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13869 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13870 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13871 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13872 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13873 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13874 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13875 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13876 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13877 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13878 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13879 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13880 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13881 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13882 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13883 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13884 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13885 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13886 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13887 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13888 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13889 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13890 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13893 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13894 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13895 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13896 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13897 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13900 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13905 if (mac->mac_phy.rev == 0) {
13906 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13907 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13908 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13909 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13910 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13913 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13918 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13919 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13920 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13921 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13922 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13924 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13928 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13930 uint32_t offset, type;
13932 type = BWN_TAB_GETTYPE(typeoffset);
13933 offset = BWN_TAB_GETOFFSET(typeoffset);
13934 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13938 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13939 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13940 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13942 case BWN_TAB_16BIT:
13943 KASSERT(!(value & ~0xffff),
13944 ("%s:%d: fail", __func__, __LINE__));
13945 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13946 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13948 case BWN_TAB_32BIT:
13949 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13950 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13951 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13954 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13959 bwn_phy_lp_loopback(struct bwn_mac *mac)
13961 struct bwn_phy_lp_iq_est ie;
13965 memset(&ie, 0, sizeof(ie));
13967 bwn_phy_lp_set_trsw_over(mac, 1, 1);
13968 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13969 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13970 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13971 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13972 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13973 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13974 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13975 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13976 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13977 for (i = 0; i < 32; i++) {
13978 bwn_phy_lp_set_rxgain_idx(mac, i);
13979 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13980 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13982 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13983 if ((tmp > 4000) && (tmp < 10000)) {
13988 bwn_phy_lp_ddfs_turnoff(mac);
13993 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13996 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
14000 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
14001 int incr1, int incr2, int scale_idx)
14004 bwn_phy_lp_ddfs_turnoff(mac);
14005 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
14006 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
14007 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
14008 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
14009 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
14010 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
14011 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
14012 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
14013 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
14014 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
14018 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
14019 struct bwn_phy_lp_iq_est *ie)
14023 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
14024 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
14025 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
14026 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
14027 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
14029 for (i = 0; i < 500; i++) {
14030 if (!(BWN_PHY_READ(mac,
14031 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
14035 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
14036 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14040 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
14041 ie->ie_iqprod <<= 16;
14042 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
14043 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
14044 ie->ie_ipwr <<= 16;
14045 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
14046 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
14047 ie->ie_qpwr <<= 16;
14048 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
14050 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
14055 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
14057 uint32_t offset, type, value;
14059 type = BWN_TAB_GETTYPE(typeoffset);
14060 offset = BWN_TAB_GETOFFSET(typeoffset);
14061 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
14065 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14066 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
14068 case BWN_TAB_16BIT:
14069 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14070 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14072 case BWN_TAB_32BIT:
14073 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
14074 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
14076 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
14079 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
14087 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
14090 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
14091 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
14095 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
14099 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
14101 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
14105 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
14108 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
14109 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
14113 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
14116 if (mac->mac_phy.rev < 2)
14117 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
14119 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
14120 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
14122 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
14126 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
14129 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
14133 bwn_nbits(int32_t val)
14138 for (tmp = abs(val); tmp != 0; tmp >>= 1)
14144 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
14145 struct bwn_txgain_entry *table)
14149 for (i = offset; i < count; i++)
14150 bwn_phy_lp_gaintbl_write(mac, i, table[i]);
14154 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
14155 struct bwn_txgain_entry data)
14158 if (mac->mac_phy.rev >= 2)
14159 bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14161 bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14165 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14166 struct bwn_txgain_entry te)
14168 struct bwn_softc *sc = mac->mac_sc;
14169 struct ifnet *ifp = sc->sc_ifp;
14170 struct ieee80211com *ic = ifp->if_l2com;
14173 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14175 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14176 if (mac->mac_phy.rev >= 3) {
14177 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14178 (0x10 << 24) : (0x70 << 24));
14180 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14181 (0x14 << 24) : (0x7f << 24));
14183 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14184 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14185 te.te_bbmult << 20 | te.te_dac << 28);
14189 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14190 struct bwn_txgain_entry te)
14193 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14195 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14196 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) |
14198 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14202 bwn_sysctl_node(struct bwn_softc *sc)
14204 device_t dev = sc->sc_dev;
14205 struct bwn_mac *mac;
14206 struct bwn_stats *stats;
14208 /* XXX assume that count of MAC is only 1. */
14210 if ((mac = sc->sc_curmac) == NULL)
14212 stats = &mac->mac_stats;
14214 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14215 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14216 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14217 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14218 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14219 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14220 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14221 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14222 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14225 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14226 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14227 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14231 static device_method_t bwn_methods[] = {
14232 /* Device interface */
14233 DEVMETHOD(device_probe, bwn_probe),
14234 DEVMETHOD(device_attach, bwn_attach),
14235 DEVMETHOD(device_detach, bwn_detach),
14236 DEVMETHOD(device_suspend, bwn_suspend),
14237 DEVMETHOD(device_resume, bwn_resume),
14240 static driver_t bwn_driver = {
14243 sizeof(struct bwn_softc)
14245 static devclass_t bwn_devclass;
14246 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
14247 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14248 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */
14249 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */
14250 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);