2 * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13 * redistribution must be conditioned upon including a substantially
14 * similar Disclaimer requirement for further binary redistribution.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
34 * The Broadcom Wireless LAN controller driver.
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/module.h>
40 #include <sys/kernel.h>
41 #include <sys/endian.h>
42 #include <sys/errno.h>
43 #include <sys/firmware.h>
45 #include <sys/mutex.h>
46 #include <machine/bus.h>
47 #include <machine/resource.h>
50 #include <sys/socket.h>
51 #include <sys/sockio.h>
53 #include <net/ethernet.h>
55 #include <net/if_var.h>
56 #include <net/if_arp.h>
57 #include <net/if_dl.h>
58 #include <net/if_llc.h>
59 #include <net/if_media.h>
60 #include <net/if_types.h>
62 #include <dev/pci/pcivar.h>
63 #include <dev/pci/pcireg.h>
64 #include <dev/siba/siba_ids.h>
65 #include <dev/siba/sibareg.h>
66 #include <dev/siba/sibavar.h>
68 #include <net80211/ieee80211_var.h>
69 #include <net80211/ieee80211_radiotap.h>
70 #include <net80211/ieee80211_regdomain.h>
71 #include <net80211/ieee80211_phy.h>
72 #include <net80211/ieee80211_ratectl.h>
74 #include <dev/bwn/if_bwnreg.h>
75 #include <dev/bwn/if_bwnvar.h>
77 static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0,
78 "Broadcom driver parameters");
81 * Tunable & sysctl variables.
85 static int bwn_debug = 0;
86 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RWTUN, &bwn_debug, 0,
87 "Broadcom debugging printfs");
89 BWN_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
90 BWN_DEBUG_RECV = 0x00000002, /* basic recv operation */
91 BWN_DEBUG_STATE = 0x00000004, /* 802.11 state transitions */
92 BWN_DEBUG_TXPOW = 0x00000008, /* tx power processing */
93 BWN_DEBUG_RESET = 0x00000010, /* reset processing */
94 BWN_DEBUG_OPS = 0x00000020, /* bwn_ops processing */
95 BWN_DEBUG_BEACON = 0x00000040, /* beacon handling */
96 BWN_DEBUG_WATCHDOG = 0x00000080, /* watchdog timeout */
97 BWN_DEBUG_INTR = 0x00000100, /* ISR */
98 BWN_DEBUG_CALIBRATE = 0x00000200, /* periodic calibration */
99 BWN_DEBUG_NODE = 0x00000400, /* node management */
100 BWN_DEBUG_LED = 0x00000800, /* led management */
101 BWN_DEBUG_CMD = 0x00001000, /* cmd submission */
102 BWN_DEBUG_LO = 0x00002000, /* LO */
103 BWN_DEBUG_FW = 0x00004000, /* firmware */
104 BWN_DEBUG_WME = 0x00008000, /* WME */
105 BWN_DEBUG_RF = 0x00010000, /* RF */
106 BWN_DEBUG_FATAL = 0x80000000, /* fatal errors */
107 BWN_DEBUG_ANY = 0xffffffff
109 #define DPRINTF(sc, m, fmt, ...) do { \
110 if (sc->sc_debug & (m)) \
111 printf(fmt, __VA_ARGS__); \
114 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
117 static int bwn_bfp = 0; /* use "Bad Frames Preemption" */
118 SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0,
119 "uses Bad Frames Preemption");
120 static int bwn_bluetooth = 1;
121 SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0,
122 "turns on Bluetooth Coexistence");
123 static int bwn_hwpctl = 0;
124 SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0,
125 "uses H/W power control");
126 static int bwn_msi_disable = 0; /* MSI disabled */
127 TUNABLE_INT("hw.bwn.msi_disable", &bwn_msi_disable);
128 static int bwn_usedma = 1;
129 SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0,
131 TUNABLE_INT("hw.bwn.usedma", &bwn_usedma);
132 static int bwn_wme = 1;
133 SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0,
136 static void bwn_attach_pre(struct bwn_softc *);
137 static int bwn_attach_post(struct bwn_softc *);
138 static void bwn_sprom_bugfixes(device_t);
139 static int bwn_init(struct bwn_softc *);
140 static void bwn_parent(struct ieee80211com *);
141 static void bwn_start(struct bwn_softc *);
142 static int bwn_transmit(struct ieee80211com *, struct mbuf *);
143 static int bwn_attach_core(struct bwn_mac *);
144 static void bwn_reset_core(struct bwn_mac *, uint32_t);
145 static int bwn_phy_getinfo(struct bwn_mac *, int);
146 static int bwn_chiptest(struct bwn_mac *);
147 static int bwn_setup_channels(struct bwn_mac *, int, int);
148 static int bwn_phy_g_attach(struct bwn_mac *);
149 static void bwn_phy_g_detach(struct bwn_mac *);
150 static void bwn_phy_g_init_pre(struct bwn_mac *);
151 static int bwn_phy_g_prepare_hw(struct bwn_mac *);
152 static int bwn_phy_g_init(struct bwn_mac *);
153 static void bwn_phy_g_exit(struct bwn_mac *);
154 static uint16_t bwn_phy_g_read(struct bwn_mac *, uint16_t);
155 static void bwn_phy_g_write(struct bwn_mac *, uint16_t,
157 static uint16_t bwn_phy_g_rf_read(struct bwn_mac *, uint16_t);
158 static void bwn_phy_g_rf_write(struct bwn_mac *, uint16_t,
160 static int bwn_phy_g_hwpctl(struct bwn_mac *);
161 static void bwn_phy_g_rf_onoff(struct bwn_mac *, int);
162 static int bwn_phy_g_switch_channel(struct bwn_mac *, uint32_t);
163 static uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *);
164 static void bwn_phy_g_set_antenna(struct bwn_mac *, int);
165 static int bwn_phy_g_im(struct bwn_mac *, int);
166 static int bwn_phy_g_recalc_txpwr(struct bwn_mac *, int);
167 static void bwn_phy_g_set_txpwr(struct bwn_mac *);
168 static void bwn_phy_g_task_15s(struct bwn_mac *);
169 static void bwn_phy_g_task_60s(struct bwn_mac *);
170 static uint16_t bwn_phy_g_txctl(struct bwn_mac *);
171 static void bwn_phy_switch_analog(struct bwn_mac *, int);
172 static uint16_t bwn_shm_read_2(struct bwn_mac *, uint16_t, uint16_t);
173 static void bwn_shm_write_2(struct bwn_mac *, uint16_t, uint16_t,
175 static uint32_t bwn_shm_read_4(struct bwn_mac *, uint16_t, uint16_t);
176 static void bwn_shm_write_4(struct bwn_mac *, uint16_t, uint16_t,
178 static void bwn_shm_ctlword(struct bwn_mac *, uint16_t,
180 static void bwn_addchannels(struct ieee80211_channel [], int, int *,
181 const struct bwn_channelinfo *, int);
182 static int bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
183 const struct ieee80211_bpf_params *);
184 static void bwn_updateslot(struct ieee80211com *);
185 static void bwn_update_promisc(struct ieee80211com *);
186 static void bwn_wme_init(struct bwn_mac *);
187 static int bwn_wme_update(struct ieee80211com *);
188 static void bwn_wme_clear(struct bwn_softc *);
189 static void bwn_wme_load(struct bwn_mac *);
190 static void bwn_wme_loadparams(struct bwn_mac *,
191 const struct wmeParams *, uint16_t);
192 static void bwn_scan_start(struct ieee80211com *);
193 static void bwn_scan_end(struct ieee80211com *);
194 static void bwn_set_channel(struct ieee80211com *);
195 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *,
196 const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
197 const uint8_t [IEEE80211_ADDR_LEN],
198 const uint8_t [IEEE80211_ADDR_LEN]);
199 static void bwn_vap_delete(struct ieee80211vap *);
200 static void bwn_stop(struct bwn_softc *);
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 int bwn_tx_start(struct bwn_softc *, struct ieee80211_node *,
413 static int bwn_tx_isfull(struct bwn_softc *, struct mbuf *);
414 static int bwn_set_txhdr(struct bwn_mac *,
415 struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *,
417 static void bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t,
419 static uint8_t bwn_antenna_sanitize(struct bwn_mac *, uint8_t);
420 static uint8_t bwn_get_fbrate(uint8_t);
421 static int bwn_phy_shm_tssi_read(struct bwn_mac *, uint16_t);
422 static void bwn_phy_g_setatt(struct bwn_mac *, int *, int *);
423 static void bwn_phy_lock(struct bwn_mac *);
424 static void bwn_phy_unlock(struct bwn_mac *);
425 static void bwn_rf_lock(struct bwn_mac *);
426 static void bwn_rf_unlock(struct bwn_mac *);
427 static void bwn_txpwr(void *, int);
428 static void bwn_tasks(void *);
429 static void bwn_task_15s(struct bwn_mac *);
430 static void bwn_task_30s(struct bwn_mac *);
431 static void bwn_task_60s(struct bwn_mac *);
432 static int bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *,
434 static int bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *);
435 static void bwn_rx_radiotap(struct bwn_mac *, struct mbuf *,
436 const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int,
438 static void bwn_tsf_read(struct bwn_mac *, uint64_t *);
439 static void bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t);
440 static void bwn_set_slot_time(struct bwn_mac *, uint16_t);
441 static void bwn_watchdog(void *);
442 static void bwn_dma_stop(struct bwn_mac *);
443 static void bwn_pio_stop(struct bwn_mac *);
444 static void bwn_dma_ringstop(struct bwn_dma_ring **);
445 static void bwn_led_attach(struct bwn_mac *);
446 static void bwn_led_newstate(struct bwn_mac *, enum ieee80211_state);
447 static void bwn_led_event(struct bwn_mac *, int);
448 static void bwn_led_blink_start(struct bwn_mac *, int, int);
449 static void bwn_led_blink_next(void *);
450 static void bwn_led_blink_end(void *);
451 static void bwn_rfswitch(void *);
452 static void bwn_rf_turnon(struct bwn_mac *);
453 static void bwn_rf_turnoff(struct bwn_mac *);
454 static void bwn_phy_lp_init_pre(struct bwn_mac *);
455 static int bwn_phy_lp_init(struct bwn_mac *);
456 static uint16_t bwn_phy_lp_read(struct bwn_mac *, uint16_t);
457 static void bwn_phy_lp_write(struct bwn_mac *, uint16_t, uint16_t);
458 static void bwn_phy_lp_maskset(struct bwn_mac *, uint16_t, uint16_t,
460 static uint16_t bwn_phy_lp_rf_read(struct bwn_mac *, uint16_t);
461 static void bwn_phy_lp_rf_write(struct bwn_mac *, uint16_t, uint16_t);
462 static void bwn_phy_lp_rf_onoff(struct bwn_mac *, int);
463 static int bwn_phy_lp_switch_channel(struct bwn_mac *, uint32_t);
464 static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *);
465 static void bwn_phy_lp_set_antenna(struct bwn_mac *, int);
466 static void bwn_phy_lp_task_60s(struct bwn_mac *);
467 static void bwn_phy_lp_readsprom(struct bwn_mac *);
468 static void bwn_phy_lp_bbinit(struct bwn_mac *);
469 static void bwn_phy_lp_txpctl_init(struct bwn_mac *);
470 static void bwn_phy_lp_calib(struct bwn_mac *);
471 static void bwn_phy_lp_switch_analog(struct bwn_mac *, int);
472 static int bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t);
473 static int bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t);
474 static void bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t);
475 static void bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t);
476 static void bwn_phy_lp_digflt_save(struct bwn_mac *);
477 static void bwn_phy_lp_get_txpctlmode(struct bwn_mac *);
478 static void bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t);
479 static void bwn_phy_lp_bugfix(struct bwn_mac *);
480 static void bwn_phy_lp_digflt_restore(struct bwn_mac *);
481 static void bwn_phy_lp_tblinit(struct bwn_mac *);
482 static void bwn_phy_lp_bbinit_r2(struct bwn_mac *);
483 static void bwn_phy_lp_bbinit_r01(struct bwn_mac *);
484 static void bwn_phy_lp_b2062_init(struct bwn_mac *);
485 static void bwn_phy_lp_b2063_init(struct bwn_mac *);
486 static void bwn_phy_lp_rxcal_r2(struct bwn_mac *);
487 static void bwn_phy_lp_rccal_r12(struct bwn_mac *);
488 static void bwn_phy_lp_set_rccap(struct bwn_mac *);
489 static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t);
490 static void bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *);
491 static void bwn_phy_lp_b2062_vco_calib(struct bwn_mac *);
492 static void bwn_tab_write_multi(struct bwn_mac *, uint32_t, int,
494 static void bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *);
495 static struct bwn_txgain
496 bwn_phy_lp_get_txgain(struct bwn_mac *);
497 static uint8_t bwn_phy_lp_get_bbmult(struct bwn_mac *);
498 static void bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *);
499 static void bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t);
500 static void bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t);
501 static void bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t);
502 static void bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t);
503 static int bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t);
504 static void bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t);
505 static void bwn_phy_lp_tblinit_r01(struct bwn_mac *);
506 static void bwn_phy_lp_tblinit_r2(struct bwn_mac *);
507 static void bwn_phy_lp_tblinit_txgain(struct bwn_mac *);
508 static void bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t);
509 static void bwn_phy_lp_b2062_tblinit(struct bwn_mac *);
510 static void bwn_phy_lp_b2063_tblinit(struct bwn_mac *);
511 static int bwn_phy_lp_loopback(struct bwn_mac *);
512 static void bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t);
513 static void bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int,
515 static uint8_t bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t,
516 struct bwn_phy_lp_iq_est *);
517 static void bwn_phy_lp_ddfs_turnoff(struct bwn_mac *);
518 static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t);
519 static void bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t);
520 static void bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t);
521 static void bwn_phy_lp_set_txgain_override(struct bwn_mac *);
522 static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *);
523 static uint8_t bwn_nbits(int32_t);
524 static void bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int,
525 struct bwn_txgain_entry *);
526 static void bwn_phy_lp_gaintbl_write(struct bwn_mac *, int,
527 struct bwn_txgain_entry);
528 static void bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int,
529 struct bwn_txgain_entry);
530 static void bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int,
531 struct bwn_txgain_entry);
532 static void bwn_sysctl_node(struct bwn_softc *);
534 static struct resource_spec bwn_res_spec_legacy[] = {
535 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE },
539 static struct resource_spec bwn_res_spec_msi[] = {
540 { SYS_RES_IRQ, 1, RF_ACTIVE },
544 static const struct bwn_channelinfo bwn_chantable_bg = {
546 { 2412, 1, 30 }, { 2417, 2, 30 }, { 2422, 3, 30 },
547 { 2427, 4, 30 }, { 2432, 5, 30 }, { 2437, 6, 30 },
548 { 2442, 7, 30 }, { 2447, 8, 30 }, { 2452, 9, 30 },
549 { 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 },
550 { 2472, 13, 30 }, { 2484, 14, 30 } },
554 static const struct bwn_channelinfo bwn_chantable_a = {
556 { 5170, 34, 30 }, { 5180, 36, 30 }, { 5190, 38, 30 },
557 { 5200, 40, 30 }, { 5210, 42, 30 }, { 5220, 44, 30 },
558 { 5230, 46, 30 }, { 5240, 48, 30 }, { 5260, 52, 30 },
559 { 5280, 56, 30 }, { 5300, 60, 30 }, { 5320, 64, 30 },
560 { 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 },
561 { 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 },
562 { 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 },
563 { 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 },
564 { 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 },
565 { 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 },
566 { 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 },
567 { 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 },
572 static const struct bwn_channelinfo bwn_chantable_n = {
574 { 5160, 32, 30 }, { 5170, 34, 30 }, { 5180, 36, 30 },
575 { 5190, 38, 30 }, { 5200, 40, 30 }, { 5210, 42, 30 },
576 { 5220, 44, 30 }, { 5230, 46, 30 }, { 5240, 48, 30 },
577 { 5250, 50, 30 }, { 5260, 52, 30 }, { 5270, 54, 30 },
578 { 5280, 56, 30 }, { 5290, 58, 30 }, { 5300, 60, 30 },
579 { 5310, 62, 30 }, { 5320, 64, 30 }, { 5330, 66, 30 },
580 { 5340, 68, 30 }, { 5350, 70, 30 }, { 5360, 72, 30 },
581 { 5370, 74, 30 }, { 5380, 76, 30 }, { 5390, 78, 30 },
582 { 5400, 80, 30 }, { 5410, 82, 30 }, { 5420, 84, 30 },
583 { 5430, 86, 30 }, { 5440, 88, 30 }, { 5450, 90, 30 },
584 { 5460, 92, 30 }, { 5470, 94, 30 }, { 5480, 96, 30 },
585 { 5490, 98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 },
586 { 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 },
587 { 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 },
588 { 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 },
589 { 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 },
590 { 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 },
591 { 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 },
592 { 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 },
593 { 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 },
594 { 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 },
595 { 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 },
596 { 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 },
597 { 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 },
598 { 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 },
599 { 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 },
600 { 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 },
601 { 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 },
602 { 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 },
603 { 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 },
604 { 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 },
605 { 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 },
606 { 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
607 { 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
608 { 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
609 { 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
610 { 6130, 226, 30 }, { 6140, 228, 30 } },
614 static const uint8_t bwn_b2063_chantable_data[33][12] = {
615 { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
616 { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
617 { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
618 { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
619 { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
620 { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 },
621 { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 },
622 { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 },
623 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 },
624 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 },
625 { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 },
626 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 },
627 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 },
628 { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 },
629 { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
630 { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
631 { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 },
632 { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 },
633 { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 },
634 { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
635 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
636 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
637 { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
638 { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
639 { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 },
640 { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
641 { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
642 { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
643 { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
644 { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
645 { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
646 { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
647 { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }
650 static const struct bwn_b206x_chan bwn_b2063_chantable[] = {
651 { 1, 2412, bwn_b2063_chantable_data[0] },
652 { 2, 2417, bwn_b2063_chantable_data[0] },
653 { 3, 2422, bwn_b2063_chantable_data[0] },
654 { 4, 2427, bwn_b2063_chantable_data[1] },
655 { 5, 2432, bwn_b2063_chantable_data[1] },
656 { 6, 2437, bwn_b2063_chantable_data[1] },
657 { 7, 2442, bwn_b2063_chantable_data[1] },
658 { 8, 2447, bwn_b2063_chantable_data[1] },
659 { 9, 2452, bwn_b2063_chantable_data[2] },
660 { 10, 2457, bwn_b2063_chantable_data[2] },
661 { 11, 2462, bwn_b2063_chantable_data[3] },
662 { 12, 2467, bwn_b2063_chantable_data[3] },
663 { 13, 2472, bwn_b2063_chantable_data[3] },
664 { 14, 2484, bwn_b2063_chantable_data[4] },
665 { 34, 5170, bwn_b2063_chantable_data[5] },
666 { 36, 5180, bwn_b2063_chantable_data[6] },
667 { 38, 5190, bwn_b2063_chantable_data[7] },
668 { 40, 5200, bwn_b2063_chantable_data[8] },
669 { 42, 5210, bwn_b2063_chantable_data[9] },
670 { 44, 5220, bwn_b2063_chantable_data[10] },
671 { 46, 5230, bwn_b2063_chantable_data[11] },
672 { 48, 5240, bwn_b2063_chantable_data[12] },
673 { 52, 5260, bwn_b2063_chantable_data[13] },
674 { 56, 5280, bwn_b2063_chantable_data[14] },
675 { 60, 5300, bwn_b2063_chantable_data[14] },
676 { 64, 5320, bwn_b2063_chantable_data[15] },
677 { 100, 5500, bwn_b2063_chantable_data[16] },
678 { 104, 5520, bwn_b2063_chantable_data[17] },
679 { 108, 5540, bwn_b2063_chantable_data[18] },
680 { 112, 5560, bwn_b2063_chantable_data[19] },
681 { 116, 5580, bwn_b2063_chantable_data[20] },
682 { 120, 5600, bwn_b2063_chantable_data[21] },
683 { 124, 5620, bwn_b2063_chantable_data[21] },
684 { 128, 5640, bwn_b2063_chantable_data[22] },
685 { 132, 5660, bwn_b2063_chantable_data[22] },
686 { 136, 5680, bwn_b2063_chantable_data[22] },
687 { 140, 5700, bwn_b2063_chantable_data[23] },
688 { 149, 5745, bwn_b2063_chantable_data[23] },
689 { 153, 5765, bwn_b2063_chantable_data[23] },
690 { 157, 5785, bwn_b2063_chantable_data[23] },
691 { 161, 5805, bwn_b2063_chantable_data[23] },
692 { 165, 5825, bwn_b2063_chantable_data[23] },
693 { 184, 4920, bwn_b2063_chantable_data[24] },
694 { 188, 4940, bwn_b2063_chantable_data[25] },
695 { 192, 4960, bwn_b2063_chantable_data[26] },
696 { 196, 4980, bwn_b2063_chantable_data[27] },
697 { 200, 5000, bwn_b2063_chantable_data[28] },
698 { 204, 5020, bwn_b2063_chantable_data[29] },
699 { 208, 5040, bwn_b2063_chantable_data[30] },
700 { 212, 5060, bwn_b2063_chantable_data[31] },
701 { 216, 5080, bwn_b2063_chantable_data[32] }
704 static const uint8_t bwn_b2062_chantable_data[22][12] = {
705 { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 },
706 { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
707 { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
708 { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
709 { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
710 { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
711 { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
712 { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
713 { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
714 { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
715 { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
716 { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
717 { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
718 { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
719 { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
720 { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
721 { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
722 { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
723 { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
724 { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
725 { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
726 { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }
729 static const struct bwn_b206x_chan bwn_b2062_chantable[] = {
730 { 1, 2412, bwn_b2062_chantable_data[0] },
731 { 2, 2417, bwn_b2062_chantable_data[0] },
732 { 3, 2422, bwn_b2062_chantable_data[0] },
733 { 4, 2427, bwn_b2062_chantable_data[0] },
734 { 5, 2432, bwn_b2062_chantable_data[0] },
735 { 6, 2437, bwn_b2062_chantable_data[0] },
736 { 7, 2442, bwn_b2062_chantable_data[0] },
737 { 8, 2447, bwn_b2062_chantable_data[0] },
738 { 9, 2452, bwn_b2062_chantable_data[0] },
739 { 10, 2457, bwn_b2062_chantable_data[0] },
740 { 11, 2462, bwn_b2062_chantable_data[0] },
741 { 12, 2467, bwn_b2062_chantable_data[0] },
742 { 13, 2472, bwn_b2062_chantable_data[0] },
743 { 14, 2484, bwn_b2062_chantable_data[0] },
744 { 34, 5170, bwn_b2062_chantable_data[1] },
745 { 38, 5190, bwn_b2062_chantable_data[2] },
746 { 42, 5210, bwn_b2062_chantable_data[2] },
747 { 46, 5230, bwn_b2062_chantable_data[3] },
748 { 36, 5180, bwn_b2062_chantable_data[4] },
749 { 40, 5200, bwn_b2062_chantable_data[5] },
750 { 44, 5220, bwn_b2062_chantable_data[6] },
751 { 48, 5240, bwn_b2062_chantable_data[3] },
752 { 52, 5260, bwn_b2062_chantable_data[3] },
753 { 56, 5280, bwn_b2062_chantable_data[3] },
754 { 60, 5300, bwn_b2062_chantable_data[7] },
755 { 64, 5320, bwn_b2062_chantable_data[8] },
756 { 100, 5500, bwn_b2062_chantable_data[9] },
757 { 104, 5520, bwn_b2062_chantable_data[10] },
758 { 108, 5540, bwn_b2062_chantable_data[10] },
759 { 112, 5560, bwn_b2062_chantable_data[10] },
760 { 116, 5580, bwn_b2062_chantable_data[11] },
761 { 120, 5600, bwn_b2062_chantable_data[12] },
762 { 124, 5620, bwn_b2062_chantable_data[12] },
763 { 128, 5640, bwn_b2062_chantable_data[12] },
764 { 132, 5660, bwn_b2062_chantable_data[12] },
765 { 136, 5680, bwn_b2062_chantable_data[12] },
766 { 140, 5700, bwn_b2062_chantable_data[12] },
767 { 149, 5745, bwn_b2062_chantable_data[12] },
768 { 153, 5765, bwn_b2062_chantable_data[12] },
769 { 157, 5785, bwn_b2062_chantable_data[12] },
770 { 161, 5805, bwn_b2062_chantable_data[12] },
771 { 165, 5825, bwn_b2062_chantable_data[12] },
772 { 184, 4920, bwn_b2062_chantable_data[13] },
773 { 188, 4940, bwn_b2062_chantable_data[14] },
774 { 192, 4960, bwn_b2062_chantable_data[15] },
775 { 196, 4980, bwn_b2062_chantable_data[16] },
776 { 200, 5000, bwn_b2062_chantable_data[17] },
777 { 204, 5020, bwn_b2062_chantable_data[18] },
778 { 208, 5040, bwn_b2062_chantable_data[19] },
779 { 212, 5060, bwn_b2062_chantable_data[20] },
780 { 216, 5080, bwn_b2062_chantable_data[21] }
784 static const struct bwn_rxcompco bwn_rxcompco_5354[] = {
785 { 1, -66, 15 }, { 2, -66, 15 }, { 3, -66, 15 }, { 4, -66, 15 },
786 { 5, -66, 15 }, { 6, -66, 15 }, { 7, -66, 14 }, { 8, -66, 14 },
787 { 9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 },
788 { 13, -66, 13 }, { 14, -66, 13 },
792 static const struct bwn_rxcompco bwn_rxcompco_r12[] = {
793 { 1, -64, 13 }, { 2, -64, 13 }, { 3, -64, 13 }, { 4, -64, 13 },
794 { 5, -64, 12 }, { 6, -64, 12 }, { 7, -64, 12 }, { 8, -64, 12 },
795 { 9, -64, 12 }, { 10, -64, 11 }, { 11, -64, 11 }, { 12, -64, 11 },
796 { 13, -64, 11 }, { 14, -64, 10 }, { 34, -62, 24 }, { 38, -62, 24 },
797 { 42, -62, 24 }, { 46, -62, 23 }, { 36, -62, 24 }, { 40, -62, 24 },
798 { 44, -62, 23 }, { 48, -62, 23 }, { 52, -62, 23 }, { 56, -62, 22 },
799 { 60, -62, 22 }, { 64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 },
800 { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 },
801 { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 },
802 { 140, -62, 10 }, { 149, -61, 9 }, { 153, -61, 9 }, { 157, -61, 9 },
803 { 161, -61, 8 }, { 165, -61, 8 }, { 184, -62, 25 }, { 188, -62, 25 },
804 { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 },
805 { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 },
808 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 };
810 static const uint8_t bwn_tab_sigsq_tbl[] = {
811 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd,
812 0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
813 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00,
814 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
815 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
816 0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
819 static const uint8_t bwn_tab_pllfrac_tbl[] = {
820 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80,
821 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
824 static const uint16_t bwn_tabl_iqlocal_tbl[] = {
825 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002,
826 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
827 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
828 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
829 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006,
830 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
831 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 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, 0x4000, 0x0000, 0x0000,
835 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
836 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
839 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
840 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
841 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
842 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
843 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
844 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
846 #define VENDOR_LED_ACT(vendor) \
848 .vid = PCI_VENDOR_##vendor, \
849 .led_act = { BWN_VENDOR_LED_ACT_##vendor } \
852 static const struct {
854 uint8_t led_act[BWN_LED_MAX];
855 } bwn_vendor_led_act[] = {
856 VENDOR_LED_ACT(COMPAQ),
857 VENDOR_LED_ACT(ASUSTEK)
860 static const uint8_t bwn_default_led_act[BWN_LED_MAX] =
861 { BWN_VENDOR_LED_ACT_DEFAULT };
863 #undef VENDOR_LED_ACT
865 static const struct {
868 } bwn_led_duration[109] = {
884 static const uint16_t bwn_wme_shm_offsets[] = {
885 [0] = BWN_WME_BESTEFFORT,
886 [1] = BWN_WME_BACKGROUND,
891 static const struct siba_devid bwn_devs[] = {
892 SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"),
893 SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"),
894 SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"),
895 SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"),
896 SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"),
897 SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"),
898 SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"),
899 SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"),
900 SIBA_DEV(BROADCOM, 80211, 16, "Revision 16")
904 bwn_probe(device_t dev)
908 for (i = 0; i < sizeof(bwn_devs) / sizeof(bwn_devs[0]); i++) {
909 if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor &&
910 siba_get_device(dev) == bwn_devs[i].sd_device &&
911 siba_get_revid(dev) == bwn_devs[i].sd_rev)
912 return (BUS_PROBE_DEFAULT);
919 bwn_attach(device_t dev)
922 struct bwn_softc *sc = device_get_softc(dev);
923 int error, i, msic, reg;
927 sc->sc_debug = bwn_debug;
930 if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
932 bwn_sprom_bugfixes(dev);
933 sc->sc_flags |= BWN_FLAG_ATTACHED;
936 if (!TAILQ_EMPTY(&sc->sc_maclist)) {
937 if (siba_get_pci_device(dev) != 0x4313 &&
938 siba_get_pci_device(dev) != 0x431a &&
939 siba_get_pci_device(dev) != 0x4321) {
940 device_printf(sc->sc_dev,
941 "skip 802.11 cores\n");
946 mac = malloc(sizeof(*mac), M_DEVBUF, M_WAITOK | M_ZERO);
948 mac->mac_status = BWN_MAC_STATUS_UNINIT;
950 mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
952 TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac);
953 TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac);
954 TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac);
956 error = bwn_attach_core(mac);
961 device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) "
962 "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
963 siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev),
964 mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev,
965 mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver,
966 mac->mac_phy.rf_rev);
967 if (mac->mac_flags & BWN_MAC_FLAG_DMA)
968 device_printf(sc->sc_dev, "DMA (%d bits)\n",
969 mac->mac_method.dma.dmatype);
971 device_printf(sc->sc_dev, "PIO\n");
974 * setup PCI resources and interrupt.
976 if (pci_find_cap(dev, PCIY_EXPRESS, ®) == 0) {
977 msic = pci_msi_count(dev);
979 device_printf(sc->sc_dev, "MSI count : %d\n", msic);
983 mac->mac_intr_spec = bwn_res_spec_legacy;
984 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) {
985 if (pci_alloc_msi(dev, &msic) == 0) {
986 device_printf(sc->sc_dev,
987 "Using %d MSI messages\n", msic);
988 mac->mac_intr_spec = bwn_res_spec_msi;
993 error = bus_alloc_resources(dev, mac->mac_intr_spec,
996 device_printf(sc->sc_dev,
997 "couldn't allocate IRQ resources (%d)\n", error);
1001 if (mac->mac_msi == 0)
1002 error = bus_setup_intr(dev, mac->mac_res_irq[0],
1003 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1004 &mac->mac_intrhand[0]);
1006 for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1007 error = bus_setup_intr(dev, mac->mac_res_irq[i],
1008 INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
1009 &mac->mac_intrhand[i]);
1011 device_printf(sc->sc_dev,
1012 "couldn't setup interrupt (%d)\n", error);
1018 TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list);
1021 * calls attach-post routine
1023 if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0)
1024 bwn_attach_post(sc);
1028 if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0)
1029 pci_release_msi(dev);
1031 free(mac, M_DEVBUF);
1036 bwn_is_valid_ether_addr(uint8_t *addr)
1038 char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
1040 if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN)))
1047 bwn_attach_post(struct bwn_softc *sc)
1049 struct ieee80211com *ic = &sc->sc_ic;
1052 ic->ic_name = device_get_nameunit(sc->sc_dev);
1053 /* XXX not right but it's not used anywhere important */
1054 ic->ic_phytype = IEEE80211_T_OFDM;
1055 ic->ic_opmode = IEEE80211_M_STA;
1057 IEEE80211_C_STA /* station mode supported */
1058 | IEEE80211_C_MONITOR /* monitor mode */
1059 | IEEE80211_C_AHDEMO /* adhoc demo mode */
1060 | IEEE80211_C_SHPREAMBLE /* short preamble supported */
1061 | IEEE80211_C_SHSLOT /* short slot time supported */
1062 | IEEE80211_C_WME /* WME/WMM supported */
1063 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */
1064 | IEEE80211_C_BGSCAN /* capable of bg scanning */
1065 | IEEE80211_C_TXPMGT /* capable of txpow mgt */
1068 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */
1070 IEEE80211_ADDR_COPY(ic->ic_macaddr,
1071 bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
1072 siba_sprom_get_mac_80211a(sc->sc_dev) :
1073 siba_sprom_get_mac_80211bg(sc->sc_dev));
1075 /* call MI attach routine. */
1076 ieee80211_ifattach(ic);
1078 ic->ic_headroom = sizeof(struct bwn_txhdr);
1080 /* override default methods */
1081 ic->ic_raw_xmit = bwn_raw_xmit;
1082 ic->ic_updateslot = bwn_updateslot;
1083 ic->ic_update_promisc = bwn_update_promisc;
1084 ic->ic_wme.wme_update = bwn_wme_update;
1085 ic->ic_scan_start = bwn_scan_start;
1086 ic->ic_scan_end = bwn_scan_end;
1087 ic->ic_set_channel = bwn_set_channel;
1088 ic->ic_vap_create = bwn_vap_create;
1089 ic->ic_vap_delete = bwn_vap_delete;
1090 ic->ic_transmit = bwn_transmit;
1091 ic->ic_parent = bwn_parent;
1093 ieee80211_radiotap_attach(ic,
1094 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
1095 BWN_TX_RADIOTAP_PRESENT,
1096 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
1097 BWN_RX_RADIOTAP_PRESENT);
1099 bwn_sysctl_node(sc);
1102 ieee80211_announce(ic);
1107 bwn_phy_detach(struct bwn_mac *mac)
1110 if (mac->mac_phy.detach != NULL)
1111 mac->mac_phy.detach(mac);
1115 bwn_detach(device_t dev)
1117 struct bwn_softc *sc = device_get_softc(dev);
1118 struct bwn_mac *mac = sc->sc_curmac;
1119 struct ieee80211com *ic = &sc->sc_ic;
1122 sc->sc_flags |= BWN_FLAG_INVALID;
1124 if (device_is_attached(sc->sc_dev)) {
1129 callout_drain(&sc->sc_led_blink_ch);
1130 callout_drain(&sc->sc_rfswitch_ch);
1131 callout_drain(&sc->sc_task_ch);
1132 callout_drain(&sc->sc_watchdog_ch);
1133 bwn_phy_detach(mac);
1134 ieee80211_draintask(ic, &mac->mac_hwreset);
1135 ieee80211_draintask(ic, &mac->mac_txpower);
1136 ieee80211_ifdetach(ic);
1138 taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
1139 taskqueue_free(sc->sc_tq);
1141 for (i = 0; i < BWN_MSI_MESSAGES; i++) {
1142 if (mac->mac_intrhand[i] != NULL) {
1143 bus_teardown_intr(dev, mac->mac_res_irq[i],
1144 mac->mac_intrhand[i]);
1145 mac->mac_intrhand[i] = NULL;
1148 bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq);
1149 if (mac->mac_msi != 0)
1150 pci_release_msi(dev);
1151 mbufq_drain(&sc->sc_snd);
1152 BWN_LOCK_DESTROY(sc);
1157 bwn_attach_pre(struct bwn_softc *sc)
1161 TAILQ_INIT(&sc->sc_maclist);
1162 callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0);
1163 callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0);
1164 callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0);
1165 mbufq_init(&sc->sc_snd, ifqmaxlen);
1166 sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT,
1167 taskqueue_thread_enqueue, &sc->sc_tq);
1168 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
1169 "%s taskq", device_get_nameunit(sc->sc_dev));
1173 bwn_sprom_bugfixes(device_t dev)
1175 #define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \
1176 ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \
1177 (siba_get_pci_device(dev) == _device) && \
1178 (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \
1179 (siba_get_pci_subdevice(dev) == _subdevice))
1181 if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE &&
1182 siba_get_pci_subdevice(dev) == 0x4e &&
1183 siba_get_pci_revid(dev) > 0x40)
1184 siba_sprom_set_bf_lo(dev,
1185 siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL);
1186 if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL &&
1187 siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74)
1188 siba_sprom_set_bf_lo(dev,
1189 siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST);
1190 if (siba_get_type(dev) == SIBA_TYPE_PCI) {
1191 if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) ||
1192 BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) ||
1193 BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) ||
1194 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) ||
1195 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) ||
1196 BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) ||
1197 BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010))
1198 siba_sprom_set_bf_lo(dev,
1199 siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST);
1205 bwn_parent(struct ieee80211com *ic)
1207 struct bwn_softc *sc = ic->ic_softc;
1211 if (ic->ic_nrunning > 0) {
1212 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) {
1216 bwn_update_promisc(ic);
1217 } else if (sc->sc_flags & BWN_FLAG_RUNNING)
1222 ieee80211_start_all(ic);
1226 bwn_transmit(struct ieee80211com *ic, struct mbuf *m)
1228 struct bwn_softc *sc = ic->ic_softc;
1232 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) {
1236 error = mbufq_enqueue(&sc->sc_snd, m);
1247 bwn_start(struct bwn_softc *sc)
1249 struct bwn_mac *mac = sc->sc_curmac;
1250 struct ieee80211_frame *wh;
1251 struct ieee80211_node *ni;
1252 struct ieee80211_key *k;
1255 BWN_ASSERT_LOCKED(sc);
1257 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 || mac == NULL ||
1258 mac->mac_status < BWN_MAC_STATUS_STARTED)
1261 while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
1262 if (bwn_tx_isfull(sc, m))
1264 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1266 device_printf(sc->sc_dev, "unexpected NULL ni\n");
1268 counter_u64_add(sc->sc_ic.ic_oerrors, 1);
1271 wh = mtod(m, struct ieee80211_frame *);
1272 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1273 k = ieee80211_crypto_encap(ni, m);
1275 if_inc_counter(ni->ni_vap->iv_ifp,
1276 IFCOUNTER_OERRORS, 1);
1277 ieee80211_free_node(ni);
1282 wh = NULL; /* Catch any invalid use */
1283 if (bwn_tx_start(sc, ni, m) != 0) {
1285 if_inc_counter(ni->ni_vap->iv_ifp,
1286 IFCOUNTER_OERRORS, 1);
1287 ieee80211_free_node(ni);
1291 sc->sc_watchdog_timer = 5;
1296 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1298 struct bwn_dma_ring *dr;
1299 struct bwn_mac *mac = sc->sc_curmac;
1300 struct bwn_pio_txqueue *tq;
1301 int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1303 BWN_ASSERT_LOCKED(sc);
1305 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1306 dr = bwn_dma_select(mac, M_WME_GETAC(m));
1307 if (dr->dr_stop == 1 ||
1308 bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1313 tq = bwn_pio_select(mac, M_WME_GETAC(m));
1314 if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1315 pktlen > (tq->tq_size - tq->tq_used))
1320 mbufq_prepend(&sc->sc_snd, m);
1325 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1327 struct bwn_mac *mac = sc->sc_curmac;
1330 BWN_ASSERT_LOCKED(sc);
1332 if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1337 error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1338 bwn_dma_tx_start(mac, ni, m) : bwn_pio_tx_start(mac, ni, m);
1347 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1349 struct bwn_pio_txpkt *tp;
1350 struct bwn_pio_txqueue *tq = bwn_pio_select(mac, M_WME_GETAC(m));
1351 struct bwn_softc *sc = mac->mac_sc;
1352 struct bwn_txhdr txhdr;
1358 BWN_ASSERT_LOCKED(sc);
1360 /* XXX TODO send packets after DTIM */
1362 KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1363 tp = TAILQ_FIRST(&tq->tq_pktlist);
1367 error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1369 device_printf(sc->sc_dev, "tx fail\n");
1373 TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1374 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1377 if (siba_get_revid(sc->sc_dev) >= 8) {
1379 * XXX please removes m_defrag(9)
1381 m_new = m_defrag(m, M_NOWAIT);
1382 if (m_new == NULL) {
1383 device_printf(sc->sc_dev,
1384 "%s: can't defrag TX buffer\n",
1388 if (m_new->m_next != NULL)
1389 device_printf(sc->sc_dev,
1390 "TODO: fragmented packets for PIO\n");
1394 ctl32 = bwn_pio_write_multi_4(mac, tq,
1395 (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1396 BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1397 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1399 ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1400 mtod(m_new, const void *), m_new->m_pkthdr.len);
1401 bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1402 ctl32 | BWN_PIO8_TXCTL_EOF);
1404 ctl16 = bwn_pio_write_multi_2(mac, tq,
1405 (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1406 BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1407 (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1408 ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1409 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1410 ctl16 | BWN_PIO_TXCTL_EOF);
1416 static struct bwn_pio_txqueue *
1417 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1420 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1421 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1425 return (&mac->mac_method.pio.wme[WME_AC_BE]);
1427 return (&mac->mac_method.pio.wme[WME_AC_BK]);
1429 return (&mac->mac_method.pio.wme[WME_AC_VI]);
1431 return (&mac->mac_method.pio.wme[WME_AC_VO]);
1433 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1438 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
1440 #define BWN_GET_TXHDRCACHE(slot) \
1441 &(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)])
1442 struct bwn_dma *dma = &mac->mac_method.dma;
1443 struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(m));
1444 struct bwn_dmadesc_generic *desc;
1445 struct bwn_dmadesc_meta *mt;
1446 struct bwn_softc *sc = mac->mac_sc;
1447 uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1448 int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1450 BWN_ASSERT_LOCKED(sc);
1451 KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1453 /* XXX send after DTIM */
1455 slot = bwn_dma_getslot(dr);
1456 dr->getdesc(dr, slot, &desc, &mt);
1457 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1458 ("%s:%d: fail", __func__, __LINE__));
1460 error = bwn_set_txhdr(dr->dr_mac, ni, m,
1461 (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1462 BWN_DMA_COOKIE(dr, slot));
1465 error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap,
1466 BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr,
1467 &mt->mt_paddr, BUS_DMA_NOWAIT);
1469 device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n",
1473 bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1474 BUS_DMASYNC_PREWRITE);
1475 dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1476 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1477 BUS_DMASYNC_PREWRITE);
1479 slot = bwn_dma_getslot(dr);
1480 dr->getdesc(dr, slot, &desc, &mt);
1481 KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1482 mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1486 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1487 bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1488 if (error && error != EFBIG) {
1489 device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n",
1493 if (error) { /* error == EFBIG */
1496 m_new = m_defrag(m, M_NOWAIT);
1497 if (m_new == NULL) {
1498 device_printf(sc->sc_dev,
1499 "%s: can't defrag TX buffer\n",
1508 error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1509 m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1511 device_printf(sc->sc_dev,
1512 "%s: can't load TX buffer (2) %d\n",
1517 bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1518 dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1519 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1520 BUS_DMASYNC_PREWRITE);
1522 /* XXX send after DTIM */
1524 dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1527 dr->dr_curslot = backup[0];
1528 dr->dr_usedslot = backup[1];
1530 #undef BWN_GET_TXHDRCACHE
1534 bwn_watchdog(void *arg)
1536 struct bwn_softc *sc = arg;
1538 if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1539 device_printf(sc->sc_dev, "device timeout\n");
1540 counter_u64_add(sc->sc_ic.ic_oerrors, 1);
1542 callout_schedule(&sc->sc_watchdog_ch, hz);
1546 bwn_attach_core(struct bwn_mac *mac)
1548 struct bwn_softc *sc = mac->mac_sc;
1549 int error, have_bg = 0, have_a = 0;
1552 KASSERT(siba_get_revid(sc->sc_dev) >= 5,
1553 ("unsupported revision %d", siba_get_revid(sc->sc_dev)));
1555 siba_powerup(sc->sc_dev, 0);
1557 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
1559 (high & BWN_TGSHIGH_HAVE_2GHZ) ? BWN_TGSLOW_SUPPORT_G : 0);
1560 error = bwn_phy_getinfo(mac, high);
1564 have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0;
1565 have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1566 if (siba_get_pci_device(sc->sc_dev) != 0x4312 &&
1567 siba_get_pci_device(sc->sc_dev) != 0x4319 &&
1568 siba_get_pci_device(sc->sc_dev) != 0x4324) {
1569 have_a = have_bg = 0;
1570 if (mac->mac_phy.type == BWN_PHYTYPE_A)
1572 else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1573 mac->mac_phy.type == BWN_PHYTYPE_N ||
1574 mac->mac_phy.type == BWN_PHYTYPE_LP)
1577 KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1578 mac->mac_phy.type));
1580 /* XXX turns off PHY A because it's not supported */
1581 if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1582 mac->mac_phy.type != BWN_PHYTYPE_N) {
1587 if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1588 mac->mac_phy.attach = bwn_phy_g_attach;
1589 mac->mac_phy.detach = bwn_phy_g_detach;
1590 mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1591 mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1592 mac->mac_phy.init = bwn_phy_g_init;
1593 mac->mac_phy.exit = bwn_phy_g_exit;
1594 mac->mac_phy.phy_read = bwn_phy_g_read;
1595 mac->mac_phy.phy_write = bwn_phy_g_write;
1596 mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1597 mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1598 mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1599 mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1600 mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1601 mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1602 mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1603 mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1604 mac->mac_phy.set_im = bwn_phy_g_im;
1605 mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1606 mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1607 mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1608 mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1609 } else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1610 mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1611 mac->mac_phy.init = bwn_phy_lp_init;
1612 mac->mac_phy.phy_read = bwn_phy_lp_read;
1613 mac->mac_phy.phy_write = bwn_phy_lp_write;
1614 mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1615 mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1616 mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1617 mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1618 mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1619 mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1620 mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1621 mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1622 mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1624 device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1630 mac->mac_phy.gmode = have_bg;
1631 if (mac->mac_phy.attach != NULL) {
1632 error = mac->mac_phy.attach(mac);
1634 device_printf(sc->sc_dev, "failed\n");
1639 bwn_reset_core(mac, have_bg ? BWN_TGSLOW_SUPPORT_G : 0);
1641 error = bwn_chiptest(mac);
1644 error = bwn_setup_channels(mac, have_bg, have_a);
1646 device_printf(sc->sc_dev, "failed to setup channels\n");
1650 if (sc->sc_curmac == NULL)
1651 sc->sc_curmac = mac;
1653 error = bwn_dma_attach(mac);
1655 device_printf(sc->sc_dev, "failed to initialize DMA\n");
1659 mac->mac_phy.switch_analog(mac, 0);
1661 siba_dev_down(sc->sc_dev, 0);
1663 siba_powerdown(sc->sc_dev);
1668 bwn_reset_core(struct bwn_mac *mac, uint32_t flags)
1670 struct bwn_softc *sc = mac->mac_sc;
1673 flags |= (BWN_TGSLOW_PHYCLOCK_ENABLE | BWN_TGSLOW_PHYRESET);
1675 siba_dev_up(sc->sc_dev, flags);
1678 low = (siba_read_4(sc->sc_dev, SIBA_TGSLOW) | SIBA_TGSLOW_FGC) &
1679 ~BWN_TGSLOW_PHYRESET;
1680 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low);
1681 siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1683 siba_write_4(sc->sc_dev, SIBA_TGSLOW, low & ~SIBA_TGSLOW_FGC);
1684 siba_read_4(sc->sc_dev, SIBA_TGSLOW);
1687 if (mac->mac_phy.switch_analog != NULL)
1688 mac->mac_phy.switch_analog(mac, 1);
1690 ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1691 if (flags & BWN_TGSLOW_SUPPORT_G)
1692 ctl |= BWN_MACCTL_GMODE;
1693 BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1697 bwn_phy_getinfo(struct bwn_mac *mac, int tgshigh)
1699 struct bwn_phy *phy = &mac->mac_phy;
1700 struct bwn_softc *sc = mac->mac_sc;
1704 tmp = BWN_READ_2(mac, BWN_PHYVER);
1705 phy->gmode = (tgshigh & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0;
1707 phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1708 phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1709 phy->rev = (tmp & BWN_PHYVER_VERSION);
1710 if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1711 (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1712 phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1713 (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1714 (phy->type == BWN_PHYTYPE_N && phy->rev > 4) ||
1715 (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1719 if (siba_get_chipid(sc->sc_dev) == 0x4317) {
1720 if (siba_get_chiprev(sc->sc_dev) == 0)
1722 else if (siba_get_chiprev(sc->sc_dev) == 1)
1727 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1728 tmp = BWN_READ_2(mac, BWN_RFDATALO);
1729 BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1730 tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1732 phy->rf_rev = (tmp & 0xf0000000) >> 28;
1733 phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1734 phy->rf_manuf = (tmp & 0x00000fff);
1735 if (phy->rf_manuf != 0x17f) /* 0x17f is broadcom */
1737 if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1738 phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1739 (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1740 (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1741 (phy->type == BWN_PHYTYPE_N &&
1742 phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1743 (phy->type == BWN_PHYTYPE_LP &&
1744 phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1749 device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1751 phy->type, phy->rev, phy->analog);
1754 device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1756 phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1761 bwn_chiptest(struct bwn_mac *mac)
1763 #define TESTVAL0 0x55aaaa55
1764 #define TESTVAL1 0xaa5555aa
1765 struct bwn_softc *sc = mac->mac_sc;
1770 backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1772 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1773 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1775 bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1776 if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1779 bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1781 if ((siba_get_revid(sc->sc_dev) >= 3) &&
1782 (siba_get_revid(sc->sc_dev) <= 10)) {
1783 BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1784 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1785 if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1787 if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1790 BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1792 v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1793 if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1800 device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1804 #define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT | IEEE80211_CHAN_G)
1805 #define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT | IEEE80211_CHAN_A)
1808 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1810 struct bwn_softc *sc = mac->mac_sc;
1811 struct ieee80211com *ic = &sc->sc_ic;
1813 memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1817 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1818 &ic->ic_nchans, &bwn_chantable_bg, IEEE80211_CHAN_G);
1819 if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1821 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1822 &ic->ic_nchans, &bwn_chantable_n,
1823 IEEE80211_CHAN_HTA);
1826 bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1827 &ic->ic_nchans, &bwn_chantable_a,
1831 mac->mac_phy.supports_2ghz = have_bg;
1832 mac->mac_phy.supports_5ghz = have_a;
1834 return (ic->ic_nchans == 0 ? ENXIO : 0);
1838 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1842 BWN_ASSERT_LOCKED(mac->mac_sc);
1844 if (way == BWN_SHARED) {
1845 KASSERT((offset & 0x0001) == 0,
1846 ("%s:%d warn", __func__, __LINE__));
1847 if (offset & 0x0003) {
1848 bwn_shm_ctlword(mac, way, offset >> 2);
1849 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1851 bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1852 ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1857 bwn_shm_ctlword(mac, way, offset);
1858 ret = BWN_READ_4(mac, BWN_SHM_DATA);
1864 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1868 BWN_ASSERT_LOCKED(mac->mac_sc);
1870 if (way == BWN_SHARED) {
1871 KASSERT((offset & 0x0001) == 0,
1872 ("%s:%d warn", __func__, __LINE__));
1873 if (offset & 0x0003) {
1874 bwn_shm_ctlword(mac, way, offset >> 2);
1875 ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1880 bwn_shm_ctlword(mac, way, offset);
1881 ret = BWN_READ_2(mac, BWN_SHM_DATA);
1888 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1896 BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1900 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1903 BWN_ASSERT_LOCKED(mac->mac_sc);
1905 if (way == BWN_SHARED) {
1906 KASSERT((offset & 0x0001) == 0,
1907 ("%s:%d warn", __func__, __LINE__));
1908 if (offset & 0x0003) {
1909 bwn_shm_ctlword(mac, way, offset >> 2);
1910 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1911 (value >> 16) & 0xffff);
1912 bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1913 BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1918 bwn_shm_ctlword(mac, way, offset);
1919 BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1923 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1926 BWN_ASSERT_LOCKED(mac->mac_sc);
1928 if (way == BWN_SHARED) {
1929 KASSERT((offset & 0x0001) == 0,
1930 ("%s:%d warn", __func__, __LINE__));
1931 if (offset & 0x0003) {
1932 bwn_shm_ctlword(mac, way, offset >> 2);
1933 BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1938 bwn_shm_ctlword(mac, way, offset);
1939 BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1943 bwn_addchan(struct ieee80211_channel *c, int freq, int flags, int ieee,
1948 c->ic_flags = flags;
1951 c->ic_maxpower = 2 * txpow;
1952 c->ic_maxregpower = txpow;
1956 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
1957 const struct bwn_channelinfo *ci, int flags)
1959 struct ieee80211_channel *c;
1962 c = &chans[*nchans];
1964 for (i = 0; i < ci->nchannels; i++) {
1965 const struct bwn_channel *hc;
1967 hc = &ci->channels[i];
1968 if (*nchans >= maxchans)
1970 bwn_addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
1972 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
1973 /* g channel have a separate b-only entry */
1974 if (*nchans >= maxchans)
1977 c[-1].ic_flags = IEEE80211_CHAN_B;
1980 if (flags == IEEE80211_CHAN_HTG) {
1981 /* HT g channel have a separate g-only entry */
1982 if (*nchans >= maxchans)
1984 c[-1].ic_flags = IEEE80211_CHAN_G;
1986 c[0].ic_flags &= ~IEEE80211_CHAN_HT;
1987 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */
1990 if (flags == IEEE80211_CHAN_HTA) {
1991 /* HT a channel have a separate a-only entry */
1992 if (*nchans >= maxchans)
1994 c[-1].ic_flags = IEEE80211_CHAN_A;
1996 c[0].ic_flags &= ~IEEE80211_CHAN_HT;
1997 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */
2004 bwn_phy_g_attach(struct bwn_mac *mac)
2006 struct bwn_softc *sc = mac->mac_sc;
2007 struct bwn_phy *phy = &mac->mac_phy;
2008 struct bwn_phy_g *pg = &phy->phy_g;
2010 int16_t pab0, pab1, pab2;
2011 static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
2014 bg = (int8_t)siba_sprom_get_tssi_bg(sc->sc_dev);
2015 pab0 = (int16_t)siba_sprom_get_pa0b0(sc->sc_dev);
2016 pab1 = (int16_t)siba_sprom_get_pa0b1(sc->sc_dev);
2017 pab2 = (int16_t)siba_sprom_get_pa0b2(sc->sc_dev);
2019 if ((siba_get_chipid(sc->sc_dev) == 0x4301) && (phy->rf_ver != 0x2050))
2020 device_printf(sc->sc_dev, "not supported anymore\n");
2023 if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
2025 pg->pg_idletssi = 52;
2026 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
2030 pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
2031 pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
2032 if (pg->pg_tssi2dbm == NULL) {
2033 device_printf(sc->sc_dev, "failed to allocate buffer\n");
2036 for (i = 0; i < 64; i++) {
2037 int32_t m1, m2, f, q, delta;
2040 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
2041 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
2046 device_printf(sc->sc_dev,
2047 "failed to generate tssi2dBm\n");
2048 free(pg->pg_tssi2dbm, M_DEVBUF);
2051 q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
2056 } while (delta >= 2);
2058 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
2062 pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
2067 bwn_phy_g_detach(struct bwn_mac *mac)
2069 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
2071 if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
2072 free(pg->pg_tssi2dbm, M_DEVBUF);
2073 pg->pg_tssi2dbm = NULL;
2079 bwn_phy_g_init_pre(struct bwn_mac *mac)
2081 struct bwn_phy *phy = &mac->mac_phy;
2082 struct bwn_phy_g *pg = &phy->phy_g;
2087 tssi2dbm = pg->pg_tssi2dbm;
2088 idletssi = pg->pg_idletssi;
2090 memset(pg, 0, sizeof(*pg));
2092 pg->pg_tssi2dbm = tssi2dbm;
2093 pg->pg_idletssi = idletssi;
2095 memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
2097 for (i = 0; i < N(pg->pg_nrssi); i++)
2098 pg->pg_nrssi[i] = -1000;
2099 for (i = 0; i < N(pg->pg_nrssi_lt); i++)
2100 pg->pg_nrssi_lt[i] = i;
2101 pg->pg_lofcal = 0xffff;
2102 pg->pg_initval = 0xffff;
2103 pg->pg_immode = BWN_IMMODE_NONE;
2104 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
2105 pg->pg_avgtssi = 0xff;
2107 pg->pg_loctl.tx_bias = 0xff;
2108 TAILQ_INIT(&pg->pg_loctl.calib_list);
2112 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
2114 struct bwn_phy *phy = &mac->mac_phy;
2115 struct bwn_phy_g *pg = &phy->phy_g;
2116 struct bwn_softc *sc = mac->mac_sc;
2117 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2118 static const struct bwn_rfatt rfatt0[] = {
2119 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
2120 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
2123 static const struct bwn_rfatt rfatt1[] = {
2124 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
2127 static const struct bwn_rfatt rfatt2[] = {
2128 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
2131 static const struct bwn_bbatt bbatt_0[] = {
2132 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
2135 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
2137 if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
2138 pg->pg_bbatt.att = 0;
2140 pg->pg_bbatt.att = 2;
2142 /* prepare Radio Attenuation */
2143 pg->pg_rfatt.padmix = 0;
2145 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
2146 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4309G) {
2147 if (siba_get_pci_revid(sc->sc_dev) < 0x43) {
2148 pg->pg_rfatt.att = 2;
2150 } else if (siba_get_pci_revid(sc->sc_dev) < 0x51) {
2151 pg->pg_rfatt.att = 3;
2156 if (phy->type == BWN_PHYTYPE_A) {
2157 pg->pg_rfatt.att = 0x60;
2161 switch (phy->rf_ver) {
2163 switch (phy->rf_rev) {
2165 pg->pg_rfatt.att = 5;
2168 if (phy->type == BWN_PHYTYPE_G) {
2169 if (siba_get_pci_subvendor(sc->sc_dev) ==
2170 SIBA_BOARDVENDOR_BCM &&
2171 siba_get_pci_subdevice(sc->sc_dev) ==
2172 SIBA_BOARD_BCM4309G &&
2173 siba_get_pci_revid(sc->sc_dev) >= 30)
2174 pg->pg_rfatt.att = 3;
2175 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2176 SIBA_BOARDVENDOR_BCM &&
2177 siba_get_pci_subdevice(sc->sc_dev) ==
2179 pg->pg_rfatt.att = 3;
2181 pg->pg_rfatt.att = 1;
2183 if (siba_get_pci_subvendor(sc->sc_dev) ==
2184 SIBA_BOARDVENDOR_BCM &&
2185 siba_get_pci_subdevice(sc->sc_dev) ==
2186 SIBA_BOARD_BCM4309G &&
2187 siba_get_pci_revid(sc->sc_dev) >= 30)
2188 pg->pg_rfatt.att = 7;
2190 pg->pg_rfatt.att = 6;
2194 if (phy->type == BWN_PHYTYPE_G) {
2195 if (siba_get_pci_subvendor(sc->sc_dev) ==
2196 SIBA_BOARDVENDOR_BCM &&
2197 siba_get_pci_subdevice(sc->sc_dev) ==
2198 SIBA_BOARD_BCM4309G &&
2199 siba_get_pci_revid(sc->sc_dev) >= 30)
2200 pg->pg_rfatt.att = 3;
2201 else if (siba_get_pci_subvendor(sc->sc_dev) ==
2202 SIBA_BOARDVENDOR_BCM &&
2203 siba_get_pci_subdevice(sc->sc_dev) ==
2205 pg->pg_rfatt.att = 5;
2206 else if (siba_get_chipid(sc->sc_dev) == 0x4320)
2207 pg->pg_rfatt.att = 4;
2209 pg->pg_rfatt.att = 3;
2211 pg->pg_rfatt.att = 6;
2214 pg->pg_rfatt.att = 5;
2218 pg->pg_rfatt.att = 1;
2222 pg->pg_rfatt.att = 5;
2225 pg->pg_rfatt.att = 0xa;
2226 pg->pg_rfatt.padmix = 1;
2230 pg->pg_rfatt.att = 5;
2235 switch (phy->rf_rev) {
2237 pg->pg_rfatt.att = 6;
2242 pg->pg_rfatt.att = 5;
2244 pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
2246 if (!bwn_has_hwpctl(mac)) {
2247 lo->rfatt.array = rfatt0;
2248 lo->rfatt.len = N(rfatt0);
2253 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
2254 lo->rfatt.array = rfatt1;
2255 lo->rfatt.len = N(rfatt1);
2260 lo->rfatt.array = rfatt2;
2261 lo->rfatt.len = N(rfatt2);
2265 lo->bbatt.array = bbatt_0;
2266 lo->bbatt.len = N(bbatt_0);
2270 BWN_READ_4(mac, BWN_MACCTL);
2271 if (phy->rev == 1) {
2273 bwn_reset_core(mac, 0);
2274 bwn_phy_g_init_sub(mac);
2276 bwn_reset_core(mac, BWN_TGSLOW_SUPPORT_G);
2282 bwn_phy_g_txctl(struct bwn_mac *mac)
2284 struct bwn_phy *phy = &mac->mac_phy;
2286 if (phy->rf_ver != 0x2050)
2288 if (phy->rf_rev == 1)
2289 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
2290 if (phy->rf_rev < 6)
2291 return (BWN_TXCTL_PA2DB);
2292 if (phy->rf_rev == 8)
2293 return (BWN_TXCTL_TXMIX);
2298 bwn_phy_g_init(struct bwn_mac *mac)
2301 bwn_phy_g_init_sub(mac);
2306 bwn_phy_g_exit(struct bwn_mac *mac)
2308 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
2309 struct bwn_lo_calib *cal, *tmp;
2313 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2314 TAILQ_REMOVE(&lo->calib_list, cal, list);
2315 free(cal, M_DEVBUF);
2320 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
2323 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2324 return (BWN_READ_2(mac, BWN_PHYDATA));
2328 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2331 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
2332 BWN_WRITE_2(mac, BWN_PHYDATA, value);
2336 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
2339 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2340 BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
2341 return (BWN_READ_2(mac, BWN_RFDATALO));
2345 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
2348 KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
2349 BWN_WRITE_2(mac, BWN_RFCTL, reg);
2350 BWN_WRITE_2(mac, BWN_RFDATALO, value);
2354 bwn_phy_g_hwpctl(struct bwn_mac *mac)
2357 return (mac->mac_phy.rev >= 6);
2361 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
2363 struct bwn_phy *phy = &mac->mac_phy;
2364 struct bwn_phy_g *pg = &phy->phy_g;
2365 unsigned int channel;
2366 uint16_t rfover, rfoverval;
2372 BWN_PHY_WRITE(mac, 0x15, 0x8000);
2373 BWN_PHY_WRITE(mac, 0x15, 0xcc00);
2374 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
2375 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
2376 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
2377 pg->pg_radioctx_over);
2378 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
2379 pg->pg_radioctx_overval);
2380 pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
2382 channel = phy->chan;
2383 bwn_phy_g_switch_chan(mac, 6, 1);
2384 bwn_phy_g_switch_chan(mac, channel, 0);
2388 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
2389 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
2390 pg->pg_radioctx_over = rfover;
2391 pg->pg_radioctx_overval = rfoverval;
2392 pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
2393 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
2394 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
2398 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
2401 if ((newchan < 1) || (newchan > 14))
2403 bwn_phy_g_switch_chan(mac, newchan, 0);
2409 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
2416 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
2418 struct bwn_phy *phy = &mac->mac_phy;
2423 if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
2426 hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
2427 bwn_hf_write(mac, hf);
2429 BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
2430 (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
2431 ((autodiv ? BWN_ANTAUTO1 : antenna)
2432 << BWN_PHY_BBANDCFG_RXANT_SHIFT));
2435 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
2436 if (antenna == BWN_ANTAUTO1)
2437 tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
2439 tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
2440 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
2442 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
2444 tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
2446 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
2447 BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
2448 if (phy->rev >= 2) {
2449 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
2450 BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
2451 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
2452 (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
2455 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
2457 BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
2458 (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
2462 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
2464 hf |= BWN_HF_UCODE_ANTDIV_HELPER;
2465 bwn_hf_write(mac, hf);
2469 bwn_phy_g_im(struct bwn_mac *mac, int mode)
2471 struct bwn_phy *phy = &mac->mac_phy;
2472 struct bwn_phy_g *pg = &phy->phy_g;
2474 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2475 KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
2477 if (phy->rev == 0 || !phy->gmode)
2480 pg->pg_aci_wlan_automatic = 0;
2485 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
2487 struct bwn_phy *phy = &mac->mac_phy;
2488 struct bwn_phy_g *pg = &phy->phy_g;
2489 struct bwn_softc *sc = mac->mac_sc;
2496 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
2498 cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
2499 ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
2500 if (cck < 0 && ofdm < 0) {
2501 if (ignore_tssi == 0)
2502 return (BWN_TXPWR_RES_DONE);
2506 tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
2507 if (pg->pg_avgtssi != 0xff)
2508 tssi = (tssi + pg->pg_avgtssi) / 2;
2509 pg->pg_avgtssi = tssi;
2510 KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
2512 max = siba_sprom_get_maxpwr_bg(sc->sc_dev);
2513 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
2516 device_printf(sc->sc_dev, "invalid max TX-power value\n");
2518 siba_sprom_set_maxpwr_bg(sc->sc_dev, max);
2521 power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
2522 (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
2523 tssi, 0x00), 0x3f)]);
2525 return (BWN_TXPWR_RES_DONE);
2527 rfatt = -((power + 7) / 8);
2528 bbatt = (-(power / 2)) - (4 * rfatt);
2529 if ((rfatt == 0) && (bbatt == 0))
2530 return (BWN_TXPWR_RES_DONE);
2531 pg->pg_bbatt_delta = bbatt;
2532 pg->pg_rfatt_delta = rfatt;
2533 return (BWN_TXPWR_RES_NEED_ADJUST);
2537 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
2539 struct bwn_phy *phy = &mac->mac_phy;
2540 struct bwn_phy_g *pg = &phy->phy_g;
2541 struct bwn_softc *sc = mac->mac_sc;
2545 bwn_mac_suspend(mac);
2547 BWN_ASSERT_LOCKED(sc);
2549 bbatt = pg->pg_bbatt.att;
2550 bbatt += pg->pg_bbatt_delta;
2551 rfatt = pg->pg_rfatt.att;
2552 rfatt += pg->pg_rfatt_delta;
2554 bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2555 txctl = pg->pg_txctl;
2556 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
2559 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
2562 } else if (siba_sprom_get_bf_lo(sc->sc_dev) &
2564 bbatt += 4 * (rfatt - 2);
2567 } else if (rfatt > 4 && txctl) {
2578 pg->pg_txctl = txctl;
2579 bwn_phy_g_setatt(mac, &bbatt, &rfatt);
2580 pg->pg_rfatt.att = rfatt;
2581 pg->pg_bbatt.att = bbatt;
2583 DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
2587 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
2590 bwn_phy_unlock(mac);
2592 bwn_mac_enable(mac);
2596 bwn_phy_g_task_15s(struct bwn_mac *mac)
2598 struct bwn_phy *phy = &mac->mac_phy;
2599 struct bwn_phy_g *pg = &phy->phy_g;
2600 struct bwn_softc *sc = mac->mac_sc;
2601 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
2602 unsigned long expire, now;
2603 struct bwn_lo_calib *cal, *tmp;
2604 uint8_t expired = 0;
2606 bwn_mac_suspend(mac);
2612 if (bwn_has_hwpctl(mac)) {
2613 expire = now - BWN_LO_PWRVEC_EXPIRE;
2614 if (time_before(lo->pwr_vec_read_time, expire)) {
2615 bwn_lo_get_powervector(mac);
2616 bwn_phy_g_dc_lookup_init(mac, 0);
2621 expire = now - BWN_LO_CALIB_EXPIRE;
2622 TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
2623 if (!time_before(cal->calib_time, expire))
2625 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
2626 BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
2627 KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
2631 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
2632 cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
2633 cal->ctl.i, cal->ctl.q);
2635 TAILQ_REMOVE(&lo->calib_list, cal, list);
2636 free(cal, M_DEVBUF);
2638 if (expired || TAILQ_EMPTY(&lo->calib_list)) {
2639 cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
2642 device_printf(sc->sc_dev,
2643 "failed to recalibrate LO\n");
2646 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
2647 bwn_lo_write(mac, &cal->ctl);
2651 bwn_mac_enable(mac);
2655 bwn_phy_g_task_60s(struct bwn_mac *mac)
2657 struct bwn_phy *phy = &mac->mac_phy;
2658 struct bwn_softc *sc = mac->mac_sc;
2659 uint8_t old = phy->chan;
2661 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI))
2664 bwn_mac_suspend(mac);
2665 bwn_nrssi_slope_11g(mac);
2666 if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
2667 bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
2668 bwn_switch_channel(mac, old);
2670 bwn_mac_enable(mac);
2674 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
2677 BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
2681 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2682 const struct ieee80211_bpf_params *params)
2684 struct ieee80211com *ic = ni->ni_ic;
2685 struct bwn_softc *sc = ic->ic_softc;
2686 struct bwn_mac *mac = sc->sc_curmac;
2688 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 ||
2689 mac->mac_status < BWN_MAC_STATUS_STARTED) {
2690 ieee80211_free_node(ni);
2696 if (bwn_tx_isfull(sc, m)) {
2697 ieee80211_free_node(ni);
2703 if (bwn_tx_start(sc, ni, m) != 0) {
2705 ieee80211_free_node(ni);
2707 sc->sc_watchdog_timer = 5;
2713 * Callback from the 802.11 layer to update the slot time
2714 * based on the current setting. We use it to notify the
2715 * firmware of ERP changes and the f/w takes care of things
2716 * like slot time and preamble.
2719 bwn_updateslot(struct ieee80211com *ic)
2721 struct bwn_softc *sc = ic->ic_softc;
2722 struct bwn_mac *mac;
2725 if (sc->sc_flags & BWN_FLAG_RUNNING) {
2726 mac = (struct bwn_mac *)sc->sc_curmac;
2727 bwn_set_slot_time(mac,
2728 (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
2734 * Callback from the 802.11 layer after a promiscuous mode change.
2735 * Note this interface does not check the operating mode as this
2736 * is an internal callback and we are expected to honor the current
2737 * state (e.g. this is used for setting the interface in promiscuous
2738 * mode when operating in hostap mode to do ACS).
2741 bwn_update_promisc(struct ieee80211com *ic)
2743 struct bwn_softc *sc = ic->ic_softc;
2744 struct bwn_mac *mac = sc->sc_curmac;
2747 mac = sc->sc_curmac;
2748 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2749 if (ic->ic_promisc > 0)
2750 sc->sc_filters |= BWN_MACCTL_PROMISC;
2752 sc->sc_filters &= ~BWN_MACCTL_PROMISC;
2753 bwn_set_opmode(mac);
2759 * Callback from the 802.11 layer to update WME parameters.
2762 bwn_wme_update(struct ieee80211com *ic)
2764 struct bwn_softc *sc = ic->ic_softc;
2765 struct bwn_mac *mac = sc->sc_curmac;
2766 struct wmeParams *wmep;
2770 mac = sc->sc_curmac;
2771 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2772 bwn_mac_suspend(mac);
2773 for (i = 0; i < N(sc->sc_wmeParams); i++) {
2774 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2775 bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
2777 bwn_mac_enable(mac);
2784 bwn_scan_start(struct ieee80211com *ic)
2786 struct bwn_softc *sc = ic->ic_softc;
2787 struct bwn_mac *mac;
2790 mac = sc->sc_curmac;
2791 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2792 sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
2793 bwn_set_opmode(mac);
2794 /* disable CFP update during scan */
2795 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
2801 bwn_scan_end(struct ieee80211com *ic)
2803 struct bwn_softc *sc = ic->ic_softc;
2804 struct bwn_mac *mac;
2807 mac = sc->sc_curmac;
2808 if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
2809 sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
2810 bwn_set_opmode(mac);
2811 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
2817 bwn_set_channel(struct ieee80211com *ic)
2819 struct bwn_softc *sc = ic->ic_softc;
2820 struct bwn_mac *mac = sc->sc_curmac;
2821 struct bwn_phy *phy = &mac->mac_phy;
2826 error = bwn_switch_band(sc, ic->ic_curchan);
2829 bwn_mac_suspend(mac);
2830 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2831 chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2832 if (chan != phy->chan)
2833 bwn_switch_channel(mac, chan);
2835 /* TX power level */
2836 if (ic->ic_curchan->ic_maxpower != 0 &&
2837 ic->ic_curchan->ic_maxpower != phy->txpower) {
2838 phy->txpower = ic->ic_curchan->ic_maxpower / 2;
2839 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
2840 BWN_TXPWR_IGNORE_TSSI);
2843 bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2844 if (phy->set_antenna)
2845 phy->set_antenna(mac, BWN_ANT_DEFAULT);
2847 if (sc->sc_rf_enabled != phy->rf_on) {
2848 if (sc->sc_rf_enabled) {
2850 if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2851 device_printf(sc->sc_dev,
2852 "please turn on the RF switch\n");
2854 bwn_rf_turnoff(mac);
2857 bwn_mac_enable(mac);
2861 * Setup radio tap channel freq and flags
2863 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2864 htole16(ic->ic_curchan->ic_freq);
2865 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2866 htole16(ic->ic_curchan->ic_flags & 0xffff);
2871 static struct ieee80211vap *
2872 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
2873 enum ieee80211_opmode opmode, int flags,
2874 const uint8_t bssid[IEEE80211_ADDR_LEN],
2875 const uint8_t mac[IEEE80211_ADDR_LEN])
2877 struct ieee80211vap *vap;
2878 struct bwn_vap *bvp;
2881 case IEEE80211_M_HOSTAP:
2882 case IEEE80211_M_MBSS:
2883 case IEEE80211_M_STA:
2884 case IEEE80211_M_WDS:
2885 case IEEE80211_M_MONITOR:
2886 case IEEE80211_M_IBSS:
2887 case IEEE80211_M_AHDEMO:
2893 bvp = malloc(sizeof(struct bwn_vap), M_80211_VAP, M_WAITOK | M_ZERO);
2895 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
2896 /* override with driver methods */
2897 bvp->bv_newstate = vap->iv_newstate;
2898 vap->iv_newstate = bwn_newstate;
2900 /* override max aid so sta's cannot assoc when we're out of sta id's */
2901 vap->iv_max_aid = BWN_STAID_MAX;
2903 ieee80211_ratectl_init(vap);
2905 /* complete setup */
2906 ieee80211_vap_attach(vap, ieee80211_media_change,
2907 ieee80211_media_status, mac);
2912 bwn_vap_delete(struct ieee80211vap *vap)
2914 struct bwn_vap *bvp = BWN_VAP(vap);
2916 ieee80211_ratectl_deinit(vap);
2917 ieee80211_vap_detach(vap);
2918 free(bvp, M_80211_VAP);
2922 bwn_init(struct bwn_softc *sc)
2924 struct bwn_mac *mac;
2927 BWN_ASSERT_LOCKED(sc);
2929 bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
2930 sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
2933 sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
2934 sc->sc_rf_enabled = 1;
2936 mac = sc->sc_curmac;
2937 if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
2938 error = bwn_core_init(mac);
2942 if (mac->mac_status == BWN_MAC_STATUS_INITED)
2943 bwn_core_start(mac);
2945 bwn_set_opmode(mac);
2946 bwn_set_pretbtt(mac);
2947 bwn_spu_setdelay(mac, 0);
2948 bwn_set_macaddr(mac);
2950 sc->sc_flags |= BWN_FLAG_RUNNING;
2951 callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
2952 callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
2958 bwn_stop(struct bwn_softc *sc)
2960 struct bwn_mac *mac = sc->sc_curmac;
2962 BWN_ASSERT_LOCKED(sc);
2964 if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
2965 /* XXX FIXME opmode not based on VAP */
2966 bwn_set_opmode(mac);
2967 bwn_set_macaddr(mac);
2970 if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
2973 callout_stop(&sc->sc_led_blink_ch);
2974 sc->sc_led_blinking = 0;
2977 sc->sc_rf_enabled = 0;
2979 sc->sc_flags &= ~BWN_FLAG_RUNNING;
2983 bwn_wme_clear(struct bwn_softc *sc)
2985 #define MS(_v, _f) (((_v) & _f) >> _f##_S)
2986 struct wmeParams *p;
2989 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
2990 ("%s:%d: fail", __func__, __LINE__));
2992 for (i = 0; i < N(sc->sc_wmeParams); i++) {
2993 p = &(sc->sc_wmeParams[i]);
2995 switch (bwn_wme_shm_offsets[i]) {
2997 p->wmep_txopLimit = 0;
2999 /* XXX FIXME: log2(cwmin) */
3000 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3001 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3004 p->wmep_txopLimit = 0;
3006 /* XXX FIXME: log2(cwmin) */
3007 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3008 p->wmep_logcwmax = MS(0x0001, WME_PARAM_LOGCWMAX);
3010 case BWN_WME_BESTEFFORT:
3011 p->wmep_txopLimit = 0;
3013 /* XXX FIXME: log2(cwmin) */
3014 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3015 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3017 case BWN_WME_BACKGROUND:
3018 p->wmep_txopLimit = 0;
3020 /* XXX FIXME: log2(cwmin) */
3021 p->wmep_logcwmin = MS(0x0001, WME_PARAM_LOGCWMIN);
3022 p->wmep_logcwmax = MS(0x03ff, WME_PARAM_LOGCWMAX);
3025 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3031 bwn_core_init(struct bwn_mac *mac)
3033 struct bwn_softc *sc = mac->mac_sc;
3037 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3038 ("%s:%d: fail", __func__, __LINE__));
3040 siba_powerup(sc->sc_dev, 0);
3041 if (!siba_dev_isup(sc->sc_dev))
3043 mac->mac_phy.gmode ? BWN_TGSLOW_SUPPORT_G : 0);
3045 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
3046 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
3047 mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
3048 BWN_GETTIME(mac->mac_phy.nexttime);
3049 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
3050 bzero(&mac->mac_stats, sizeof(mac->mac_stats));
3051 mac->mac_stats.link_noise = -95;
3052 mac->mac_reason_intr = 0;
3053 bzero(mac->mac_reason, sizeof(mac->mac_reason));
3054 mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
3056 if (sc->sc_debug & BWN_DEBUG_XMIT)
3057 mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
3059 mac->mac_suspended = 1;
3060 mac->mac_task_state = 0;
3061 memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
3063 mac->mac_phy.init_pre(mac);
3065 siba_pcicore_intr(sc->sc_dev);
3067 siba_fix_imcfglobug(sc->sc_dev);
3068 bwn_bt_disable(mac);
3069 if (mac->mac_phy.prepare_hw) {
3070 error = mac->mac_phy.prepare_hw(mac);
3074 error = bwn_chip_init(mac);
3077 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
3078 siba_get_revid(sc->sc_dev));
3079 hf = bwn_hf_read(mac);
3080 if (mac->mac_phy.type == BWN_PHYTYPE_G) {
3081 hf |= BWN_HF_GPHY_SYM_WORKAROUND;
3082 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
3083 hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
3084 if (mac->mac_phy.rev == 1)
3085 hf |= BWN_HF_GPHY_DC_CANCELFILTER;
3087 if (mac->mac_phy.rf_ver == 0x2050) {
3088 if (mac->mac_phy.rf_rev < 6)
3089 hf |= BWN_HF_FORCE_VCO_RECALC;
3090 if (mac->mac_phy.rf_rev == 6)
3091 hf |= BWN_HF_4318_TSSI;
3093 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW)
3094 hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
3095 if ((siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) &&
3096 (siba_get_pcicore_revid(sc->sc_dev) <= 10))
3097 hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
3098 hf &= ~BWN_HF_SKIP_CFP_UPDATE;
3099 bwn_hf_write(mac, hf);
3101 bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
3102 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
3103 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
3104 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
3107 bwn_set_phytxctl(mac);
3109 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
3110 (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
3111 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
3113 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
3118 bwn_spu_setdelay(mac, 1);
3121 siba_powerup(sc->sc_dev,
3122 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_CRYSTAL_NOSLOW));
3123 bwn_set_macaddr(mac);
3124 bwn_crypt_init(mac);
3126 /* XXX LED initializatin */
3128 mac->mac_status = BWN_MAC_STATUS_INITED;
3133 siba_powerdown(sc->sc_dev);
3134 KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
3135 ("%s:%d: fail", __func__, __LINE__));
3140 bwn_core_start(struct bwn_mac *mac)
3142 struct bwn_softc *sc = mac->mac_sc;
3145 KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
3146 ("%s:%d: fail", __func__, __LINE__));
3148 if (siba_get_revid(sc->sc_dev) < 5)
3152 tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
3153 if (!(tmp & 0x00000001))
3155 tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
3158 bwn_mac_enable(mac);
3159 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
3160 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
3162 mac->mac_status = BWN_MAC_STATUS_STARTED;
3166 bwn_core_exit(struct bwn_mac *mac)
3168 struct bwn_softc *sc = mac->mac_sc;
3171 BWN_ASSERT_LOCKED(mac->mac_sc);
3173 KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
3174 ("%s:%d: fail", __func__, __LINE__));
3176 if (mac->mac_status != BWN_MAC_STATUS_INITED)
3178 mac->mac_status = BWN_MAC_STATUS_UNINIT;
3180 macctl = BWN_READ_4(mac, BWN_MACCTL);
3181 macctl &= ~BWN_MACCTL_MCODE_RUN;
3182 macctl |= BWN_MACCTL_MCODE_JMP0;
3183 BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3188 mac->mac_phy.switch_analog(mac, 0);
3189 siba_dev_down(sc->sc_dev, 0);
3190 siba_powerdown(sc->sc_dev);
3194 bwn_bt_disable(struct bwn_mac *mac)
3196 struct bwn_softc *sc = mac->mac_sc;
3199 /* XXX do nothing yet */
3203 bwn_chip_init(struct bwn_mac *mac)
3205 struct bwn_softc *sc = mac->mac_sc;
3206 struct bwn_phy *phy = &mac->mac_phy;
3210 macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
3212 macctl |= BWN_MACCTL_GMODE;
3213 BWN_WRITE_4(mac, BWN_MACCTL, macctl);
3215 error = bwn_fw_fillinfo(mac);
3218 error = bwn_fw_loaducode(mac);
3222 error = bwn_gpio_init(mac);
3226 error = bwn_fw_loadinitvals(mac);
3228 siba_gpio_set(sc->sc_dev, 0);
3231 phy->switch_analog(mac, 1);
3232 error = bwn_phy_init(mac);
3234 siba_gpio_set(sc->sc_dev, 0);
3238 phy->set_im(mac, BWN_IMMODE_NONE);
3239 if (phy->set_antenna)
3240 phy->set_antenna(mac, BWN_ANT_DEFAULT);
3241 bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
3243 if (phy->type == BWN_PHYTYPE_B)
3244 BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
3245 BWN_WRITE_4(mac, 0x0100, 0x01000000);
3246 if (siba_get_revid(sc->sc_dev) < 5)
3247 BWN_WRITE_4(mac, 0x010c, 0x01000000);
3249 BWN_WRITE_4(mac, BWN_MACCTL,
3250 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
3251 BWN_WRITE_4(mac, BWN_MACCTL,
3252 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
3253 bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
3255 bwn_set_opmode(mac);
3256 if (siba_get_revid(sc->sc_dev) < 3) {
3257 BWN_WRITE_2(mac, 0x060e, 0x0000);
3258 BWN_WRITE_2(mac, 0x0610, 0x8000);
3259 BWN_WRITE_2(mac, 0x0604, 0x0000);
3260 BWN_WRITE_2(mac, 0x0606, 0x0200);
3262 BWN_WRITE_4(mac, 0x0188, 0x80000000);
3263 BWN_WRITE_4(mac, 0x018c, 0x02000000);
3265 BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
3266 BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
3267 BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
3268 BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
3269 BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
3270 BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
3271 BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
3272 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
3273 siba_read_4(sc->sc_dev, SIBA_TGSLOW) | 0x00100000);
3274 BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev));
3278 /* read hostflags */
3280 bwn_hf_read(struct bwn_mac *mac)
3284 ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
3286 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
3288 ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
3293 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
3296 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
3297 (value & 0x00000000ffffull));
3298 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
3299 (value & 0x0000ffff0000ull) >> 16);
3300 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
3301 (value & 0xffff00000000ULL) >> 32);
3305 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
3308 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
3309 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
3313 bwn_rate_init(struct bwn_mac *mac)
3316 switch (mac->mac_phy.type) {
3319 case BWN_PHYTYPE_LP:
3321 bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
3322 bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
3323 bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
3324 bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
3325 bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
3326 bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
3327 bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
3328 if (mac->mac_phy.type == BWN_PHYTYPE_A)
3332 bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
3333 bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
3334 bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
3335 bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
3338 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3343 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
3349 offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
3352 offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
3354 bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
3355 bwn_shm_read_2(mac, BWN_SHARED, offset));
3359 bwn_plcp_getcck(const uint8_t bitrate)
3363 case BWN_CCK_RATE_1MB:
3365 case BWN_CCK_RATE_2MB:
3367 case BWN_CCK_RATE_5MB:
3369 case BWN_CCK_RATE_11MB:
3372 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3377 bwn_plcp_getofdm(const uint8_t bitrate)
3381 case BWN_OFDM_RATE_6MB:
3383 case BWN_OFDM_RATE_9MB:
3385 case BWN_OFDM_RATE_12MB:
3387 case BWN_OFDM_RATE_18MB:
3389 case BWN_OFDM_RATE_24MB:
3391 case BWN_OFDM_RATE_36MB:
3393 case BWN_OFDM_RATE_48MB:
3395 case BWN_OFDM_RATE_54MB:
3398 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3403 bwn_set_phytxctl(struct bwn_mac *mac)
3407 ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
3409 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
3410 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
3411 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
3415 bwn_pio_init(struct bwn_mac *mac)
3417 struct bwn_pio *pio = &mac->mac_method.pio;
3419 BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
3420 & ~BWN_MACCTL_BIGENDIAN);
3421 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
3423 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
3424 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
3425 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
3426 bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
3427 bwn_pio_set_txqueue(mac, &pio->mcast, 4);
3428 bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
3432 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3435 struct bwn_pio_txpkt *tp;
3436 struct bwn_softc *sc = mac->mac_sc;
3439 tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
3440 tq->tq_index = index;
3442 tq->tq_free = BWN_PIO_MAX_TXPACKETS;
3443 if (siba_get_revid(sc->sc_dev) >= 8)
3446 tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
3450 TAILQ_INIT(&tq->tq_pktlist);
3451 for (i = 0; i < N(tq->tq_pkts); i++) {
3452 tp = &(tq->tq_pkts[i]);
3455 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
3460 bwn_pio_idx2base(struct bwn_mac *mac, int index)
3462 struct bwn_softc *sc = mac->mac_sc;
3463 static const uint16_t bases[] = {
3473 static const uint16_t bases_rev11[] = {
3482 if (siba_get_revid(sc->sc_dev) >= 11) {
3483 if (index >= N(bases_rev11))
3484 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3485 return (bases_rev11[index]);
3487 if (index >= N(bases))
3488 device_printf(sc->sc_dev, "%s: warning\n", __func__);
3489 return (bases[index]);
3493 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
3496 struct bwn_softc *sc = mac->mac_sc;
3499 prq->prq_rev = siba_get_revid(sc->sc_dev);
3500 prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
3501 bwn_dma_rxdirectfifo(mac, index, 1);
3505 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
3509 bwn_pio_cancel_tx_packets(tq);
3513 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
3516 bwn_destroy_pioqueue_tx(pio);
3520 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
3524 return (BWN_READ_2(mac, tq->tq_base + offset));
3528 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
3534 type = bwn_dma_mask2type(bwn_dma_mask(mac));
3535 base = bwn_dma_base(type, idx);
3536 if (type == BWN_DMA_64BIT) {
3537 ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
3538 ctl &= ~BWN_DMA64_RXDIRECTFIFO;
3540 ctl |= BWN_DMA64_RXDIRECTFIFO;
3541 BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
3543 ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
3544 ctl &= ~BWN_DMA32_RXDIRECTFIFO;
3546 ctl |= BWN_DMA32_RXDIRECTFIFO;
3547 BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
3552 bwn_dma_mask(struct bwn_mac *mac)
3557 tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
3558 if (tmp & SIBA_TGSHIGH_DMA64)
3559 return (BWN_DMA_BIT_MASK(64));
3560 base = bwn_dma_base(0, 0);
3561 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
3562 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
3563 if (tmp & BWN_DMA32_TXADDREXT_MASK)
3564 return (BWN_DMA_BIT_MASK(32));
3566 return (BWN_DMA_BIT_MASK(30));
3570 bwn_dma_mask2type(uint64_t dmamask)
3573 if (dmamask == BWN_DMA_BIT_MASK(30))
3574 return (BWN_DMA_30BIT);
3575 if (dmamask == BWN_DMA_BIT_MASK(32))
3576 return (BWN_DMA_32BIT);
3577 if (dmamask == BWN_DMA_BIT_MASK(64))
3578 return (BWN_DMA_64BIT);
3579 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3580 return (BWN_DMA_30BIT);
3584 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
3586 struct bwn_pio_txpkt *tp;
3589 for (i = 0; i < N(tq->tq_pkts); i++) {
3590 tp = &(tq->tq_pkts[i]);
3599 bwn_dma_base(int type, int controller_idx)
3601 static const uint16_t map64[] = {
3609 static const uint16_t map32[] = {
3618 if (type == BWN_DMA_64BIT) {
3619 KASSERT(controller_idx >= 0 && controller_idx < N(map64),
3620 ("%s:%d: fail", __func__, __LINE__));
3621 return (map64[controller_idx]);
3623 KASSERT(controller_idx >= 0 && controller_idx < N(map32),
3624 ("%s:%d: fail", __func__, __LINE__));
3625 return (map32[controller_idx]);
3629 bwn_dma_init(struct bwn_mac *mac)
3631 struct bwn_dma *dma = &mac->mac_method.dma;
3633 /* setup TX DMA channels. */
3634 bwn_dma_setup(dma->wme[WME_AC_BK]);
3635 bwn_dma_setup(dma->wme[WME_AC_BE]);
3636 bwn_dma_setup(dma->wme[WME_AC_VI]);
3637 bwn_dma_setup(dma->wme[WME_AC_VO]);
3638 bwn_dma_setup(dma->mcast);
3639 /* setup RX DMA channel. */
3640 bwn_dma_setup(dma->rx);
3643 static struct bwn_dma_ring *
3644 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
3645 int for_tx, int type)
3647 struct bwn_dma *dma = &mac->mac_method.dma;
3648 struct bwn_dma_ring *dr;
3649 struct bwn_dmadesc_generic *desc;
3650 struct bwn_dmadesc_meta *mt;
3651 struct bwn_softc *sc = mac->mac_sc;
3654 dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO);
3657 dr->dr_numslots = BWN_RXRING_SLOTS;
3659 dr->dr_numslots = BWN_TXRING_SLOTS;
3661 dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
3662 M_DEVBUF, M_NOWAIT | M_ZERO);
3663 if (dr->dr_meta == NULL)
3668 dr->dr_base = bwn_dma_base(type, controller_index);
3669 dr->dr_index = controller_index;
3670 if (type == BWN_DMA_64BIT) {
3671 dr->getdesc = bwn_dma_64_getdesc;
3672 dr->setdesc = bwn_dma_64_setdesc;
3673 dr->start_transfer = bwn_dma_64_start_transfer;
3674 dr->suspend = bwn_dma_64_suspend;
3675 dr->resume = bwn_dma_64_resume;
3676 dr->get_curslot = bwn_dma_64_get_curslot;
3677 dr->set_curslot = bwn_dma_64_set_curslot;
3679 dr->getdesc = bwn_dma_32_getdesc;
3680 dr->setdesc = bwn_dma_32_setdesc;
3681 dr->start_transfer = bwn_dma_32_start_transfer;
3682 dr->suspend = bwn_dma_32_suspend;
3683 dr->resume = bwn_dma_32_resume;
3684 dr->get_curslot = bwn_dma_32_get_curslot;
3685 dr->set_curslot = bwn_dma_32_set_curslot;
3689 dr->dr_curslot = -1;
3691 if (dr->dr_index == 0) {
3692 dr->dr_rx_bufsize = BWN_DMA0_RX_BUFFERSIZE;
3693 dr->dr_frameoffset = BWN_DMA0_RX_FRAMEOFFSET;
3695 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3698 error = bwn_dma_allocringmemory(dr);
3704 * Assumption: BWN_TXRING_SLOTS can be divided by
3705 * BWN_TX_SLOTS_PER_FRAME
3707 KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
3708 ("%s:%d: fail", __func__, __LINE__));
3710 dr->dr_txhdr_cache =
3711 malloc((dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
3712 BWN_HDRSIZE(mac), M_DEVBUF, M_NOWAIT | M_ZERO);
3713 KASSERT(dr->dr_txhdr_cache != NULL,
3714 ("%s:%d: fail", __func__, __LINE__));
3717 * Create TX ring DMA stuffs
3719 error = bus_dma_tag_create(dma->parent_dtag,
3726 BUS_SPACE_MAXSIZE_32BIT,
3729 &dr->dr_txring_dtag);
3731 device_printf(sc->sc_dev,
3732 "can't create TX ring DMA tag: TODO frees\n");
3736 for (i = 0; i < dr->dr_numslots; i += 2) {
3737 dr->getdesc(dr, i, &desc, &mt);
3739 mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
3743 error = bus_dmamap_create(dr->dr_txring_dtag, 0,
3746 device_printf(sc->sc_dev,
3747 "can't create RX buf DMA map\n");
3751 dr->getdesc(dr, i + 1, &desc, &mt);
3753 mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
3757 error = bus_dmamap_create(dma->txbuf_dtag, 0,
3760 device_printf(sc->sc_dev,
3761 "can't create RX buf DMA map\n");
3766 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3767 &dr->dr_spare_dmap);
3769 device_printf(sc->sc_dev,
3770 "can't create RX buf DMA map\n");
3771 goto out; /* XXX wrong! */
3774 for (i = 0; i < dr->dr_numslots; i++) {
3775 dr->getdesc(dr, i, &desc, &mt);
3777 error = bus_dmamap_create(dma->rxbuf_dtag, 0,
3780 device_printf(sc->sc_dev,
3781 "can't create RX buf DMA map\n");
3782 goto out; /* XXX wrong! */
3784 error = bwn_dma_newbuf(dr, desc, mt, 1);
3786 device_printf(sc->sc_dev,
3787 "failed to allocate RX buf\n");
3788 goto out; /* XXX wrong! */
3792 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
3793 BUS_DMASYNC_PREWRITE);
3795 dr->dr_usedslot = dr->dr_numslots;
3802 free(dr->dr_txhdr_cache, M_DEVBUF);
3804 free(dr->dr_meta, M_DEVBUF);
3811 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3817 bwn_dma_free_descbufs(*dr);
3818 bwn_dma_free_ringmemory(*dr);
3820 free((*dr)->dr_txhdr_cache, M_DEVBUF);
3821 free((*dr)->dr_meta, M_DEVBUF);
3822 free(*dr, M_DEVBUF);
3828 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3829 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3831 struct bwn_dmadesc32 *desc;
3833 *meta = &(dr->dr_meta[slot]);
3834 desc = dr->dr_ring_descbase;
3835 desc = &(desc[slot]);
3837 *gdesc = (struct bwn_dmadesc_generic *)desc;
3841 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3842 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3843 int start, int end, int irq)
3845 struct bwn_dmadesc32 *descbase = dr->dr_ring_descbase;
3846 struct bwn_softc *sc = dr->dr_mac->mac_sc;
3847 uint32_t addr, addrext, ctl;
3850 slot = (int)(&(desc->dma.dma32) - descbase);
3851 KASSERT(slot >= 0 && slot < dr->dr_numslots,
3852 ("%s:%d: fail", __func__, __LINE__));
3854 addr = (uint32_t) (dmaaddr & ~SIBA_DMA_TRANSLATION_MASK);
3855 addrext = (uint32_t) (dmaaddr & SIBA_DMA_TRANSLATION_MASK) >> 30;
3856 addr |= siba_dma_translation(sc->sc_dev);
3857 ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3858 if (slot == dr->dr_numslots - 1)
3859 ctl |= BWN_DMA32_DCTL_DTABLEEND;
3861 ctl |= BWN_DMA32_DCTL_FRAMESTART;
3863 ctl |= BWN_DMA32_DCTL_FRAMEEND;
3865 ctl |= BWN_DMA32_DCTL_IRQ;
3866 ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3867 & BWN_DMA32_DCTL_ADDREXT_MASK;
3869 desc->dma.dma32.control = htole32(ctl);
3870 desc->dma.dma32.address = htole32(addr);
3874 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3877 BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3878 (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3882 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3885 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3886 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3890 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3893 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3894 BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
3898 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
3902 val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
3903 val &= BWN_DMA32_RXDPTR;
3905 return (val / sizeof(struct bwn_dmadesc32));
3909 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
3912 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
3913 (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
3917 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
3918 struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3920 struct bwn_dmadesc64 *desc;
3922 *meta = &(dr->dr_meta[slot]);
3923 desc = dr->dr_ring_descbase;
3924 desc = &(desc[slot]);
3926 *gdesc = (struct bwn_dmadesc_generic *)desc;
3930 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
3931 struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3932 int start, int end, int irq)
3934 struct bwn_dmadesc64 *descbase = dr->dr_ring_descbase;
3935 struct bwn_softc *sc = dr->dr_mac->mac_sc;
3937 uint32_t ctl0 = 0, ctl1 = 0;
3938 uint32_t addrlo, addrhi;
3941 slot = (int)(&(desc->dma.dma64) - descbase);
3942 KASSERT(slot >= 0 && slot < dr->dr_numslots,
3943 ("%s:%d: fail", __func__, __LINE__));
3945 addrlo = (uint32_t) (dmaaddr & 0xffffffff);
3946 addrhi = (((uint64_t) dmaaddr >> 32) & ~SIBA_DMA_TRANSLATION_MASK);
3947 addrext = (((uint64_t) dmaaddr >> 32) & SIBA_DMA_TRANSLATION_MASK) >>
3949 addrhi |= (siba_dma_translation(sc->sc_dev) << 1);
3950 if (slot == dr->dr_numslots - 1)
3951 ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
3953 ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
3955 ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
3957 ctl0 |= BWN_DMA64_DCTL0_IRQ;
3958 ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
3959 ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
3960 & BWN_DMA64_DCTL1_ADDREXT_MASK;
3962 desc->dma.dma64.control0 = htole32(ctl0);
3963 desc->dma.dma64.control1 = htole32(ctl1);
3964 desc->dma.dma64.address_low = htole32(addrlo);
3965 desc->dma.dma64.address_high = htole32(addrhi);
3969 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
3972 BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
3973 (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
3977 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
3980 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
3981 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
3985 bwn_dma_64_resume(struct bwn_dma_ring *dr)
3988 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
3989 BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
3993 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
3997 val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
3998 val &= BWN_DMA64_RXSTATDPTR;
4000 return (val / sizeof(struct bwn_dmadesc64));
4004 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
4007 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
4008 (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
4012 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
4014 struct bwn_mac *mac = dr->dr_mac;
4015 struct bwn_dma *dma = &mac->mac_method.dma;
4016 struct bwn_softc *sc = mac->mac_sc;
4019 error = bus_dma_tag_create(dma->parent_dtag,
4024 BWN_DMA_RINGMEMSIZE,
4026 BUS_SPACE_MAXSIZE_32BIT,
4031 device_printf(sc->sc_dev,
4032 "can't create TX ring DMA tag: TODO frees\n");
4036 error = bus_dmamem_alloc(dr->dr_ring_dtag,
4037 &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
4040 device_printf(sc->sc_dev,
4041 "can't allocate DMA mem: TODO frees\n");
4044 error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
4045 dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
4046 bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
4048 device_printf(sc->sc_dev,
4049 "can't load DMA mem: TODO free\n");
4057 bwn_dma_setup(struct bwn_dma_ring *dr)
4059 struct bwn_softc *sc = dr->dr_mac->mac_sc;
4061 uint32_t addrext, ring32, value;
4062 uint32_t trans = siba_dma_translation(sc->sc_dev);
4065 dr->dr_curslot = -1;
4067 if (dr->dr_type == BWN_DMA_64BIT) {
4068 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4069 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK)
4071 value = BWN_DMA64_TXENABLE;
4072 value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
4073 & BWN_DMA64_TXADDREXT_MASK;
4074 BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
4075 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO,
4076 (ring64 & 0xffffffff));
4077 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI,
4079 ~SIBA_DMA_TRANSLATION_MASK) | (trans << 1));
4081 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4082 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4083 value = BWN_DMA32_TXENABLE;
4084 value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
4085 & BWN_DMA32_TXADDREXT_MASK;
4086 BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
4087 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING,
4088 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4096 dr->dr_usedslot = dr->dr_numslots;
4098 if (dr->dr_type == BWN_DMA_64BIT) {
4099 ring64 = (uint64_t)(dr->dr_ring_dmabase);
4100 addrext = ((ring64 >> 32) & SIBA_DMA_TRANSLATION_MASK) >> 30;
4101 value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
4102 value |= BWN_DMA64_RXENABLE;
4103 value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
4104 & BWN_DMA64_RXADDREXT_MASK;
4105 BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
4106 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, (ring64 & 0xffffffff));
4107 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI,
4108 ((ring64 >> 32) & ~SIBA_DMA_TRANSLATION_MASK)
4110 BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
4111 sizeof(struct bwn_dmadesc64));
4113 ring32 = (uint32_t)(dr->dr_ring_dmabase);
4114 addrext = (ring32 & SIBA_DMA_TRANSLATION_MASK) >> 30;
4115 value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
4116 value |= BWN_DMA32_RXENABLE;
4117 value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
4118 & BWN_DMA32_RXADDREXT_MASK;
4119 BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
4120 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING,
4121 (ring32 & ~SIBA_DMA_TRANSLATION_MASK) | trans);
4122 BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
4123 sizeof(struct bwn_dmadesc32));
4128 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
4131 bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
4132 bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
4137 bwn_dma_cleanup(struct bwn_dma_ring *dr)
4141 bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4142 if (dr->dr_type == BWN_DMA_64BIT) {
4143 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
4144 BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
4146 BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
4148 bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
4149 if (dr->dr_type == BWN_DMA_64BIT) {
4150 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
4151 BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
4153 BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
4158 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
4160 struct bwn_dmadesc_generic *desc;
4161 struct bwn_dmadesc_meta *meta;
4162 struct bwn_mac *mac = dr->dr_mac;
4163 struct bwn_dma *dma = &mac->mac_method.dma;
4164 struct bwn_softc *sc = mac->mac_sc;
4167 if (!dr->dr_usedslot)
4169 for (i = 0; i < dr->dr_numslots; i++) {
4170 dr->getdesc(dr, i, &desc, &meta);
4172 if (meta->mt_m == NULL) {
4174 device_printf(sc->sc_dev, "%s: not TX?\n",
4179 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
4180 bus_dmamap_unload(dr->dr_txring_dtag,
4182 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
4183 bus_dmamap_unload(dma->txbuf_dtag,
4186 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
4187 bwn_dma_free_descbuf(dr, meta);
4192 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
4195 struct bwn_softc *sc = mac->mac_sc;
4200 for (i = 0; i < 10; i++) {
4201 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4203 value = BWN_READ_4(mac, base + offset);
4204 if (type == BWN_DMA_64BIT) {
4205 value &= BWN_DMA64_TXSTAT;
4206 if (value == BWN_DMA64_TXSTAT_DISABLED ||
4207 value == BWN_DMA64_TXSTAT_IDLEWAIT ||
4208 value == BWN_DMA64_TXSTAT_STOPPED)
4211 value &= BWN_DMA32_TXSTATE;
4212 if (value == BWN_DMA32_TXSTAT_DISABLED ||
4213 value == BWN_DMA32_TXSTAT_IDLEWAIT ||
4214 value == BWN_DMA32_TXSTAT_STOPPED)
4219 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXCTL : BWN_DMA32_TXCTL;
4220 BWN_WRITE_4(mac, base + offset, 0);
4221 for (i = 0; i < 10; i++) {
4222 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_TXSTATUS :
4224 value = BWN_READ_4(mac, base + offset);
4225 if (type == BWN_DMA_64BIT) {
4226 value &= BWN_DMA64_TXSTAT;
4227 if (value == BWN_DMA64_TXSTAT_DISABLED) {
4232 value &= BWN_DMA32_TXSTATE;
4233 if (value == BWN_DMA32_TXSTAT_DISABLED) {
4241 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4250 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
4253 struct bwn_softc *sc = mac->mac_sc;
4258 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXCTL : BWN_DMA32_RXCTL;
4259 BWN_WRITE_4(mac, base + offset, 0);
4260 for (i = 0; i < 10; i++) {
4261 offset = (type == BWN_DMA_64BIT) ? BWN_DMA64_RXSTATUS :
4263 value = BWN_READ_4(mac, base + offset);
4264 if (type == BWN_DMA_64BIT) {
4265 value &= BWN_DMA64_RXSTAT;
4266 if (value == BWN_DMA64_RXSTAT_DISABLED) {
4271 value &= BWN_DMA32_RXSTATE;
4272 if (value == BWN_DMA32_RXSTAT_DISABLED) {
4280 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
4288 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
4289 struct bwn_dmadesc_meta *meta)
4292 if (meta->mt_m != NULL) {
4293 m_freem(meta->mt_m);
4296 if (meta->mt_ni != NULL) {
4297 ieee80211_free_node(meta->mt_ni);
4303 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4305 struct bwn_rxhdr4 *rxhdr;
4306 unsigned char *frame;
4308 rxhdr = mtod(m, struct bwn_rxhdr4 *);
4309 rxhdr->frame_len = 0;
4311 KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
4312 sizeof(struct bwn_plcp6) + 2,
4313 ("%s:%d: fail", __func__, __LINE__));
4314 frame = mtod(m, char *) + dr->dr_frameoffset;
4315 memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
4319 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
4321 unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
4323 return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
4328 bwn_wme_init(struct bwn_mac *mac)
4333 /* enable WME support. */
4334 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
4335 BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
4336 BWN_IFSCTL_USE_EDCF);
4340 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
4342 struct bwn_softc *sc = mac->mac_sc;
4343 struct ieee80211com *ic = &sc->sc_ic;
4344 uint16_t delay; /* microsec */
4346 delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
4347 if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
4349 if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
4350 delay = max(delay, (uint16_t)2400);
4352 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
4356 bwn_bt_enable(struct bwn_mac *mac)
4358 struct bwn_softc *sc = mac->mac_sc;
4361 if (bwn_bluetooth == 0)
4363 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCOEXIST) == 0)
4365 if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
4368 hf = bwn_hf_read(mac);
4369 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_BTCMOD)
4370 hf |= BWN_HF_BT_COEXISTALT;
4372 hf |= BWN_HF_BT_COEXIST;
4373 bwn_hf_write(mac, hf);
4377 bwn_set_macaddr(struct bwn_mac *mac)
4380 bwn_mac_write_bssid(mac);
4381 bwn_mac_setfilter(mac, BWN_MACFILTER_SELF,
4382 mac->mac_sc->sc_ic.ic_macaddr);
4386 bwn_clear_keys(struct bwn_mac *mac)
4390 for (i = 0; i < mac->mac_max_nr_keys; i++) {
4391 KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
4392 ("%s:%d: fail", __func__, __LINE__));
4394 bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
4395 NULL, BWN_SEC_KEYSIZE, NULL);
4396 if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
4397 bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
4398 NULL, BWN_SEC_KEYSIZE, NULL);
4400 mac->mac_key[i].keyconf = NULL;
4405 bwn_crypt_init(struct bwn_mac *mac)
4407 struct bwn_softc *sc = mac->mac_sc;
4409 mac->mac_max_nr_keys = (siba_get_revid(sc->sc_dev) >= 5) ? 58 : 20;
4410 KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
4411 ("%s:%d: fail", __func__, __LINE__));
4412 mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
4414 if (siba_get_revid(sc->sc_dev) >= 5)
4415 BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
4416 bwn_clear_keys(mac);
4420 bwn_chip_exit(struct bwn_mac *mac)
4422 struct bwn_softc *sc = mac->mac_sc;
4425 siba_gpio_set(sc->sc_dev, 0);
4429 bwn_fw_fillinfo(struct bwn_mac *mac)
4433 error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
4436 error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
4443 bwn_gpio_init(struct bwn_mac *mac)
4445 struct bwn_softc *sc = mac->mac_sc;
4446 uint32_t mask = 0x1f, set = 0xf, value;
4448 BWN_WRITE_4(mac, BWN_MACCTL,
4449 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
4450 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4451 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x000f);
4453 if (siba_get_chipid(sc->sc_dev) == 0x4301) {
4457 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL) {
4458 BWN_WRITE_2(mac, BWN_GPIO_MASK,
4459 BWN_READ_2(mac, BWN_GPIO_MASK) | 0x0200);
4463 if (siba_get_revid(sc->sc_dev) >= 2)
4466 value = siba_gpio_get(sc->sc_dev);
4469 siba_gpio_set(sc->sc_dev, (value & mask) | set);
4475 bwn_fw_loadinitvals(struct bwn_mac *mac)
4477 #define GETFWOFFSET(fwp, offset) \
4478 ((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
4479 const size_t hdr_len = sizeof(struct bwn_fwhdr);
4480 const struct bwn_fwhdr *hdr;
4481 struct bwn_fw *fw = &mac->mac_fw;
4484 hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
4485 error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
4486 be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
4489 if (fw->initvals_band.fw) {
4490 hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
4491 error = bwn_fwinitvals_write(mac,
4492 GETFWOFFSET(fw->initvals_band, hdr_len),
4494 fw->initvals_band.fw->datasize - hdr_len);
4501 bwn_phy_init(struct bwn_mac *mac)
4503 struct bwn_softc *sc = mac->mac_sc;
4506 mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
4507 mac->mac_phy.rf_onoff(mac, 1);
4508 error = mac->mac_phy.init(mac);
4510 device_printf(sc->sc_dev, "PHY init failed\n");
4513 error = bwn_switch_channel(mac,
4514 mac->mac_phy.get_default_chan(mac));
4516 device_printf(sc->sc_dev,
4517 "failed to switch default channel\n");
4522 if (mac->mac_phy.exit)
4523 mac->mac_phy.exit(mac);
4525 mac->mac_phy.rf_onoff(mac, 0);
4531 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
4536 ant = bwn_ant2phy(antenna);
4539 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
4540 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4541 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
4542 /* For Probe Resposes */
4543 tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
4544 tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
4545 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
4549 bwn_set_opmode(struct bwn_mac *mac)
4551 struct bwn_softc *sc = mac->mac_sc;
4552 struct ieee80211com *ic = &sc->sc_ic;
4554 uint16_t cfp_pretbtt;
4556 ctl = BWN_READ_4(mac, BWN_MACCTL);
4557 ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
4558 BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
4559 BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
4560 ctl |= BWN_MACCTL_STA;
4562 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
4563 ic->ic_opmode == IEEE80211_M_MBSS)
4564 ctl |= BWN_MACCTL_HOSTAP;
4565 else if (ic->ic_opmode == IEEE80211_M_IBSS)
4566 ctl &= ~BWN_MACCTL_STA;
4567 ctl |= sc->sc_filters;
4569 if (siba_get_revid(sc->sc_dev) <= 4)
4570 ctl |= BWN_MACCTL_PROMISC;
4572 BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4575 if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
4576 if (siba_get_chipid(sc->sc_dev) == 0x4306 &&
4577 siba_get_chiprev(sc->sc_dev) == 3)
4582 BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
4586 bwn_dma_gettype(struct bwn_mac *mac)
4591 tmp = BWN_READ_4(mac, SIBA_TGSHIGH);
4592 if (tmp & SIBA_TGSHIGH_DMA64)
4593 return (BWN_DMA_64BIT);
4594 base = bwn_dma_base(0, 0);
4595 BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, BWN_DMA32_TXADDREXT_MASK);
4596 tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
4597 if (tmp & BWN_DMA32_TXADDREXT_MASK)
4598 return (BWN_DMA_32BIT);
4600 return (BWN_DMA_30BIT);
4604 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
4607 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
4608 *((bus_addr_t *)arg) = seg->ds_addr;
4613 bwn_phy_g_init_sub(struct bwn_mac *mac)
4615 struct bwn_phy *phy = &mac->mac_phy;
4616 struct bwn_phy_g *pg = &phy->phy_g;
4617 struct bwn_softc *sc = mac->mac_sc;
4621 bwn_phy_init_b5(mac);
4623 bwn_phy_init_b6(mac);
4625 if (phy->rev >= 2 || phy->gmode)
4626 bwn_phy_init_a(mac);
4628 if (phy->rev >= 2) {
4629 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
4630 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
4632 if (phy->rev == 2) {
4633 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
4634 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4637 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
4638 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
4640 if (phy->gmode || phy->rev >= 2) {
4641 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
4642 tmp &= BWN_PHYVER_VERSION;
4643 if (tmp == 3 || tmp == 5) {
4644 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
4645 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
4648 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
4652 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
4653 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
4654 if (phy->rf_rev == 8) {
4655 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
4656 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
4658 if (BWN_HAS_LOOPBACK(phy))
4659 bwn_loopback_calcgain(mac);
4661 if (phy->rf_rev != 8) {
4662 if (pg->pg_initval == 0xffff)
4663 pg->pg_initval = bwn_rf_init_bcm2050(mac);
4665 BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
4668 if (BWN_HAS_TXMAG(phy)) {
4669 BWN_RF_WRITE(mac, 0x52,
4670 (BWN_RF_READ(mac, 0x52) & 0xff00)
4671 | pg->pg_loctl.tx_bias |
4672 pg->pg_loctl.tx_magn);
4674 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
4676 if (phy->rev >= 6) {
4677 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
4678 (pg->pg_loctl.tx_bias << 12));
4680 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL)
4681 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
4683 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
4685 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
4687 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
4688 if (phy->gmode || phy->rev >= 2) {
4689 bwn_lo_g_adjust(mac);
4690 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
4693 if (!(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
4694 for (i = 0; i < 64; i++) {
4695 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
4696 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
4697 (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
4700 bwn_nrssi_threshold(mac);
4701 } else if (phy->gmode || phy->rev >= 2) {
4702 if (pg->pg_nrssi[0] == -1000) {
4703 KASSERT(pg->pg_nrssi[1] == -1000,
4704 ("%s:%d: fail", __func__, __LINE__));
4705 bwn_nrssi_slope_11g(mac);
4707 bwn_nrssi_threshold(mac);
4709 if (phy->rf_rev == 8)
4710 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
4711 bwn_phy_hwpctl_init(mac);
4712 if ((siba_get_chipid(sc->sc_dev) == 0x4306
4713 && siba_get_chippkg(sc->sc_dev) == 2) || 0) {
4714 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
4715 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
4720 bwn_has_hwpctl(struct bwn_mac *mac)
4723 if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
4725 return (mac->mac_phy.use_hwpctl(mac));
4729 bwn_phy_init_b5(struct bwn_mac *mac)
4731 struct bwn_phy *phy = &mac->mac_phy;
4732 struct bwn_phy_g *pg = &phy->phy_g;
4733 struct bwn_softc *sc = mac->mac_sc;
4734 uint16_t offset, value;
4735 uint8_t old_channel;
4737 if (phy->analog == 1)
4738 BWN_RF_SET(mac, 0x007a, 0x0050);
4739 if ((siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) &&
4740 (siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306)) {
4742 for (offset = 0x00a8; offset < 0x00c7; offset++) {
4743 BWN_PHY_WRITE(mac, offset, value);
4747 BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
4748 if (phy->rf_ver == 0x2050)
4749 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
4751 if (phy->gmode || phy->rev >= 2) {
4752 if (phy->rf_ver == 0x2050) {
4753 BWN_RF_SET(mac, 0x007a, 0x0020);
4754 BWN_RF_SET(mac, 0x0051, 0x0004);
4756 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
4758 BWN_PHY_SET(mac, 0x0802, 0x0100);
4759 BWN_PHY_SET(mac, 0x042b, 0x2000);
4761 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
4763 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
4764 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
4765 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
4768 if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
4769 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
4771 if (phy->analog == 1) {
4772 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
4773 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
4774 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
4775 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
4776 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
4778 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
4779 BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
4780 BWN_WRITE_2(mac, 0x03ec, 0x3f22);
4782 if (phy->analog == 1)
4783 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
4785 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
4787 if (phy->analog == 0)
4788 BWN_WRITE_2(mac, 0x03e4, 0x3000);
4790 old_channel = phy->chan;
4791 bwn_phy_g_switch_chan(mac, 7, 0);
4793 if (phy->rf_ver != 0x2050) {
4794 BWN_RF_WRITE(mac, 0x0075, 0x0080);
4795 BWN_RF_WRITE(mac, 0x0079, 0x0081);
4798 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4799 BWN_RF_WRITE(mac, 0x0050, 0x0023);
4801 if (phy->rf_ver == 0x2050) {
4802 BWN_RF_WRITE(mac, 0x0050, 0x0020);
4803 BWN_RF_WRITE(mac, 0x005a, 0x0070);
4806 BWN_RF_WRITE(mac, 0x005b, 0x007b);
4807 BWN_RF_WRITE(mac, 0x005c, 0x00b0);
4808 BWN_RF_SET(mac, 0x007a, 0x0007);
4810 bwn_phy_g_switch_chan(mac, old_channel, 0);
4811 BWN_PHY_WRITE(mac, 0x0014, 0x0080);
4812 BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
4813 BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
4815 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
4818 if (phy->rf_ver == 0x2050)
4819 BWN_RF_WRITE(mac, 0x005d, 0x000d);
4821 BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
4825 bwn_loopback_calcgain(struct bwn_mac *mac)
4827 struct bwn_phy *phy = &mac->mac_phy;
4828 struct bwn_phy_g *pg = &phy->phy_g;
4829 struct bwn_softc *sc = mac->mac_sc;
4830 uint16_t backup_phy[16] = { 0 };
4831 uint16_t backup_radio[3];
4832 uint16_t backup_bband;
4833 uint16_t i, j, loop_i_max;
4835 uint16_t loop1_outer_done, loop1_inner_done;
4837 backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
4838 backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
4839 backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
4840 backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
4841 if (phy->rev != 1) {
4842 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
4843 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
4845 backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
4846 backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
4847 backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
4848 backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
4849 backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
4850 backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
4851 backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
4852 backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
4853 backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
4854 backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
4855 backup_bband = pg->pg_bbatt.att;
4856 backup_radio[0] = BWN_RF_READ(mac, 0x52);
4857 backup_radio[1] = BWN_RF_READ(mac, 0x43);
4858 backup_radio[2] = BWN_RF_READ(mac, 0x7a);
4860 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
4861 BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
4862 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
4863 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
4864 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
4865 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
4866 if (phy->rev != 1) {
4867 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
4868 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
4869 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
4870 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
4872 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
4873 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
4874 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
4875 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
4877 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
4878 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
4879 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
4881 BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
4882 if (phy->rev != 1) {
4883 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
4884 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
4886 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
4888 if (phy->rf_rev == 8)
4889 BWN_RF_WRITE(mac, 0x43, 0x000f);
4891 BWN_RF_WRITE(mac, 0x52, 0);
4892 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
4894 bwn_phy_g_set_bbatt(mac, 11);
4897 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
4899 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
4900 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
4902 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
4903 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
4905 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
4906 BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
4908 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) {
4909 if (phy->rev >= 7) {
4910 BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
4911 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
4914 BWN_RF_MASK(mac, 0x7a, 0x00f7);
4917 loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
4918 for (i = 0; i < loop_i_max; i++) {
4919 for (j = 0; j < 16; j++) {
4920 BWN_RF_WRITE(mac, 0x43, i);
4921 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
4923 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4924 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4926 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4931 loop1_outer_done = i;
4932 loop1_inner_done = j;
4934 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
4936 for (j = j - 8; j < 16; j++) {
4937 BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
4938 BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
4939 BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
4942 if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
4949 if (phy->rev != 1) {
4950 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
4951 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
4953 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
4954 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
4955 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
4956 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
4957 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
4958 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
4959 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
4960 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
4961 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
4963 bwn_phy_g_set_bbatt(mac, backup_bband);
4965 BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
4966 BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
4967 BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
4969 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
4971 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
4972 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
4973 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
4974 BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
4976 pg->pg_max_lb_gain =
4977 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
4978 pg->pg_trsw_rx_gain = trsw_rx * 2;
4982 bwn_rf_init_bcm2050(struct bwn_mac *mac)
4984 struct bwn_phy *phy = &mac->mac_phy;
4985 uint32_t tmp1 = 0, tmp2 = 0;
4986 uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
4987 analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
4988 radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
4989 static const uint8_t rcc_table[] = {
4990 0x02, 0x03, 0x01, 0x0f,
4991 0x06, 0x07, 0x05, 0x0f,
4992 0x0a, 0x0b, 0x09, 0x0f,
4993 0x0e, 0x0f, 0x0d, 0x0f,
4996 loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
4997 rfoverval = rfover = cck3 = 0;
4998 radio0 = BWN_RF_READ(mac, 0x43);
4999 radio1 = BWN_RF_READ(mac, 0x51);
5000 radio2 = BWN_RF_READ(mac, 0x52);
5001 pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
5002 cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
5003 cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
5004 cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
5006 if (phy->type == BWN_PHYTYPE_B) {
5007 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
5008 reg0 = BWN_READ_2(mac, 0x3ec);
5010 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
5011 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
5012 } else if (phy->gmode || phy->rev >= 2) {
5013 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
5014 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
5015 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
5016 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
5017 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
5018 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
5020 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
5021 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
5022 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
5023 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
5024 if (BWN_HAS_LOOPBACK(phy)) {
5025 lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
5026 loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
5028 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
5030 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
5031 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
5034 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5035 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5037 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
5038 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
5040 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
5042 syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
5043 BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
5044 reg1 = BWN_READ_2(mac, 0x3e6);
5045 reg2 = BWN_READ_2(mac, 0x3f4);
5047 if (phy->analog == 0)
5048 BWN_WRITE_2(mac, 0x03e6, 0x0122);
5050 if (phy->analog >= 2)
5051 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
5052 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
5053 (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
5056 reg = BWN_RF_READ(mac, 0x60);
5057 index = (reg & 0x001e) >> 1;
5058 rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
5060 if (phy->type == BWN_PHYTYPE_B)
5061 BWN_RF_WRITE(mac, 0x78, 0x26);
5062 if (phy->gmode || phy->rev >= 2) {
5063 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5064 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5067 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
5068 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
5069 if (phy->gmode || phy->rev >= 2) {
5070 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5071 bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
5074 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
5075 BWN_RF_SET(mac, 0x51, 0x0004);
5076 if (phy->rf_rev == 8)
5077 BWN_RF_WRITE(mac, 0x43, 0x1f);
5079 BWN_RF_WRITE(mac, 0x52, 0);
5080 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
5082 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5084 for (i = 0; i < 16; i++) {
5085 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
5086 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5087 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5088 if (phy->gmode || phy->rev >= 2) {
5089 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5090 bwn_rf_2050_rfoverval(mac,
5091 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5093 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5095 if (phy->gmode || phy->rev >= 2) {
5096 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5097 bwn_rf_2050_rfoverval(mac,
5098 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5100 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5102 if (phy->gmode || phy->rev >= 2) {
5103 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5104 bwn_rf_2050_rfoverval(mac,
5105 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5107 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5109 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5110 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5111 if (phy->gmode || phy->rev >= 2) {
5112 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5113 bwn_rf_2050_rfoverval(mac,
5114 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5116 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5120 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5124 for (i = 0; i < 16; i++) {
5125 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
5126 BWN_RF_WRITE(mac, 0x78, radio78);
5128 for (j = 0; j < 16; j++) {
5129 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
5130 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
5131 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
5132 if (phy->gmode || phy->rev >= 2) {
5133 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5134 bwn_rf_2050_rfoverval(mac,
5135 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5137 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5139 if (phy->gmode || phy->rev >= 2) {
5140 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5141 bwn_rf_2050_rfoverval(mac,
5142 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5144 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
5146 if (phy->gmode || phy->rev >= 2) {
5147 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5148 bwn_rf_2050_rfoverval(mac,
5149 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
5151 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
5153 tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5154 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
5155 if (phy->gmode || phy->rev >= 2) {
5156 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
5157 bwn_rf_2050_rfoverval(mac,
5158 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
5160 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
5168 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
5169 BWN_RF_WRITE(mac, 0x51, radio1);
5170 BWN_RF_WRITE(mac, 0x52, radio2);
5171 BWN_RF_WRITE(mac, 0x43, radio0);
5172 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
5173 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
5174 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
5175 BWN_WRITE_2(mac, 0x3e6, reg1);
5176 if (phy->analog != 0)
5177 BWN_WRITE_2(mac, 0x3f4, reg2);
5178 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
5179 bwn_spu_workaround(mac, phy->chan);
5180 if (phy->type == BWN_PHYTYPE_B) {
5181 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
5182 BWN_WRITE_2(mac, 0x3ec, reg0);
5183 } else if (phy->gmode) {
5184 BWN_WRITE_2(mac, BWN_PHY_RADIO,
5185 BWN_READ_2(mac, BWN_PHY_RADIO)
5187 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
5188 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
5189 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
5190 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
5192 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
5193 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
5194 if (BWN_HAS_LOOPBACK(phy)) {
5195 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
5196 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
5200 return ((i > 15) ? radio78 : rcc);
5204 bwn_phy_init_b6(struct bwn_mac *mac)
5206 struct bwn_phy *phy = &mac->mac_phy;
5207 struct bwn_phy_g *pg = &phy->phy_g;
5208 struct bwn_softc *sc = mac->mac_sc;
5209 uint16_t offset, val;
5210 uint8_t old_channel;
5212 KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
5213 ("%s:%d: fail", __func__, __LINE__));
5215 BWN_PHY_WRITE(mac, 0x003e, 0x817a);
5216 BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
5217 if (phy->rf_rev == 4 || phy->rf_rev == 5) {
5218 BWN_RF_WRITE(mac, 0x51, 0x37);
5219 BWN_RF_WRITE(mac, 0x52, 0x70);
5220 BWN_RF_WRITE(mac, 0x53, 0xb3);
5221 BWN_RF_WRITE(mac, 0x54, 0x9b);
5222 BWN_RF_WRITE(mac, 0x5a, 0x88);
5223 BWN_RF_WRITE(mac, 0x5b, 0x88);
5224 BWN_RF_WRITE(mac, 0x5d, 0x88);
5225 BWN_RF_WRITE(mac, 0x5e, 0x88);
5226 BWN_RF_WRITE(mac, 0x7d, 0x88);
5228 bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
5230 if (phy->rf_rev == 8) {
5231 BWN_RF_WRITE(mac, 0x51, 0);
5232 BWN_RF_WRITE(mac, 0x52, 0x40);
5233 BWN_RF_WRITE(mac, 0x53, 0xb7);
5234 BWN_RF_WRITE(mac, 0x54, 0x98);
5235 BWN_RF_WRITE(mac, 0x5a, 0x88);
5236 BWN_RF_WRITE(mac, 0x5b, 0x6b);
5237 BWN_RF_WRITE(mac, 0x5c, 0x0f);
5238 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_ALTIQ) {
5239 BWN_RF_WRITE(mac, 0x5d, 0xfa);
5240 BWN_RF_WRITE(mac, 0x5e, 0xd8);
5242 BWN_RF_WRITE(mac, 0x5d, 0xf5);
5243 BWN_RF_WRITE(mac, 0x5e, 0xb8);
5245 BWN_RF_WRITE(mac, 0x0073, 0x0003);
5246 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
5247 BWN_RF_WRITE(mac, 0x007c, 0x0001);
5248 BWN_RF_WRITE(mac, 0x007e, 0x0008);
5250 for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
5251 BWN_PHY_WRITE(mac, offset, val);
5254 for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
5255 BWN_PHY_WRITE(mac, offset, val);
5258 for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
5259 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
5262 if (phy->type == BWN_PHYTYPE_G) {
5263 BWN_RF_SET(mac, 0x007a, 0x0020);
5264 BWN_RF_SET(mac, 0x0051, 0x0004);
5265 BWN_PHY_SET(mac, 0x0802, 0x0100);
5266 BWN_PHY_SET(mac, 0x042b, 0x2000);
5267 BWN_PHY_WRITE(mac, 0x5b, 0);
5268 BWN_PHY_WRITE(mac, 0x5c, 0);
5271 old_channel = phy->chan;
5272 bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
5274 BWN_RF_WRITE(mac, 0x0050, 0x0020);
5275 BWN_RF_WRITE(mac, 0x0050, 0x0023);
5277 if (phy->rf_rev < 6 || phy->rf_rev == 8) {
5278 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
5279 BWN_RF_WRITE(mac, 0x50, 0x20);
5281 if (phy->rf_rev <= 2) {
5282 BWN_RF_WRITE(mac, 0x7c, 0x20);
5283 BWN_RF_WRITE(mac, 0x5a, 0x70);
5284 BWN_RF_WRITE(mac, 0x5b, 0x7b);
5285 BWN_RF_WRITE(mac, 0x5c, 0xb0);
5287 BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
5289 bwn_phy_g_switch_chan(mac, old_channel, 0);
5291 BWN_PHY_WRITE(mac, 0x0014, 0x0200);
5292 if (phy->rf_rev >= 6)
5293 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
5295 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
5296 BWN_PHY_WRITE(mac, 0x0038, 0x0668);
5297 bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
5299 if (phy->rf_rev <= 5)
5300 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
5301 if (phy->rf_rev <= 2)
5302 BWN_RF_WRITE(mac, 0x005d, 0x000d);
5304 if (phy->analog == 4) {
5305 BWN_WRITE_2(mac, 0x3e4, 9);
5306 BWN_PHY_MASK(mac, 0x61, 0x0fff);
5308 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
5309 if (phy->type == BWN_PHYTYPE_B)
5310 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5311 else if (phy->type == BWN_PHYTYPE_G)
5312 BWN_WRITE_2(mac, 0x03e6, 0x0);
5316 bwn_phy_init_a(struct bwn_mac *mac)
5318 struct bwn_phy *phy = &mac->mac_phy;
5319 struct bwn_softc *sc = mac->mac_sc;
5321 KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
5322 ("%s:%d: fail", __func__, __LINE__));
5324 if (phy->rev >= 6) {
5325 if (phy->type == BWN_PHYTYPE_A)
5326 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
5327 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
5328 BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
5330 BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
5335 if (phy->type == BWN_PHYTYPE_G &&
5336 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_PACTRL))
5337 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
5341 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
5345 for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
5346 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
5350 bwn_wa_agc(struct bwn_mac *mac)
5352 struct bwn_phy *phy = &mac->mac_phy;
5354 if (phy->rev == 1) {
5355 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
5356 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
5357 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
5358 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
5359 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
5360 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
5361 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
5362 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
5363 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
5365 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
5366 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
5367 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
5368 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
5371 BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
5373 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
5374 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
5375 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
5376 BWN_RF_SET(mac, 0x7a, 0x0008);
5377 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
5378 BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
5379 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
5380 BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
5382 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
5383 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
5384 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
5385 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
5386 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
5387 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
5388 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
5389 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
5390 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
5391 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
5392 if (phy->rev == 1) {
5393 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
5394 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
5396 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
5397 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
5398 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
5399 if (phy->rev >= 6) {
5400 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
5401 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
5402 (uint16_t)~0xf000, 0x3000);
5405 BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
5406 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
5407 if (phy->rev == 1) {
5408 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
5409 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
5410 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
5411 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
5412 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
5413 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
5414 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
5415 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
5417 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
5418 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
5419 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
5420 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
5422 if (phy->rev >= 6) {
5423 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
5424 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
5426 BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
5430 bwn_wa_grev1(struct bwn_mac *mac)
5432 struct bwn_phy *phy = &mac->mac_phy;
5434 static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
5435 static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
5436 static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
5438 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5440 /* init CRSTHRES and ANTDWELL */
5441 if (phy->rev == 1) {
5442 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5443 } else if (phy->rev == 2) {
5444 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5445 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5446 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5448 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5449 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5450 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5451 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5453 BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
5454 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
5455 BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
5457 /* XXX support PHY-A??? */
5458 for (i = 0; i < N(bwn_tab_finefreqg); i++)
5459 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
5460 bwn_tab_finefreqg[i]);
5462 /* XXX support PHY-A??? */
5464 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5465 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5466 bwn_tab_noise_g1[i]);
5468 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5469 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5470 bwn_tab_noise_g2[i]);
5473 for (i = 0; i < N(bwn_tab_rotor); i++)
5474 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
5477 /* XXX support PHY-A??? */
5478 if (phy->rev >= 6) {
5479 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5481 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5483 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5485 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5487 for (i = 0; i < N(bwn_tab_retard); i++)
5488 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
5491 if (phy->rev == 1) {
5492 for (i = 0; i < 16; i++)
5493 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
5496 for (i = 0; i < 32; i++)
5497 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5504 bwn_wa_grev26789(struct bwn_mac *mac)
5506 struct bwn_phy *phy = &mac->mac_phy;
5508 static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
5511 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5513 bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
5515 /* init CRSTHRES and ANTDWELL */
5517 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
5518 else if (phy->rev == 2) {
5519 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
5520 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
5521 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5523 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
5524 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
5525 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
5526 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
5529 for (i = 0; i < 64; i++)
5530 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
5532 /* XXX support PHY-A??? */
5534 for (i = 0; i < N(bwn_tab_noise_g1); i++)
5535 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5536 bwn_tab_noise_g1[i]);
5538 for (i = 0; i < N(bwn_tab_noise_g2); i++)
5539 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
5540 bwn_tab_noise_g2[i]);
5542 /* XXX support PHY-A??? */
5543 if (phy->rev >= 6) {
5544 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
5546 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
5548 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
5550 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
5552 for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
5553 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
5554 bwn_tab_sigmasqr2[i]);
5556 if (phy->rev == 1) {
5557 for (i = 0; i < 16; i++)
5558 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
5561 for (i = 0; i < 32; i++)
5562 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
5567 ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
5569 if (phy->type == BWN_PHYTYPE_A)
5570 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
5572 BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
5574 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
5575 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
5576 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
5579 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
5580 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
5584 bwn_wa_init(struct bwn_mac *mac)
5586 struct bwn_phy *phy = &mac->mac_phy;
5587 struct bwn_softc *sc = mac->mac_sc;
5589 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
5600 bwn_wa_grev26789(mac);
5603 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5606 if (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM ||
5607 siba_get_pci_subdevice(sc->sc_dev) != SIBA_BOARD_BU4306 ||
5608 siba_get_pci_revid(sc->sc_dev) != 0x17) {
5610 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
5612 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
5615 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
5616 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
5617 if ((siba_sprom_get_bf_lo(sc->sc_dev) &
5620 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
5621 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5623 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5625 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5627 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5629 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5631 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
5636 if (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) {
5637 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
5638 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
5641 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
5642 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
5646 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5649 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5652 addr = table + offset;
5653 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5654 (addr - 1 != pg->pg_ofdmtab_addr)) {
5655 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5656 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5658 pg->pg_ofdmtab_addr = addr;
5659 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5663 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5666 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5669 addr = table + offset;
5670 if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
5671 (addr - 1 != pg->pg_ofdmtab_addr)) {
5672 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
5673 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
5675 pg->pg_ofdmtab_addr = addr;
5677 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
5678 BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
5682 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
5686 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
5687 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
5691 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
5693 struct bwn_phy *phy = &mac->mac_phy;
5694 struct bwn_softc *sc = mac->mac_sc;
5695 unsigned int i, max_loop;
5697 uint32_t buffer[5] = {
5698 0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
5703 buffer[0] = 0x000201cc;
5706 buffer[0] = 0x000b846e;
5709 BWN_ASSERT_LOCKED(mac->mac_sc);
5711 for (i = 0; i < 5; i++)
5712 bwn_ram_write(mac, i * 4, buffer[i]);
5714 BWN_WRITE_2(mac, 0x0568, 0x0000);
5715 BWN_WRITE_2(mac, 0x07c0,
5716 (siba_get_revid(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
5717 value = ((phy->type == BWN_PHYTYPE_A) ? 0x41 : 0x40);
5718 BWN_WRITE_2(mac, 0x050c, value);
5719 if (phy->type == BWN_PHYTYPE_LP)
5720 BWN_WRITE_2(mac, 0x0514, 0x1a02);
5721 BWN_WRITE_2(mac, 0x0508, 0x0000);
5722 BWN_WRITE_2(mac, 0x050a, 0x0000);
5723 BWN_WRITE_2(mac, 0x054c, 0x0000);
5724 BWN_WRITE_2(mac, 0x056a, 0x0014);
5725 BWN_WRITE_2(mac, 0x0568, 0x0826);
5726 BWN_WRITE_2(mac, 0x0500, 0x0000);
5727 if (phy->type == BWN_PHYTYPE_LP)
5728 BWN_WRITE_2(mac, 0x0502, 0x0050);
5730 BWN_WRITE_2(mac, 0x0502, 0x0030);
5732 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5733 BWN_RF_WRITE(mac, 0x0051, 0x0017);
5734 for (i = 0x00; i < max_loop; i++) {
5735 value = BWN_READ_2(mac, 0x050e);
5740 for (i = 0x00; i < 0x0a; i++) {
5741 value = BWN_READ_2(mac, 0x050e);
5746 for (i = 0x00; i < 0x19; i++) {
5747 value = BWN_READ_2(mac, 0x0690);
5748 if (!(value & 0x0100))
5752 if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
5753 BWN_RF_WRITE(mac, 0x0051, 0x0037);
5757 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
5761 KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
5763 macctl = BWN_READ_4(mac, BWN_MACCTL);
5764 if (macctl & BWN_MACCTL_BIGENDIAN)
5765 printf("TODO: need swap\n");
5767 BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
5768 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
5769 BWN_WRITE_4(mac, BWN_RAM_DATA, val);
5773 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
5777 KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
5778 ("%s:%d: fail", __func__, __LINE__));
5780 value = (uint8_t) (ctl->q);
5781 value |= ((uint8_t) (ctl->i)) << 8;
5782 BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
5786 bwn_lo_calcfeed(struct bwn_mac *mac,
5787 uint16_t lna, uint16_t pga, uint16_t trsw_rx)
5789 struct bwn_phy *phy = &mac->mac_phy;
5790 struct bwn_softc *sc = mac->mac_sc;
5792 uint16_t feedthrough;
5795 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
5796 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
5798 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
5799 ("%s:%d: fail", __func__, __LINE__));
5800 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
5801 ("%s:%d: fail", __func__, __LINE__));
5803 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
5805 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
5806 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) &&
5808 rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
5810 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
5811 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5813 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
5814 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5816 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
5817 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
5819 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
5821 pga |= BWN_PHY_PGACTL_UNKNOWN;
5822 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5824 pga |= BWN_PHY_PGACTL_LOWBANDW;
5825 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5827 pga |= BWN_PHY_PGACTL_LPF;
5828 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
5831 feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
5833 return (feedthrough);
5837 bwn_lo_txctl_regtable(struct bwn_mac *mac,
5838 uint16_t *value, uint16_t *pad_mix_gain)
5840 struct bwn_phy *phy = &mac->mac_phy;
5841 uint16_t reg, v, padmix;
5843 if (phy->type == BWN_PHYTYPE_B) {
5845 if (phy->rf_rev <= 5) {
5853 if (phy->rev >= 2 && phy->rf_rev == 8) {
5866 *pad_mix_gain = padmix;
5872 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
5874 struct bwn_phy *phy = &mac->mac_phy;
5875 struct bwn_phy_g *pg = &phy->phy_g;
5876 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5878 uint16_t trsw_rx, pga;
5879 uint16_t rf_pctl_reg;
5881 static const uint8_t tx_bias_values[] = {
5882 0x09, 0x08, 0x0a, 0x01, 0x00,
5883 0x02, 0x05, 0x04, 0x06,
5885 static const uint8_t tx_magn_values[] = {
5889 if (!BWN_HAS_LOOPBACK(phy)) {
5897 lb_gain = pg->pg_max_lb_gain / 2;
5900 pga = abs(10 - lb_gain) / 6;
5901 pga = MIN(MAX(pga, 0), 15);
5908 if ((phy->rev >= 2) &&
5909 (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
5912 if ((10 - lb_gain) < cmp_val)
5913 tmp = (10 - lb_gain);
5921 rf_pctl_reg = cmp_val;
5926 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
5927 bwn_phy_g_set_bbatt(mac, 2);
5929 reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
5931 BWN_RF_MASK(mac, reg, mask);
5933 if (BWN_HAS_TXMAG(phy)) {
5936 int min_feedth = 0xffff;
5937 uint8_t tx_magn, tx_bias;
5939 for (i = 0; i < N(tx_magn_values); i++) {
5940 tx_magn = tx_magn_values[i];
5941 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
5942 for (j = 0; j < N(tx_bias_values); j++) {
5943 tx_bias = tx_bias_values[j];
5944 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
5945 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
5947 if (feedthrough < min_feedth) {
5948 lo->tx_bias = tx_bias;
5949 lo->tx_magn = tx_magn;
5950 min_feedth = feedthrough;
5952 if (lo->tx_bias == 0)
5955 BWN_RF_WRITE(mac, 0x52,
5956 (BWN_RF_READ(mac, 0x52)
5957 & 0xff00) | lo->tx_bias | lo->
5963 BWN_RF_MASK(mac, 0x52, 0xfff0);
5966 BWN_GETTIME(lo->txctl_measured_time);
5970 bwn_lo_get_powervector(struct bwn_mac *mac)
5972 struct bwn_phy *phy = &mac->mac_phy;
5973 struct bwn_phy_g *pg = &phy->phy_g;
5974 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
5977 uint64_t power_vector = 0;
5979 for (i = 0; i < 8; i += 2) {
5980 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
5981 power_vector |= (tmp << (i * 8));
5982 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
5985 lo->power_vector = power_vector;
5987 BWN_GETTIME(lo->pwr_vec_read_time);
5991 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
5994 struct bwn_phy *phy = &mac->mac_phy;
5995 struct bwn_phy_g *pg = &phy->phy_g;
5998 if (max_rx_gain < 0)
6001 if (BWN_HAS_LOOPBACK(phy)) {
6006 trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
6007 if (max_rx_gain >= trsw_rx_gain) {
6008 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
6012 trsw_rx_gain = max_rx_gain;
6013 if (trsw_rx_gain < 9) {
6014 pg->pg_lna_lod_gain = 0;
6016 pg->pg_lna_lod_gain = 1;
6019 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
6020 pg->pg_pga_gain = trsw_rx_gain / 3;
6021 if (pg->pg_pga_gain >= 5) {
6022 pg->pg_pga_gain -= 5;
6023 pg->pg_lna_gain = 2;
6025 pg->pg_lna_gain = 0;
6027 pg->pg_lna_gain = 0;
6028 pg->pg_trsw_rx_gain = 0x20;
6029 if (max_rx_gain >= 0x14) {
6030 pg->pg_lna_lod_gain = 1;
6031 pg->pg_pga_gain = 2;
6032 } else if (max_rx_gain >= 0x12) {
6033 pg->pg_lna_lod_gain = 1;
6034 pg->pg_pga_gain = 1;
6035 } else if (max_rx_gain >= 0xf) {
6036 pg->pg_lna_lod_gain = 1;
6037 pg->pg_pga_gain = 0;
6039 pg->pg_lna_lod_gain = 0;
6040 pg->pg_pga_gain = 0;
6044 tmp = BWN_RF_READ(mac, 0x7a);
6045 if (pg->pg_lna_lod_gain == 0)
6049 BWN_RF_WRITE(mac, 0x7a, tmp);
6053 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6055 struct bwn_phy *phy = &mac->mac_phy;
6056 struct bwn_phy_g *pg = &phy->phy_g;
6057 struct bwn_softc *sc = mac->mac_sc;
6058 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6062 if (bwn_has_hwpctl(mac)) {
6063 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
6064 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
6065 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6066 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
6067 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
6069 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
6070 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
6071 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
6072 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
6074 if (phy->type == BWN_PHYTYPE_B &&
6075 phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
6076 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
6077 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
6079 if (phy->rev >= 2) {
6080 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
6081 sav->phy_analogoverval =
6082 BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
6083 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
6084 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
6085 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
6086 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
6087 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
6089 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
6090 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
6091 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
6092 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
6093 if (phy->type == BWN_PHYTYPE_G) {
6094 if ((phy->rev >= 7) &&
6095 (siba_sprom_get_bf_lo(sc->sc_dev) &
6097 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
6099 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
6102 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
6104 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
6106 sav->reg0 = BWN_READ_2(mac, 0x3f4);
6107 sav->reg1 = BWN_READ_2(mac, 0x3e2);
6108 sav->rf0 = BWN_RF_READ(mac, 0x43);
6109 sav->rf1 = BWN_RF_READ(mac, 0x7a);
6110 sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
6111 sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
6112 sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
6113 sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
6115 if (!BWN_HAS_TXMAG(phy)) {
6116 sav->rf2 = BWN_RF_READ(mac, 0x52);
6119 if (phy->type == BWN_PHYTYPE_B) {
6120 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
6121 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
6122 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
6123 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
6125 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
6128 BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
6132 (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
6133 BWN_PHY_WRITE(mac, tmp, 0x007f);
6135 tmp = sav->phy_syncctl;
6136 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
6138 BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
6140 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
6141 if (phy->type == BWN_PHYTYPE_G ||
6142 (phy->type == BWN_PHYTYPE_B &&
6143 phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
6144 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
6146 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
6148 bwn_dummy_transmission(mac, 0, 1);
6149 bwn_phy_g_switch_chan(mac, 6, 0);
6150 BWN_RF_READ(mac, 0x51);
6151 if (phy->type == BWN_PHYTYPE_G)
6152 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
6155 if (time_before(lo->txctl_measured_time,
6156 (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
6157 bwn_lo_measure_txctl_values(mac);
6159 if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
6160 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
6162 if (phy->type == BWN_PHYTYPE_B)
6163 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6165 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
6170 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
6172 struct bwn_phy *phy = &mac->mac_phy;
6173 struct bwn_phy_g *pg = &phy->phy_g;
6176 if (phy->rev >= 2) {
6177 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
6178 tmp = (pg->pg_pga_gain << 8);
6179 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
6181 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
6183 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
6185 tmp = (pg->pg_pga_gain | 0xefa0);
6186 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
6188 if (phy->type == BWN_PHYTYPE_G) {
6190 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
6192 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
6194 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
6196 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
6198 BWN_WRITE_2(mac, 0x3f4, sav->reg0);
6199 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
6200 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
6201 BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
6202 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
6203 BWN_RF_WRITE(mac, 0x43, sav->rf0);
6204 BWN_RF_WRITE(mac, 0x7a, sav->rf1);
6205 if (!BWN_HAS_TXMAG(phy)) {
6207 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
6209 BWN_WRITE_2(mac, 0x3e2, sav->reg1);
6210 if (phy->type == BWN_PHYTYPE_B &&
6211 phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
6212 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
6213 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
6215 if (phy->rev >= 2) {
6216 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
6217 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
6218 sav->phy_analogoverval);
6219 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
6220 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
6221 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
6222 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
6223 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
6225 if (bwn_has_hwpctl(mac)) {
6226 tmp = (sav->phy_lomask & 0xbfff);
6227 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
6228 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
6229 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
6230 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
6231 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
6233 bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
6237 bwn_lo_probe_loctl(struct bwn_mac *mac,
6238 struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
6240 struct bwn_phy *phy = &mac->mac_phy;
6241 struct bwn_phy_g *pg = &phy->phy_g;
6242 struct bwn_loctl orig, test;
6243 struct bwn_loctl prev = { -100, -100 };
6244 static const struct bwn_loctl modifiers[] = {
6245 { 1, 1,}, { 1, 0,}, { 1, -1,}, { 0, -1,},
6246 { -1, -1,}, { -1, 0,}, { -1, 1,}, { 0, 1,}
6248 int begin, end, lower = 0, i;
6251 if (d->curstate == 0) {
6254 } else if (d->curstate % 2 == 0) {
6255 begin = d->curstate - 1;
6256 end = d->curstate + 1;
6258 begin = d->curstate - 2;
6259 end = d->curstate + 2;
6266 memcpy(&orig, probe, sizeof(struct bwn_loctl));
6270 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
6271 memcpy(&test, &orig, sizeof(struct bwn_loctl));
6272 test.i += modifiers[i - 1].i * d->multipler;
6273 test.q += modifiers[i - 1].q * d->multipler;
6274 if ((test.i != prev.i || test.q != prev.q) &&
6275 (abs(test.i) <= 16 && abs(test.q) <= 16)) {
6276 bwn_lo_write(mac, &test);
6277 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6278 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6279 if (feedth < d->feedth) {
6280 memcpy(probe, &test,
6281 sizeof(struct bwn_loctl));
6284 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
6288 memcpy(&prev, &test, sizeof(prev));
6302 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
6304 struct bwn_phy *phy = &mac->mac_phy;
6305 struct bwn_phy_g *pg = &phy->phy_g;
6306 struct bwn_lo_g_sm d;
6307 struct bwn_loctl probe;
6308 int lower, repeat, cnt = 0;
6313 if (BWN_HAS_LOOPBACK(phy))
6316 memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
6317 repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
6320 bwn_lo_write(mac, &d.loctl);
6321 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6322 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6323 if (feedth < 0x258) {
6324 if (feedth >= 0x12c)
6328 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
6329 pg->pg_pga_gain, pg->pg_trsw_rx_gain);
6334 KASSERT(d.curstate >= 0 && d.curstate <= 8,
6335 ("%s:%d: fail", __func__, __LINE__));
6336 memcpy(&probe, &d.loctl,
6337 sizeof(struct bwn_loctl));
6338 lower = bwn_lo_probe_loctl(mac, &probe, &d);
6341 if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
6343 memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
6345 } while (d.nmeasure < 24);
6346 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
6348 if (BWN_HAS_LOOPBACK(phy)) {
6349 if (d.feedth > 0x1194)
6351 else if (d.feedth < 0x5dc)
6354 if (d.feedth <= 0x5dc) {
6359 } else if (cnt == 2)
6362 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
6363 } while (++cnt < repeat);
6366 static struct bwn_lo_calib *
6367 bwn_lo_calibset(struct bwn_mac *mac,
6368 const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
6370 struct bwn_phy *phy = &mac->mac_phy;
6371 struct bwn_phy_g *pg = &phy->phy_g;
6372 struct bwn_loctl loctl = { 0, 0 };
6373 struct bwn_lo_calib *cal;
6374 struct bwn_lo_g_value sval = { 0 };
6376 uint16_t pad, reg, value;
6378 sval.old_channel = phy->chan;
6379 bwn_mac_suspend(mac);
6380 bwn_lo_save(mac, &sval);
6382 reg = bwn_lo_txctl_regtable(mac, &value, &pad);
6383 BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
6384 BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
6386 rxgain = (rfatt->att * 2) + (bbatt->att / 2);
6389 if (BWN_HAS_LOOPBACK(phy))
6390 rxgain += pg->pg_max_lb_gain;
6391 bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
6392 bwn_phy_g_set_bbatt(mac, bbatt->att);
6393 bwn_lo_probe_sm(mac, &loctl, &rxgain);
6395 bwn_lo_restore(mac, &sval);
6396 bwn_mac_enable(mac);
6398 cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
6400 device_printf(mac->mac_sc->sc_dev, "out of memory\n");
6403 memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
6404 memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
6405 memcpy(&cal->ctl, &loctl, sizeof(loctl));
6407 BWN_GETTIME(cal->calib_time);
6412 static struct bwn_lo_calib *
6413 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
6414 const struct bwn_rfatt *rfatt)
6416 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
6417 struct bwn_lo_calib *c;
6419 TAILQ_FOREACH(c, &lo->calib_list, list) {
6420 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
6422 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
6427 c = bwn_lo_calibset(mac, bbatt, rfatt);
6430 TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
6436 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
6438 struct bwn_phy *phy = &mac->mac_phy;
6439 struct bwn_phy_g *pg = &phy->phy_g;
6440 struct bwn_softc *sc = mac->mac_sc;
6441 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
6442 const struct bwn_rfatt *rfatt;
6443 const struct bwn_bbatt *bbatt;
6446 int rf_offset, bb_offset;
6447 uint8_t changed = 0;
6449 KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
6450 KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
6451 ("%s:%d: fail", __func__, __LINE__));
6453 pvector = lo->power_vector;
6454 if (!update && !pvector)
6457 bwn_mac_suspend(mac);
6459 for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
6460 struct bwn_lo_calib *cal;
6464 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
6466 bb_offset = i / lo->rfatt.len;
6467 rf_offset = i % lo->rfatt.len;
6468 bbatt = &(lo->bbatt.array[bb_offset]);
6469 rfatt = &(lo->rfatt.array[rf_offset]);
6471 cal = bwn_lo_calibset(mac, bbatt, rfatt);
6473 device_printf(sc->sc_dev, "LO: Could not "
6474 "calibrate DC table entry\n");
6477 val = (uint8_t)(cal->ctl.q);
6478 val |= ((uint8_t)(cal->ctl.i)) << 4;
6479 free(cal, M_DEVBUF);
6483 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
6484 | ((val & 0x00ff) << 8);
6486 lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
6491 for (i = 0; i < BWN_DC_LT_SIZE; i++)
6492 BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
6494 bwn_mac_enable(mac);
6498 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
6503 if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
6508 bwn_lo_g_adjust(struct bwn_mac *mac)
6510 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
6511 struct bwn_lo_calib *cal;
6512 struct bwn_rfatt rf;
6514 memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
6515 bwn_lo_fixup_rfatt(&rf);
6517 cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
6520 bwn_lo_write(mac, &cal->ctl);
6524 bwn_lo_g_init(struct bwn_mac *mac)
6527 if (!bwn_has_hwpctl(mac))
6530 bwn_lo_get_powervector(mac);
6531 bwn_phy_g_dc_lookup_init(mac, 1);
6535 bwn_mac_suspend(struct bwn_mac *mac)
6537 struct bwn_softc *sc = mac->mac_sc;
6541 KASSERT(mac->mac_suspended >= 0,
6542 ("%s:%d: fail", __func__, __LINE__));
6544 if (mac->mac_suspended == 0) {
6545 bwn_psctl(mac, BWN_PS_AWAKE);
6546 BWN_WRITE_4(mac, BWN_MACCTL,
6547 BWN_READ_4(mac, BWN_MACCTL)
6549 BWN_READ_4(mac, BWN_MACCTL);
6550 for (i = 35; i; i--) {
6551 tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6552 if (tmp & BWN_INTR_MAC_SUSPENDED)
6556 for (i = 40; i; i--) {
6557 tmp = BWN_READ_4(mac, BWN_INTR_REASON);
6558 if (tmp & BWN_INTR_MAC_SUSPENDED)
6562 device_printf(sc->sc_dev, "MAC suspend failed\n");
6565 mac->mac_suspended++;
6569 bwn_mac_enable(struct bwn_mac *mac)
6571 struct bwn_softc *sc = mac->mac_sc;
6574 state = bwn_shm_read_2(mac, BWN_SHARED,
6575 BWN_SHARED_UCODESTAT);
6576 if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
6577 state != BWN_SHARED_UCODESTAT_SLEEP)
6578 device_printf(sc->sc_dev, "warn: firmware state (%d)\n", state);
6580 mac->mac_suspended--;
6581 KASSERT(mac->mac_suspended >= 0,
6582 ("%s:%d: fail", __func__, __LINE__));
6583 if (mac->mac_suspended == 0) {
6584 BWN_WRITE_4(mac, BWN_MACCTL,
6585 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
6586 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
6587 BWN_READ_4(mac, BWN_MACCTL);
6588 BWN_READ_4(mac, BWN_INTR_REASON);
6594 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
6596 struct bwn_softc *sc = mac->mac_sc;
6600 KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
6601 ("%s:%d: fail", __func__, __LINE__));
6602 KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
6603 ("%s:%d: fail", __func__, __LINE__));
6605 /* XXX forcibly awake and hwps-off */
6607 BWN_WRITE_4(mac, BWN_MACCTL,
6608 (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
6610 BWN_READ_4(mac, BWN_MACCTL);
6611 if (siba_get_revid(sc->sc_dev) >= 5) {
6612 for (i = 0; i < 100; i++) {
6613 ucstat = bwn_shm_read_2(mac, BWN_SHARED,
6614 BWN_SHARED_UCODESTAT);
6615 if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
6623 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
6626 BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
6627 return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
6631 bwn_nrssi_threshold(struct bwn_mac *mac)
6633 struct bwn_phy *phy = &mac->mac_phy;
6634 struct bwn_phy_g *pg = &phy->phy_g;
6635 struct bwn_softc *sc = mac->mac_sc;
6640 KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
6642 if (phy->gmode && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_RSSI)) {
6643 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
6651 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6652 a += (pg->pg_nrssi[0] << 6);
6653 a += (a < 32) ? 31 : 32;
6655 a = MIN(MAX(a, -31), 31);
6657 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
6658 b += (pg->pg_nrssi[0] << 6);
6664 b = MIN(MAX(b, -31), 31);
6666 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
6667 tmpu16 |= ((uint32_t)b & 0x0000003f);
6668 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
6669 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
6673 tmp16 = bwn_nrssi_read(mac, 0x20);
6676 BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
6680 bwn_nrssi_slope_11g(struct bwn_mac *mac)
6682 #define SAVE_RF_MAX 3
6683 #define SAVE_PHY_COMM_MAX 4
6684 #define SAVE_PHY3_MAX 8
6685 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6686 { 0x7a, 0x52, 0x43 };
6687 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
6688 { 0x15, 0x5a, 0x59, 0x58 };
6689 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
6690 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
6691 0x0801, 0x0060, 0x0014, 0x0478
6693 struct bwn_phy *phy = &mac->mac_phy;
6694 struct bwn_phy_g *pg = &phy->phy_g;
6695 int32_t i, tmp32, phy3_idx = 0;
6696 uint16_t delta, tmp;
6697 uint16_t save_rf[SAVE_RF_MAX];
6698 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6699 uint16_t save_phy3[SAVE_PHY3_MAX];
6700 uint16_t ant_div, phy0, chan_ex;
6701 int16_t nrssi0, nrssi1;
6703 KASSERT(phy->type == BWN_PHYTYPE_G,
6704 ("%s:%d: fail", __func__, __LINE__));
6706 if (phy->rf_rev >= 9)
6708 if (phy->rf_rev == 8)
6709 bwn_nrssi_offset(mac);
6711 BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
6712 BWN_PHY_MASK(mac, 0x0802, 0xfffc);
6715 * Save RF/PHY registers for later restoration
6717 ant_div = BWN_READ_2(mac, 0x03e2);
6718 BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
6719 for (i = 0; i < SAVE_RF_MAX; ++i)
6720 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6721 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6722 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6724 phy0 = BWN_READ_2(mac, BWN_PHY0);
6725 chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
6726 if (phy->rev >= 3) {
6727 for (i = 0; i < SAVE_PHY3_MAX; ++i)
6728 save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
6729 BWN_PHY_WRITE(mac, 0x002e, 0);
6730 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
6735 BWN_PHY_SET(mac, 0x0478, 0x0100);
6736 BWN_PHY_SET(mac, 0x0801, 0x0040);
6740 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
6743 BWN_PHY_SET(mac, 0x0060, 0x0040);
6744 BWN_PHY_SET(mac, 0x0014, 0x0200);
6749 BWN_RF_SET(mac, 0x007a, 0x0070);
6750 bwn_set_all_gains(mac, 0, 8, 0);
6751 BWN_RF_MASK(mac, 0x007a, 0x00f7);
6752 if (phy->rev >= 2) {
6753 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
6754 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
6756 BWN_RF_SET(mac, 0x007a, 0x0080);
6759 nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6760 if (nrssi0 >= 0x0020)
6766 BWN_RF_MASK(mac, 0x007a, 0x007f);
6768 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6770 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
6771 BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
6772 BWN_RF_SET(mac, 0x007a, 0x000f);
6773 BWN_PHY_WRITE(mac, 0x0015, 0xf330);
6774 if (phy->rev >= 2) {
6775 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
6776 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
6779 bwn_set_all_gains(mac, 3, 0, 1);
6780 if (phy->rf_rev == 8) {
6781 BWN_RF_WRITE(mac, 0x0043, 0x001f);
6783 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
6784 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
6785 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
6786 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
6788 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6789 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6790 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6792 nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6795 * Install calculated narrow RSSI values
6797 if (nrssi1 >= 0x0020)
6799 if (nrssi0 == nrssi1)
6800 pg->pg_nrssi_slope = 0x00010000;
6802 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
6804 pg->pg_nrssi[0] = nrssi1;
6805 pg->pg_nrssi[1] = nrssi0;
6809 * Restore saved RF/PHY registers
6811 if (phy->rev >= 3) {
6812 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
6813 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6814 save_phy3[phy3_idx]);
6817 if (phy->rev >= 2) {
6818 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
6819 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
6822 for (i = 0; i < SAVE_RF_MAX; ++i)
6823 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6825 BWN_WRITE_2(mac, 0x03e2, ant_div);
6826 BWN_WRITE_2(mac, 0x03e6, phy0);
6827 BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
6829 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6830 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6832 bwn_spu_workaround(mac, phy->chan);
6833 BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
6834 bwn_set_original_gains(mac);
6835 BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
6836 if (phy->rev >= 3) {
6837 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
6838 BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
6839 save_phy3[phy3_idx]);
6843 delta = 0x1f - pg->pg_nrssi[0];
6844 for (i = 0; i < 64; i++) {
6845 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
6846 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
6847 pg->pg_nrssi_lt[i] = tmp32;
6850 bwn_nrssi_threshold(mac);
6852 #undef SAVE_PHY_COMM_MAX
6853 #undef SAVE_PHY3_MAX
6857 bwn_nrssi_offset(struct bwn_mac *mac)
6859 #define SAVE_RF_MAX 2
6860 #define SAVE_PHY_COMM_MAX 10
6861 #define SAVE_PHY6_MAX 8
6862 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
6864 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
6865 0x0001, 0x0811, 0x0812, 0x0814,
6866 0x0815, 0x005a, 0x0059, 0x0058,
6869 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
6870 0x002e, 0x002f, 0x080f, 0x0810,
6871 0x0801, 0x0060, 0x0014, 0x0478
6873 struct bwn_phy *phy = &mac->mac_phy;
6874 int i, phy6_idx = 0;
6875 uint16_t save_rf[SAVE_RF_MAX];
6876 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
6877 uint16_t save_phy6[SAVE_PHY6_MAX];
6879 uint16_t saved = 0xffff;
6881 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
6882 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
6883 for (i = 0; i < SAVE_RF_MAX; ++i)
6884 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
6886 BWN_PHY_MASK(mac, 0x0429, 0x7fff);
6887 BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
6888 BWN_PHY_SET(mac, 0x0811, 0x000c);
6889 BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
6890 BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
6891 if (phy->rev >= 6) {
6892 for (i = 0; i < SAVE_PHY6_MAX; ++i)
6893 save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
6895 BWN_PHY_WRITE(mac, 0x002e, 0);
6896 BWN_PHY_WRITE(mac, 0x002f, 0);
6897 BWN_PHY_WRITE(mac, 0x080f, 0);
6898 BWN_PHY_WRITE(mac, 0x0810, 0);
6899 BWN_PHY_SET(mac, 0x0478, 0x0100);
6900 BWN_PHY_SET(mac, 0x0801, 0x0040);
6901 BWN_PHY_SET(mac, 0x0060, 0x0040);
6902 BWN_PHY_SET(mac, 0x0014, 0x0200);
6904 BWN_RF_SET(mac, 0x007a, 0x0070);
6905 BWN_RF_SET(mac, 0x007a, 0x0080);
6908 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6912 for (i = 7; i >= 4; i--) {
6913 BWN_RF_WRITE(mac, 0x007b, i);
6915 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
6919 if (nrssi < 31 && saved == 0xffff)
6922 if (saved == 0xffff)
6925 BWN_RF_MASK(mac, 0x007a, 0x007f);
6926 if (phy->rev != 1) {
6927 BWN_PHY_SET(mac, 0x0814, 0x0001);
6928 BWN_PHY_MASK(mac, 0x0815, 0xfffe);
6930 BWN_PHY_SET(mac, 0x0811, 0x000c);
6931 BWN_PHY_SET(mac, 0x0812, 0x000c);
6932 BWN_PHY_SET(mac, 0x0811, 0x0030);
6933 BWN_PHY_SET(mac, 0x0812, 0x0030);
6934 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
6935 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
6936 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
6938 BWN_PHY_WRITE(mac, 0x0003, 0x0122);
6940 BWN_PHY_SET(mac, 0x000a, 0x2000);
6941 if (phy->rev != 1) {
6942 BWN_PHY_SET(mac, 0x0814, 0x0004);
6943 BWN_PHY_MASK(mac, 0x0815, 0xfffb);
6945 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
6946 BWN_RF_SET(mac, 0x007a, 0x000f);
6947 bwn_set_all_gains(mac, 3, 0, 1);
6948 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
6950 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
6954 for (i = 0; i < 4; i++) {
6955 BWN_RF_WRITE(mac, 0x007b, i);
6957 nrssi = (int16_t)((BWN_PHY_READ(mac,
6958 0x047f) >> 8) & 0x003f);
6961 if (nrssi > -31 && saved == 0xffff)
6964 if (saved == 0xffff)
6969 BWN_RF_WRITE(mac, 0x007b, saved);
6972 * Restore saved RF/PHY registers
6974 if (phy->rev >= 6) {
6975 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
6976 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
6977 save_phy6[phy6_idx]);
6980 if (phy->rev != 1) {
6981 for (i = 3; i < 5; i++)
6982 BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
6985 for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
6986 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
6988 for (i = SAVE_RF_MAX - 1; i >= 0; --i)
6989 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
6991 BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
6992 BWN_PHY_SET(mac, 0x0429, 0x8000);
6993 bwn_set_original_gains(mac);
6994 if (phy->rev >= 6) {
6995 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
6996 BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
6997 save_phy6[phy6_idx]);
7001 BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
7002 BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
7003 BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
7007 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
7010 struct bwn_phy *phy = &mac->mac_phy;
7012 uint16_t start = 0x08, end = 0x18;
7016 if (phy->rev <= 1) {
7021 table = BWN_OFDMTAB_GAINX;
7023 table = BWN_OFDMTAB_GAINX_R1;
7024 for (i = 0; i < 4; i++)
7025 bwn_ofdmtab_write_2(mac, table, i, first);
7027 for (i = start; i < end; i++)
7028 bwn_ofdmtab_write_2(mac, table, i, second);
7031 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
7032 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
7033 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
7034 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
7036 bwn_dummy_transmission(mac, 0, 1);
7040 bwn_set_original_gains(struct bwn_mac *mac)
7042 struct bwn_phy *phy = &mac->mac_phy;
7045 uint16_t start = 0x0008, end = 0x0018;
7047 if (phy->rev <= 1) {
7052 table = BWN_OFDMTAB_GAINX;
7054 table = BWN_OFDMTAB_GAINX_R1;
7055 for (i = 0; i < 4; i++) {
7057 tmp |= (i & 0x0001) << 1;
7058 tmp |= (i & 0x0002) >> 1;
7060 bwn_ofdmtab_write_2(mac, table, i, tmp);
7063 for (i = start; i < end; i++)
7064 bwn_ofdmtab_write_2(mac, table, i, i - start);
7066 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
7067 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
7068 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
7069 bwn_dummy_transmission(mac, 0, 1);
7073 bwn_phy_hwpctl_init(struct bwn_mac *mac)
7075 struct bwn_phy *phy = &mac->mac_phy;
7076 struct bwn_phy_g *pg = &phy->phy_g;
7077 struct bwn_rfatt old_rfatt, rfatt;
7078 struct bwn_bbatt old_bbatt, bbatt;
7079 struct bwn_softc *sc = mac->mac_sc;
7080 uint8_t old_txctl = 0;
7082 KASSERT(phy->type == BWN_PHYTYPE_G,
7083 ("%s:%d: fail", __func__, __LINE__));
7085 if ((siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM) &&
7086 (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306))
7089 BWN_PHY_WRITE(mac, 0x0028, 0x8018);
7091 BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
7095 bwn_hwpctl_early_init(mac);
7096 if (pg->pg_curtssi == 0) {
7097 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
7098 BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
7100 memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
7101 memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
7102 old_txctl = pg->pg_txctl;
7105 if (phy->rf_rev == 8) {
7112 bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
7114 bwn_dummy_transmission(mac, 0, 1);
7115 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
7116 if (phy->rf_ver == 0x2050 && phy->analog == 0)
7117 BWN_RF_MASK(mac, 0x0076, 0xff7b);
7119 bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
7120 &old_rfatt, old_txctl);
7122 bwn_hwpctl_init_gphy(mac);
7125 bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
7126 bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
7127 bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
7128 bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
7132 bwn_hwpctl_early_init(struct bwn_mac *mac)
7134 struct bwn_phy *phy = &mac->mac_phy;
7136 if (!bwn_has_hwpctl(mac)) {
7137 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
7141 BWN_PHY_MASK(mac, 0x0036, 0xfeff);
7142 BWN_PHY_WRITE(mac, 0x002f, 0x0202);
7143 BWN_PHY_SET(mac, 0x047c, 0x0002);
7144 BWN_PHY_SET(mac, 0x047a, 0xf000);
7145 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
7146 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7147 BWN_PHY_SET(mac, 0x005d, 0x8000);
7148 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7149 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7150 BWN_PHY_SET(mac, 0x0036, 0x0400);
7152 BWN_PHY_SET(mac, 0x0036, 0x0200);
7153 BWN_PHY_SET(mac, 0x0036, 0x0400);
7154 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
7155 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
7156 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
7157 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
7158 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
7163 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
7165 struct bwn_phy *phy = &mac->mac_phy;
7166 struct bwn_phy_g *pg = &phy->phy_g;
7167 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7169 uint16_t nr_written = 0, tmp, value;
7172 if (!bwn_has_hwpctl(mac)) {
7173 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
7177 BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
7178 (pg->pg_idletssi - pg->pg_curtssi));
7179 BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
7180 (pg->pg_idletssi - pg->pg_curtssi));
7182 for (i = 0; i < 32; i++)
7183 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
7184 for (i = 32; i < 64; i++)
7185 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
7186 for (i = 0; i < 64; i += 2) {
7187 value = (uint16_t) pg->pg_tssi2dbm[i];
7188 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
7189 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
7192 for (rf = 0; rf < lo->rfatt.len; rf++) {
7193 for (bb = 0; bb < lo->bbatt.len; bb++) {
7194 if (nr_written >= 0x40)
7196 tmp = lo->bbatt.array[bb].att;
7198 if (phy->rf_rev == 8)
7202 tmp |= lo->rfatt.array[rf].att;
7203 BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
7208 BWN_PHY_MASK(mac, 0x0060, 0xffbf);
7209 BWN_PHY_WRITE(mac, 0x0014, 0x0000);
7211 KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
7212 BWN_PHY_SET(mac, 0x0478, 0x0800);
7213 BWN_PHY_MASK(mac, 0x0478, 0xfeff);
7214 BWN_PHY_MASK(mac, 0x0801, 0xffbf);
7216 bwn_phy_g_dc_lookup_init(mac, 1);
7217 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
7221 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
7223 struct bwn_softc *sc = mac->mac_sc;
7226 bwn_spu_workaround(mac, channel);
7228 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7230 if (channel == 14) {
7231 if (siba_sprom_get_ccode(sc->sc_dev) == SIBA_CCODE_JAPAN)
7233 bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
7236 bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
7237 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7238 BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
7242 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
7243 BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
7247 bwn_phy_g_chan2freq(uint8_t channel)
7249 static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
7251 KASSERT(channel >= 1 && channel <= 14,
7252 ("%s:%d: fail", __func__, __LINE__));
7254 return (bwn_phy_g_rf_channels[channel - 1]);
7258 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
7259 const struct bwn_rfatt *rfatt, uint8_t txctl)
7261 struct bwn_phy *phy = &mac->mac_phy;
7262 struct bwn_phy_g *pg = &phy->phy_g;
7263 struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
7265 uint16_t tx_bias, tx_magn;
7269 tx_bias = lo->tx_bias;
7270 tx_magn = lo->tx_magn;
7271 if (tx_bias == 0xff)
7274 pg->pg_txctl = txctl;
7275 memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
7276 pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
7277 memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
7278 bwn_phy_g_set_bbatt(mac, bb);
7279 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
7280 if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
7281 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
7283 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
7284 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
7286 if (BWN_HAS_TXMAG(phy))
7287 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
7289 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
7290 bwn_lo_g_adjust(mac);
7294 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
7297 struct bwn_phy *phy = &mac->mac_phy;
7299 if (phy->analog == 0) {
7300 BWN_WRITE_2(mac, BWN_PHY0,
7301 (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
7304 if (phy->analog > 1) {
7305 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
7308 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
7312 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
7314 struct bwn_phy *phy = &mac->mac_phy;
7315 struct bwn_phy_g *pg = &phy->phy_g;
7316 struct bwn_softc *sc = mac->mac_sc;
7321 if (phy->gmode == 0)
7324 if (BWN_HAS_LOOPBACK(phy)) {
7325 max_lb_gain = pg->pg_max_lb_gain;
7326 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
7327 if (max_lb_gain >= 0x46) {
7329 max_lb_gain -= 0x46;
7330 } else if (max_lb_gain >= 0x3a) {
7332 max_lb_gain -= 0x3a;
7333 } else if (max_lb_gain >= 0x2e) {
7335 max_lb_gain -= 0x2e;
7338 max_lb_gain -= 0x10;
7341 for (i = 0; i < 16; i++) {
7342 max_lb_gain -= (i * 6);
7343 if (max_lb_gain < 6)
7347 if ((phy->rev < 7) ||
7348 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7349 if (reg == BWN_PHY_RFOVER) {
7351 } else if (reg == BWN_PHY_RFOVERVAL) {
7354 case BWN_LPD(0, 1, 1):
7356 case BWN_LPD(0, 0, 1):
7357 case BWN_LPD(1, 0, 1):
7358 return (0x0092 | extlna);
7359 case BWN_LPD(1, 0, 0):
7360 return (0x0093 | extlna);
7363 ("%s:%d: fail", __func__, __LINE__));
7365 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7367 if (reg == BWN_PHY_RFOVER)
7369 if (reg == BWN_PHY_RFOVERVAL) {
7374 case BWN_LPD(0, 1, 1):
7376 case BWN_LPD(0, 0, 1):
7377 return (0x8092 | extlna);
7378 case BWN_LPD(1, 0, 1):
7379 return (0x2092 | extlna);
7380 case BWN_LPD(1, 0, 0):
7381 return (0x2093 | extlna);
7384 ("%s:%d: fail", __func__, __LINE__));
7386 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7391 if ((phy->rev < 7) ||
7392 !(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA)) {
7393 if (reg == BWN_PHY_RFOVER) {
7395 } else if (reg == BWN_PHY_RFOVERVAL) {
7397 case BWN_LPD(0, 1, 1):
7399 case BWN_LPD(0, 0, 1):
7401 case BWN_LPD(1, 0, 1):
7403 case BWN_LPD(1, 0, 0):
7407 ("%s:%d: fail", __func__, __LINE__));
7409 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7411 if (reg == BWN_PHY_RFOVER) {
7413 } else if (reg == BWN_PHY_RFOVERVAL) {
7415 case BWN_LPD(0, 1, 1):
7417 case BWN_LPD(0, 0, 1):
7419 case BWN_LPD(1, 0, 1):
7421 case BWN_LPD(1, 0, 0):
7425 ("%s:%d: fail", __func__, __LINE__));
7427 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7433 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
7436 if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
7438 BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
7439 bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
7441 BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
7445 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
7447 struct bwn_softc *sc = mac->mac_sc;
7448 struct bwn_fw *fw = &mac->mac_fw;
7449 const uint8_t rev = siba_get_revid(sc->sc_dev);
7450 const char *filename;
7455 if (rev >= 5 && rev <= 10)
7456 filename = "ucode5";
7457 else if (rev >= 11 && rev <= 12)
7458 filename = "ucode11";
7460 filename = "ucode13";
7462 filename = "ucode14";
7464 filename = "ucode15";
7466 device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
7467 bwn_release_firmware(mac);
7468 return (EOPNOTSUPP);
7470 error = bwn_fw_get(mac, type, filename, &fw->ucode);
7472 bwn_release_firmware(mac);
7477 KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
7478 if (rev >= 5 && rev <= 10) {
7479 error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
7480 if (error == ENOENT)
7483 bwn_release_firmware(mac);
7486 } else if (rev < 11) {
7487 device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
7488 return (EOPNOTSUPP);
7492 high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH);
7493 switch (mac->mac_phy.type) {
7495 if (rev < 5 || rev > 10)
7497 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7498 filename = "a0g1initvals5";
7500 filename = "a0g0initvals5";
7503 if (rev >= 5 && rev <= 10)
7504 filename = "b0g0initvals5";
7506 filename = "b0g0initvals13";
7510 case BWN_PHYTYPE_LP:
7512 filename = "lp0initvals13";
7514 filename = "lp0initvals14";
7516 filename = "lp0initvals15";
7521 if (rev >= 11 && rev <= 12)
7522 filename = "n0initvals11";
7529 error = bwn_fw_get(mac, type, filename, &fw->initvals);
7531 bwn_release_firmware(mac);
7535 /* bandswitch initvals */
7536 switch (mac->mac_phy.type) {
7538 if (rev >= 5 && rev <= 10) {
7539 if (high & BWN_TGSHIGH_HAVE_2GHZ)
7540 filename = "a0g1bsinitvals5";
7542 filename = "a0g0bsinitvals5";
7543 } else if (rev >= 11)
7549 if (rev >= 5 && rev <= 10)
7550 filename = "b0g0bsinitvals5";
7556 case BWN_PHYTYPE_LP:
7558 filename = "lp0bsinitvals13";
7560 filename = "lp0bsinitvals14";
7562 filename = "lp0bsinitvals15";
7567 if (rev >= 11 && rev <= 12)
7568 filename = "n0bsinitvals11";
7575 error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
7577 bwn_release_firmware(mac);
7582 device_printf(sc->sc_dev, "no INITVALS for rev %d\n", rev);
7583 bwn_release_firmware(mac);
7584 return (EOPNOTSUPP);
7588 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
7589 const char *name, struct bwn_fwfile *bfw)
7591 const struct bwn_fwhdr *hdr;
7592 struct bwn_softc *sc = mac->mac_sc;
7593 const struct firmware *fw;
7597 bwn_do_release_fw(bfw);
7600 if (bfw->filename != NULL) {
7601 if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
7603 bwn_do_release_fw(bfw);
7606 snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
7607 (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
7608 (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
7609 /* XXX Sleeping on "fwload" with the non-sleepable locks held */
7610 fw = firmware_get(namebuf);
7612 device_printf(sc->sc_dev, "the fw file(%s) not found\n",
7616 if (fw->datasize < sizeof(struct bwn_fwhdr))
7618 hdr = (const struct bwn_fwhdr *)(fw->data);
7619 switch (hdr->type) {
7620 case BWN_FWTYPE_UCODE:
7621 case BWN_FWTYPE_PCM:
7622 if (be32toh(hdr->size) !=
7623 (fw->datasize - sizeof(struct bwn_fwhdr)))
7633 bfw->filename = name;
7638 device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
7640 firmware_put(fw, FIRMWARE_UNLOAD);
7645 bwn_release_firmware(struct bwn_mac *mac)
7648 bwn_do_release_fw(&mac->mac_fw.ucode);
7649 bwn_do_release_fw(&mac->mac_fw.pcm);
7650 bwn_do_release_fw(&mac->mac_fw.initvals);
7651 bwn_do_release_fw(&mac->mac_fw.initvals_band);
7655 bwn_do_release_fw(struct bwn_fwfile *bfw)
7658 if (bfw->fw != NULL)
7659 firmware_put(bfw->fw, FIRMWARE_UNLOAD);
7661 bfw->filename = NULL;
7665 bwn_fw_loaducode(struct bwn_mac *mac)
7667 #define GETFWOFFSET(fwp, offset) \
7668 ((const uint32_t *)((const char *)fwp.fw->data + offset))
7669 #define GETFWSIZE(fwp, offset) \
7670 ((fwp.fw->datasize - offset) / sizeof(uint32_t))
7671 struct bwn_softc *sc = mac->mac_sc;
7672 const uint32_t *data;
7675 uint16_t date, fwcaps, time;
7678 ctl = BWN_READ_4(mac, BWN_MACCTL);
7679 ctl |= BWN_MACCTL_MCODE_JMP0;
7680 KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
7682 BWN_WRITE_4(mac, BWN_MACCTL, ctl);
7683 for (i = 0; i < 64; i++)
7684 bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
7685 for (i = 0; i < 4096; i += 2)
7686 bwn_shm_write_2(mac, BWN_SHARED, i, 0);
7688 data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7689 bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
7690 for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
7692 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7696 if (mac->mac_fw.pcm.fw) {
7697 data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
7698 bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
7699 BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
7700 bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
7701 for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
7702 sizeof(struct bwn_fwhdr)); i++) {
7703 BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
7708 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
7709 BWN_WRITE_4(mac, BWN_MACCTL,
7710 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
7711 BWN_MACCTL_MCODE_RUN);
7713 for (i = 0; i < 21; i++) {
7714 if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
7717 device_printf(sc->sc_dev, "ucode timeout\n");
7723 BWN_READ_4(mac, BWN_INTR_REASON);
7725 mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
7726 if (mac->mac_fw.rev <= 0x128) {
7727 device_printf(sc->sc_dev, "the firmware is too old\n");
7731 mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
7732 BWN_SHARED_UCODE_PATCH);
7733 date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
7734 mac->mac_fw.opensource = (date == 0xffff);
7736 mac->mac_flags |= BWN_MAC_FLAG_WME;
7737 mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
7739 time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
7740 if (mac->mac_fw.opensource == 0) {
7741 device_printf(sc->sc_dev,
7742 "firmware version (rev %u patch %u date %#x time %#x)\n",
7743 mac->mac_fw.rev, mac->mac_fw.patch, date, time);
7744 if (mac->mac_fw.no_pcmfile)
7745 device_printf(sc->sc_dev,
7746 "no HW crypto acceleration due to pcm5\n");
7748 mac->mac_fw.patch = time;
7749 fwcaps = bwn_fwcaps_read(mac);
7750 if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
7751 device_printf(sc->sc_dev,
7752 "disabling HW crypto acceleration\n");
7753 mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
7755 if (!(fwcaps & BWN_FWCAPS_WME)) {
7756 device_printf(sc->sc_dev, "disabling WME support\n");
7757 mac->mac_flags &= ~BWN_MAC_FLAG_WME;
7761 if (BWN_ISOLDFMT(mac))
7762 device_printf(sc->sc_dev, "using old firmware image\n");
7767 BWN_WRITE_4(mac, BWN_MACCTL,
7768 (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
7769 BWN_MACCTL_MCODE_JMP0);
7776 /* OpenFirmware only */
7778 bwn_fwcaps_read(struct bwn_mac *mac)
7781 KASSERT(mac->mac_fw.opensource == 1,
7782 ("%s:%d: fail", __func__, __LINE__));
7783 return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
7787 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
7788 size_t count, size_t array_size)
7790 #define GET_NEXTIV16(iv) \
7791 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \
7792 sizeof(uint16_t) + sizeof(uint16_t)))
7793 #define GET_NEXTIV32(iv) \
7794 ((const struct bwn_fwinitvals *)((const uint8_t *)(iv) + \
7795 sizeof(uint16_t) + sizeof(uint32_t)))
7796 struct bwn_softc *sc = mac->mac_sc;
7797 const struct bwn_fwinitvals *iv;
7802 KASSERT(sizeof(struct bwn_fwinitvals) == 6,
7803 ("%s:%d: fail", __func__, __LINE__));
7805 for (i = 0; i < count; i++) {
7806 if (array_size < sizeof(iv->offset_size))
7808 array_size -= sizeof(iv->offset_size);
7809 offset = be16toh(iv->offset_size);
7810 bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
7811 offset &= BWN_FWINITVALS_OFFSET_MASK;
7812 if (offset >= 0x1000)
7815 if (array_size < sizeof(iv->data.d32))
7817 array_size -= sizeof(iv->data.d32);
7818 BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
7819 iv = GET_NEXTIV32(iv);
7822 if (array_size < sizeof(iv->data.d16))
7824 array_size -= sizeof(iv->data.d16);
7825 BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
7827 iv = GET_NEXTIV16(iv);
7830 if (array_size != 0)
7834 device_printf(sc->sc_dev, "initvals: invalid format\n");
7841 bwn_switch_channel(struct bwn_mac *mac, int chan)
7843 struct bwn_phy *phy = &(mac->mac_phy);
7844 struct bwn_softc *sc = mac->mac_sc;
7845 struct ieee80211com *ic = &sc->sc_ic;
7846 uint16_t channelcookie, savedcookie;
7850 chan = phy->get_default_chan(mac);
7852 channelcookie = chan;
7853 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
7854 channelcookie |= 0x100;
7855 savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
7856 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
7857 error = phy->switch_channel(mac, chan);
7861 mac->mac_phy.chan = chan;
7865 device_printf(sc->sc_dev, "failed to switch channel\n");
7866 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
7871 bwn_ant2phy(int antenna)
7876 return (BWN_TX_PHY_ANT0);
7878 return (BWN_TX_PHY_ANT1);
7880 return (BWN_TX_PHY_ANT2);
7882 return (BWN_TX_PHY_ANT3);
7884 return (BWN_TX_PHY_ANT01AUTO);
7886 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
7891 bwn_wme_load(struct bwn_mac *mac)
7893 struct bwn_softc *sc = mac->mac_sc;
7896 KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
7897 ("%s:%d: fail", __func__, __LINE__));
7899 bwn_mac_suspend(mac);
7900 for (i = 0; i < N(sc->sc_wmeParams); i++)
7901 bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
7902 bwn_wme_shm_offsets[i]);
7903 bwn_mac_enable(mac);
7907 bwn_wme_loadparams(struct bwn_mac *mac,
7908 const struct wmeParams *p, uint16_t shm_offset)
7910 #define SM(_v, _f) (((_v) << _f##_S) & _f)
7911 struct bwn_softc *sc = mac->mac_sc;
7912 uint16_t params[BWN_NR_WMEPARAMS];
7916 slot = BWN_READ_2(mac, BWN_RNG) &
7917 SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7919 memset(¶ms, 0, sizeof(params));
7921 DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
7922 "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
7923 p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
7925 params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
7926 params[BWN_WMEPARAM_CWMIN] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7927 params[BWN_WMEPARAM_CWMAX] = SM(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
7928 params[BWN_WMEPARAM_CWCUR] = SM(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
7929 params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
7930 params[BWN_WMEPARAM_BSLOTS] = slot;
7931 params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
7933 for (i = 0; i < N(params); i++) {
7934 if (i == BWN_WMEPARAM_STATUS) {
7935 tmp = bwn_shm_read_2(mac, BWN_SHARED,
7936 shm_offset + (i * 2));
7938 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
7941 bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
7948 bwn_mac_write_bssid(struct bwn_mac *mac)
7950 struct bwn_softc *sc = mac->mac_sc;
7953 uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
7955 bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
7956 memcpy(mac_bssid, sc->sc_ic.ic_macaddr, IEEE80211_ADDR_LEN);
7957 memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
7958 IEEE80211_ADDR_LEN);
7960 for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
7961 tmp = (uint32_t) (mac_bssid[i + 0]);
7962 tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
7963 tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
7964 tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
7965 bwn_ram_write(mac, 0x20 + i, tmp);
7970 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
7971 const uint8_t *macaddr)
7973 static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
7980 BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
7983 data |= macaddr[1] << 8;
7984 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7986 data |= macaddr[3] << 8;
7987 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7989 data |= macaddr[5] << 8;
7990 BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
7994 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
7995 const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
7997 uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
7998 uint8_t per_sta_keys_start = 8;
8000 if (BWN_SEC_NEWAPI(mac))
8001 per_sta_keys_start = 4;
8003 KASSERT(index < mac->mac_max_nr_keys,
8004 ("%s:%d: fail", __func__, __LINE__));
8005 KASSERT(key_len <= BWN_SEC_KEYSIZE,
8006 ("%s:%d: fail", __func__, __LINE__));
8008 if (index >= per_sta_keys_start)
8009 bwn_key_macwrite(mac, index, NULL);
8011 memcpy(buf, key, key_len);
8012 bwn_key_write(mac, index, algorithm, buf);
8013 if (index >= per_sta_keys_start)
8014 bwn_key_macwrite(mac, index, mac_addr);
8016 mac->mac_key[index].algorithm = algorithm;
8020 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
8022 struct bwn_softc *sc = mac->mac_sc;
8023 uint32_t addrtmp[2] = { 0, 0 };
8026 if (BWN_SEC_NEWAPI(mac))
8029 KASSERT(index >= start,
8030 ("%s:%d: fail", __func__, __LINE__));
8034 addrtmp[0] = addr[0];
8035 addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
8036 addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
8037 addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
8038 addrtmp[1] = addr[4];
8039 addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
8042 if (siba_get_revid(sc->sc_dev) >= 5) {
8043 bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
8044 bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
8047 bwn_shm_write_4(mac, BWN_SHARED,
8048 BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
8049 bwn_shm_write_2(mac, BWN_SHARED,
8050 BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
8056 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
8061 uint16_t kidx, value;
8063 kidx = BWN_SEC_KEY2FW(mac, index);
8064 bwn_shm_write_2(mac, BWN_SHARED,
8065 BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
8067 offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
8068 for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
8070 value |= (uint16_t)(key[i + 1]) << 8;
8071 bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
8076 bwn_phy_exit(struct bwn_mac *mac)
8079 mac->mac_phy.rf_onoff(mac, 0);
8080 if (mac->mac_phy.exit != NULL)
8081 mac->mac_phy.exit(mac);
8085 bwn_dma_free(struct bwn_mac *mac)
8087 struct bwn_dma *dma;
8089 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
8091 dma = &mac->mac_method.dma;
8093 bwn_dma_ringfree(&dma->rx);
8094 bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
8095 bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
8096 bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
8097 bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
8098 bwn_dma_ringfree(&dma->mcast);
8102 bwn_core_stop(struct bwn_mac *mac)
8104 struct bwn_softc *sc = mac->mac_sc;
8106 BWN_ASSERT_LOCKED(sc);
8108 if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8111 callout_stop(&sc->sc_rfswitch_ch);
8112 callout_stop(&sc->sc_task_ch);
8113 callout_stop(&sc->sc_watchdog_ch);
8114 sc->sc_watchdog_timer = 0;
8115 BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8116 BWN_READ_4(mac, BWN_INTR_MASK);
8117 bwn_mac_suspend(mac);
8119 mac->mac_status = BWN_MAC_STATUS_INITED;
8123 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
8125 struct bwn_mac *up_dev = NULL;
8126 struct bwn_mac *down_dev;
8127 struct bwn_mac *mac;
8131 BWN_ASSERT_LOCKED(sc);
8133 TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
8134 if (IEEE80211_IS_CHAN_2GHZ(chan) &&
8135 mac->mac_phy.supports_2ghz) {
8138 } else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
8139 mac->mac_phy.supports_5ghz) {
8143 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8149 if (up_dev == NULL) {
8150 device_printf(sc->sc_dev, "Could not find a device\n");
8153 if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
8156 device_printf(sc->sc_dev, "switching to %s-GHz band\n",
8157 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8159 down_dev = sc->sc_curmac;
8160 status = down_dev->mac_status;
8161 if (status >= BWN_MAC_STATUS_STARTED)
8162 bwn_core_stop(down_dev);
8163 if (status >= BWN_MAC_STATUS_INITED)
8164 bwn_core_exit(down_dev);
8166 if (down_dev != up_dev)
8167 bwn_phy_reset(down_dev);
8169 up_dev->mac_phy.gmode = gmode;
8170 if (status >= BWN_MAC_STATUS_INITED) {
8171 err = bwn_core_init(up_dev);
8173 device_printf(sc->sc_dev,
8174 "fatal: failed to initialize for %s-GHz\n",
8175 IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
8179 if (status >= BWN_MAC_STATUS_STARTED)
8180 bwn_core_start(up_dev);
8181 KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
8182 sc->sc_curmac = up_dev;
8186 sc->sc_curmac = NULL;
8191 bwn_rf_turnon(struct bwn_mac *mac)
8194 bwn_mac_suspend(mac);
8195 mac->mac_phy.rf_onoff(mac, 1);
8196 mac->mac_phy.rf_on = 1;
8197 bwn_mac_enable(mac);
8201 bwn_rf_turnoff(struct bwn_mac *mac)
8204 bwn_mac_suspend(mac);
8205 mac->mac_phy.rf_onoff(mac, 0);
8206 mac->mac_phy.rf_on = 0;
8207 bwn_mac_enable(mac);
8211 bwn_phy_reset(struct bwn_mac *mac)
8213 struct bwn_softc *sc = mac->mac_sc;
8215 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8216 ((siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~BWN_TGSLOW_SUPPORT_G) |
8217 BWN_TGSLOW_PHYRESET) | SIBA_TGSLOW_FGC);
8219 siba_write_4(sc->sc_dev, SIBA_TGSLOW,
8220 (siba_read_4(sc->sc_dev, SIBA_TGSLOW) & ~SIBA_TGSLOW_FGC) |
8221 BWN_TGSLOW_PHYRESET);
8226 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8228 struct bwn_vap *bvp = BWN_VAP(vap);
8229 struct ieee80211com *ic= vap->iv_ic;
8230 enum ieee80211_state ostate = vap->iv_state;
8231 struct bwn_softc *sc = ic->ic_softc;
8232 struct bwn_mac *mac = sc->sc_curmac;
8235 DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
8236 ieee80211_state_name[vap->iv_state],
8237 ieee80211_state_name[nstate]);
8239 error = bvp->bv_newstate(vap, nstate, arg);
8245 bwn_led_newstate(mac, nstate);
8248 * Clear the BSSID when we stop a STA
8250 if (vap->iv_opmode == IEEE80211_M_STA) {
8251 if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
8253 * Clear out the BSSID. If we reassociate to
8254 * the same AP, this will reinialize things
8257 if (ic->ic_opmode == IEEE80211_M_STA &&
8258 (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
8259 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
8260 bwn_set_macaddr(mac);
8265 if (vap->iv_opmode == IEEE80211_M_MONITOR ||
8266 vap->iv_opmode == IEEE80211_M_AHDEMO) {
8267 /* XXX nothing to do? */
8268 } else if (nstate == IEEE80211_S_RUN) {
8269 memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
8270 bwn_set_opmode(mac);
8271 bwn_set_pretbtt(mac);
8272 bwn_spu_setdelay(mac, 0);
8273 bwn_set_macaddr(mac);
8282 bwn_set_pretbtt(struct bwn_mac *mac)
8284 struct bwn_softc *sc = mac->mac_sc;
8285 struct ieee80211com *ic = &sc->sc_ic;
8288 if (ic->ic_opmode == IEEE80211_M_IBSS)
8291 pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
8292 bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
8293 BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
8299 struct bwn_mac *mac = arg;
8300 struct bwn_softc *sc = mac->mac_sc;
8303 if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8304 (sc->sc_flags & BWN_FLAG_INVALID))
8305 return (FILTER_STRAY);
8307 reason = BWN_READ_4(mac, BWN_INTR_REASON);
8308 if (reason == 0xffffffff) /* shared IRQ */
8309 return (FILTER_STRAY);
8310 reason &= mac->mac_intr_mask;
8312 return (FILTER_HANDLED);
8314 mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
8315 mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
8316 mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
8317 mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
8318 mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
8319 BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
8320 BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
8321 BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
8322 BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
8323 BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
8324 BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
8326 /* Disable interrupts. */
8327 BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
8329 mac->mac_reason_intr = reason;
8331 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8332 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8334 taskqueue_enqueue_fast(sc->sc_tq, &mac->mac_intrtask);
8335 return (FILTER_HANDLED);
8339 bwn_intrtask(void *arg, int npending)
8341 struct bwn_mac *mac = arg;
8342 struct bwn_softc *sc = mac->mac_sc;
8343 uint32_t merged = 0;
8344 int i, tx = 0, rx = 0;
8347 if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
8348 (sc->sc_flags & BWN_FLAG_INVALID)) {
8353 for (i = 0; i < N(mac->mac_reason); i++)
8354 merged |= mac->mac_reason[i];
8356 if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
8357 device_printf(sc->sc_dev, "MAC trans error\n");
8359 if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
8360 DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
8361 mac->mac_phy.txerrors--;
8362 if (mac->mac_phy.txerrors == 0) {
8363 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
8364 bwn_restart(mac, "PHY TX errors");
8368 if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
8369 if (merged & BWN_DMAINTR_FATALMASK) {
8370 device_printf(sc->sc_dev,
8371 "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
8372 mac->mac_reason[0], mac->mac_reason[1],
8373 mac->mac_reason[2], mac->mac_reason[3],
8374 mac->mac_reason[4], mac->mac_reason[5]);
8375 bwn_restart(mac, "DMA error");
8379 if (merged & BWN_DMAINTR_NONFATALMASK) {
8380 device_printf(sc->sc_dev,
8381 "DMA error: %#x %#x %#x %#x %#x %#x\n",
8382 mac->mac_reason[0], mac->mac_reason[1],
8383 mac->mac_reason[2], mac->mac_reason[3],
8384 mac->mac_reason[4], mac->mac_reason[5]);
8388 if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
8389 bwn_intr_ucode_debug(mac);
8390 if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
8391 bwn_intr_tbtt_indication(mac);
8392 if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
8393 bwn_intr_atim_end(mac);
8394 if (mac->mac_reason_intr & BWN_INTR_BEACON)
8395 bwn_intr_beacon(mac);
8396 if (mac->mac_reason_intr & BWN_INTR_PMQ)
8398 if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
8399 bwn_intr_noise(mac);
8401 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8402 if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
8403 bwn_dma_rx(mac->mac_method.dma.rx);
8407 rx = bwn_pio_rx(&mac->mac_method.pio.rx);
8409 KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8410 KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8411 KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8412 KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8413 KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
8415 if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
8416 bwn_intr_txeof(mac);
8420 BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
8422 if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
8423 int evt = BWN_LED_EVENT_NONE;
8426 if (sc->sc_rx_rate > sc->sc_tx_rate)
8427 evt = BWN_LED_EVENT_RX;
8429 evt = BWN_LED_EVENT_TX;
8431 evt = BWN_LED_EVENT_TX;
8433 evt = BWN_LED_EVENT_RX;
8434 } else if (rx == 0) {
8435 evt = BWN_LED_EVENT_POLL;
8438 if (evt != BWN_LED_EVENT_NONE)
8439 bwn_led_event(mac, evt);
8442 if (mbufq_first(&sc->sc_snd) != NULL)
8445 BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
8446 BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
8452 bwn_restart(struct bwn_mac *mac, const char *msg)
8454 struct bwn_softc *sc = mac->mac_sc;
8455 struct ieee80211com *ic = &sc->sc_ic;
8457 if (mac->mac_status < BWN_MAC_STATUS_INITED)
8460 device_printf(sc->sc_dev, "HW reset: %s\n", msg);
8461 ieee80211_runtask(ic, &mac->mac_hwreset);
8465 bwn_intr_ucode_debug(struct bwn_mac *mac)
8467 struct bwn_softc *sc = mac->mac_sc;
8470 if (mac->mac_fw.opensource == 0)
8473 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
8475 case BWN_DEBUGINTR_PANIC:
8476 bwn_handle_fwpanic(mac);
8478 case BWN_DEBUGINTR_DUMP_SHM:
8479 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
8481 case BWN_DEBUGINTR_DUMP_REGS:
8482 device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
8484 case BWN_DEBUGINTR_MARKER:
8485 device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
8488 device_printf(sc->sc_dev,
8489 "ucode debug unknown reason: %#x\n", reason);
8492 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
8497 bwn_intr_tbtt_indication(struct bwn_mac *mac)
8499 struct bwn_softc *sc = mac->mac_sc;
8500 struct ieee80211com *ic = &sc->sc_ic;
8502 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
8504 if (ic->ic_opmode == IEEE80211_M_IBSS)
8505 mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
8509 bwn_intr_atim_end(struct bwn_mac *mac)
8512 if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
8513 BWN_WRITE_4(mac, BWN_MACCMD,
8514 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
8515 mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
8520 bwn_intr_beacon(struct bwn_mac *mac)
8522 struct bwn_softc *sc = mac->mac_sc;
8523 struct ieee80211com *ic = &sc->sc_ic;
8524 uint32_t cmd, beacon0, beacon1;
8526 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
8527 ic->ic_opmode == IEEE80211_M_MBSS)
8530 mac->mac_intr_mask &= ~BWN_INTR_BEACON;
8532 cmd = BWN_READ_4(mac, BWN_MACCMD);
8533 beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
8534 beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
8536 if (beacon0 && beacon1) {
8537 BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
8538 mac->mac_intr_mask |= BWN_INTR_BEACON;
8542 if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
8543 sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
8544 bwn_load_beacon0(mac);
8545 bwn_load_beacon1(mac);
8546 cmd = BWN_READ_4(mac, BWN_MACCMD);
8547 cmd |= BWN_MACCMD_BEACON0_VALID;
8548 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8551 bwn_load_beacon0(mac);
8552 cmd = BWN_READ_4(mac, BWN_MACCMD);
8553 cmd |= BWN_MACCMD_BEACON0_VALID;
8554 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8555 } else if (!beacon1) {
8556 bwn_load_beacon1(mac);
8557 cmd = BWN_READ_4(mac, BWN_MACCMD);
8558 cmd |= BWN_MACCMD_BEACON1_VALID;
8559 BWN_WRITE_4(mac, BWN_MACCMD, cmd);
8565 bwn_intr_pmq(struct bwn_mac *mac)
8570 tmp = BWN_READ_4(mac, BWN_PS_STATUS);
8571 if (!(tmp & 0x00000008))
8574 BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
8578 bwn_intr_noise(struct bwn_mac *mac)
8580 struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
8586 if (mac->mac_phy.type != BWN_PHYTYPE_G)
8589 KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
8590 *((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
8591 if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
8595 KASSERT(mac->mac_noise.noi_nsamples < 8,
8596 ("%s:%d: fail", __func__, __LINE__));
8597 i = mac->mac_noise.noi_nsamples;
8598 noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
8599 noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
8600 noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
8601 noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
8602 mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
8603 mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
8604 mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
8605 mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
8606 mac->mac_noise.noi_nsamples++;
8607 if (mac->mac_noise.noi_nsamples == 8) {
8609 for (i = 0; i < 8; i++) {
8610 for (j = 0; j < 4; j++)
8611 average += mac->mac_noise.noi_samples[i][j];
8613 average = (((average / 32) * 125) + 64) / 128;
8614 tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
8619 average -= (tmp == 8) ? 72 : 48;
8621 mac->mac_stats.link_noise = average;
8622 mac->mac_noise.noi_running = 0;
8626 bwn_noise_gensample(mac);
8630 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
8632 struct bwn_mac *mac = prq->prq_mac;
8633 struct bwn_softc *sc = mac->mac_sc;
8636 BWN_ASSERT_LOCKED(sc);
8638 if (mac->mac_status < BWN_MAC_STATUS_STARTED)
8641 for (i = 0; i < 5000; i++) {
8642 if (bwn_pio_rxeof(prq) == 0)
8646 device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
8647 return ((i > 0) ? 1 : 0);
8651 bwn_dma_rx(struct bwn_dma_ring *dr)
8655 KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
8656 curslot = dr->get_curslot(dr);
8657 KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
8658 ("%s:%d: fail", __func__, __LINE__));
8660 slot = dr->dr_curslot;
8661 for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
8662 bwn_dma_rxeof(dr, &slot);
8664 bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
8665 BUS_DMASYNC_PREWRITE);
8667 dr->set_curslot(dr, slot);
8668 dr->dr_curslot = slot;
8672 bwn_intr_txeof(struct bwn_mac *mac)
8674 struct bwn_txstatus stat;
8675 uint32_t stat0, stat1;
8678 BWN_ASSERT_LOCKED(mac->mac_sc);
8681 stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
8682 if (!(stat0 & 0x00000001))
8684 stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
8686 stat.cookie = (stat0 >> 16);
8687 stat.seq = (stat1 & 0x0000ffff);
8688 stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
8689 tmp = (stat0 & 0x0000ffff);
8690 stat.framecnt = ((tmp & 0xf000) >> 12);
8691 stat.rtscnt = ((tmp & 0x0f00) >> 8);
8692 stat.sreason = ((tmp & 0x001c) >> 2);
8693 stat.pm = (tmp & 0x0080) ? 1 : 0;
8694 stat.im = (tmp & 0x0040) ? 1 : 0;
8695 stat.ampdu = (tmp & 0x0020) ? 1 : 0;
8696 stat.ack = (tmp & 0x0002) ? 1 : 0;
8698 bwn_handle_txeof(mac, &stat);
8703 bwn_hwreset(void *arg, int npending)
8705 struct bwn_mac *mac = arg;
8706 struct bwn_softc *sc = mac->mac_sc;
8712 prev_status = mac->mac_status;
8713 if (prev_status >= BWN_MAC_STATUS_STARTED)
8715 if (prev_status >= BWN_MAC_STATUS_INITED)
8718 if (prev_status >= BWN_MAC_STATUS_INITED) {
8719 error = bwn_core_init(mac);
8723 if (prev_status >= BWN_MAC_STATUS_STARTED)
8724 bwn_core_start(mac);
8727 device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
8728 sc->sc_curmac = NULL;
8734 bwn_handle_fwpanic(struct bwn_mac *mac)
8736 struct bwn_softc *sc = mac->mac_sc;
8739 reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
8740 device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
8742 if (reason == BWN_FWPANIC_RESTART)
8743 bwn_restart(mac, "ucode panic");
8747 bwn_load_beacon0(struct bwn_mac *mac)
8750 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8754 bwn_load_beacon1(struct bwn_mac *mac)
8757 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
8761 bwn_jssi_read(struct bwn_mac *mac)
8765 val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
8767 val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
8773 bwn_noise_gensample(struct bwn_mac *mac)
8775 uint32_t jssi = 0x7f7f7f7f;
8777 bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
8778 bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
8779 BWN_WRITE_4(mac, BWN_MACCMD,
8780 BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
8784 bwn_dma_freeslot(struct bwn_dma_ring *dr)
8786 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8788 return (dr->dr_numslots - dr->dr_usedslot);
8792 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
8794 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
8796 KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
8797 ("%s:%d: fail", __func__, __LINE__));
8798 if (slot == dr->dr_numslots - 1)
8804 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
8806 struct bwn_mac *mac = dr->dr_mac;
8807 struct bwn_softc *sc = mac->mac_sc;
8808 struct bwn_dma *dma = &mac->mac_method.dma;
8809 struct bwn_dmadesc_generic *desc;
8810 struct bwn_dmadesc_meta *meta;
8811 struct bwn_rxhdr4 *rxhdr;
8818 dr->getdesc(dr, *slot, &desc, &meta);
8820 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
8823 if (bwn_dma_newbuf(dr, desc, meta, 0)) {
8824 counter_u64_add(sc->sc_ic.ic_ierrors, 1);
8828 rxhdr = mtod(m, struct bwn_rxhdr4 *);
8829 len = le16toh(rxhdr->frame_len);
8831 counter_u64_add(sc->sc_ic.ic_ierrors, 1);
8834 if (bwn_dma_check_redzone(dr, m)) {
8835 device_printf(sc->sc_dev, "redzone error.\n");
8836 bwn_dma_set_redzone(dr, m);
8837 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8838 BUS_DMASYNC_PREWRITE);
8841 if (len > dr->dr_rx_bufsize) {
8844 dr->getdesc(dr, *slot, &desc, &meta);
8845 bwn_dma_set_redzone(dr, meta->mt_m);
8846 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
8847 BUS_DMASYNC_PREWRITE);
8848 *slot = bwn_dma_nextslot(dr, *slot);
8850 tmp -= dr->dr_rx_bufsize;
8854 device_printf(sc->sc_dev, "too small buffer "
8855 "(len %u buffer %u dropped %d)\n",
8856 len, dr->dr_rx_bufsize, cnt);
8859 macstat = le32toh(rxhdr->mac_status);
8860 if (macstat & BWN_RX_MAC_FCSERR) {
8861 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
8862 device_printf(sc->sc_dev, "RX drop\n");
8867 m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
8868 m_adj(m, dr->dr_frameoffset);
8870 bwn_rxeof(dr->dr_mac, m, rxhdr);
8874 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
8876 struct bwn_dma_ring *dr;
8877 struct bwn_dmadesc_generic *desc;
8878 struct bwn_dmadesc_meta *meta;
8879 struct bwn_pio_txqueue *tq;
8880 struct bwn_pio_txpkt *tp = NULL;
8881 struct bwn_softc *sc = mac->mac_sc;
8882 struct bwn_stats *stats = &mac->mac_stats;
8883 struct ieee80211_node *ni;
8884 struct ieee80211vap *vap;
8885 int retrycnt = 0, slot;
8887 BWN_ASSERT_LOCKED(mac->mac_sc);
8890 device_printf(sc->sc_dev, "TODO: STATUS IM\n");
8892 device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
8893 if (status->rtscnt) {
8894 if (status->rtscnt == 0xf)
8900 if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
8902 dr = bwn_dma_parse_cookie(mac, status,
8903 status->cookie, &slot);
8905 device_printf(sc->sc_dev,
8906 "failed to parse cookie\n");
8910 dr->getdesc(dr, slot, &desc, &meta);
8911 if (meta->mt_islast) {
8914 ieee80211_ratectl_tx_complete(vap, ni,
8916 IEEE80211_RATECTL_TX_SUCCESS :
8917 IEEE80211_RATECTL_TX_FAILURE,
8921 slot = bwn_dma_nextslot(dr, slot);
8924 bwn_dma_handle_txeof(mac, status);
8927 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
8929 device_printf(sc->sc_dev,
8930 "failed to parse cookie\n");
8935 ieee80211_ratectl_tx_complete(vap, ni,
8937 IEEE80211_RATECTL_TX_SUCCESS :
8938 IEEE80211_RATECTL_TX_FAILURE,
8941 bwn_pio_handle_txeof(mac, status);
8944 bwn_phy_txpower_check(mac, 0);
8948 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
8950 struct bwn_mac *mac = prq->prq_mac;
8951 struct bwn_softc *sc = mac->mac_sc;
8952 struct bwn_rxhdr4 rxhdr;
8954 uint32_t ctl32, macstat, v32;
8955 unsigned int i, padding;
8956 uint16_t ctl16, len, totlen, v16;
8960 memset(&rxhdr, 0, sizeof(rxhdr));
8962 if (prq->prq_rev >= 8) {
8963 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
8964 if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
8966 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
8967 BWN_PIO8_RXCTL_FRAMEREADY);
8968 for (i = 0; i < 10; i++) {
8969 ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
8970 if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
8975 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
8976 if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
8978 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
8979 BWN_PIO_RXCTL_FRAMEREADY);
8980 for (i = 0; i < 10; i++) {
8981 ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
8982 if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
8987 device_printf(sc->sc_dev, "%s: timed out\n", __func__);
8990 if (prq->prq_rev >= 8)
8991 siba_read_multi_4(sc->sc_dev, &rxhdr, sizeof(rxhdr),
8992 prq->prq_base + BWN_PIO8_RXDATA);
8994 siba_read_multi_2(sc->sc_dev, &rxhdr, sizeof(rxhdr),
8995 prq->prq_base + BWN_PIO_RXDATA);
8996 len = le16toh(rxhdr.frame_len);
8998 device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
9002 device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
9006 macstat = le32toh(rxhdr.mac_status);
9007 if (macstat & BWN_RX_MAC_FCSERR) {
9008 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
9009 device_printf(sc->sc_dev, "%s: FCS error", __func__);
9014 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9015 totlen = len + padding;
9016 KASSERT(totlen <= MCLBYTES, ("too big..\n"));
9017 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9019 device_printf(sc->sc_dev, "%s: out of memory", __func__);
9022 mp = mtod(m, unsigned char *);
9023 if (prq->prq_rev >= 8) {
9024 siba_read_multi_4(sc->sc_dev, mp, (totlen & ~3),
9025 prq->prq_base + BWN_PIO8_RXDATA);
9027 v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
9028 data = &(mp[totlen - 1]);
9029 switch (totlen & 3) {
9031 *data = (v32 >> 16);
9041 siba_read_multi_2(sc->sc_dev, mp, (totlen & ~1),
9042 prq->prq_base + BWN_PIO_RXDATA);
9044 v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
9045 mp[totlen - 1] = v16;
9049 m->m_len = m->m_pkthdr.len = totlen;
9051 bwn_rxeof(prq->prq_mac, m, &rxhdr);
9055 if (prq->prq_rev >= 8)
9056 bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
9057 BWN_PIO8_RXCTL_DATAREADY);
9059 bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
9064 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
9065 struct bwn_dmadesc_meta *meta, int init)
9067 struct bwn_mac *mac = dr->dr_mac;
9068 struct bwn_dma *dma = &mac->mac_method.dma;
9069 struct bwn_rxhdr4 *hdr;
9075 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
9080 * If the NIC is up and running, we need to:
9081 * - Clear RX buffer's header.
9082 * - Restore RX descriptor settings.
9089 m->m_len = m->m_pkthdr.len = MCLBYTES;
9091 bwn_dma_set_redzone(dr, m);
9094 * Try to load RX buf into temporary DMA map
9096 error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
9097 bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
9102 * See the comment above
9111 bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
9113 meta->mt_paddr = paddr;
9116 * Swap RX buf's DMA map with the loaded temporary one
9118 map = meta->mt_dmap;
9119 meta->mt_dmap = dr->dr_spare_dmap;
9120 dr->dr_spare_dmap = map;
9124 * Clear RX buf header
9126 hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
9127 bzero(hdr, sizeof(*hdr));
9128 bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
9129 BUS_DMASYNC_PREWRITE);
9132 * Setup RX buf descriptor
9134 dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len -
9135 sizeof(*hdr), 0, 0, 0);
9140 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
9141 bus_size_t mapsz __unused, int error)
9145 KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
9146 *((bus_addr_t *)arg) = seg->ds_addr;
9151 bwn_hwrate2ieeerate(int rate)
9155 case BWN_CCK_RATE_1MB:
9157 case BWN_CCK_RATE_2MB:
9159 case BWN_CCK_RATE_5MB:
9161 case BWN_CCK_RATE_11MB:
9163 case BWN_OFDM_RATE_6MB:
9165 case BWN_OFDM_RATE_9MB:
9167 case BWN_OFDM_RATE_12MB:
9169 case BWN_OFDM_RATE_18MB:
9171 case BWN_OFDM_RATE_24MB:
9173 case BWN_OFDM_RATE_36MB:
9175 case BWN_OFDM_RATE_48MB:
9177 case BWN_OFDM_RATE_54MB:
9186 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
9188 const struct bwn_rxhdr4 *rxhdr = _rxhdr;
9189 struct bwn_plcp6 *plcp;
9190 struct bwn_softc *sc = mac->mac_sc;
9191 struct ieee80211_frame_min *wh;
9192 struct ieee80211_node *ni;
9193 struct ieee80211com *ic = &sc->sc_ic;
9195 int padding, rate, rssi = 0, noise = 0, type;
9196 uint16_t phytype, phystat0, phystat3, chanstat;
9197 unsigned char *mp = mtod(m, unsigned char *);
9198 static int rx_mac_dec_rpt = 0;
9200 BWN_ASSERT_LOCKED(sc);
9202 phystat0 = le16toh(rxhdr->phy_status0);
9203 phystat3 = le16toh(rxhdr->phy_status3);
9204 macstat = le32toh(rxhdr->mac_status);
9205 chanstat = le16toh(rxhdr->channel);
9206 phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
9208 if (macstat & BWN_RX_MAC_FCSERR)
9209 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
9210 if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
9211 device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
9212 if (macstat & BWN_RX_MAC_DECERR)
9215 padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
9216 if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
9217 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9221 plcp = (struct bwn_plcp6 *)(mp + padding);
9222 m_adj(m, sizeof(struct bwn_plcp6) + padding);
9223 if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
9224 device_printf(sc->sc_dev, "frame too short (length=%d)\n",
9228 wh = mtod(m, struct ieee80211_frame_min *);
9230 if (macstat & BWN_RX_MAC_DEC && rx_mac_dec_rpt++ < 50)
9231 device_printf(sc->sc_dev,
9232 "RX decryption attempted (old %d keyidx %#x)\n",
9234 (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
9236 /* XXX calculating RSSI & noise & antenna */
9238 if (phystat0 & BWN_RX_PHYST0_OFDM)
9239 rate = bwn_plcp_get_ofdmrate(mac, plcp,
9240 phytype == BWN_PHYTYPE_A);
9242 rate = bwn_plcp_get_cckrate(mac, plcp);
9244 if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
9247 sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
9250 if (ieee80211_radiotap_active(ic))
9251 bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
9252 m_adj(m, -IEEE80211_CRC_LEN);
9254 rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */
9255 noise = mac->mac_stats.link_noise;
9259 ni = ieee80211_find_rxnode(ic, wh);
9261 type = ieee80211_input(ni, m, rssi, noise);
9262 ieee80211_free_node(ni);
9264 type = ieee80211_input_all(ic, m, rssi, noise);
9269 device_printf(sc->sc_dev, "%s: dropped\n", __func__);
9273 bwn_dma_handle_txeof(struct bwn_mac *mac,
9274 const struct bwn_txstatus *status)
9276 struct bwn_dma *dma = &mac->mac_method.dma;
9277 struct bwn_dma_ring *dr;
9278 struct bwn_dmadesc_generic *desc;
9279 struct bwn_dmadesc_meta *meta;
9280 struct bwn_softc *sc = mac->mac_sc;
9283 BWN_ASSERT_LOCKED(sc);
9285 dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
9287 device_printf(sc->sc_dev, "failed to parse cookie\n");
9290 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9293 KASSERT(slot >= 0 && slot < dr->dr_numslots,
9294 ("%s:%d: fail", __func__, __LINE__));
9295 dr->getdesc(dr, slot, &desc, &meta);
9297 if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
9298 bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
9299 else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
9300 bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
9302 if (meta->mt_islast) {
9303 KASSERT(meta->mt_m != NULL,
9304 ("%s:%d: fail", __func__, __LINE__));
9306 ieee80211_tx_complete(meta->mt_ni, meta->mt_m, 0);
9310 KASSERT(meta->mt_m == NULL,
9311 ("%s:%d: fail", __func__, __LINE__));
9314 if (meta->mt_islast)
9316 slot = bwn_dma_nextslot(dr, slot);
9318 sc->sc_watchdog_timer = 0;
9320 KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
9321 ("%s:%d: fail", __func__, __LINE__));
9327 bwn_pio_handle_txeof(struct bwn_mac *mac,
9328 const struct bwn_txstatus *status)
9330 struct bwn_pio_txqueue *tq;
9331 struct bwn_pio_txpkt *tp = NULL;
9332 struct bwn_softc *sc = mac->mac_sc;
9334 BWN_ASSERT_LOCKED(sc);
9336 tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
9340 tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
9343 if (tp->tp_ni != NULL) {
9345 * Do any tx complete callback. Note this must
9346 * be done before releasing the node reference.
9348 if (tp->tp_m->m_flags & M_TXCB)
9349 ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
9350 ieee80211_free_node(tp->tp_ni);
9355 TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
9357 sc->sc_watchdog_timer = 0;
9361 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
9363 struct bwn_softc *sc = mac->mac_sc;
9364 struct bwn_phy *phy = &mac->mac_phy;
9365 struct ieee80211com *ic = &sc->sc_ic;
9371 if (!(flags & BWN_TXPWR_IGNORE_TIME) && time_before(now, phy->nexttime))
9373 phy->nexttime = now + 2 * 1000;
9375 if (siba_get_pci_subvendor(sc->sc_dev) == SIBA_BOARDVENDOR_BCM &&
9376 siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BU4306)
9379 if (phy->recalc_txpwr != NULL) {
9380 result = phy->recalc_txpwr(mac,
9381 (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
9382 if (result == BWN_TXPWR_RES_DONE)
9384 KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
9385 ("%s: fail", __func__));
9386 KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
9388 ieee80211_runtask(ic, &mac->mac_txpower);
9393 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
9396 return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
9400 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
9403 return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
9407 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
9410 BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
9414 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
9417 BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
9421 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
9425 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
9427 return (BWN_OFDM_RATE_6MB);
9429 return (BWN_OFDM_RATE_9MB);
9431 return (BWN_OFDM_RATE_12MB);
9433 return (BWN_OFDM_RATE_18MB);
9435 return (BWN_OFDM_RATE_24MB);
9437 return (BWN_OFDM_RATE_36MB);
9439 return (BWN_OFDM_RATE_48MB);
9441 return (BWN_OFDM_RATE_54MB);
9442 /* CCK rates (NB: not IEEE std, device-specific) */
9444 return (BWN_CCK_RATE_1MB);
9446 return (BWN_CCK_RATE_2MB);
9448 return (BWN_CCK_RATE_5MB);
9450 return (BWN_CCK_RATE_11MB);
9453 device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
9454 return (BWN_CCK_RATE_1MB);
9458 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
9459 struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
9461 const struct bwn_phy *phy = &mac->mac_phy;
9462 struct bwn_softc *sc = mac->mac_sc;
9463 struct ieee80211_frame *wh;
9464 struct ieee80211_frame *protwh;
9465 struct ieee80211_frame_cts *cts;
9466 struct ieee80211_frame_rts *rts;
9467 const struct ieee80211_txparam *tp;
9468 struct ieee80211vap *vap = ni->ni_vap;
9469 struct ieee80211com *ic = &sc->sc_ic;
9472 uint32_t macctl = 0;
9473 int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type;
9474 uint16_t phyctl = 0;
9475 uint8_t rate, rate_fb;
9477 wh = mtod(m, struct ieee80211_frame *);
9478 memset(txhdr, 0, sizeof(*txhdr));
9480 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9481 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
9482 isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
9487 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
9488 if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
9489 rate = rate_fb = tp->mgmtrate;
9491 rate = rate_fb = tp->mcastrate;
9492 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
9493 rate = rate_fb = tp->ucastrate;
9495 rix = ieee80211_ratectl_rate(ni, NULL, 0);
9496 rate = ni->ni_txrate;
9499 rate_fb = ni->ni_rates.rs_rates[rix - 1] &
9505 sc->sc_tx_rate = rate;
9507 rate = bwn_ieeerate2hwrate(sc, rate);
9508 rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
9510 txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
9511 bwn_plcp_getcck(rate);
9512 bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
9513 bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
9515 if ((rate_fb == rate) ||
9516 (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
9517 (*(u_int16_t *)wh->i_dur == htole16(0)))
9518 txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
9520 txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
9521 m->m_pkthdr.len, rate, isshort);
9523 /* XXX TX encryption */
9524 bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
9525 (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
9526 (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
9527 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
9528 bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
9529 m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
9531 txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
9533 txhdr->chan = phy->chan;
9534 phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
9536 if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9537 rate == BWN_CCK_RATE_11MB))
9538 phyctl |= BWN_TX_PHY_SHORTPRMBL;
9540 /* XXX TX antenna selection */
9542 switch (bwn_antenna_sanitize(mac, 0)) {
9544 phyctl |= BWN_TX_PHY_ANT01AUTO;
9547 phyctl |= BWN_TX_PHY_ANT0;
9550 phyctl |= BWN_TX_PHY_ANT1;
9553 phyctl |= BWN_TX_PHY_ANT2;
9556 phyctl |= BWN_TX_PHY_ANT3;
9559 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9563 macctl |= BWN_TX_MAC_ACK;
9565 macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
9566 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
9567 m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
9568 macctl |= BWN_TX_MAC_LONGFRAME;
9570 if (ic->ic_flags & IEEE80211_F_USEPROT) {
9571 /* XXX RTS rate is always 1MB??? */
9572 rts_rate = BWN_CCK_RATE_1MB;
9573 rts_rate_fb = bwn_get_fbrate(rts_rate);
9575 protdur = ieee80211_compute_duration(ic->ic_rt,
9576 m->m_pkthdr.len, rate, isshort) +
9577 + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
9579 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
9580 cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
9581 (txhdr->body.old.rts_frame) :
9582 (txhdr->body.new.rts_frame));
9583 mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
9585 KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9586 bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts,
9587 mprot->m_pkthdr.len);
9589 macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
9590 len = sizeof(struct ieee80211_frame_cts);
9592 rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
9593 (txhdr->body.old.rts_frame) :
9594 (txhdr->body.new.rts_frame));
9595 protdur += ieee80211_ack_duration(ic->ic_rt, rate,
9597 mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
9598 wh->i_addr2, protdur);
9599 KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
9600 bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts,
9601 mprot->m_pkthdr.len);
9603 macctl |= BWN_TX_MAC_SEND_RTSCTS;
9604 len = sizeof(struct ieee80211_frame_rts);
9606 len += IEEE80211_CRC_LEN;
9607 bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
9608 &txhdr->body.old.rts_plcp :
9609 &txhdr->body.new.rts_plcp), len, rts_rate);
9610 bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
9613 protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
9614 (&txhdr->body.old.rts_frame) :
9615 (&txhdr->body.new.rts_frame));
9616 txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
9618 if (BWN_ISOFDMRATE(rts_rate)) {
9619 txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
9620 txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
9622 txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
9623 txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
9625 txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
9626 BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
9629 if (BWN_ISOLDFMT(mac))
9630 txhdr->body.old.cookie = htole16(cookie);
9632 txhdr->body.new.cookie = htole16(cookie);
9634 txhdr->macctl = htole32(macctl);
9635 txhdr->phyctl = htole16(phyctl);
9640 if (ieee80211_radiotap_active_vap(vap)) {
9641 sc->sc_tx_th.wt_flags = 0;
9642 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
9643 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
9645 (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
9646 rate == BWN_CCK_RATE_11MB))
9647 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
9648 sc->sc_tx_th.wt_rate = rate;
9650 ieee80211_radiotap_tx(vap, m);
9657 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
9661 uint8_t *raw = plcp->o.raw;
9663 if (BWN_ISOFDMRATE(rate)) {
9664 d = bwn_plcp_getofdm(rate);
9665 KASSERT(!(octets & 0xf000),
9666 ("%s:%d: fail", __func__, __LINE__));
9668 plcp->o.data = htole32(d);
9670 plen = octets * 16 / rate;
9671 if ((octets * 16 % rate) > 0) {
9673 if ((rate == BWN_CCK_RATE_11MB)
9674 && ((octets * 8 % 11) < 4)) {
9680 plcp->o.data |= htole32(plen << 16);
9681 raw[0] = bwn_plcp_getcck(rate);
9686 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
9688 struct bwn_softc *sc = mac->mac_sc;
9693 if (mac->mac_phy.gmode)
9694 mask = siba_sprom_get_ant_bg(sc->sc_dev);
9696 mask = siba_sprom_get_ant_a(sc->sc_dev);
9697 if (!(mask & (1 << (n - 1))))
9703 bwn_get_fbrate(uint8_t bitrate)
9706 case BWN_CCK_RATE_1MB:
9707 return (BWN_CCK_RATE_1MB);
9708 case BWN_CCK_RATE_2MB:
9709 return (BWN_CCK_RATE_1MB);
9710 case BWN_CCK_RATE_5MB:
9711 return (BWN_CCK_RATE_2MB);
9712 case BWN_CCK_RATE_11MB:
9713 return (BWN_CCK_RATE_5MB);
9714 case BWN_OFDM_RATE_6MB:
9715 return (BWN_CCK_RATE_5MB);
9716 case BWN_OFDM_RATE_9MB:
9717 return (BWN_OFDM_RATE_6MB);
9718 case BWN_OFDM_RATE_12MB:
9719 return (BWN_OFDM_RATE_9MB);
9720 case BWN_OFDM_RATE_18MB:
9721 return (BWN_OFDM_RATE_12MB);
9722 case BWN_OFDM_RATE_24MB:
9723 return (BWN_OFDM_RATE_18MB);
9724 case BWN_OFDM_RATE_36MB:
9725 return (BWN_OFDM_RATE_24MB);
9726 case BWN_OFDM_RATE_48MB:
9727 return (BWN_OFDM_RATE_36MB);
9728 case BWN_OFDM_RATE_54MB:
9729 return (BWN_OFDM_RATE_48MB);
9731 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9736 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9737 uint32_t ctl, const void *_data, int len)
9739 struct bwn_softc *sc = mac->mac_sc;
9741 const uint8_t *data = _data;
9743 ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
9744 BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
9745 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9747 siba_write_multi_4(sc->sc_dev, data, (len & ~3),
9748 tq->tq_base + BWN_PIO8_TXDATA);
9750 ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
9751 BWN_PIO8_TXCTL_24_31);
9752 data = &(data[len - 1]);
9755 ctl |= BWN_PIO8_TXCTL_16_23;
9756 value |= (uint32_t)(*data) << 16;
9759 ctl |= BWN_PIO8_TXCTL_8_15;
9760 value |= (uint32_t)(*data) << 8;
9763 value |= (uint32_t)(*data);
9765 bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
9766 bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
9773 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9774 uint16_t offset, uint32_t value)
9777 BWN_WRITE_4(mac, tq->tq_base + offset, value);
9781 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9782 uint16_t ctl, const void *_data, int len)
9784 struct bwn_softc *sc = mac->mac_sc;
9785 const uint8_t *data = _data;
9787 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9788 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9790 siba_write_multi_2(sc->sc_dev, data, (len & ~1),
9791 tq->tq_base + BWN_PIO_TXDATA);
9793 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9794 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9795 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
9802 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
9803 uint16_t ctl, struct mbuf *m0)
9808 struct mbuf *m = m0;
9810 ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
9811 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9813 for (; m != NULL; m = m->m_next) {
9814 buf = mtod(m, const uint8_t *);
9815 for (i = 0; i < m->m_len; i++) {
9819 data |= (buf[i] << 8);
9820 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9825 if (m0->m_pkthdr.len % 2) {
9826 ctl &= ~BWN_PIO_TXCTL_WRITEHI;
9827 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
9828 BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
9835 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
9838 if (mac->mac_phy.type != BWN_PHYTYPE_G)
9840 BWN_WRITE_2(mac, 0x684, 510 + time);
9841 bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
9844 static struct bwn_dma_ring *
9845 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
9848 if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
9849 return (mac->mac_method.dma.wme[WME_AC_BE]);
9853 return (mac->mac_method.dma.wme[WME_AC_VO]);
9855 return (mac->mac_method.dma.wme[WME_AC_VI]);
9857 return (mac->mac_method.dma.wme[WME_AC_BE]);
9859 return (mac->mac_method.dma.wme[WME_AC_BK]);
9861 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
9866 bwn_dma_getslot(struct bwn_dma_ring *dr)
9870 BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
9872 KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
9873 KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
9874 KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
9876 slot = bwn_dma_nextslot(dr, dr->dr_curslot);
9877 KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
9878 dr->dr_curslot = slot;
9885 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
9887 const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
9888 unsigned int a, b, c, d;
9892 tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
9894 b = (tmp >> 8) & 0xff;
9895 c = (tmp >> 16) & 0xff;
9896 d = (tmp >> 24) & 0xff;
9897 if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
9898 c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
9900 bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
9901 BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
9902 (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
9905 a = (a + 32) & 0x3f;
9906 b = (b + 32) & 0x3f;
9907 c = (c + 32) & 0x3f;
9908 d = (d + 32) & 0x3f;
9911 avg = (a + b + c + d + 2) / 4;
9913 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
9914 & BWN_HF_4DB_CCK_POWERBOOST)
9915 avg = (avg >= 13) ? (avg - 13) : 0;
9921 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
9923 struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
9924 int rfatt = *rfattp;
9925 int bbatt = *bbattp;
9928 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
9930 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
9932 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
9934 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
9936 if (bbatt > lo->bbatt.max) {
9941 if (bbatt < lo->bbatt.min) {
9946 if (rfatt > lo->rfatt.max) {
9951 if (rfatt < lo->rfatt.min) {
9959 *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
9960 *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
9964 bwn_phy_lock(struct bwn_mac *mac)
9966 struct bwn_softc *sc = mac->mac_sc;
9967 struct ieee80211com *ic = &sc->sc_ic;
9969 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
9970 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
9972 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
9973 bwn_psctl(mac, BWN_PS_AWAKE);
9977 bwn_phy_unlock(struct bwn_mac *mac)
9979 struct bwn_softc *sc = mac->mac_sc;
9980 struct ieee80211com *ic = &sc->sc_ic;
9982 KASSERT(siba_get_revid(sc->sc_dev) >= 3,
9983 ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
9985 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
9990 bwn_rf_lock(struct bwn_mac *mac)
9993 BWN_WRITE_4(mac, BWN_MACCTL,
9994 BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
9995 BWN_READ_4(mac, BWN_MACCTL);
10000 bwn_rf_unlock(struct bwn_mac *mac)
10003 BWN_READ_2(mac, BWN_PHYVER);
10004 BWN_WRITE_4(mac, BWN_MACCTL,
10005 BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
10008 static struct bwn_pio_txqueue *
10009 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
10010 struct bwn_pio_txpkt **pack)
10012 struct bwn_pio *pio = &mac->mac_method.pio;
10013 struct bwn_pio_txqueue *tq = NULL;
10014 unsigned int index;
10016 switch (cookie & 0xf000) {
10018 tq = &pio->wme[WME_AC_BK];
10021 tq = &pio->wme[WME_AC_BE];
10024 tq = &pio->wme[WME_AC_VI];
10027 tq = &pio->wme[WME_AC_VO];
10033 KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
10036 index = (cookie & 0x0fff);
10037 KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
10038 if (index >= N(tq->tq_pkts))
10040 *pack = &tq->tq_pkts[index];
10041 KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
10046 bwn_txpwr(void *arg, int npending)
10048 struct bwn_mac *mac = arg;
10049 struct bwn_softc *sc = mac->mac_sc;
10052 if (mac && mac->mac_status >= BWN_MAC_STATUS_STARTED &&
10053 mac->mac_phy.set_txpwr != NULL)
10054 mac->mac_phy.set_txpwr(mac);
10059 bwn_task_15s(struct bwn_mac *mac)
10063 if (mac->mac_fw.opensource) {
10064 reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
10066 bwn_restart(mac, "fw watchdog");
10069 bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
10071 if (mac->mac_phy.task_15s)
10072 mac->mac_phy.task_15s(mac);
10074 mac->mac_phy.txerrors = BWN_TXERROR_MAX;
10078 bwn_task_30s(struct bwn_mac *mac)
10081 if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
10083 mac->mac_noise.noi_running = 1;
10084 mac->mac_noise.noi_nsamples = 0;
10086 bwn_noise_gensample(mac);
10090 bwn_task_60s(struct bwn_mac *mac)
10093 if (mac->mac_phy.task_60s)
10094 mac->mac_phy.task_60s(mac);
10095 bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
10099 bwn_tasks(void *arg)
10101 struct bwn_mac *mac = arg;
10102 struct bwn_softc *sc = mac->mac_sc;
10104 BWN_ASSERT_LOCKED(sc);
10105 if (mac->mac_status != BWN_MAC_STATUS_STARTED)
10108 if (mac->mac_task_state % 4 == 0)
10110 if (mac->mac_task_state % 2 == 0)
10114 mac->mac_task_state++;
10115 callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
10119 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
10121 struct bwn_softc *sc = mac->mac_sc;
10123 KASSERT(a == 0, ("not support APHY\n"));
10125 switch (plcp->o.raw[0] & 0xf) {
10127 return (BWN_OFDM_RATE_6MB);
10129 return (BWN_OFDM_RATE_9MB);
10131 return (BWN_OFDM_RATE_12MB);
10133 return (BWN_OFDM_RATE_18MB);
10135 return (BWN_OFDM_RATE_24MB);
10137 return (BWN_OFDM_RATE_36MB);
10139 return (BWN_OFDM_RATE_48MB);
10141 return (BWN_OFDM_RATE_54MB);
10143 device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
10144 plcp->o.raw[0] & 0xf);
10149 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
10151 struct bwn_softc *sc = mac->mac_sc;
10153 switch (plcp->o.raw[0]) {
10155 return (BWN_CCK_RATE_1MB);
10157 return (BWN_CCK_RATE_2MB);
10159 return (BWN_CCK_RATE_5MB);
10161 return (BWN_CCK_RATE_11MB);
10163 device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
10168 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
10169 const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
10170 int rssi, int noise)
10172 struct bwn_softc *sc = mac->mac_sc;
10173 const struct ieee80211_frame_min *wh;
10175 uint16_t low_mactime_now;
10177 if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
10178 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
10180 wh = mtod(m, const struct ieee80211_frame_min *);
10181 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
10182 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
10184 bwn_tsf_read(mac, &tsf);
10185 low_mactime_now = tsf;
10186 tsf = tsf & ~0xffffULL;
10187 tsf += le16toh(rxhdr->mac_time);
10188 if (low_mactime_now < le16toh(rxhdr->mac_time))
10191 sc->sc_rx_th.wr_tsf = tsf;
10192 sc->sc_rx_th.wr_rate = rate;
10193 sc->sc_rx_th.wr_antsignal = rssi;
10194 sc->sc_rx_th.wr_antnoise = noise;
10198 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
10200 uint32_t low, high;
10202 KASSERT(siba_get_revid(mac->mac_sc->sc_dev) >= 3,
10203 ("%s:%d: fail", __func__, __LINE__));
10205 low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
10206 high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
10213 bwn_dma_attach(struct bwn_mac *mac)
10215 struct bwn_dma *dma = &mac->mac_method.dma;
10216 struct bwn_softc *sc = mac->mac_sc;
10217 bus_addr_t lowaddr = 0;
10220 if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCMCIA || bwn_usedma == 0)
10223 KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("%s: fail", __func__));
10225 mac->mac_flags |= BWN_MAC_FLAG_DMA;
10227 dma->dmatype = bwn_dma_gettype(mac);
10228 if (dma->dmatype == BWN_DMA_30BIT)
10229 lowaddr = BWN_BUS_SPACE_MAXADDR_30BIT;
10230 else if (dma->dmatype == BWN_DMA_32BIT)
10231 lowaddr = BUS_SPACE_MAXADDR_32BIT;
10233 lowaddr = BUS_SPACE_MAXADDR;
10236 * Create top level DMA tag
10238 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
10239 BWN_ALIGN, 0, /* alignment, bounds */
10240 lowaddr, /* lowaddr */
10241 BUS_SPACE_MAXADDR, /* highaddr */
10242 NULL, NULL, /* filter, filterarg */
10243 BUS_SPACE_MAXSIZE, /* maxsize */
10244 BUS_SPACE_UNRESTRICTED, /* nsegments */
10245 BUS_SPACE_MAXSIZE, /* maxsegsize */
10247 NULL, NULL, /* lockfunc, lockarg */
10248 &dma->parent_dtag);
10250 device_printf(sc->sc_dev, "can't create parent DMA tag\n");
10255 * Create TX/RX mbuf DMA tag
10257 error = bus_dma_tag_create(dma->parent_dtag,
10265 BUS_SPACE_MAXSIZE_32BIT,
10270 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10273 error = bus_dma_tag_create(dma->parent_dtag,
10281 BUS_SPACE_MAXSIZE_32BIT,
10286 device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
10290 dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1, dma->dmatype);
10291 if (!dma->wme[WME_AC_BK])
10294 dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1, dma->dmatype);
10295 if (!dma->wme[WME_AC_BE])
10298 dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1, dma->dmatype);
10299 if (!dma->wme[WME_AC_VI])
10302 dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1, dma->dmatype);
10303 if (!dma->wme[WME_AC_VO])
10306 dma->mcast = bwn_dma_ringsetup(mac, 4, 1, dma->dmatype);
10309 dma->rx = bwn_dma_ringsetup(mac, 0, 0, dma->dmatype);
10315 fail7: bwn_dma_ringfree(&dma->mcast);
10316 fail6: bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
10317 fail5: bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
10318 fail4: bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
10319 fail3: bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
10320 fail2: bus_dma_tag_destroy(dma->txbuf_dtag);
10321 fail1: bus_dma_tag_destroy(dma->rxbuf_dtag);
10322 fail0: bus_dma_tag_destroy(dma->parent_dtag);
10326 static struct bwn_dma_ring *
10327 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
10328 uint16_t cookie, int *slot)
10330 struct bwn_dma *dma = &mac->mac_method.dma;
10331 struct bwn_dma_ring *dr;
10332 struct bwn_softc *sc = mac->mac_sc;
10334 BWN_ASSERT_LOCKED(mac->mac_sc);
10336 switch (cookie & 0xf000) {
10338 dr = dma->wme[WME_AC_BK];
10341 dr = dma->wme[WME_AC_BE];
10344 dr = dma->wme[WME_AC_VI];
10347 dr = dma->wme[WME_AC_VO];
10355 ("invalid cookie value %d", cookie & 0xf000));
10357 *slot = (cookie & 0x0fff);
10358 if (*slot < 0 || *slot >= dr->dr_numslots) {
10360 * XXX FIXME: sometimes H/W returns TX DONE events duplicately
10361 * that it occurs events which have same H/W sequence numbers.
10362 * When it's occurred just prints a WARNING msgs and ignores.
10364 KASSERT(status->seq == dma->lastseq,
10365 ("%s:%d: fail", __func__, __LINE__));
10366 device_printf(sc->sc_dev,
10367 "out of slot ranges (0 < %d < %d)\n", *slot,
10371 dma->lastseq = status->seq;
10376 bwn_dma_stop(struct bwn_mac *mac)
10378 struct bwn_dma *dma;
10380 if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
10382 dma = &mac->mac_method.dma;
10384 bwn_dma_ringstop(&dma->rx);
10385 bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
10386 bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
10387 bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
10388 bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
10389 bwn_dma_ringstop(&dma->mcast);
10393 bwn_dma_ringstop(struct bwn_dma_ring **dr)
10399 bwn_dma_cleanup(*dr);
10403 bwn_pio_stop(struct bwn_mac *mac)
10405 struct bwn_pio *pio;
10407 if (mac->mac_flags & BWN_MAC_FLAG_DMA)
10409 pio = &mac->mac_method.pio;
10411 bwn_destroy_queue_tx(&pio->mcast);
10412 bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
10413 bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
10414 bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
10415 bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
10419 bwn_led_attach(struct bwn_mac *mac)
10421 struct bwn_softc *sc = mac->mac_sc;
10422 const uint8_t *led_act = NULL;
10423 uint16_t val[BWN_LED_MAX];
10426 sc->sc_led_idle = (2350 * hz) / 1000;
10427 sc->sc_led_blink = 1;
10429 for (i = 0; i < N(bwn_vendor_led_act); ++i) {
10430 if (siba_get_pci_subvendor(sc->sc_dev) ==
10431 bwn_vendor_led_act[i].vid) {
10432 led_act = bwn_vendor_led_act[i].led_act;
10436 if (led_act == NULL)
10437 led_act = bwn_default_led_act;
10439 val[0] = siba_sprom_get_gpio0(sc->sc_dev);
10440 val[1] = siba_sprom_get_gpio1(sc->sc_dev);
10441 val[2] = siba_sprom_get_gpio2(sc->sc_dev);
10442 val[3] = siba_sprom_get_gpio3(sc->sc_dev);
10444 for (i = 0; i < BWN_LED_MAX; ++i) {
10445 struct bwn_led *led = &sc->sc_leds[i];
10447 if (val[i] == 0xff) {
10448 led->led_act = led_act[i];
10450 if (val[i] & BWN_LED_ACT_LOW)
10451 led->led_flags |= BWN_LED_F_ACTLOW;
10452 led->led_act = val[i] & BWN_LED_ACT_MASK;
10454 led->led_mask = (1 << i);
10456 if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
10457 led->led_act == BWN_LED_ACT_BLINK_POLL ||
10458 led->led_act == BWN_LED_ACT_BLINK) {
10459 led->led_flags |= BWN_LED_F_BLINK;
10460 if (led->led_act == BWN_LED_ACT_BLINK_POLL)
10461 led->led_flags |= BWN_LED_F_POLLABLE;
10462 else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
10463 led->led_flags |= BWN_LED_F_SLOW;
10465 if (sc->sc_blink_led == NULL) {
10466 sc->sc_blink_led = led;
10467 if (led->led_flags & BWN_LED_F_SLOW)
10468 BWN_LED_SLOWDOWN(sc->sc_led_idle);
10472 DPRINTF(sc, BWN_DEBUG_LED,
10473 "%dth led, act %d, lowact %d\n", i,
10474 led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
10476 callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
10479 static __inline uint16_t
10480 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
10483 if (led->led_flags & BWN_LED_F_ACTLOW)
10486 val |= led->led_mask;
10488 val &= ~led->led_mask;
10493 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
10495 struct bwn_softc *sc = mac->mac_sc;
10496 struct ieee80211com *ic = &sc->sc_ic;
10500 if (nstate == IEEE80211_S_INIT) {
10501 callout_stop(&sc->sc_led_blink_ch);
10502 sc->sc_led_blinking = 0;
10505 if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0)
10508 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10509 for (i = 0; i < BWN_LED_MAX; ++i) {
10510 struct bwn_led *led = &sc->sc_leds[i];
10513 if (led->led_act == BWN_LED_ACT_UNKN ||
10514 led->led_act == BWN_LED_ACT_NULL)
10517 if ((led->led_flags & BWN_LED_F_BLINK) &&
10518 nstate != IEEE80211_S_INIT)
10521 switch (led->led_act) {
10522 case BWN_LED_ACT_ON: /* Always on */
10525 case BWN_LED_ACT_OFF: /* Always off */
10526 case BWN_LED_ACT_5GHZ: /* TODO: 11A */
10532 case IEEE80211_S_INIT:
10535 case IEEE80211_S_RUN:
10536 if (led->led_act == BWN_LED_ACT_11G &&
10537 ic->ic_curmode != IEEE80211_MODE_11G)
10541 if (led->led_act == BWN_LED_ACT_ASSOC)
10548 val = bwn_led_onoff(led, val, on);
10550 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10554 bwn_led_event(struct bwn_mac *mac, int event)
10556 struct bwn_softc *sc = mac->mac_sc;
10557 struct bwn_led *led = sc->sc_blink_led;
10560 if (event == BWN_LED_EVENT_POLL) {
10561 if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
10563 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
10567 sc->sc_led_ticks = ticks;
10568 if (sc->sc_led_blinking)
10572 case BWN_LED_EVENT_RX:
10573 rate = sc->sc_rx_rate;
10575 case BWN_LED_EVENT_TX:
10576 rate = sc->sc_tx_rate;
10578 case BWN_LED_EVENT_POLL:
10582 panic("unknown LED event %d\n", event);
10585 bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
10586 bwn_led_duration[rate].off_dur);
10590 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
10592 struct bwn_softc *sc = mac->mac_sc;
10593 struct bwn_led *led = sc->sc_blink_led;
10596 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10597 val = bwn_led_onoff(led, val, 1);
10598 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10600 if (led->led_flags & BWN_LED_F_SLOW) {
10601 BWN_LED_SLOWDOWN(on_dur);
10602 BWN_LED_SLOWDOWN(off_dur);
10605 sc->sc_led_blinking = 1;
10606 sc->sc_led_blink_offdur = off_dur;
10608 callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
10612 bwn_led_blink_next(void *arg)
10614 struct bwn_mac *mac = arg;
10615 struct bwn_softc *sc = mac->mac_sc;
10618 val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
10619 val = bwn_led_onoff(sc->sc_blink_led, val, 0);
10620 BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
10622 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
10623 bwn_led_blink_end, mac);
10627 bwn_led_blink_end(void *arg)
10629 struct bwn_mac *mac = arg;
10630 struct bwn_softc *sc = mac->mac_sc;
10632 sc->sc_led_blinking = 0;
10636 bwn_suspend(device_t dev)
10638 struct bwn_softc *sc = device_get_softc(dev);
10647 bwn_resume(device_t dev)
10649 struct bwn_softc *sc = device_get_softc(dev);
10650 int error = EDOOFUS;
10653 if (sc->sc_ic.ic_nrunning > 0)
10654 error = bwn_init(sc);
10657 ieee80211_start_all(&sc->sc_ic);
10662 bwn_rfswitch(void *arg)
10664 struct bwn_softc *sc = arg;
10665 struct bwn_mac *mac = sc->sc_curmac;
10666 int cur = 0, prev = 0;
10668 KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
10669 ("%s: invalid MAC status %d", __func__, mac->mac_status));
10671 if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP) {
10672 if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
10673 & BWN_RF_HWENABLED_HI_MASK))
10676 if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
10677 & BWN_RF_HWENABLED_LO_MASK)
10681 if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
10686 mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
10688 mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
10690 device_printf(sc->sc_dev,
10691 "status of RF switch is changed to %s\n",
10692 cur ? "ON" : "OFF");
10693 if (cur != mac->mac_phy.rf_on) {
10695 bwn_rf_turnon(mac);
10697 bwn_rf_turnoff(mac);
10701 callout_schedule(&sc->sc_rfswitch_ch, hz);
10705 bwn_phy_lp_init_pre(struct bwn_mac *mac)
10707 struct bwn_phy *phy = &mac->mac_phy;
10708 struct bwn_phy_lp *plp = &phy->phy_lp;
10710 plp->plp_antenna = BWN_ANT_DEFAULT;
10714 bwn_phy_lp_init(struct bwn_mac *mac)
10716 static const struct bwn_stxtable tables[] = {
10717 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
10718 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff },
10719 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff },
10720 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
10721 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f },
10722 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
10723 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 },
10724 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f },
10725 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
10726 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 },
10727 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
10728 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 },
10729 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f },
10730 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f },
10731 { 2, 11, 0x40, 0, 0x0f }
10733 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10734 struct bwn_softc *sc = mac->mac_sc;
10735 const struct bwn_stxtable *st;
10736 struct ieee80211com *ic = &sc->sc_ic;
10740 bwn_phy_lp_readsprom(mac); /* XXX bad place */
10741 bwn_phy_lp_bbinit(mac);
10743 /* initialize RF */
10744 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
10746 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
10749 if (mac->mac_phy.rf_ver == 0x2062)
10750 bwn_phy_lp_b2062_init(mac);
10752 bwn_phy_lp_b2063_init(mac);
10754 /* synchronize stx table. */
10755 for (i = 0; i < N(tables); i++) {
10757 tmp = BWN_RF_READ(mac, st->st_rfaddr);
10758 tmp >>= st->st_rfshift;
10759 tmp <<= st->st_physhift;
10760 BWN_PHY_SETMASK(mac,
10761 BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
10762 ~(st->st_mask << st->st_physhift), tmp);
10765 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
10766 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
10770 if (mac->mac_phy.rev >= 2)
10771 bwn_phy_lp_rxcal_r2(mac);
10772 else if (!plp->plp_rccap) {
10773 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
10774 bwn_phy_lp_rccal_r12(mac);
10776 bwn_phy_lp_set_rccap(mac);
10778 error = bwn_phy_lp_switch_channel(mac, 7);
10780 device_printf(sc->sc_dev,
10781 "failed to change channel 7 (%d)\n", error);
10782 bwn_phy_lp_txpctl_init(mac);
10783 bwn_phy_lp_calib(mac);
10788 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
10791 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10792 return (BWN_READ_2(mac, BWN_PHYDATA));
10796 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10799 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10800 BWN_WRITE_2(mac, BWN_PHYDATA, value);
10804 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
10808 BWN_WRITE_2(mac, BWN_PHYCTL, reg);
10809 BWN_WRITE_2(mac, BWN_PHYDATA,
10810 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
10814 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
10817 KASSERT(reg != 1, ("unaccessible register %d", reg));
10818 if (mac->mac_phy.rev < 2 && reg != 0x4001)
10820 if (mac->mac_phy.rev >= 2)
10822 BWN_WRITE_2(mac, BWN_RFCTL, reg);
10823 return BWN_READ_2(mac, BWN_RFDATALO);
10827 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
10830 KASSERT(reg != 1, ("unaccessible register %d", reg));
10831 BWN_WRITE_2(mac, BWN_RFCTL, reg);
10832 BWN_WRITE_2(mac, BWN_RFDATALO, value);
10836 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
10840 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
10841 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
10842 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
10846 if (mac->mac_phy.rev >= 2) {
10847 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
10848 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10849 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
10850 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
10851 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
10855 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
10856 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
10857 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
10858 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
10862 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
10864 struct bwn_phy *phy = &mac->mac_phy;
10865 struct bwn_phy_lp *plp = &phy->phy_lp;
10868 if (phy->rf_ver == 0x2063) {
10869 error = bwn_phy_lp_b2063_switch_channel(mac, chan);
10873 error = bwn_phy_lp_b2062_switch_channel(mac, chan);
10876 bwn_phy_lp_set_anafilter(mac, chan);
10877 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
10880 plp->plp_chan = chan;
10881 BWN_WRITE_2(mac, BWN_CHANNEL, chan);
10886 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
10888 struct bwn_softc *sc = mac->mac_sc;
10889 struct ieee80211com *ic = &sc->sc_ic;
10891 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
10895 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
10897 struct bwn_phy *phy = &mac->mac_phy;
10898 struct bwn_phy_lp *plp = &phy->phy_lp;
10900 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
10903 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
10904 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
10905 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
10906 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
10907 plp->plp_antenna = antenna;
10911 bwn_phy_lp_task_60s(struct bwn_mac *mac)
10914 bwn_phy_lp_calib(mac);
10918 bwn_phy_lp_readsprom(struct bwn_mac *mac)
10920 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10921 struct bwn_softc *sc = mac->mac_sc;
10922 struct ieee80211com *ic = &sc->sc_ic;
10924 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
10925 plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
10926 plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
10927 plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
10928 plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
10929 plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
10930 plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
10934 plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
10935 plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
10936 plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
10937 plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
10938 plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
10939 plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
10940 plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
10941 plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
10945 bwn_phy_lp_bbinit(struct bwn_mac *mac)
10948 bwn_phy_lp_tblinit(mac);
10949 if (mac->mac_phy.rev >= 2)
10950 bwn_phy_lp_bbinit_r2(mac);
10952 bwn_phy_lp_bbinit_r01(mac);
10956 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
10958 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
10959 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
10960 struct bwn_softc *sc = mac->mac_sc;
10961 struct ieee80211com *ic = &sc->sc_ic;
10963 bwn_phy_lp_set_txgain(mac,
10964 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
10965 bwn_phy_lp_set_bbmult(mac, 150);
10969 bwn_phy_lp_calib(struct bwn_mac *mac)
10971 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
10972 struct bwn_softc *sc = mac->mac_sc;
10973 struct ieee80211com *ic = &sc->sc_ic;
10974 const struct bwn_rxcompco *rc = NULL;
10975 struct bwn_txgain ogain;
10976 int i, omode, oafeovr, orf, obbmult;
10977 uint8_t mode, fc = 0;
10979 if (plp->plp_chanfullcal != plp->plp_chan) {
10980 plp->plp_chanfullcal = plp->plp_chan;
10984 bwn_mac_suspend(mac);
10986 /* BlueTooth Coexistance Override */
10987 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
10988 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
10990 if (mac->mac_phy.rev >= 2)
10991 bwn_phy_lp_digflt_save(mac);
10992 bwn_phy_lp_get_txpctlmode(mac);
10993 mode = plp->plp_txpctlmode;
10994 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
10995 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
10996 bwn_phy_lp_bugfix(mac);
10997 if (mac->mac_phy.rev >= 2 && fc == 1) {
10998 bwn_phy_lp_get_txpctlmode(mac);
10999 omode = plp->plp_txpctlmode;
11000 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
11002 ogain = bwn_phy_lp_get_txgain(mac);
11003 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
11004 obbmult = bwn_phy_lp_get_bbmult(mac);
11005 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11007 bwn_phy_lp_set_txgain(mac, &ogain);
11008 bwn_phy_lp_set_bbmult(mac, obbmult);
11009 bwn_phy_lp_set_txpctlmode(mac, omode);
11010 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
11012 bwn_phy_lp_set_txpctlmode(mac, mode);
11013 if (mac->mac_phy.rev >= 2)
11014 bwn_phy_lp_digflt_restore(mac);
11016 /* do RX IQ Calculation; assumes that noise is true. */
11017 if (siba_get_chipid(sc->sc_dev) == 0x5354) {
11018 for (i = 0; i < N(bwn_rxcompco_5354); i++) {
11019 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
11020 rc = &bwn_rxcompco_5354[i];
11022 } else if (mac->mac_phy.rev >= 2)
11023 rc = &bwn_rxcompco_r2;
11025 for (i = 0; i < N(bwn_rxcompco_r12); i++) {
11026 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
11027 rc = &bwn_rxcompco_r12[i];
11033 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
11034 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
11036 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
11038 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11039 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
11040 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
11042 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
11043 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
11046 bwn_phy_lp_set_rxgain(mac, 0x2d5d);
11047 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11048 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
11049 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
11050 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
11051 bwn_phy_lp_set_deaf(mac, 0);
11052 /* XXX no checking return value? */
11053 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
11054 bwn_phy_lp_clear_deaf(mac, 0);
11055 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
11056 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
11057 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
11059 /* disable RX GAIN override. */
11060 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
11061 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
11062 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
11063 if (mac->mac_phy.rev >= 2) {
11064 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11065 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11066 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
11067 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
11070 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
11073 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
11074 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
11076 bwn_mac_enable(mac);
11080 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
11084 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
11088 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
11089 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
11093 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
11095 static const struct bwn_b206x_chan *bc = NULL;
11096 struct bwn_softc *sc = mac->mac_sc;
11097 uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
11099 uint16_t old, scale, tmp16;
11102 for (i = 0; i < N(bwn_b2063_chantable); i++) {
11103 if (bwn_b2063_chantable[i].bc_chan == chan) {
11104 bc = &bwn_b2063_chantable[i];
11111 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
11112 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
11113 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
11114 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
11115 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
11116 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
11117 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
11118 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
11119 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
11120 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
11121 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
11122 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
11124 old = BWN_RF_READ(mac, BWN_B2063_COM15);
11125 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
11127 freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11128 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
11129 freqref = freqxtal * 3;
11130 div = (freqxtal <= 26000000 ? 1 : 2);
11131 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
11132 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
11133 999999) / 1000000) + 1;
11135 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
11136 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
11137 0xfff8, timeout >> 2);
11138 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11139 0xff9f,timeout << 5);
11140 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
11142 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
11143 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
11144 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
11146 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
11147 (timeoutref + 1)) - 1;
11148 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
11150 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
11152 tmp[0] = ((val[2] * 62500) / freqref) << 4;
11153 tmp[1] = ((val[2] * 62500) % freqref) << 4;
11154 while (tmp[1] >= freqref) {
11158 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
11159 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
11160 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
11161 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
11162 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
11164 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
11165 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
11166 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
11167 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
11169 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
11170 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
11172 if ((tmp[3] + tmp[2] - 1) / tmp[2] > 60) {
11174 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
11177 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
11179 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
11180 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
11182 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
11187 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
11188 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
11190 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
11191 if (freqxtal > 26000000)
11192 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
11194 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
11197 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
11199 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
11201 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
11203 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
11205 /* VCO Calibration */
11206 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
11207 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
11208 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
11210 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
11212 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
11214 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
11216 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
11218 BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
11223 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
11225 struct bwn_softc *sc = mac->mac_sc;
11226 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11227 const struct bwn_b206x_chan *bc = NULL;
11228 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11232 for (i = 0; i < N(bwn_b2062_chantable); i++) {
11233 if (bwn_b2062_chantable[i].bc_chan == chan) {
11234 bc = &bwn_b2062_chantable[i];
11242 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
11243 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
11244 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
11245 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
11246 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
11247 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
11248 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
11249 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
11250 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
11251 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
11253 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
11254 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
11255 bwn_phy_lp_b2062_reset_pllbias(mac);
11256 tmp[0] = freqxtal / 1000;
11257 tmp[1] = plp->plp_div * 1000;
11258 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
11259 if (ieee80211_ieee2mhz(chan, 0) < 4000)
11261 tmp[3] = 48 * tmp[0];
11262 tmp[5] = tmp[2] / tmp[3];
11263 tmp[6] = tmp[2] % tmp[3];
11264 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
11265 tmp[4] = tmp[6] * 0x100;
11266 tmp[5] = tmp[4] / tmp[3];
11267 tmp[6] = tmp[4] % tmp[3];
11268 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
11269 tmp[4] = tmp[6] * 0x100;
11270 tmp[5] = tmp[4] / tmp[3];
11271 tmp[6] = tmp[4] % tmp[3];
11272 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
11273 tmp[4] = tmp[6] * 0x100;
11274 tmp[5] = tmp[4] / tmp[3];
11275 tmp[6] = tmp[4] % tmp[3];
11276 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
11277 tmp[5] + ((2 * tmp[6]) / tmp[3]));
11278 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
11279 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
11280 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
11281 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
11283 bwn_phy_lp_b2062_vco_calib(mac);
11284 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11285 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
11286 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
11287 bwn_phy_lp_b2062_reset_pllbias(mac);
11288 bwn_phy_lp_b2062_vco_calib(mac);
11289 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
11290 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11294 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
11299 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
11301 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11302 uint16_t tmp = (channel == 14);
11304 if (mac->mac_phy.rev < 2) {
11305 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
11306 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
11307 bwn_phy_lp_set_rccap(mac);
11311 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
11315 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
11317 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11318 struct bwn_softc *sc = mac->mac_sc;
11319 struct ieee80211com *ic = &sc->sc_ic;
11320 uint16_t iso, tmp[3];
11322 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
11324 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11325 iso = plp->plp_txisoband_m;
11326 else if (freq <= 5320)
11327 iso = plp->plp_txisoband_l;
11328 else if (freq <= 5700)
11329 iso = plp->plp_txisoband_m;
11331 iso = plp->plp_txisoband_h;
11333 tmp[0] = ((iso - 26) / 12) << 12;
11334 tmp[1] = tmp[0] + 0x1000;
11335 tmp[2] = tmp[0] + 0x2000;
11337 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
11338 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
11342 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
11344 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11346 static const uint16_t addr[] = {
11347 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11348 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11349 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11350 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11351 BWN_PHY_OFDM(0xcf),
11353 static const uint16_t val[] = {
11354 0xde5e, 0xe832, 0xe331, 0x4d26,
11355 0x0026, 0x1420, 0x0020, 0xfe08,
11359 for (i = 0; i < N(addr); i++) {
11360 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
11361 BWN_PHY_WRITE(mac, addr[i], val[i]);
11366 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
11368 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11369 struct bwn_softc *sc = mac->mac_sc;
11372 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
11373 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
11374 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
11375 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
11377 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
11378 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
11380 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
11381 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
11384 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
11385 device_printf(sc->sc_dev, "unknown command mode\n");
11391 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
11393 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11397 bwn_phy_lp_get_txpctlmode(mac);
11398 old = plp->plp_txpctlmode;
11401 plp->plp_txpctlmode = mode;
11403 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
11404 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
11406 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
11407 0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
11409 /* disable TX GAIN override */
11410 if (mac->mac_phy.rev < 2)
11411 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
11413 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
11414 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
11416 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
11418 plp->plp_txpwridx = -1;
11420 if (mac->mac_phy.rev >= 2) {
11421 if (mode == BWN_PHYLP_TXPCTL_ON_HW)
11422 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
11424 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
11427 /* writes TX Power Control mode */
11428 switch (plp->plp_txpctlmode) {
11429 case BWN_PHYLP_TXPCTL_OFF:
11430 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
11432 case BWN_PHYLP_TXPCTL_ON_HW:
11433 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
11435 case BWN_PHYLP_TXPCTL_ON_SW:
11436 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
11440 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
11442 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
11443 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
11447 bwn_phy_lp_bugfix(struct bwn_mac *mac)
11449 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11450 struct bwn_softc *sc = mac->mac_sc;
11451 const unsigned int size = 256;
11452 struct bwn_txgain tg;
11453 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
11454 uint16_t tssinpt, tssiidx, value[2];
11458 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
11459 M_NOWAIT | M_ZERO);
11460 if (tabs == NULL) {
11461 device_printf(sc->sc_dev, "failed to allocate buffer.\n");
11465 bwn_phy_lp_get_txpctlmode(mac);
11466 mode = plp->plp_txpctlmode;
11467 txpwridx = plp->plp_txpwridx;
11468 tssinpt = plp->plp_tssinpt;
11469 tssiidx = plp->plp_tssiidx;
11471 bwn_tab_read_multi(mac,
11472 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11473 BWN_TAB_4(7, 0x140), size, tabs);
11475 bwn_phy_lp_tblinit(mac);
11476 bwn_phy_lp_bbinit(mac);
11477 bwn_phy_lp_txpctl_init(mac);
11478 bwn_phy_lp_rf_onoff(mac, 1);
11479 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
11481 bwn_tab_write_multi(mac,
11482 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
11483 BWN_TAB_4(7, 0x140), size, tabs);
11485 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
11486 plp->plp_tssinpt = tssinpt;
11487 plp->plp_tssiidx = tssiidx;
11488 bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
11489 if (txpwridx != -1) {
11490 /* set TX power by index */
11491 plp->plp_txpwridx = txpwridx;
11492 bwn_phy_lp_get_txpctlmode(mac);
11493 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
11494 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
11495 if (mac->mac_phy.rev >= 2) {
11496 rxcomp = bwn_tab_read(mac,
11497 BWN_TAB_4(7, txpwridx + 320));
11498 txgain = bwn_tab_read(mac,
11499 BWN_TAB_4(7, txpwridx + 192));
11500 tg.tg_pad = (txgain >> 16) & 0xff;
11501 tg.tg_gm = txgain & 0xff;
11502 tg.tg_pga = (txgain >> 8) & 0xff;
11503 tg.tg_dac = (rxcomp >> 28) & 0xff;
11504 bwn_phy_lp_set_txgain(mac, &tg);
11506 rxcomp = bwn_tab_read(mac,
11507 BWN_TAB_4(10, txpwridx + 320));
11508 txgain = bwn_tab_read(mac,
11509 BWN_TAB_4(10, txpwridx + 192));
11510 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
11511 0xf800, (txgain >> 4) & 0x7fff);
11512 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
11513 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
11515 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
11518 value[0] = (rxcomp >> 10) & 0x3ff;
11519 value[1] = rxcomp & 0x3ff;
11520 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
11522 coeff = bwn_tab_read(mac,
11523 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
11524 BWN_TAB_4(10, txpwridx + 448));
11525 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
11526 if (mac->mac_phy.rev >= 2) {
11527 rfpwr = bwn_tab_read(mac,
11528 BWN_TAB_4(7, txpwridx + 576));
11529 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
11532 bwn_phy_lp_set_txgain_override(mac);
11534 if (plp->plp_rccap)
11535 bwn_phy_lp_set_rccap(mac);
11536 bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
11537 bwn_phy_lp_set_txpctlmode(mac, mode);
11538 free(tabs, M_DEVBUF);
11542 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
11544 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11546 static const uint16_t addr[] = {
11547 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
11548 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
11549 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
11550 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
11551 BWN_PHY_OFDM(0xcf),
11554 for (i = 0; i < N(addr); i++)
11555 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
11559 bwn_phy_lp_tblinit(struct bwn_mac *mac)
11561 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
11563 if (mac->mac_phy.rev < 2) {
11564 bwn_phy_lp_tblinit_r01(mac);
11565 bwn_phy_lp_tblinit_txgain(mac);
11566 bwn_phy_lp_set_gaintbl(mac, freq);
11570 bwn_phy_lp_tblinit_r2(mac);
11571 bwn_phy_lp_tblinit_txgain(mac);
11579 struct bwn_smpair {
11586 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
11588 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11589 struct bwn_softc *sc = mac->mac_sc;
11590 struct ieee80211com *ic = &sc->sc_ic;
11591 static const struct bwn_wpair v1[] = {
11592 { BWN_PHY_AFE_DAC_CTL, 0x50 },
11593 { BWN_PHY_AFE_CTL, 0x8800 },
11594 { BWN_PHY_AFE_CTL_OVR, 0 },
11595 { BWN_PHY_AFE_CTL_OVRVAL, 0 },
11596 { BWN_PHY_RF_OVERRIDE_0, 0 },
11597 { BWN_PHY_RF_OVERRIDE_2, 0 },
11598 { BWN_PHY_OFDM(0xf9), 0 },
11599 { BWN_PHY_TR_LOOKUP_1, 0 }
11601 static const struct bwn_smpair v2[] = {
11602 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
11603 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
11604 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
11605 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
11606 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
11608 static const struct bwn_smpair v3[] = {
11609 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
11610 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11611 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
11612 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
11613 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
11614 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
11615 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
11616 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
11617 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
11618 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
11623 for (i = 0; i < N(v1); i++)
11624 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
11625 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
11626 for (i = 0; i < N(v2); i++)
11627 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
11629 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
11630 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
11631 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
11632 if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
11633 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
11634 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
11636 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
11638 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
11639 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
11640 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
11641 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
11642 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
11643 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
11644 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
11645 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
11646 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
11647 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
11648 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
11649 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11650 (siba_get_chiprev(sc->sc_dev) == 0)) {
11651 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11652 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
11654 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
11655 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
11657 for (i = 0; i < N(v3); i++)
11658 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
11659 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11660 (siba_get_chiprev(sc->sc_dev) == 0)) {
11661 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
11662 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
11665 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11666 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
11667 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
11668 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
11669 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
11670 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
11671 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11673 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
11675 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
11676 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
11677 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
11678 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
11679 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
11680 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
11681 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
11682 0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
11683 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
11685 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
11686 (siba_get_chiprev(sc->sc_dev) == 0)) {
11687 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
11688 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
11689 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
11692 bwn_phy_lp_digflt_save(mac);
11696 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
11698 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11699 struct bwn_softc *sc = mac->mac_sc;
11700 struct ieee80211com *ic = &sc->sc_ic;
11701 static const struct bwn_smpair v1[] = {
11702 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
11703 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
11704 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
11705 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
11706 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
11707 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
11708 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
11710 static const struct bwn_smpair v2[] = {
11711 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11712 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
11713 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11714 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11715 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
11716 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
11717 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
11718 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
11719 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
11720 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
11721 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
11722 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
11723 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
11724 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
11725 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
11726 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
11728 static const struct bwn_smpair v3[] = {
11729 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
11730 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
11731 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
11732 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
11733 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11734 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
11735 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11736 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
11738 static const struct bwn_smpair v4[] = {
11739 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
11740 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
11741 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
11742 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
11743 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
11744 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
11745 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
11746 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
11748 static const struct bwn_smpair v5[] = {
11749 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
11750 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
11751 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
11752 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
11753 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
11754 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
11755 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
11756 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
11759 uint16_t tmp, tmp2;
11761 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
11762 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
11763 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
11764 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
11765 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
11766 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
11767 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
11768 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
11769 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
11770 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
11771 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
11772 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
11773 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
11774 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
11775 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
11776 for (i = 0; i < N(v1); i++)
11777 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
11778 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
11779 0xff00, plp->plp_rxpwroffset);
11780 if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
11781 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
11782 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
11783 siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
11784 siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
11785 if (mac->mac_phy.rev == 0)
11786 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
11788 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
11790 siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
11791 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
11792 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
11794 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
11795 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
11796 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
11797 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
11799 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
11800 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
11801 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
11802 0xfff9, (plp->plp_bxarch << 1));
11803 if (mac->mac_phy.rev == 1 &&
11804 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
11805 for (i = 0; i < N(v2); i++)
11806 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
11808 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
11809 (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
11810 ((mac->mac_phy.rev == 0) &&
11811 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
11812 for (i = 0; i < N(v3); i++)
11813 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
11815 } else if (mac->mac_phy.rev == 1 ||
11816 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
11817 for (i = 0; i < N(v4); i++)
11818 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
11821 for (i = 0; i < N(v5); i++)
11822 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
11825 if (mac->mac_phy.rev == 1 &&
11826 (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
11827 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
11828 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
11829 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
11830 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
11832 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
11833 (siba_get_chipid(sc->sc_dev) == 0x5354) &&
11834 (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
11835 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
11836 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
11837 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
11838 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
11840 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
11841 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
11842 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
11843 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
11844 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
11845 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
11846 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
11847 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
11848 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
11850 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
11851 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
11853 if (mac->mac_phy.rev == 1) {
11854 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
11855 tmp2 = (tmp & 0x03e0) >> 5;
11857 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
11858 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
11859 tmp2 = (tmp & 0x1f00) >> 8;
11861 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
11862 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
11863 tmp2 = tmp & 0x00ff;
11865 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
11869 struct bwn_b2062_freq {
11875 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
11877 #define CALC_CTL7(freq, div) \
11878 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
11879 #define CALC_CTL18(freq, div) \
11880 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
11881 #define CALC_CTL19(freq, div) \
11882 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
11883 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
11884 struct bwn_softc *sc = mac->mac_sc;
11885 struct ieee80211com *ic = &sc->sc_ic;
11886 static const struct bwn_b2062_freq freqdata_tab[] = {
11887 { 12000, { 6, 6, 6, 6, 10, 6 } },
11888 { 13000, { 4, 4, 4, 4, 11, 7 } },
11889 { 14400, { 3, 3, 3, 3, 12, 7 } },
11890 { 16200, { 3, 3, 3, 3, 13, 8 } },
11891 { 18000, { 2, 2, 2, 2, 14, 8 } },
11892 { 19200, { 1, 1, 1, 1, 14, 9 } }
11894 static const struct bwn_wpair v1[] = {
11895 { BWN_B2062_N_TXCTL3, 0 },
11896 { BWN_B2062_N_TXCTL4, 0 },
11897 { BWN_B2062_N_TXCTL5, 0 },
11898 { BWN_B2062_N_TXCTL6, 0 },
11899 { BWN_B2062_N_PDNCTL0, 0x40 },
11900 { BWN_B2062_N_PDNCTL0, 0 },
11901 { BWN_B2062_N_CALIB_TS, 0x10 },
11902 { BWN_B2062_N_CALIB_TS, 0 }
11904 const struct bwn_b2062_freq *f = NULL;
11905 uint32_t xtalfreq, ref;
11908 bwn_phy_lp_b2062_tblinit(mac);
11910 for (i = 0; i < N(v1); i++)
11911 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
11912 if (mac->mac_phy.rev > 0)
11913 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
11914 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
11915 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
11916 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
11918 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
11920 KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
11921 ("%s:%d: fail", __func__, __LINE__));
11922 xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
11923 KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
11925 if (xtalfreq <= 30000000) {
11927 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
11930 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
11933 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
11934 CALC_CTL7(xtalfreq, plp->plp_div));
11935 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
11936 CALC_CTL18(xtalfreq, plp->plp_div));
11937 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
11938 CALC_CTL19(xtalfreq, plp->plp_div));
11940 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
11942 for (i = 0; i < N(freqdata_tab); i++) {
11943 if (ref < freqdata_tab[i].freq) {
11944 f = &freqdata_tab[i];
11949 f = &freqdata_tab[N(freqdata_tab) - 1];
11950 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
11951 ((uint16_t)(f->value[1]) << 4) | f->value[0]);
11952 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
11953 ((uint16_t)(f->value[3]) << 4) | f->value[2]);
11954 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
11955 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
11962 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
11965 bwn_phy_lp_b2063_tblinit(mac);
11966 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
11967 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
11968 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
11969 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
11970 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
11971 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
11972 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
11973 if (mac->mac_phy.rev == 2) {
11974 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
11975 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
11976 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
11978 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
11979 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
11984 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
11986 struct bwn_softc *sc = mac->mac_sc;
11987 static const struct bwn_wpair v1[] = {
11988 { BWN_B2063_RX_BB_SP8, 0x0 },
11989 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
11990 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
11991 { BWN_B2063_RC_CALIB_CTL2, 0x15 },
11992 { BWN_B2063_RC_CALIB_CTL3, 0x70 },
11993 { BWN_B2063_RC_CALIB_CTL4, 0x52 },
11994 { BWN_B2063_RC_CALIB_CTL5, 0x1 },
11995 { BWN_B2063_RC_CALIB_CTL1, 0x7d }
11997 static const struct bwn_wpair v2[] = {
11998 { BWN_B2063_TX_BB_SP3, 0x0 },
11999 { BWN_B2063_RC_CALIB_CTL1, 0x7e },
12000 { BWN_B2063_RC_CALIB_CTL1, 0x7c },
12001 { BWN_B2063_RC_CALIB_CTL2, 0x55 },
12002 { BWN_B2063_RC_CALIB_CTL3, 0x76 }
12004 uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
12008 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
12010 for (i = 0; i < 2; i++)
12011 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12012 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
12013 for (i = 2; i < N(v1); i++)
12014 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
12015 for (i = 0; i < 10000; i++) {
12016 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12021 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12022 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
12024 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
12026 for (i = 0; i < N(v2); i++)
12027 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
12028 if (freqxtal == 24000000) {
12029 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
12030 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
12032 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
12033 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
12035 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
12036 for (i = 0; i < 10000; i++) {
12037 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
12041 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
12042 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
12043 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
12047 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
12049 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12050 struct bwn_softc *sc = mac->mac_sc;
12051 struct bwn_phy_lp_iq_est ie;
12052 struct bwn_txgain tx_gains;
12053 static const uint32_t pwrtbl[21] = {
12054 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
12055 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
12056 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
12057 0x0004c, 0x0002c, 0x0001a,
12059 uint32_t npwr, ipwr, sqpwr, tmp;
12060 int loopback, i, j, sum, error;
12062 uint8_t txo, bbmult, txpctlmode;
12064 error = bwn_phy_lp_switch_channel(mac, 7);
12066 device_printf(sc->sc_dev,
12067 "failed to change channel to 7 (%d)\n", error);
12068 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
12069 bbmult = bwn_phy_lp_get_bbmult(mac);
12071 tx_gains = bwn_phy_lp_get_txgain(mac);
12073 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
12074 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
12075 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
12076 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
12077 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
12078 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
12079 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
12081 bwn_phy_lp_get_txpctlmode(mac);
12082 txpctlmode = plp->plp_txpctlmode;
12083 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
12086 bwn_phy_lp_set_deaf(mac, 1);
12087 bwn_phy_lp_set_trsw_over(mac, 0, 1);
12088 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
12089 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
12090 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
12091 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
12092 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
12093 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12094 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
12095 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
12096 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
12097 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12098 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
12099 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
12100 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
12101 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
12102 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
12103 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
12104 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
12105 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
12106 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
12107 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
12108 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
12109 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
12110 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
12112 loopback = bwn_phy_lp_loopback(mac);
12113 if (loopback == -1)
12115 bwn_phy_lp_set_rxgain_idx(mac, loopback);
12116 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
12117 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
12118 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
12119 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
12122 memset(&ie, 0, sizeof(ie));
12123 for (i = 128; i <= 159; i++) {
12124 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
12126 for (j = 5; j <= 25; j++) {
12127 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
12128 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
12130 sqpwr = ie.ie_ipwr + ie.ie_qpwr;
12131 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
12132 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
12134 sum += ((ipwr - npwr) * (ipwr - npwr));
12135 if ((i == 128) || (sum < tmp)) {
12136 plp->plp_rccap = i;
12141 bwn_phy_lp_ddfs_turnoff(mac);
12144 bwn_phy_lp_clear_deaf(mac, 1);
12145 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
12146 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
12148 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
12149 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
12150 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
12151 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
12152 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
12153 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
12154 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
12156 bwn_phy_lp_set_bbmult(mac, bbmult);
12158 bwn_phy_lp_set_txgain(mac, &tx_gains);
12159 bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
12160 if (plp->plp_rccap)
12161 bwn_phy_lp_set_rccap(mac);
12165 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
12167 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12168 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
12170 if (mac->mac_phy.rev == 1)
12171 rc_cap = MIN(rc_cap + 5, 15);
12173 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
12174 MAX(plp->plp_rccap - 4, 0x80));
12175 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
12176 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
12177 ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
12181 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
12188 for (i = 0, q = value / div, r = value % div; i < pre; i++) {
12190 if (r << 1 >= div) {
12192 r = (r << 1) - div;
12201 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
12203 struct bwn_softc *sc = mac->mac_sc;
12205 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
12207 if (siba_get_chipid(sc->sc_dev) == 0x5354) {
12208 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
12209 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
12211 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
12217 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
12220 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
12221 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
12226 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
12228 #define FLAG_A 0x01
12229 #define FLAG_G 0x02
12230 struct bwn_softc *sc = mac->mac_sc;
12231 struct ieee80211com *ic = &sc->sc_ic;
12232 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
12233 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12234 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
12235 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
12236 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
12237 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
12238 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
12239 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
12240 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
12241 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
12242 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
12243 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
12244 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
12245 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
12246 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
12247 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
12248 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
12249 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
12250 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
12251 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
12252 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
12253 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
12254 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
12255 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
12256 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
12257 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
12258 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
12259 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
12260 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
12261 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
12262 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
12263 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
12264 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
12265 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
12266 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
12267 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
12268 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
12269 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
12270 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
12271 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
12272 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
12273 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
12274 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
12275 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
12276 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
12277 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
12278 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
12279 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
12281 const struct bwn_b206x_rfinit_entry *br;
12284 for (i = 0; i < N(bwn_b2062_init_tab); i++) {
12285 br = &bwn_b2062_init_tab[i];
12286 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12287 if (br->br_flags & FLAG_G)
12288 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12290 if (br->br_flags & FLAG_A)
12291 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12299 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
12301 #define FLAG_A 0x01
12302 #define FLAG_G 0x02
12303 struct bwn_softc *sc = mac->mac_sc;
12304 struct ieee80211com *ic = &sc->sc_ic;
12305 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
12306 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
12307 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
12308 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
12309 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
12310 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
12311 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
12312 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
12313 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
12314 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
12315 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
12316 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
12317 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
12318 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
12319 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
12320 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
12321 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
12322 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
12323 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
12324 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
12325 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
12326 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
12327 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
12328 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
12329 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
12330 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
12331 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
12332 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
12333 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
12334 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
12335 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
12336 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
12337 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
12338 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
12339 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
12340 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
12341 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
12342 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
12343 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
12344 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
12345 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
12346 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
12347 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
12349 const struct bwn_b206x_rfinit_entry *br;
12352 for (i = 0; i < N(bwn_b2063_init_tab); i++) {
12353 br = &bwn_b2063_init_tab[i];
12354 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12355 if (br->br_flags & FLAG_G)
12356 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
12358 if (br->br_flags & FLAG_A)
12359 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
12367 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
12368 int count, void *_data)
12371 uint32_t offset, type;
12372 uint8_t *data = _data;
12374 type = BWN_TAB_GETTYPE(typenoffset);
12375 offset = BWN_TAB_GETOFFSET(typenoffset);
12376 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12378 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12380 for (i = 0; i < count; i++) {
12383 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
12386 case BWN_TAB_16BIT:
12387 *((uint16_t *)data) = BWN_PHY_READ(mac,
12388 BWN_PHY_TABLEDATALO);
12391 case BWN_TAB_32BIT:
12392 *((uint32_t *)data) = BWN_PHY_READ(mac,
12393 BWN_PHY_TABLEDATAHI);
12394 *((uint32_t *)data) <<= 16;
12395 *((uint32_t *)data) |= BWN_PHY_READ(mac,
12396 BWN_PHY_TABLEDATALO);
12400 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12406 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
12407 int count, const void *_data)
12409 uint32_t offset, type, value;
12410 const uint8_t *data = _data;
12413 type = BWN_TAB_GETTYPE(typenoffset);
12414 offset = BWN_TAB_GETOFFSET(typenoffset);
12415 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
12417 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
12419 for (i = 0; i < count; i++) {
12424 KASSERT(!(value & ~0xff),
12425 ("%s:%d: fail", __func__, __LINE__));
12426 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12428 case BWN_TAB_16BIT:
12429 value = *((const uint16_t *)data);
12431 KASSERT(!(value & ~0xffff),
12432 ("%s:%d: fail", __func__, __LINE__));
12433 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12435 case BWN_TAB_32BIT:
12436 value = *((const uint32_t *)data);
12438 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
12439 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
12442 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
12447 static struct bwn_txgain
12448 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
12450 struct bwn_txgain tg;
12453 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
12454 if (mac->mac_phy.rev < 2) {
12455 tmp = BWN_PHY_READ(mac,
12456 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
12457 tg.tg_gm = tmp & 0x0007;
12458 tg.tg_pga = (tmp & 0x0078) >> 3;
12459 tg.tg_pad = (tmp & 0x780) >> 7;
12463 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
12464 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
12465 tg.tg_gm = tmp & 0xff;
12466 tg.tg_pga = (tmp >> 8) & 0xff;
12471 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
12474 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
12478 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
12482 if (mac->mac_phy.rev < 2) {
12483 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
12484 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
12485 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12486 bwn_phy_lp_set_txgain_override(mac);
12490 pa = bwn_phy_lp_get_pa_gain(mac);
12491 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
12492 (tg->tg_pga << 8) | tg->tg_gm);
12493 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
12494 tg->tg_pad | (pa << 6));
12495 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
12496 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
12497 tg->tg_pad | (pa << 8));
12498 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
12499 bwn_phy_lp_set_txgain_override(mac);
12503 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
12506 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
12510 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
12512 uint16_t trsw = (tx << 1) | rx;
12514 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
12515 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
12519 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
12521 struct bwn_softc *sc = mac->mac_sc;
12522 struct ieee80211com *ic = &sc->sc_ic;
12523 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
12525 if (mac->mac_phy.rev < 2) {
12527 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
12528 ext_lna = (gain & 2) >> 1;
12530 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12531 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12532 0xfbff, ext_lna << 10);
12533 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12534 0xf7ff, ext_lna << 11);
12535 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
12537 low_gain = gain & 0xffff;
12538 high_gain = (gain >> 16) & 0xf;
12539 ext_lna = (gain >> 21) & 0x1;
12540 trsw = ~(gain >> 20) & 0x1;
12542 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
12543 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12544 0xfdff, ext_lna << 9);
12545 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12546 0xfbff, ext_lna << 10);
12547 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
12548 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
12549 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12550 tmp = (gain >> 2) & 0x3;
12551 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
12553 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
12558 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
12559 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
12560 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
12561 if (mac->mac_phy.rev >= 2) {
12562 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
12563 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
12564 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
12565 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
12569 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
12573 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
12575 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12578 plp->plp_crsusr_off = 1;
12580 plp->plp_crssys_off = 1;
12582 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
12586 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
12588 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
12589 struct bwn_softc *sc = mac->mac_sc;
12590 struct ieee80211com *ic = &sc->sc_ic;
12593 plp->plp_crsusr_off = 0;
12595 plp->plp_crssys_off = 0;
12597 if (plp->plp_crsusr_off || plp->plp_crssys_off)
12600 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
12601 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
12603 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
12606 static unsigned int
12607 bwn_sqrt(struct bwn_mac *mac, unsigned int x)
12609 /* Table holding (10 * sqrt(x)) for x between 1 and 256. */
12610 static uint8_t sqrt_table[256] = {
12611 10, 14, 17, 20, 22, 24, 26, 28,
12612 30, 31, 33, 34, 36, 37, 38, 40,
12613 41, 42, 43, 44, 45, 46, 47, 48,
12614 50, 50, 51, 52, 53, 54, 55, 56,
12615 57, 58, 59, 60, 60, 61, 62, 63,
12616 64, 64, 65, 66, 67, 67, 68, 69,
12617 70, 70, 71, 72, 72, 73, 74, 74,
12618 75, 76, 76, 77, 78, 78, 79, 80,
12619 80, 81, 81, 82, 83, 83, 84, 84,
12620 85, 86, 86, 87, 87, 88, 88, 89,
12621 90, 90, 91, 91, 92, 92, 93, 93,
12622 94, 94, 95, 95, 96, 96, 97, 97,
12623 98, 98, 99, 100, 100, 100, 101, 101,
12624 102, 102, 103, 103, 104, 104, 105, 105,
12625 106, 106, 107, 107, 108, 108, 109, 109,
12626 110, 110, 110, 111, 111, 112, 112, 113,
12627 113, 114, 114, 114, 115, 115, 116, 116,
12628 117, 117, 117, 118, 118, 119, 119, 120,
12629 120, 120, 121, 121, 122, 122, 122, 123,
12630 123, 124, 124, 124, 125, 125, 126, 126,
12631 126, 127, 127, 128, 128, 128, 129, 129,
12632 130, 130, 130, 131, 131, 131, 132, 132,
12633 133, 133, 133, 134, 134, 134, 135, 135,
12634 136, 136, 136, 137, 137, 137, 138, 138,
12635 138, 139, 139, 140, 140, 140, 141, 141,
12636 141, 142, 142, 142, 143, 143, 143, 144,
12637 144, 144, 145, 145, 145, 146, 146, 146,
12638 147, 147, 147, 148, 148, 148, 149, 149,
12639 150, 150, 150, 150, 151, 151, 151, 152,
12640 152, 152, 153, 153, 153, 154, 154, 154,
12641 155, 155, 155, 156, 156, 156, 157, 157,
12642 157, 158, 158, 158, 159, 159, 159, 160
12650 for (tmp = 0; x >= (2 * tmp) + 1; x -= (2 * tmp++) + 1)
12654 return (sqrt_table[x - 1] / 10);
12658 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
12660 #define CALC_COEFF(_v, _x, _y, _z) do { \
12664 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
12666 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
12669 #define CALC_COEFF2(_v, _x, _y, _z) do { \
12673 _v = (_y << (31 - _x)) / (_z >> _t); \
12675 _v = (_y << (31 - _x)) / (_z << -_t); \
12677 struct bwn_phy_lp_iq_est ie;
12681 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
12685 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
12686 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
12688 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
12692 if (ie.ie_ipwr + ie.ie_qpwr < 2) {
12697 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
12698 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
12700 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
12704 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
12705 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
12712 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
12714 static const uint16_t noisescale[] = {
12715 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12716 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
12717 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
12718 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12719 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
12721 static const uint16_t crsgainnft[] = {
12722 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
12723 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
12724 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
12725 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
12728 static const uint16_t filterctl[] = {
12729 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
12732 static const uint32_t psctl[] = {
12733 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
12734 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
12735 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
12736 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
12737 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
12738 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
12739 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
12740 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
12742 static const uint16_t ofdmcckgain_r0[] = {
12743 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12744 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12745 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12746 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12749 static const uint16_t ofdmcckgain_r1[] = {
12750 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
12751 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
12752 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
12753 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
12756 static const uint16_t gaindelta[] = {
12757 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12760 static const uint32_t txpwrctl[] = {
12761 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
12762 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
12763 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
12764 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
12765 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
12766 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
12767 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
12768 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
12769 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
12770 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
12771 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
12772 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
12773 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
12774 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12775 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12776 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12777 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12778 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12779 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12780 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12781 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12782 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12783 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12784 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12785 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12786 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12787 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12788 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12789 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12790 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12791 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12792 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12793 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12794 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12795 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12796 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12797 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12798 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12799 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
12800 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
12801 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
12802 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
12803 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
12804 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
12805 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
12806 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
12807 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
12808 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
12809 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
12810 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
12811 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
12812 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
12813 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
12814 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
12815 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
12816 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
12817 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
12818 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
12819 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
12820 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
12821 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
12822 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
12823 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
12824 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
12825 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12826 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12827 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12828 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12829 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12830 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12831 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12832 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12833 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12834 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12835 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12836 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12837 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12838 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12839 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12840 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12841 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12842 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12843 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12844 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12845 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12846 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12847 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12848 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
12849 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
12850 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
12851 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
12852 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
12853 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
12854 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
12855 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
12856 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
12857 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
12858 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
12859 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
12860 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
12861 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
12862 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
12863 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
12864 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
12865 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
12866 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
12867 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
12868 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
12869 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
12870 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
12871 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
12872 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
12873 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
12874 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
12875 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
12879 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
12881 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
12882 bwn_tab_sigsq_tbl);
12883 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
12884 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
12885 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
12886 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
12887 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
12888 bwn_tab_pllfrac_tbl);
12889 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
12890 bwn_tabl_iqlocal_tbl);
12891 if (mac->mac_phy.rev == 0) {
12892 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
12894 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
12897 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
12899 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
12902 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
12903 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
12907 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
12909 struct bwn_softc *sc = mac->mac_sc;
12911 static const uint16_t noisescale[] = {
12912 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12913 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12914 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12915 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12916 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12917 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
12918 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
12920 static const uint32_t filterctl[] = {
12921 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
12922 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
12924 static const uint32_t psctl[] = {
12925 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
12926 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
12927 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
12928 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
12930 static const uint32_t gainidx[] = {
12931 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12932 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12933 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12934 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
12935 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
12936 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
12937 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
12938 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
12939 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
12940 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
12941 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
12942 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
12943 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
12944 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
12945 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
12946 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12947 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12948 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12949 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
12950 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
12951 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
12952 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
12953 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
12954 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
12955 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
12956 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
12957 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
12958 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
12959 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
12960 0x0000001a, 0x64ca55ad, 0x0000001a
12962 static const uint16_t auxgainidx[] = {
12963 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
12964 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
12965 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
12968 static const uint16_t swctl[] = {
12969 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
12970 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
12971 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
12972 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
12973 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
12974 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
12975 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
12976 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
12978 static const uint8_t hf[] = {
12979 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
12980 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
12982 static const uint32_t gainval[] = {
12983 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
12984 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
12985 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
12986 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
12987 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
12988 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
12989 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12990 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12991 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
12992 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
12993 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
12994 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
12995 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
12996 0x000000f1, 0x00000000, 0x00000000
12998 static const uint16_t gain[] = {
12999 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
13000 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
13001 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
13002 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
13003 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
13004 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
13005 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13006 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13007 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13008 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13009 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13010 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13012 static const uint32_t papdeps[] = {
13013 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
13014 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
13015 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
13016 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
13017 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
13018 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
13019 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
13020 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
13021 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
13022 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
13023 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
13024 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
13025 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
13027 static const uint32_t papdmult[] = {
13028 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13029 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13030 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13031 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13032 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13033 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13034 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13035 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13036 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13037 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13038 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13039 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13040 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13042 static const uint32_t gainidx_a0[] = {
13043 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
13044 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
13045 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
13046 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
13047 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
13048 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
13049 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
13050 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
13051 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
13052 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
13053 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
13054 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
13055 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
13057 static const uint16_t auxgainidx_a0[] = {
13058 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13059 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
13060 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13063 static const uint32_t gainval_a0[] = {
13064 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
13065 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
13066 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
13067 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
13068 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
13069 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
13070 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13071 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13072 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
13073 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
13074 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
13075 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
13076 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
13077 0x000000f7, 0x00000000, 0x00000000
13079 static const uint16_t gain_a0[] = {
13080 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
13081 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
13082 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
13083 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
13084 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
13085 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
13086 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13087 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13088 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13089 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13090 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
13091 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
13094 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
13096 for (i = 0; i < 704; i++)
13097 bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
13099 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
13100 bwn_tab_sigsq_tbl);
13101 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
13102 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
13103 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
13104 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
13105 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
13106 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
13107 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
13108 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
13109 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
13110 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
13111 bwn_tab_pllfrac_tbl);
13112 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
13113 bwn_tabl_iqlocal_tbl);
13114 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
13115 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
13117 if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
13118 (siba_get_chiprev(sc->sc_dev) == 0)) {
13119 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
13121 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
13123 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
13125 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
13130 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
13132 struct bwn_softc *sc = mac->mac_sc;
13133 struct ieee80211com *ic = &sc->sc_ic;
13134 static struct bwn_txgain_entry txgain_r2[] = {
13135 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
13136 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
13137 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
13138 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
13139 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
13140 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
13141 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
13142 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
13143 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
13144 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
13145 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
13146 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
13147 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
13148 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
13149 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
13150 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13151 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
13152 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
13153 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
13154 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
13155 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13156 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
13157 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
13158 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13159 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13160 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13161 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
13162 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13163 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13164 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
13165 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
13166 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
13167 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13168 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13169 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13170 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
13171 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
13172 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
13173 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
13174 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
13175 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
13176 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
13177 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
13178 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
13179 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
13180 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
13181 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
13182 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
13183 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
13184 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
13185 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
13186 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
13187 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
13188 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
13189 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
13190 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
13191 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
13192 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
13193 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
13194 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
13195 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
13196 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
13197 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
13198 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
13200 static struct bwn_txgain_entry txgain_2ghz_r2[] = {
13201 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
13202 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
13203 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
13204 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
13205 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
13206 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
13207 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
13208 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
13209 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
13210 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
13211 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
13212 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
13213 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
13214 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
13215 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
13216 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
13217 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
13218 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
13219 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
13220 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
13221 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
13222 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
13223 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
13224 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
13225 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
13226 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
13227 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
13228 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
13229 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
13230 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
13231 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
13232 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
13233 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
13234 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
13235 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
13236 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
13237 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
13238 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
13239 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
13240 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
13241 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
13242 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
13243 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
13244 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
13245 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
13246 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
13247 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
13248 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
13249 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
13250 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
13251 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
13252 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
13253 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
13254 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
13255 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
13256 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
13257 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
13258 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
13259 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
13260 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
13261 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
13262 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
13263 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
13264 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
13266 static struct bwn_txgain_entry txgain_5ghz_r2[] = {
13267 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
13268 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
13269 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
13270 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
13271 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
13272 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
13273 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
13274 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
13275 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
13276 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
13277 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
13278 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
13279 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
13280 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
13281 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
13282 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
13283 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
13284 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
13285 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
13286 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
13287 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
13288 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
13289 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
13290 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
13291 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
13292 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
13293 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
13294 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
13295 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
13296 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
13297 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
13298 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
13299 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
13300 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
13301 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
13302 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
13303 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
13304 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
13305 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
13306 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
13307 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
13308 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
13309 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
13310 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
13311 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
13312 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
13313 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
13314 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
13315 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
13316 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
13317 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
13318 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
13319 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
13320 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
13321 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
13322 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
13323 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
13324 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
13325 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
13326 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
13327 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
13328 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
13329 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
13330 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
13332 static struct bwn_txgain_entry txgain_r0[] = {
13333 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13334 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13335 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13336 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13337 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13338 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13339 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13340 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13341 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13342 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13343 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13344 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13345 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13346 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13347 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13348 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13349 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13350 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13351 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
13352 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
13353 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13354 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
13355 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
13356 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
13357 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
13358 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
13359 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
13360 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
13361 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
13362 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
13363 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
13364 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
13365 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
13366 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
13367 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
13368 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13369 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13370 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
13371 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
13372 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
13373 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
13374 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
13375 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
13376 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13377 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13378 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13379 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13380 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
13381 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
13382 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
13383 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
13384 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
13385 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
13386 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
13387 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
13388 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
13389 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
13390 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
13391 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
13392 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
13393 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
13394 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
13395 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
13396 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
13398 static struct bwn_txgain_entry txgain_2ghz_r0[] = {
13399 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13400 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13401 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13402 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13403 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13404 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13405 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13406 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13407 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13408 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13409 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13410 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13411 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13412 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13413 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13414 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13415 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13416 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13417 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13418 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13419 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13420 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13421 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13422 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13423 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13424 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13425 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13426 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13427 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13428 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13429 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13430 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13431 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13432 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
13433 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
13434 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
13435 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
13436 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
13437 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
13438 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
13439 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
13440 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
13441 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
13442 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
13443 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
13444 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
13445 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
13446 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
13447 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
13448 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
13449 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
13450 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
13451 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
13452 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
13453 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
13454 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
13455 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
13456 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
13457 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
13458 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
13459 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
13460 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
13461 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
13462 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
13464 static struct bwn_txgain_entry txgain_5ghz_r0[] = {
13465 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13466 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13467 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13468 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13469 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13470 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13471 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13472 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13473 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13474 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13475 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13476 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13477 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13478 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13479 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13480 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13481 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13482 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13483 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13484 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13485 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13486 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13487 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13488 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13489 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13490 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13491 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13492 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13493 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13494 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13495 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13496 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13497 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13498 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13499 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13500 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13501 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13502 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13503 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13504 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13505 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13506 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13507 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13508 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13509 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13510 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13511 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13512 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13513 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13514 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13515 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13516 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13517 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13518 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13519 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13520 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13521 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13522 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13523 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13524 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13525 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13526 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13527 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13528 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13530 static struct bwn_txgain_entry txgain_r1[] = {
13531 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
13532 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
13533 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
13534 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
13535 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
13536 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
13537 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
13538 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
13539 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
13540 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
13541 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
13542 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
13543 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
13544 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
13545 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
13546 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
13547 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
13548 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
13549 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
13550 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13551 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13552 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
13553 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
13554 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
13555 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
13556 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
13557 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
13558 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
13559 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
13560 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
13561 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
13562 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
13563 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
13564 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13565 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
13566 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13567 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13568 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13569 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13570 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
13571 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
13572 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
13573 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
13574 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
13575 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
13576 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
13577 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
13578 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
13579 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
13580 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
13581 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
13582 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
13583 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13584 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13585 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13586 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
13587 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13588 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13589 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13590 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
13591 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
13592 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
13593 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
13594 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
13595 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13596 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
13597 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
13598 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
13599 { 7, 11, 6, 0, 71 }
13601 static struct bwn_txgain_entry txgain_2ghz_r1[] = {
13602 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
13603 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
13604 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
13605 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
13606 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
13607 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
13608 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
13609 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
13610 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
13611 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
13612 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
13613 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
13614 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
13615 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
13616 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
13617 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
13618 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
13619 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
13620 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
13621 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
13622 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
13623 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
13624 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
13625 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
13626 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
13627 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
13628 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
13629 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
13630 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
13631 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
13632 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
13633 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
13634 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
13635 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
13636 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
13637 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
13638 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
13639 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
13640 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
13641 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
13642 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
13643 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
13644 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
13645 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
13646 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
13647 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
13648 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
13649 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
13650 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
13651 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
13652 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
13653 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
13654 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
13655 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
13656 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
13657 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
13658 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
13659 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
13660 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
13661 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
13662 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
13663 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
13664 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
13665 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
13667 static struct bwn_txgain_entry txgain_5ghz_r1[] = {
13668 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
13669 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
13670 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
13671 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
13672 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
13673 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
13674 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
13675 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
13676 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
13677 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
13678 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
13679 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
13680 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
13681 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
13682 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
13683 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
13684 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
13685 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
13686 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
13687 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
13688 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
13689 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
13690 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
13691 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
13692 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
13693 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
13694 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
13695 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
13696 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
13697 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
13698 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
13699 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
13700 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
13701 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
13702 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
13703 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
13704 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
13705 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
13706 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
13707 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
13708 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
13709 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
13710 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
13711 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
13712 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
13713 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
13714 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
13715 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
13716 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
13717 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
13718 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
13719 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
13720 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
13721 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
13722 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
13723 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
13724 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
13725 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
13726 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
13727 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
13728 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
13729 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
13730 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
13731 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
13734 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
13735 if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
13736 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
13737 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13738 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13741 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13746 if (mac->mac_phy.rev == 0) {
13747 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13748 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13749 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
13750 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13751 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13754 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
13759 if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
13760 (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
13761 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
13762 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
13763 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
13765 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
13769 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
13771 uint32_t offset, type;
13773 type = BWN_TAB_GETTYPE(typeoffset);
13774 offset = BWN_TAB_GETOFFSET(typeoffset);
13775 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13779 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
13780 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13781 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13783 case BWN_TAB_16BIT:
13784 KASSERT(!(value & ~0xffff),
13785 ("%s:%d: fail", __func__, __LINE__));
13786 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13787 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13789 case BWN_TAB_32BIT:
13790 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13791 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
13792 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
13795 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13800 bwn_phy_lp_loopback(struct bwn_mac *mac)
13802 struct bwn_phy_lp_iq_est ie;
13806 memset(&ie, 0, sizeof(ie));
13808 bwn_phy_lp_set_trsw_over(mac, 1, 1);
13809 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
13810 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
13811 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
13812 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
13813 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
13814 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
13815 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
13816 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
13817 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
13818 for (i = 0; i < 32; i++) {
13819 bwn_phy_lp_set_rxgain_idx(mac, i);
13820 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
13821 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
13823 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
13824 if ((tmp > 4000) && (tmp < 10000)) {
13829 bwn_phy_lp_ddfs_turnoff(mac);
13834 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
13837 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
13841 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
13842 int incr1, int incr2, int scale_idx)
13845 bwn_phy_lp_ddfs_turnoff(mac);
13846 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
13847 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
13848 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
13849 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
13850 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
13851 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
13852 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
13853 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
13854 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
13855 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
13859 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
13860 struct bwn_phy_lp_iq_est *ie)
13864 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
13865 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
13866 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
13867 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
13868 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
13870 for (i = 0; i < 500; i++) {
13871 if (!(BWN_PHY_READ(mac,
13872 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
13876 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
13877 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
13881 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
13882 ie->ie_iqprod <<= 16;
13883 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
13884 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
13885 ie->ie_ipwr <<= 16;
13886 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
13887 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
13888 ie->ie_qpwr <<= 16;
13889 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
13891 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
13896 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
13898 uint32_t offset, type, value;
13900 type = BWN_TAB_GETTYPE(typeoffset);
13901 offset = BWN_TAB_GETOFFSET(typeoffset);
13902 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
13906 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13907 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
13909 case BWN_TAB_16BIT:
13910 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13911 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
13913 case BWN_TAB_32BIT:
13914 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
13915 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
13917 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
13920 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
13928 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
13931 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
13932 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
13936 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
13940 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
13942 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
13946 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
13949 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
13950 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
13954 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
13957 if (mac->mac_phy.rev < 2)
13958 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
13960 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
13961 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
13963 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
13967 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
13970 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
13974 bwn_nbits(int32_t val)
13979 for (tmp = abs(val); tmp != 0; tmp >>= 1)
13985 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
13986 struct bwn_txgain_entry *table)
13990 for (i = offset; i < count; i++)
13991 bwn_phy_lp_gaintbl_write(mac, i, table[i]);
13995 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
13996 struct bwn_txgain_entry data)
13999 if (mac->mac_phy.rev >= 2)
14000 bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
14002 bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
14006 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
14007 struct bwn_txgain_entry te)
14009 struct bwn_softc *sc = mac->mac_sc;
14010 struct ieee80211com *ic = &sc->sc_ic;
14013 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
14015 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
14016 if (mac->mac_phy.rev >= 3) {
14017 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14018 (0x10 << 24) : (0x70 << 24));
14020 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
14021 (0x14 << 24) : (0x7f << 24));
14023 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
14024 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
14025 te.te_bbmult << 20 | te.te_dac << 28);
14029 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
14030 struct bwn_txgain_entry te)
14033 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
14035 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
14036 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) |
14038 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
14042 bwn_sysctl_node(struct bwn_softc *sc)
14044 device_t dev = sc->sc_dev;
14045 struct bwn_mac *mac;
14046 struct bwn_stats *stats;
14048 /* XXX assume that count of MAC is only 1. */
14050 if ((mac = sc->sc_curmac) == NULL)
14052 stats = &mac->mac_stats;
14054 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14055 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14056 "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
14057 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14058 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14059 "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
14060 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
14061 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14062 "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
14065 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
14066 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
14067 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
14071 static device_method_t bwn_methods[] = {
14072 /* Device interface */
14073 DEVMETHOD(device_probe, bwn_probe),
14074 DEVMETHOD(device_attach, bwn_attach),
14075 DEVMETHOD(device_detach, bwn_detach),
14076 DEVMETHOD(device_suspend, bwn_suspend),
14077 DEVMETHOD(device_resume, bwn_resume),
14080 static driver_t bwn_driver = {
14083 sizeof(struct bwn_softc)
14085 static devclass_t bwn_devclass;
14086 DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0);
14087 MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
14088 MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */
14089 MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */
14090 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);