bwi.c revision 1.45 1 /* $NetBSD: bwi.c,v 1.45 2025/10/23 21:19:25 jmcneill Exp $ */
2 /* $OpenBSD: bwi.c,v 1.74 2008/02/25 21:13:30 mglocker Exp $ */
3
4 /*
5 * Copyright (c) 2007 The DragonFly Project. All rights reserved.
6 *
7 * This code is derived from software contributed to The DragonFly Project
8 * by Sepherosa Ziehau <sepherosa (at) gmail.com>
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 * 3. Neither the name of The DragonFly Project nor the names of its
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific, prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
32 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
34 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * $DragonFly: src/sys/dev/netif/bwi/bwimac.c,v 1.1 2007/09/08 06:15:54 sephe Exp $
38 */
39
40 /*
41 * Broadcom AirForce BCM43xx IEEE 802.11b/g wireless network driver
42 * Generic back end
43 */
44
45 /* [TRC: XXX Names beginning with `bwi_ieee80211_*' are those that I
46 think should be in NetBSD's generic 802.11 code, not in this
47 driver.] */
48
49
50 #include <sys/cdefs.h>
51 __KERNEL_RCSID(0, "$NetBSD: bwi.c,v 1.45 2025/10/23 21:19:25 jmcneill Exp $");
52
53 #include <sys/param.h>
54 #include <sys/callout.h>
55 #include <sys/device.h>
56 #include <sys/kernel.h>
57 #include <sys/malloc.h>
58 #include <sys/mbuf.h>
59 #include <sys/socket.h>
60 #include <sys/sockio.h>
61 #include <sys/sysctl.h>
62 #include <sys/systm.h>
63 #include <sys/bus.h>
64 #include <sys/intr.h>
65 #include <sys/pool.h>
66 #include <sys/workqueue.h>
67 #include <sys/mutex.h>
68 #include <sys/kmem.h>
69
70 #include <machine/endian.h>
71
72 #include <dev/firmload.h>
73
74 #include <net/if.h>
75 #include <net/if_dl.h>
76 #include <net/if_ether.h>
77 #include <net/if_media.h>
78
79 #include <net/bpf.h>
80
81 #include <net80211/ieee80211_var.h>
82 /* [TRC: XXX amrr] */
83 #include <net80211/ieee80211_amrr.h>
84 #include <net80211/ieee80211_radiotap.h>
85
86 #include <dev/ic/bwireg.h>
87 #include <dev/ic/bwivar.h>
88
89 #ifdef BWI_DEBUG
90 int bwi_debug = 0;
91
92 #define DPRINTF(sc, dbg, fmt, ...) \
93 do { \
94 if ((sc)->sc_debug & (dbg)) \
95 device_printf((sc)->sc_dev, fmt, ##__VA_ARGS__); \
96 } while (0)
97
98 #else /* !BWI_DEBUG */
99
100 #define DPRINTF(sc, dbg, fmt, ...) ((void)0)
101
102 #endif /* BWI_DEBUG */
103
104 /* XXX temporary porting goop */
105 #include <dev/pci/pcireg.h>
106 #include <dev/pci/pcidevs.h>
107
108 /* XXX does not belong here */
109 #define IEEE80211_OFDM_PLCP_RATE_MASK 0x0000000f
110 #define IEEE80211_OFDM_PLCP_LEN_MASK 0x0001ffe0
111
112 /*
113 * Contention window (slots). [TRC: dfly/net80211/80211.h]
114 */
115 #define IEEE80211_CW_MAX 1023 /* aCWmax */
116 #define IEEE80211_CW_MIN_0 31 /* DS/CCK aCWmin, ERP aCWmin(0) */
117 #define IEEE80211_CW_MIN_1 15 /* OFDM aCWmin, ERP aCWmin(1) */
118
119 /*
120 * Slot time (microseconds). [TRC: dfly/net80211/80211.h]
121 */
122 #define IEEE80211_DUR_SLOT 20 /* DS/CCK slottime, ERP long slottime */
123 #define IEEE80211_DUR_SHSLOT 9 /* ERP short slottime */
124 #define IEEE80211_DUR_OFDM_SLOT 9 /* OFDM slottime */
125
126 /* XXX end porting goop */
127
128 /* MAC */
129 struct bwi_retry_lim {
130 uint16_t shretry;
131 uint16_t shretry_fb;
132 uint16_t lgretry;
133 uint16_t lgretry_fb;
134 };
135
136 struct bwi_clock_freq {
137 uint clkfreq_min;
138 uint clkfreq_max;
139 };
140
141 /* XXX does not belong here */
142 struct ieee80211_ds_plcp_hdr {
143 uint8_t i_signal;
144 uint8_t i_service;
145 uint16_t i_length;
146 uint16_t i_crc;
147 } __packed;
148
149 static void bwi_sysctlattach(struct bwi_softc *);
150
151 /* MAC */
152 static void bwi_tmplt_write_4(struct bwi_mac *, uint32_t, uint32_t);
153 static void bwi_hostflags_write(struct bwi_mac *, uint64_t);
154 static uint64_t bwi_hostflags_read(struct bwi_mac *);
155 static uint16_t bwi_memobj_read_2(struct bwi_mac *, uint16_t, uint16_t);
156 static uint32_t bwi_memobj_read_4(struct bwi_mac *, uint16_t, uint16_t);
157 static void bwi_memobj_write_2(struct bwi_mac *, uint16_t, uint16_t,
158 uint16_t);
159 static void bwi_memobj_write_4(struct bwi_mac *, uint16_t, uint16_t,
160 uint32_t);
161 static int bwi_mac_lateattach(struct bwi_mac *);
162 static int bwi_mac_init(struct bwi_mac *);
163 static void bwi_mac_reset(struct bwi_mac *, int);
164 static void bwi_mac_set_tpctl_11bg(struct bwi_mac *,
165 const struct bwi_tpctl *);
166 static int bwi_mac_test(struct bwi_mac *);
167 static void bwi_mac_setup_tpctl(struct bwi_mac *);
168 static void bwi_mac_dummy_xmit(struct bwi_mac *);
169 static void bwi_mac_init_tpctl_11bg(struct bwi_mac *);
170 static void bwi_mac_detach(struct bwi_mac *);
171 static int bwi_mac_fw_alloc(struct bwi_mac *);
172 static void bwi_mac_fw_free(struct bwi_mac *);
173 static int bwi_mac_fw_image_alloc(struct bwi_mac *, const char *,
174 int idx, struct bwi_fw_image *, uint8_t);
175 static void bwi_mac_fw_image_free(struct bwi_mac *, struct bwi_fw_image *);
176 static int bwi_mac_fw_load(struct bwi_mac *);
177 static int bwi_mac_gpio_init(struct bwi_mac *);
178 static int bwi_mac_gpio_fini(struct bwi_mac *);
179 static int bwi_mac_fw_load_iv(struct bwi_mac *,
180 const struct bwi_fw_image *);
181 static int bwi_mac_fw_init(struct bwi_mac *);
182 static void bwi_mac_opmode_init(struct bwi_mac *);
183 static void bwi_mac_hostflags_init(struct bwi_mac *);
184 static void bwi_mac_bss_param_init(struct bwi_mac *);
185 static void bwi_mac_set_retry_lim(struct bwi_mac *,
186 const struct bwi_retry_lim *);
187 static void bwi_mac_set_ackrates(struct bwi_mac *,
188 const struct ieee80211_rateset *);
189 static int bwi_mac_start(struct bwi_mac *);
190 static int bwi_mac_stop(struct bwi_mac *);
191 static int bwi_mac_config_ps(struct bwi_mac *);
192 static void bwi_mac_reset_hwkeys(struct bwi_mac *);
193 static void bwi_mac_shutdown(struct bwi_mac *);
194 static int bwi_mac_get_property(struct bwi_mac *);
195 static void bwi_mac_updateslot(struct bwi_mac *, int);
196 static int bwi_mac_attach(struct bwi_softc *, int, uint8_t);
197 static void bwi_mac_balance_atten(int *, int *);
198 static void bwi_mac_adjust_tpctl(struct bwi_mac *, int, int);
199 static void bwi_mac_calibrate_txpower(struct bwi_mac *,
200 enum bwi_txpwrcb_type);
201 static void bwi_mac_lock(struct bwi_mac *);
202 static void bwi_mac_unlock(struct bwi_mac *);
203 static void bwi_mac_set_promisc(struct bwi_mac *, int);
204
205 /* PHY */
206 static void bwi_phy_write(struct bwi_mac *, uint16_t, uint16_t);
207 static uint16_t bwi_phy_read(struct bwi_mac *, uint16_t);
208 static int bwi_phy_attach(struct bwi_mac *);
209 static void bwi_phy_set_bbp_atten(struct bwi_mac *, uint16_t);
210 static int bwi_phy_calibrate(struct bwi_mac *);
211 static void bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t);
212 static void bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t);
213 static void bwi_nrssi_write(struct bwi_mac *, uint16_t, int16_t);
214 static int16_t bwi_nrssi_read(struct bwi_mac *, uint16_t);
215 static void bwi_phy_init_11a(struct bwi_mac *);
216 static void bwi_phy_init_11g(struct bwi_mac *);
217 static void bwi_phy_init_11b_rev2(struct bwi_mac *);
218 static void bwi_phy_init_11b_rev4(struct bwi_mac *);
219 static void bwi_phy_init_11b_rev5(struct bwi_mac *);
220 static void bwi_phy_init_11b_rev6(struct bwi_mac *);
221 static void bwi_phy_config_11g(struct bwi_mac *);
222 static void bwi_phy_config_agc(struct bwi_mac *);
223 static void bwi_set_gains(struct bwi_mac *, const struct bwi_gains *);
224 static void bwi_phy_clear_state(struct bwi_phy *);
225
226 /* RF */
227 static int16_t bwi_nrssi_11g(struct bwi_mac *);
228 static struct bwi_rf_lo
229 *bwi_get_rf_lo(struct bwi_mac *, uint16_t, uint16_t);
230 static int bwi_rf_lo_isused(struct bwi_mac *, const struct bwi_rf_lo *);
231 static void bwi_rf_write(struct bwi_mac *, uint16_t, uint16_t);
232 static uint16_t bwi_rf_read(struct bwi_mac *, uint16_t);
233 static int bwi_rf_attach(struct bwi_mac *);
234 static void bwi_rf_set_chan(struct bwi_mac *, uint, int);
235 static void bwi_rf_get_gains(struct bwi_mac *);
236 static void bwi_rf_init(struct bwi_mac *);
237 static void bwi_rf_off_11a(struct bwi_mac *);
238 static void bwi_rf_off_11bg(struct bwi_mac *);
239 static void bwi_rf_off_11g_rev5(struct bwi_mac *);
240 static void bwi_rf_workaround(struct bwi_mac *, uint);
241 static struct bwi_rf_lo
242 *bwi_rf_lo_find(struct bwi_mac *, const struct bwi_tpctl *);
243 static void bwi_rf_lo_adjust(struct bwi_mac *, const struct bwi_tpctl *);
244 static void bwi_rf_lo_write(struct bwi_mac *, const struct bwi_rf_lo *);
245 static int bwi_rf_gain_max_reached(struct bwi_mac *, int);
246 static uint16_t bwi_bitswap4(uint16_t);
247 static uint16_t bwi_phy812_value(struct bwi_mac *, uint16_t);
248 static void bwi_rf_init_bcm2050(struct bwi_mac *);
249 static uint16_t bwi_rf_calibval(struct bwi_mac *);
250 static int32_t _bwi_adjust_devide(int32_t, int32_t);
251 static int bwi_rf_calc_txpower(int8_t *, uint8_t, const int16_t[]);
252 static int bwi_rf_map_txpower(struct bwi_mac *);
253 static void bwi_rf_lo_update_11g(struct bwi_mac *);
254 static uint32_t bwi_rf_lo_devi_measure(struct bwi_mac *, uint16_t);
255 static uint16_t bwi_rf_get_tp_ctrl2(struct bwi_mac *);
256 static uint8_t _bwi_rf_lo_update_11g(struct bwi_mac *, uint16_t);
257 static void bwi_rf_lo_measure_11g(struct bwi_mac *,
258 const struct bwi_rf_lo *, struct bwi_rf_lo *, uint8_t);
259 static void bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *);
260 static void bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *);
261 static void bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *);
262 static void bwi_rf_init_sw_nrssi_table(struct bwi_mac *);
263 static void bwi_rf_init_hw_nrssi_table(struct bwi_mac *, uint16_t);
264 static void bwi_rf_set_nrssi_thr_11b(struct bwi_mac *);
265 static int32_t _nrssi_threshold(const struct bwi_rf *, int32_t);
266 static void bwi_rf_set_nrssi_thr_11g(struct bwi_mac *);
267 static void bwi_rf_clear_tssi(struct bwi_mac *);
268 static void bwi_rf_clear_state(struct bwi_rf *);
269 static void bwi_rf_on_11a(struct bwi_mac *);
270 static void bwi_rf_on_11bg(struct bwi_mac *);
271 static void bwi_rf_set_ant_mode(struct bwi_mac *, int);
272 static int bwi_rf_get_latest_tssi(struct bwi_mac *, int8_t[], uint16_t);
273 static int bwi_rf_tssi2dbm(struct bwi_mac *, int8_t, int8_t *);
274 static int bwi_rf_calc_rssi_bcm2050(struct bwi_mac *,
275 const struct bwi_rxbuf_hdr *);
276 static int bwi_rf_calc_rssi_bcm2053(struct bwi_mac *,
277 const struct bwi_rxbuf_hdr *);
278 static int bwi_rf_calc_rssi_bcm2060(struct bwi_mac *,
279 const struct bwi_rxbuf_hdr *);
280 static uint16_t bwi_rf_lo_measure_11b(struct bwi_mac *);
281 static void bwi_rf_lo_update_11b(struct bwi_mac *);
282
283 /* INTERFACE */
284 static uint16_t bwi_read_sprom(struct bwi_softc *, uint16_t);
285 static void bwi_setup_desc32(struct bwi_softc *, struct bwi_desc32 *, int,
286 int, bus_addr_t, int, int);
287 static void bwi_power_on(struct bwi_softc *, int);
288 static int bwi_power_off(struct bwi_softc *, int);
289 static int bwi_regwin_switch(struct bwi_softc *, struct bwi_regwin *,
290 struct bwi_regwin **);
291 static int bwi_regwin_select(struct bwi_softc *, int);
292 static void bwi_regwin_info(struct bwi_softc *, uint16_t *, uint8_t *);
293 static void bwi_led_attach(struct bwi_softc *);
294 static void bwi_led_newstate(struct bwi_softc *, enum ieee80211_state);
295 static uint16_t bwi_led_onoff(const struct bwi_led *, uint16_t, int);
296 static void bwi_led_event(struct bwi_softc *, int);
297 static void bwi_led_blink_start(struct bwi_softc *, int, int);
298 static void bwi_led_blink_next(void *);
299 static void bwi_led_blink_end(void *);
300 static int bwi_bbp_attach(struct bwi_softc *);
301 static int bwi_bus_init(struct bwi_softc *, struct bwi_mac *);
302 static void bwi_get_card_flags(struct bwi_softc *);
303 static void bwi_get_eaddr(struct bwi_softc *, uint16_t, uint8_t *);
304 static void bwi_get_clock_freq(struct bwi_softc *,
305 struct bwi_clock_freq *);
306 static int bwi_set_clock_mode(struct bwi_softc *, enum bwi_clock_mode);
307 static int bwi_set_clock_delay(struct bwi_softc *);
308 static int bwi_init(struct ifnet *);
309 static void bwi_init_statechg(struct bwi_softc *, int);
310 static int bwi_ioctl(struct ifnet *, u_long, void *);
311 static void bwi_start(struct ifnet *);
312 static void bwi_watchdog(struct ifnet *);
313 static void bwi_stop(struct ifnet *, int);
314 static void bwi_newstate_begin(struct bwi_softc *, enum ieee80211_state);
315 static int bwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
316 static int bwi_newstate_sdio(struct ieee80211com *, enum ieee80211_state,
317 int);
318 static int bwi_media_change(struct ifnet *);
319 static void bwi_task(struct work *, void *);
320 /* [TRC: XXX amrr] */
321 static void bwi_iter_func(void *, struct ieee80211_node *);
322 static void bwi_amrr_timeout(void *);
323 static void bwi_newassoc(struct ieee80211_node *, int);
324 static struct ieee80211_node *
325 bwi_node_alloc(struct ieee80211_node_table *);
326 static int bwi_pio_alloc(struct bwi_softc *);
327 static void bwi_pio_free(struct bwi_softc *);
328 static int bwi_dma_alloc(struct bwi_softc *);
329 static void bwi_dma_free(struct bwi_softc *);
330 static void bwi_ring_data_free(struct bwi_ring_data *, struct bwi_softc *);
331 static int bwi_dma_ring_alloc(struct bwi_softc *,
332 struct bwi_ring_data *, bus_size_t, uint32_t);
333 static int bwi_dma_txstats_alloc(struct bwi_softc *, uint32_t,
334 bus_size_t);
335 static void bwi_dma_txstats_free(struct bwi_softc *);
336 static int bwi_dma_mbuf_create(struct bwi_softc *);
337 static void bwi_dma_mbuf_destroy(struct bwi_softc *, int, int);
338 static void bwi_enable_intrs(struct bwi_softc *, uint32_t);
339 static void bwi_disable_intrs(struct bwi_softc *, uint32_t);
340 static int bwi_init_tx_ring_pio(struct bwi_softc *, int);
341 static int bwi_init_rx_ring_pio(struct bwi_softc *);
342 static int bwi_init_txstats_pio(struct bwi_softc *);
343 static void bwi_setup_rx_desc_pio(struct bwi_softc *, int, bus_addr_t,
344 int);
345 static void bwi_setup_tx_desc_pio(struct bwi_softc *,
346 struct bwi_ring_data *, int, bus_addr_t, int);
347 static int bwi_init_tx_ring32(struct bwi_softc *, int);
348 static void bwi_init_rxdesc_ring32(struct bwi_softc *, uint32_t,
349 bus_addr_t, int, int);
350 static int bwi_init_rx_ring32(struct bwi_softc *);
351 static int bwi_init_txstats32(struct bwi_softc *);
352 static void bwi_setup_rx_desc32(struct bwi_softc *, int, bus_addr_t, int);
353 static void bwi_setup_tx_desc32(struct bwi_softc *, struct bwi_ring_data *,
354 int, bus_addr_t, int);
355 static int bwi_init_tx_ring64(struct bwi_softc *, int);
356 static int bwi_init_rx_ring64(struct bwi_softc *);
357 static int bwi_init_txstats64(struct bwi_softc *);
358 static void bwi_setup_rx_desc64(struct bwi_softc *, int, bus_addr_t, int);
359 static void bwi_setup_tx_desc64(struct bwi_softc *, struct bwi_ring_data *,
360 int, bus_addr_t, int);
361 static int bwi_newbuf(struct bwi_softc *, int, int);
362 static void bwi_set_addr_filter(struct bwi_softc *, uint16_t,
363 const uint8_t *);
364 static int bwi_set_chan(struct bwi_softc *, struct ieee80211_channel *);
365 static void bwi_next_scan(void *);
366 static int bwi_rxeof(struct bwi_softc *, int);
367 static int bwi_rxeof_pio(struct bwi_softc *);
368 static int bwi_rxeof32(struct bwi_softc *);
369 static int bwi_rxeof64(struct bwi_softc *);
370 static void bwi_free_txstats_pio(struct bwi_softc *);
371 static void bwi_free_rx_ring_pio(struct bwi_softc *);
372 static void bwi_free_tx_ring_pio(struct bwi_softc *, int);
373 static void bwi_reset_rx_ring32(struct bwi_softc *, uint32_t);
374 static void bwi_free_txstats32(struct bwi_softc *);
375 static void bwi_free_rx_ring32(struct bwi_softc *);
376 static void bwi_free_tx_ring32(struct bwi_softc *, int);
377 static void bwi_free_txstats64(struct bwi_softc *);
378 static void bwi_free_rx_ring64(struct bwi_softc *);
379 static void bwi_free_tx_ring64(struct bwi_softc *, int);
380 static uint8_t bwi_ieee80211_rate2plcp(uint8_t rate, enum ieee80211_phymode);
381 static uint8_t bwi_ieee80211_plcp2rate(uint8_t rate, enum ieee80211_phymode);
382 static enum bwi_ieee80211_modtype
383 bwi_ieee80211_rate2modtype(uint8_t rate);
384 static uint8_t bwi_ofdm_plcp2rate(const void *);
385 static uint8_t bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *);
386 static void bwi_ofdm_plcp_header(uint32_t *, int, uint8_t);
387 static void bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *, int,
388 uint8_t);
389 static void bwi_plcp_header(void *, int, uint8_t);
390 static int bwi_encap(struct bwi_softc *, int, struct mbuf *,
391 struct ieee80211_node **, int);
392 static void bwi_start_tx_pio(struct bwi_softc *, uint32_t, int);
393 static void bwi_start_tx32(struct bwi_softc *, uint32_t, int);
394 static void bwi_start_tx64(struct bwi_softc *, uint32_t, int);
395 static void bwi_txeof_status_pio(struct bwi_softc *);
396 static void bwi_txeof_status32(struct bwi_softc *);
397 static void bwi_txeof_status64(struct bwi_softc *);
398 static void _bwi_txeof(struct bwi_softc *, uint16_t, uint8_t);
399 static void bwi_txeof_status(struct bwi_softc *, int);
400 static void bwi_txeof(struct bwi_softc *);
401 static int bwi_bbp_power_on(struct bwi_softc *, enum bwi_clock_mode);
402 static void bwi_bbp_power_off(struct bwi_softc *);
403 static int bwi_get_pwron_delay(struct bwi_softc *sc);
404 static int bwi_bus_attach(struct bwi_softc *);
405 static const char
406 *bwi_regwin_name(const struct bwi_regwin *);
407 static int bwi_regwin_is_enabled(struct bwi_softc *, struct bwi_regwin *);
408 static uint32_t bwi_regwin_disable_bits(struct bwi_softc *);
409 static void bwi_regwin_enable(struct bwi_softc *, struct bwi_regwin *,
410 uint32_t);
411 static void bwi_regwin_disable(struct bwi_softc *, struct bwi_regwin *,
412 uint32_t);
413 static void bwi_set_bssid(struct bwi_softc *, const uint8_t *);
414 static void bwi_updateslot(struct ifnet *);
415 static void bwi_updateslot_sdio(struct ifnet *);
416 static void bwi_do_calibrate(struct bwi_softc *);
417 static void bwi_calibrate(void *);
418 static int bwi_calc_rssi(struct bwi_softc *,
419 const struct bwi_rxbuf_hdr *);
420 static uint8_t bwi_ieee80211_ack_rate(struct ieee80211_node *, uint8_t);
421 static uint16_t bwi_ieee80211_txtime(struct ieee80211com *,
422 struct ieee80211_node *, uint, uint8_t, uint32_t);
423
424 /* MAC */
425 static const uint8_t bwi_sup_macrev[] = { 2, 4, 5, 6, 7, 9, 10, 12 };
426
427 /* PHY */
428 #define SUP_BPHY(num) { .rev = num, .init = bwi_phy_init_11b_rev##num }
429
430 static const struct {
431 uint8_t rev;
432 void (*init)(struct bwi_mac *);
433 } bwi_sup_bphy[] = {
434 SUP_BPHY(2),
435 SUP_BPHY(4),
436 SUP_BPHY(5),
437 SUP_BPHY(6)
438 };
439
440 #undef SUP_BPHY
441
442 #define BWI_PHYTBL_WRSSI 0x1000
443 #define BWI_PHYTBL_NOISE_SCALE 0x1400
444 #define BWI_PHYTBL_NOISE 0x1800
445 #define BWI_PHYTBL_ROTOR 0x2000
446 #define BWI_PHYTBL_DELAY 0x2400
447 #define BWI_PHYTBL_RSSI 0x4000
448 #define BWI_PHYTBL_SIGMA_SQ 0x5000
449 #define BWI_PHYTBL_WRSSI_REV1 0x5400
450 #define BWI_PHYTBL_FREQ 0x5800
451
452 static const uint16_t bwi_phy_freq_11g_rev1[] =
453 { BWI_PHY_FREQ_11G_REV1 };
454 static const uint16_t bwi_phy_noise_11g_rev1[] =
455 { BWI_PHY_NOISE_11G_REV1 };
456 static const uint16_t bwi_phy_noise_11g[] =
457 { BWI_PHY_NOISE_11G };
458 static const uint32_t bwi_phy_rotor_11g_rev1[] =
459 { BWI_PHY_ROTOR_11G_REV1 };
460 static const uint16_t bwi_phy_noise_scale_11g_rev2[] =
461 { BWI_PHY_NOISE_SCALE_11G_REV2 };
462 static const uint16_t bwi_phy_noise_scale_11g_rev7[] =
463 { BWI_PHY_NOISE_SCALE_11G_REV7 };
464 static const uint16_t bwi_phy_noise_scale_11g[] =
465 { BWI_PHY_NOISE_SCALE_11G };
466 static const uint16_t bwi_phy_sigma_sq_11g_rev2[] =
467 { BWI_PHY_SIGMA_SQ_11G_REV2 };
468 static const uint16_t bwi_phy_sigma_sq_11g_rev7[] =
469 { BWI_PHY_SIGMA_SQ_11G_REV7 };
470 static const uint32_t bwi_phy_delay_11g_rev1[] =
471 { BWI_PHY_DELAY_11G_REV1 };
472
473 /* RF */
474 #define RF_LO_WRITE(mac, lo) bwi_rf_lo_write((mac), (lo))
475
476 #define BWI_RF_2GHZ_CHAN(chan) \
477 (ieee80211_ieee2mhz((chan), IEEE80211_CHAN_2GHZ) - 2400)
478
479 #define BWI_DEFAULT_IDLE_TSSI 52
480
481 struct rf_saveregs {
482 uint16_t phy_01;
483 uint16_t phy_03;
484 uint16_t phy_0a;
485 uint16_t phy_15;
486 uint16_t phy_2a;
487 uint16_t phy_30;
488 uint16_t phy_35;
489 uint16_t phy_60;
490 uint16_t phy_429;
491 uint16_t phy_802;
492 uint16_t phy_811;
493 uint16_t phy_812;
494 uint16_t phy_814;
495 uint16_t phy_815;
496
497 uint16_t rf_43;
498 uint16_t rf_52;
499 uint16_t rf_7a;
500 };
501
502 #define SAVE_RF_REG(mac, regs, n) (regs)->rf_##n = RF_READ((mac), 0x##n)
503 #define RESTORE_RF_REG(mac, regs, n) RF_WRITE((mac), 0x##n, (regs)->rf_##n)
504
505 #define SAVE_PHY_REG(mac, regs, n) (regs)->phy_##n = PHY_READ((mac), 0x##n)
506 #define RESTORE_PHY_REG(mac, regs, n) PHY_WRITE((mac), 0x##n, (regs)->phy_##n)
507
508 static const int8_t bwi_txpower_map_11b[BWI_TSSI_MAX] =
509 { BWI_TXPOWER_MAP_11B };
510 static const int8_t bwi_txpower_map_11g[BWI_TSSI_MAX] =
511 { BWI_TXPOWER_MAP_11G };
512
513 /* INTERFACE */
514
515 struct bwi_myaddr_bssid {
516 uint8_t myaddr[IEEE80211_ADDR_LEN];
517 uint8_t bssid[IEEE80211_ADDR_LEN];
518 } __packed;
519
520 /* [TRC: XXX What are these about?] */
521
522 #define IEEE80211_DS_PLCP_SERVICE_LOCKED 0x04
523 #define IEEE80211_DS_PLCL_SERVICE_PBCC 0x08
524 #define IEEE80211_DS_PLCP_SERVICE_LENEXT5 0x20
525 #define IEEE80211_DS_PLCP_SERVICE_LENEXT6 0x40
526 #define IEEE80211_DS_PLCP_SERVICE_LENEXT7 0x80
527
528 static const struct {
529 uint16_t did_min;
530 uint16_t did_max;
531 uint16_t bbp_id;
532 } bwi_bbpid_map[] = {
533 { 0x4301, 0x4301, 0x4301 },
534 { 0x4305, 0x4307, 0x4307 },
535 { 0x4403, 0x4403, 0x4402 },
536 { 0x4610, 0x4615, 0x4610 },
537 { 0x4710, 0x4715, 0x4710 },
538 { 0x4720, 0x4725, 0x4309 }
539 };
540
541 static const struct {
542 uint16_t bbp_id;
543 int nregwin;
544 } bwi_regwin_count[] = {
545 { 0x4301, 5 },
546 { 0x4306, 6 },
547 { 0x4307, 5 },
548 { 0x4310, 8 },
549 { 0x4401, 3 },
550 { 0x4402, 3 },
551 { 0x4610, 9 },
552 { 0x4704, 9 },
553 { 0x4710, 9 },
554 { 0x5365, 7 }
555 };
556
557 #define CLKSRC(src) \
558 [BWI_CLKSRC_ ## src] = { \
559 .freq_min = BWI_CLKSRC_ ##src## _FMIN, \
560 .freq_max = BWI_CLKSRC_ ##src## _FMAX \
561 }
562
563 static const struct {
564 uint freq_min;
565 uint freq_max;
566 } bwi_clkfreq[BWI_CLKSRC_MAX] = {
567 CLKSRC(LP_OSC),
568 CLKSRC(CS_OSC),
569 CLKSRC(PCI)
570 };
571
572 #undef CLKSRC
573
574 #define VENDOR_LED_ACT(vendor) \
575 { \
576 .vid = PCI_VENDOR_##vendor, \
577 .led_act = { BWI_VENDOR_LED_ACT_##vendor } \
578 }
579
580 static const struct {
581 uint16_t vid;
582 uint8_t led_act[BWI_LED_MAX];
583 } bwi_vendor_led_act[] = {
584 VENDOR_LED_ACT(COMPAQ),
585 VENDOR_LED_ACT(LINKSYS)
586 };
587
588 static const uint8_t bwi_default_led_act[BWI_LED_MAX] =
589 { BWI_VENDOR_LED_ACT_DEFAULT };
590
591 #undef VENDOR_LED_ACT
592
593 static const struct {
594 int on_dur;
595 int off_dur;
596 } bwi_led_duration[109] = {
597 [0] = { 400, 100 },
598 [2] = { 150, 75 },
599 [4] = { 90, 45 },
600 [11] = { 66, 34 },
601 [12] = { 53, 26 },
602 [18] = { 42, 21 },
603 [22] = { 35, 17 },
604 [24] = { 32, 16 },
605 [36] = { 21, 10 },
606 [48] = { 16, 8 },
607 [72] = { 11, 5 },
608 [96] = { 9, 4 },
609 [108] = { 7, 3 }
610 };
611
612 /* [TRC: XXX Should this be zeroed?] */
613
614 static const uint8_t bwi_zero_addr[IEEE80211_ADDR_LEN];
615
616 /* [TRC: Derived from DragonFly's src/sys/netproto/802_11/_ieee80211.h */
617
618 enum bwi_ieee80211_modtype {
619 IEEE80211_MODTYPE_DS = 0, /* DS/CCK modulation */
620 IEEE80211_MODTYPE_PBCC = 1, /* PBCC modulation */
621 IEEE80211_MODTYPE_OFDM = 2 /* OFDM modulation */
622 };
623 #define IEEE80211_MODTYPE_CCK IEEE80211_MODTYPE_DS
624
625 /*
626 * Setup sysctl(3) MIB, hw.bwi.* and hw.bwiN.*
627 */
628
629 #ifdef BWI_DEBUG
630 SYSCTL_SETUP(sysctl_bwi, "sysctl bwi(4) subtree setup")
631 {
632 int rc;
633 const struct sysctlnode *rnode;
634 const struct sysctlnode *cnode;
635
636 if ((rc = sysctl_createv(clog, 0, NULL, &rnode,
637 CTLFLAG_PERMANENT, CTLTYPE_NODE, "bwi",
638 SYSCTL_DESCR("bwi global controls"),
639 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0)
640 goto err;
641
642 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
643 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
644 "debug", SYSCTL_DESCR("default debug flags"),
645 NULL, 0, &bwi_debug, 0, CTL_CREATE, CTL_EOL)) != 0)
646 goto err;
647
648 return;
649
650 err:
651 aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
652 }
653 #endif /* BWI_DEBUG */
654
655 static void
656 bwi_sysctlattach(struct bwi_softc *sc)
657 {
658 int rc;
659 const struct sysctlnode *rnode;
660 const struct sysctlnode *cnode;
661
662 struct sysctllog **clog = &sc->sc_sysctllog;
663
664 if ((rc = sysctl_createv(clog, 0, NULL, &rnode,
665 CTLFLAG_PERMANENT, CTLTYPE_NODE, device_xname(sc->sc_dev),
666 SYSCTL_DESCR("bwi controls and statistics"),
667 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0)
668 goto err;
669
670 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
671 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
672 "fw_version", SYSCTL_DESCR("firmware version"),
673 NULL, 0, &sc->sc_fw_version, 0, CTL_CREATE, CTL_EOL)) != 0)
674 goto err;
675
676 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
677 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
678 "dwell_time", SYSCTL_DESCR("channel dwell time during scan (msec)"),
679 NULL, 0, &sc->sc_dwell_time, 0, CTL_CREATE, CTL_EOL)) != 0)
680 goto err;
681
682 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
683 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
684 "led_idle", SYSCTL_DESCR("# ticks before LED enters idle state"),
685 NULL, 0, &sc->sc_led_idle, 0, CTL_CREATE, CTL_EOL)) != 0)
686 goto err;
687
688 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
689 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
690 "led_blink", SYSCTL_DESCR("allow LED to blink"),
691 NULL, 0, &sc->sc_led_blink, 0, CTL_CREATE, CTL_EOL)) != 0)
692 goto err;
693
694 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
695 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
696 "txpwr_calib", SYSCTL_DESCR("enable software TX power calibration"),
697 NULL, 0, &sc->sc_txpwr_calib, 0, CTL_CREATE, CTL_EOL)) != 0)
698 goto err;
699
700 #ifdef BWI_DEBUG
701 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
702 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
703 "debug", SYSCTL_DESCR("debug flags"),
704 NULL, 0, &sc->sc_debug, 0, CTL_CREATE, CTL_EOL)) != 0)
705 goto err;
706 #endif
707
708 return;
709
710 err:
711 aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
712 }
713
714 /* CODE */
715
716 static void
717 bwi_softintr(void *arg)
718 {
719 struct bwi_softc *sc = arg;
720 struct bwi_mac *mac;
721 struct ifnet *ifp = &sc->sc_if;
722 const uint32_t intr_mask = BWI_INIT_INTRS;
723 uint32_t intr_status;
724 uint32_t txrx_intr_status[BWI_TXRX_NRING];
725 int i, s, txrx_error, tx = 0, rx_data = -1;
726
727 if (!device_is_active(sc->sc_dev) ||
728 (ifp->if_flags & IFF_RUNNING) == 0)
729 return;
730
731 for (;;) {
732 /*
733 * Get interrupt status
734 */
735 intr_status = CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
736 if (intr_status == 0xffffffff) /* Not for us */
737 goto out;
738
739 DPRINTF(sc, BWI_DBG_INTR,
740 "intr status 0x%08x mask 0x%08x -> 0x%08x\n",
741 intr_status, intr_mask, intr_status & intr_mask);
742 intr_status &= intr_mask;
743 if (intr_status == 0) { /* Nothing is interesting */
744 goto out;
745 }
746
747 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
748 mac = (struct bwi_mac *)sc->sc_cur_regwin;
749
750 txrx_error = 0;
751
752 for (i = 0; i < BWI_TXRX_NRING; ++i) {
753 uint32_t mask;
754
755 if (BWI_TXRX_IS_RX(i))
756 mask = BWI_TXRX_RX_INTRS;
757 else
758 mask = BWI_TXRX_TX_INTRS;
759
760 txrx_intr_status[i] =
761 CSR_READ_4(sc, BWI_TXRX_INTR_STATUS(i)) & mask;
762
763 if (txrx_intr_status[i] & BWI_TXRX_INTR_ERROR) {
764 aprint_error_dev(sc->sc_dev,
765 "intr fatal TX/RX (%d) error 0x%08x\n",
766 i, txrx_intr_status[i]);
767 txrx_error = 1;
768 }
769 }
770
771 /*
772 * Acknowledge interrupt
773 */
774 CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, intr_status);
775
776 for (i = 0; i < BWI_TXRX_NRING; ++i)
777 CSR_WRITE_4(sc, BWI_TXRX_INTR_STATUS(i),
778 txrx_intr_status[i]);
779
780 if (intr_status & BWI_INTR_PHY_TXERR) {
781 if (mac->mac_flags & BWI_MAC_F_PHYE_RESET) {
782 aprint_error_dev(sc->sc_dev,
783 "intr PHY TX error\n");
784 /* XXX to netisr0? */
785 s = splnet();
786 bwi_init_statechg(sc, 0);
787 splx(s);
788 goto out;
789 }
790 }
791
792 if (txrx_error) {
793 /* TODO: reset device */
794 }
795
796 if (intr_status & BWI_INTR_TBTT)
797 bwi_mac_config_ps(mac);
798
799 if (intr_status & BWI_INTR_EO_ATIM)
800 aprint_normal_dev(sc->sc_dev, "EO_ATIM\n");
801
802 if (intr_status & BWI_INTR_PMQ) {
803 for (;;) {
804 if ((CSR_READ_4(sc, BWI_MAC_PS_STATUS) & 0x8)
805 == 0)
806 break;
807 }
808 CSR_WRITE_2(sc, BWI_MAC_PS_STATUS, 0x2);
809 }
810
811 if (intr_status & BWI_INTR_NOISE)
812 aprint_normal_dev(sc->sc_dev, "intr noise\n");
813
814 if (txrx_intr_status[0] & BWI_TXRX_INTR_RX) {
815 rx_data = (sc->sc_rxeof)(sc);
816 }
817
818 if (txrx_intr_status[3] & BWI_TXRX_INTR_RX) {
819 (sc->sc_txeof_status)(sc);
820 tx = 1;
821 }
822
823 if (intr_status & BWI_INTR_TX_DONE) {
824 bwi_txeof(sc);
825 tx = 1;
826 }
827
828 if (sc->sc_blink_led != NULL && sc->sc_led_blink &&
829 !BWI_IS_SDIO(sc)) {
830 int evt = BWI_LED_EVENT_NONE;
831
832 if (tx && rx_data > 0) {
833 if (sc->sc_rx_rate > sc->sc_tx_rate)
834 evt = BWI_LED_EVENT_RX;
835 else
836 evt = BWI_LED_EVENT_TX;
837 } else if (tx) {
838 evt = BWI_LED_EVENT_TX;
839 } else if (rx_data > 0) {
840 evt = BWI_LED_EVENT_RX;
841 } else if (rx_data == 0) {
842 evt = BWI_LED_EVENT_POLL;
843 }
844
845 if (evt != BWI_LED_EVENT_NONE)
846 bwi_led_event(sc, evt);
847 }
848 }
849
850 out:
851 /* Re-enable interrupts */
852 bwi_enable_intrs(sc, BWI_INIT_INTRS);
853 }
854
855 int
856 bwi_intr(void *arg)
857 {
858 struct bwi_softc *sc = arg;
859 struct ifnet *ifp = &sc->sc_if;
860
861 if (!device_is_active(sc->sc_dev) ||
862 (ifp->if_flags & IFF_RUNNING) == 0)
863 return (0);
864
865 /* Disable all interrupts */
866 bwi_disable_intrs(sc, BWI_ALL_INTRS);
867
868 if (BWI_IS_SDIO(sc)) {
869 bwi_softintr(sc);
870 } else {
871 softint_schedule(sc->sc_soft_ih);
872 }
873
874 return (1);
875 }
876
877 int
878 bwi_attach(struct bwi_softc *sc)
879 {
880 struct ieee80211com *ic = &sc->sc_ic;
881 struct ifnet *ifp = &sc->sc_if;
882 struct bwi_mac *mac;
883 struct bwi_phy *phy;
884 int s, i, error;
885
886 /* [TRC: XXX Is this necessary?] */
887 s = splnet();
888
889 if (BWI_IS_SDIO(sc)) {
890 error = workqueue_create(&sc->sc_taskq,
891 device_xname(sc->sc_dev), bwi_task, sc, PRI_NONE,
892 IPL_SOFTNET, 0);
893 if (error != 0) {
894 device_printf(sc->sc_dev,
895 "failed to create workqueue\n");
896 goto fail;
897 }
898 sc->sc_freetask = pool_cache_init(sizeof(struct bwi_task),
899 0, 0, 0, "bwitask", NULL, IPL_SOFTNET, NULL, NULL, NULL);
900 pool_cache_prime(sc->sc_freetask, BWI_TASK_COUNT);
901 } else {
902 sc->sc_soft_ih = softint_establish(SOFTINT_NET, bwi_softintr,
903 sc);
904 if (sc->sc_soft_ih == NULL) {
905 error = ENXIO;
906 goto fail;
907 }
908 }
909
910 /*
911 * Initialize sysctl variables
912 */
913 sc->sc_fw_version = BWI_FW_VERSION3;
914 sc->sc_dwell_time = 200;
915 sc->sc_led_idle = (2350 * hz) / 1000;
916 sc->sc_led_blink = 1;
917 sc->sc_txpwr_calib = 1;
918 #ifdef BWI_DEBUG
919 sc->sc_debug = bwi_debug;
920 #endif
921
922 DPRINTF(sc, BWI_DBG_ATTACH, "%s\n", __func__);
923
924 /* [TRC: XXX amrr] */
925 /* AMRR rate control */
926 sc->sc_amrr.amrr_min_success_threshold = 1;
927 sc->sc_amrr.amrr_max_success_threshold = 15;
928 callout_init(&sc->sc_amrr_ch, 0);
929 callout_setfunc(&sc->sc_amrr_ch, bwi_amrr_timeout, sc);
930
931 callout_init(&sc->sc_scan_ch, 0);
932 callout_setfunc(&sc->sc_scan_ch, bwi_next_scan, sc);
933 callout_init(&sc->sc_calib_ch, 0);
934 callout_setfunc(&sc->sc_calib_ch, bwi_calibrate, sc);
935
936 bwi_sysctlattach(sc);
937
938 bwi_power_on(sc, 1);
939
940 error = bwi_bbp_attach(sc);
941 if (error)
942 goto fail;
943
944 error = bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST);
945 if (error)
946 goto fail;
947
948 if (BWI_REGWIN_EXIST(&sc->sc_com_regwin)) {
949 error = bwi_set_clock_delay(sc);
950 if (error)
951 goto fail;
952
953 error = bwi_set_clock_mode(sc, BWI_CLOCK_MODE_FAST);
954 if (error)
955 goto fail;
956
957 error = bwi_get_pwron_delay(sc);
958 if (error)
959 goto fail;
960 }
961
962 error = bwi_bus_attach(sc);
963 if (error)
964 goto fail;
965
966 bwi_get_card_flags(sc);
967
968 bwi_led_attach(sc);
969
970 for (i = 0; i < sc->sc_nmac; ++i) {
971 struct bwi_regwin *old;
972
973 mac = &sc->sc_mac[i];
974 error = bwi_regwin_switch(sc, &mac->mac_regwin, &old);
975 if (error)
976 goto fail;
977
978 error = bwi_mac_lateattach(mac);
979 if (error)
980 goto fail;
981
982 error = bwi_regwin_switch(sc, old, NULL);
983 if (error)
984 goto fail;
985 }
986
987 /*
988 * XXX First MAC is known to exist
989 * TODO2
990 */
991 mac = &sc->sc_mac[0];
992 phy = &mac->mac_phy;
993
994 bwi_bbp_power_off(sc);
995
996 if (BWI_IS_PIO(sc)) {
997 error = bwi_pio_alloc(sc);
998 } else {
999 error = bwi_dma_alloc(sc);
1000 }
1001 if (error)
1002 goto fail;
1003
1004 /* setup interface */
1005 ifp->if_softc = sc;
1006 ifp->if_init = bwi_init;
1007 ifp->if_ioctl = bwi_ioctl;
1008 ifp->if_start = bwi_start;
1009 ifp->if_watchdog = bwi_watchdog;
1010 ifp->if_stop = bwi_stop;
1011 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
1012 memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
1013 IFQ_SET_READY(&ifp->if_snd);
1014
1015 /* Get locale */
1016 sc->sc_locale = __SHIFTOUT(bwi_read_sprom(sc, BWI_SPROM_CARD_INFO),
1017 BWI_SPROM_CARD_INFO_LOCALE);
1018 DPRINTF(sc, BWI_DBG_ATTACH, "locale: %d\n", sc->sc_locale);
1019
1020 /*
1021 * Setup ratesets, phytype, channels and get MAC address
1022 */
1023 if (phy->phy_mode == IEEE80211_MODE_11B ||
1024 phy->phy_mode == IEEE80211_MODE_11G) {
1025 uint16_t chan_flags;
1026
1027 ic->ic_sup_rates[IEEE80211_MODE_11B] =
1028 ieee80211_std_rateset_11b;
1029
1030 if (phy->phy_mode == IEEE80211_MODE_11B) {
1031 chan_flags = IEEE80211_CHAN_B;
1032 ic->ic_phytype = IEEE80211_T_DS;
1033 } else {
1034 chan_flags = IEEE80211_CHAN_CCK |
1035 IEEE80211_CHAN_OFDM |
1036 IEEE80211_CHAN_DYN |
1037 IEEE80211_CHAN_2GHZ;
1038 ic->ic_phytype = IEEE80211_T_OFDM;
1039 ic->ic_sup_rates[IEEE80211_MODE_11G] =
1040 ieee80211_std_rateset_11g;
1041 }
1042
1043 /* XXX depend on locale */
1044 for (i = 1; i <= 14; ++i) {
1045 ic->ic_channels[i].ic_freq =
1046 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
1047 ic->ic_channels[i].ic_flags = chan_flags;
1048 }
1049
1050 bwi_get_eaddr(sc, BWI_SPROM_11BG_EADDR, ic->ic_myaddr);
1051 if (IEEE80211_IS_MULTICAST(ic->ic_myaddr)) {
1052 bwi_get_eaddr(sc, BWI_SPROM_11A_EADDR, ic->ic_myaddr);
1053 if (IEEE80211_IS_MULTICAST(ic->ic_myaddr))
1054 aprint_error_dev(sc->sc_dev,
1055 "invalid MAC address: %s\n",
1056 ether_sprintf(ic->ic_myaddr));
1057 }
1058 } else if (phy->phy_mode == IEEE80211_MODE_11A) {
1059 /* TODO: 11A */
1060 error = ENXIO;
1061 goto fail;
1062 } else
1063 panic("unknown phymode %d\n", phy->phy_mode);
1064
1065 ic->ic_ifp = ifp;
1066 ic->ic_caps = IEEE80211_C_SHSLOT |
1067 IEEE80211_C_SHPREAMBLE |
1068 IEEE80211_C_IBSS |
1069 IEEE80211_C_HOSTAP |
1070 IEEE80211_C_MONITOR;
1071 ic->ic_state = IEEE80211_S_INIT;
1072 ic->ic_opmode = IEEE80211_M_STA;
1073
1074 ic->ic_updateslot = BWI_IS_SDIO(sc) ?
1075 bwi_updateslot_sdio : bwi_updateslot;
1076
1077 if_initialize(ifp);
1078 ieee80211_ifattach(ic);
1079 ifp->if_percpuq = if_percpuq_create(ifp);
1080 if_register(ifp);
1081
1082 /* [TRC: XXX Not supported on NetBSD?] */
1083 /* ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; */
1084
1085 sc->sc_newstate = ic->ic_newstate;
1086 ic->ic_newstate = BWI_IS_SDIO(sc) ? bwi_newstate_sdio : bwi_newstate;
1087 /* [TRC: XXX amrr] */
1088 ic->ic_newassoc = bwi_newassoc;
1089 ic->ic_node_alloc = bwi_node_alloc;
1090
1091 ieee80211_media_init(ic, bwi_media_change, ieee80211_media_status);
1092
1093 bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
1094 sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
1095 &sc->sc_drvbpf);
1096
1097 /* [TRC: XXX DragonFlyBSD rounds this up to a multiple of
1098 sizeof(uint32_t). Should we?] */
1099 sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
1100 sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
1101 sc->sc_rxtap.wr_ihdr.it_present = htole32(BWI_RX_RADIOTAP_PRESENT);
1102
1103 sc->sc_txtap_len = sizeof(sc->sc_txtapu);
1104 sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
1105 sc->sc_txtap.wt_ihdr.it_present = htole32(BWI_TX_RADIOTAP_PRESENT);
1106
1107 splx(s);
1108 ieee80211_announce(ic);
1109 return (0);
1110 fail:
1111 /* [TRC: XXX DragonFlyBSD detaches the device here. Should we?] */
1112 splx(s);
1113 return (error);
1114 }
1115
1116 void
1117 bwi_detach(struct bwi_softc *sc)
1118 {
1119 struct ifnet *ifp = &sc->sc_if;
1120 int i, s;
1121
1122 s = splnet();
1123
1124 bwi_stop(ifp, 1);
1125
1126 bpf_detach(ifp);
1127
1128 ieee80211_ifdetach(&sc->sc_ic);
1129 if_detach(ifp);
1130
1131 for (i = 0; i < sc->sc_nmac; ++i)
1132 bwi_mac_detach(&sc->sc_mac[i]);
1133
1134 sysctl_teardown(&sc->sc_sysctllog);
1135
1136 if (sc->sc_soft_ih != NULL)
1137 softint_disestablish(sc->sc_soft_ih);
1138
1139 splx(s);
1140
1141 if (BWI_IS_PIO(sc)) {
1142 bwi_pio_free(sc);
1143 if (sc->sc_taskq != NULL) {
1144 workqueue_destroy(sc->sc_taskq);
1145 }
1146 if (sc->sc_freetask != NULL) {
1147 pool_cache_destroy(sc->sc_freetask);
1148 }
1149 } else {
1150 bwi_dma_free(sc);
1151 }
1152 }
1153
1154 /* MAC */
1155
1156 static void
1157 bwi_tmplt_write_4(struct bwi_mac *mac, uint32_t ofs, uint32_t val)
1158 {
1159 struct bwi_softc *sc = mac->mac_sc;
1160
1161 if (mac->mac_flags & BWI_MAC_F_BSWAP)
1162 val = bswap32(val);
1163
1164 CSR_WRITE_4(sc, BWI_MAC_TMPLT_CTRL, ofs);
1165 CSR_WRITE_4(sc, BWI_MAC_TMPLT_DATA, val);
1166 }
1167
1168 static void
1169 bwi_hostflags_write(struct bwi_mac *mac, uint64_t flags)
1170 {
1171 uint64_t val;
1172
1173 val = flags & 0xffff;
1174 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_LO, val);
1175
1176 val = (flags >> 16) & 0xffff;
1177 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_MI, val);
1178
1179 /* HI has unclear meaning, so leave it as it is */
1180 }
1181
1182 static uint64_t
1183 bwi_hostflags_read(struct bwi_mac *mac)
1184 {
1185 uint64_t flags, val;
1186
1187 /* HI has unclear meaning, so don't touch it */
1188 flags = 0;
1189
1190 val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_MI);
1191 flags |= val << 16;
1192
1193 val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_LO);
1194 flags |= val;
1195
1196 return (flags);
1197 }
1198
1199 static uint16_t
1200 bwi_memobj_read_2(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0)
1201 {
1202 struct bwi_softc *sc = mac->mac_sc;
1203 uint32_t data_reg;
1204 int ofs;
1205
1206 data_reg = BWI_MOBJ_DATA;
1207 ofs = ofs0 / 4;
1208
1209 if (ofs0 % 4 != 0)
1210 data_reg = BWI_MOBJ_DATA_UNALIGN;
1211
1212 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
1213 return (CSR_READ_2(sc, data_reg));
1214 }
1215
1216 static uint32_t
1217 bwi_memobj_read_4(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0)
1218 {
1219 struct bwi_softc *sc = mac->mac_sc;
1220 int ofs;
1221
1222 ofs = ofs0 / 4;
1223 if (ofs0 % 4 != 0) {
1224 uint32_t ret;
1225
1226 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
1227 ret = CSR_READ_2(sc, BWI_MOBJ_DATA_UNALIGN);
1228 ret <<= 16;
1229
1230 CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
1231 BWI_MOBJ_CTRL_VAL(obj_id, ofs + 1));
1232 ret |= CSR_READ_2(sc, BWI_MOBJ_DATA);
1233
1234 return (ret);
1235 } else {
1236 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
1237 return (CSR_READ_4(sc, BWI_MOBJ_DATA));
1238 }
1239 }
1240
1241 static void
1242 bwi_memobj_write_2(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0,
1243 uint16_t v)
1244 {
1245 struct bwi_softc *sc = mac->mac_sc;
1246 uint32_t data_reg;
1247 int ofs;
1248
1249 data_reg = BWI_MOBJ_DATA;
1250 ofs = ofs0 / 4;
1251
1252 if (ofs0 % 4 != 0)
1253 data_reg = BWI_MOBJ_DATA_UNALIGN;
1254
1255 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
1256 CSR_WRITE_2(sc, data_reg, v);
1257 }
1258
1259 static void
1260 bwi_memobj_write_4(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0,
1261 uint32_t v)
1262 {
1263 struct bwi_softc *sc = mac->mac_sc;
1264 int ofs;
1265
1266 ofs = ofs0 / 4;
1267 if (ofs0 % 4 != 0) {
1268 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
1269 CSR_WRITE_2(sc, BWI_MOBJ_DATA_UNALIGN, v >> 16);
1270 CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
1271 BWI_MOBJ_CTRL_VAL(obj_id, ofs + 1));
1272 CSR_WRITE_2(sc, BWI_MOBJ_DATA, v & 0xffff);
1273 } else {
1274 CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
1275 CSR_WRITE_4(sc, BWI_MOBJ_DATA, v);
1276 }
1277 }
1278
1279 static int
1280 bwi_mac_lateattach(struct bwi_mac *mac)
1281 {
1282 int error;
1283
1284 if (mac->mac_rev >= 5)
1285 CSR_READ_4(mac->mac_sc, BWI_STATE_HI); /* dummy read */
1286
1287 bwi_mac_reset(mac, 1);
1288
1289 error = bwi_phy_attach(mac);
1290 if (error)
1291 return (error);
1292
1293 error = bwi_rf_attach(mac);
1294 if (error)
1295 return (error);
1296
1297 /* Link 11B/G PHY, unlink 11A PHY */
1298 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A)
1299 bwi_mac_reset(mac, 0);
1300 else
1301 bwi_mac_reset(mac, 1);
1302
1303 error = bwi_mac_test(mac);
1304 if (error)
1305 return (error);
1306
1307 error = bwi_mac_get_property(mac);
1308 if (error)
1309 return (error);
1310
1311 error = bwi_rf_map_txpower(mac);
1312 if (error)
1313 return (error);
1314
1315 bwi_rf_off(mac);
1316 CSR_WRITE_2(mac->mac_sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC);
1317
1318 if (BWI_IS_PIO(mac->mac_sc)) {
1319 /* Initialize RX padding data offset */
1320 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_RXPADOFF, 0);
1321 }
1322
1323 bwi_regwin_disable(mac->mac_sc, &mac->mac_regwin, 0);
1324
1325 return (0);
1326 }
1327
1328 static int
1329 bwi_mac_init(struct bwi_mac *mac)
1330 {
1331 struct bwi_softc *sc = mac->mac_sc;
1332 int error, i;
1333
1334 /* Clear MAC/PHY/RF states */
1335 bwi_mac_setup_tpctl(mac);
1336 bwi_rf_clear_state(&mac->mac_rf);
1337 bwi_phy_clear_state(&mac->mac_phy);
1338
1339 /* Enable MAC and linked it to PHY */
1340 if (!bwi_regwin_is_enabled(sc, &mac->mac_regwin))
1341 bwi_mac_reset(mac, 1);
1342
1343 /* Initialize backplane */
1344 error = bwi_bus_init(sc, mac);
1345 if (error)
1346 return (error);
1347
1348 /* XXX work around for hardware bugs? */
1349 if (sc->sc_bus_regwin.rw_rev <= 5 &&
1350 sc->sc_bus_regwin.rw_type != BWI_REGWIN_T_BUSPCIE) {
1351 CSR_SETBITS_4(sc, BWI_CONF_LO,
1352 __SHIFTIN(BWI_CONF_LO_SERVTO, BWI_CONF_LO_SERVTO_MASK) |
1353 __SHIFTIN(BWI_CONF_LO_REQTO, BWI_CONF_LO_REQTO_MASK));
1354 }
1355
1356 /* Calibrate PHY */
1357 error = bwi_phy_calibrate(mac);
1358 if (error) {
1359 aprint_error_dev(sc->sc_dev, "PHY calibrate failed\n");
1360 return (error);
1361 }
1362
1363 /* Prepare to initialize firmware */
1364 CSR_WRITE_4(sc, BWI_MAC_STATUS,
1365 BWI_MAC_STATUS_UCODE_JUMP0 |
1366 BWI_MAC_STATUS_IHREN);
1367
1368 /*
1369 * Load and initialize firmwares
1370 */
1371 error = bwi_mac_fw_alloc(mac);
1372 if (error)
1373 return (error);
1374
1375 error = bwi_mac_fw_load(mac);
1376 if (error)
1377 return (error);
1378
1379 error = bwi_mac_gpio_init(mac);
1380 if (error)
1381 return (error);
1382
1383 error = bwi_mac_fw_init(mac);
1384 if (error)
1385 return (error);
1386
1387 /*
1388 * Turn on RF
1389 */
1390 bwi_rf_on(mac);
1391
1392 /* TODO: LED, hardware rf enabled is only related to LED setting */
1393
1394 /*
1395 * Initialize PHY
1396 */
1397 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
1398 bwi_phy_init(mac);
1399
1400 /* TODO: interference mitigation */
1401
1402 /*
1403 * Setup antenna mode
1404 */
1405 bwi_rf_set_ant_mode(mac, mac->mac_rf.rf_ant_mode);
1406
1407 /*
1408 * Initialize operation mode (RX configuration)
1409 */
1410 bwi_mac_opmode_init(mac);
1411
1412 /* XXX what's these */
1413 if (mac->mac_rev < 3) {
1414 CSR_WRITE_2(sc, 0x60e, 0);
1415 CSR_WRITE_2(sc, 0x610, 0x8000);
1416 CSR_WRITE_2(sc, 0x604, 0);
1417 CSR_WRITE_2(sc, 0x606, 0x200);
1418 } else {
1419 CSR_WRITE_4(sc, 0x188, 0x80000000);
1420 CSR_WRITE_4(sc, 0x18c, 0x2000000);
1421 }
1422
1423 /*
1424 * Initialize TX/RX interrupts' mask
1425 */
1426 CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_INTR_TIMER1);
1427 for (i = 0; i < BWI_TXRX_NRING; ++i) {
1428 uint32_t intrs;
1429
1430 if (BWI_TXRX_IS_RX(i))
1431 intrs = BWI_TXRX_RX_INTRS;
1432 else
1433 intrs = BWI_TXRX_TX_INTRS;
1434 CSR_WRITE_4(sc, BWI_TXRX_INTR_MASK(i), intrs);
1435 }
1436
1437 /* XXX what's this */
1438 CSR_SETBITS_4(sc, BWI_STATE_LO, 0x100000);
1439
1440 /* Setup MAC power up delay */
1441 CSR_WRITE_2(sc, BWI_MAC_POWERUP_DELAY, sc->sc_pwron_delay);
1442
1443 /* Set MAC regwin revision */
1444 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_MACREV, mac->mac_rev);
1445
1446 /*
1447 * Initialize host flags
1448 */
1449 bwi_mac_hostflags_init(mac);
1450
1451 /*
1452 * Initialize BSS parameters
1453 */
1454 bwi_mac_bss_param_init(mac);
1455
1456 /*
1457 * Initialize TX rings
1458 */
1459 for (i = 0; i < BWI_TX_NRING; ++i) {
1460 error = (sc->sc_init_tx_ring)(sc, i);
1461 if (error) {
1462 aprint_error_dev(sc->sc_dev,
1463 "can't initialize %dth TX ring\n", i);
1464 return (error);
1465 }
1466 }
1467
1468 /*
1469 * Initialize RX ring
1470 */
1471 error = (sc->sc_init_rx_ring)(sc);
1472 if (error) {
1473 aprint_error_dev(sc->sc_dev, "can't initialize RX ring\n");
1474 return (error);
1475 }
1476
1477 /*
1478 * Initialize TX stats if the current MAC uses that
1479 */
1480 if (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) {
1481 error = (sc->sc_init_txstats)(sc);
1482 if (error) {
1483 aprint_error_dev(sc->sc_dev,
1484 "can't initialize TX stats ring\n");
1485 return (error);
1486 }
1487 }
1488
1489 /* XXX what's these */
1490 CSR_WRITE_2(sc, 0x612, 0x50); /* Force Pre-TBTT to 80? */
1491 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x416, 0x50);
1492 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x414, 0x1f4);
1493
1494 mac->mac_flags |= BWI_MAC_F_INITED;
1495
1496 return (0);
1497 }
1498
1499 static void
1500 bwi_mac_reset(struct bwi_mac *mac, int link_phy)
1501 {
1502 struct bwi_softc *sc = mac->mac_sc;
1503 uint32_t flags, state_lo, status;
1504
1505 flags = BWI_STATE_LO_FLAG_PHYRST | BWI_STATE_LO_FLAG_PHYCLKEN;
1506 if (link_phy)
1507 flags |= BWI_STATE_LO_FLAG_PHYLNK;
1508 bwi_regwin_enable(sc, &mac->mac_regwin, flags);
1509 DELAY(2000);
1510
1511 state_lo = CSR_READ_4(sc, BWI_STATE_LO);
1512 state_lo |= BWI_STATE_LO_GATED_CLOCK;
1513 state_lo &= ~__SHIFTIN(BWI_STATE_LO_FLAG_PHYRST,
1514 BWI_STATE_LO_FLAGS_MASK);
1515 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
1516 /* Flush pending bus write */
1517 CSR_READ_4(sc, BWI_STATE_LO);
1518 DELAY(1000);
1519
1520 state_lo &= ~BWI_STATE_LO_GATED_CLOCK;
1521 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
1522 /* Flush pending bus write */
1523 CSR_READ_4(sc, BWI_STATE_LO);
1524 DELAY(1000);
1525
1526 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
1527
1528 status = CSR_READ_4(sc, BWI_MAC_STATUS);
1529 status |= BWI_MAC_STATUS_IHREN;
1530 if (link_phy)
1531 status |= BWI_MAC_STATUS_PHYLNK;
1532 else
1533 status &= ~BWI_MAC_STATUS_PHYLNK;
1534 CSR_WRITE_4(sc, BWI_MAC_STATUS, status);
1535
1536 if (link_phy) {
1537 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH | BWI_DBG_INIT,
1538 "%s\n", "PHY is linked");
1539 mac->mac_phy.phy_flags |= BWI_PHY_F_LINKED;
1540 } else {
1541 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH | BWI_DBG_INIT,
1542 "%s\n", "PHY is unlinked");
1543 mac->mac_phy.phy_flags &= ~BWI_PHY_F_LINKED;
1544 }
1545 }
1546
1547 static void
1548 bwi_mac_set_tpctl_11bg(struct bwi_mac *mac, const struct bwi_tpctl *new_tpctl)
1549 {
1550 struct bwi_rf *rf = &mac->mac_rf;
1551 struct bwi_tpctl *tpctl = &mac->mac_tpctl;
1552
1553 if (new_tpctl != NULL) {
1554 KASSERT(new_tpctl->bbp_atten <= BWI_BBP_ATTEN_MAX);
1555 KASSERT(new_tpctl->rf_atten <=
1556 (rf->rf_rev < 6 ? BWI_RF_ATTEN_MAX0
1557 : BWI_RF_ATTEN_MAX1));
1558 KASSERT(new_tpctl->tp_ctrl1 <= BWI_TPCTL1_MAX);
1559
1560 tpctl->bbp_atten = new_tpctl->bbp_atten;
1561 tpctl->rf_atten = new_tpctl->rf_atten;
1562 tpctl->tp_ctrl1 = new_tpctl->tp_ctrl1;
1563 }
1564
1565 /* Set BBP attenuation */
1566 bwi_phy_set_bbp_atten(mac, tpctl->bbp_atten);
1567
1568 /* Set RF attenuation */
1569 RF_WRITE(mac, BWI_RFR_ATTEN, tpctl->rf_atten);
1570 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_RF_ATTEN,
1571 tpctl->rf_atten);
1572
1573 /* Set TX power */
1574 if (rf->rf_type == BWI_RF_T_BCM2050) {
1575 RF_FILT_SETBITS(mac, BWI_RFR_TXPWR, ~BWI_RFR_TXPWR1_MASK,
1576 __SHIFTIN(tpctl->tp_ctrl1, BWI_RFR_TXPWR1_MASK));
1577 }
1578
1579 /* Adjust RF Local Oscillator */
1580 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11G)
1581 bwi_rf_lo_adjust(mac, tpctl);
1582 }
1583
1584 static int
1585 bwi_mac_test(struct bwi_mac *mac)
1586 {
1587 struct bwi_softc *sc = mac->mac_sc;
1588 uint32_t orig_val, val;
1589
1590 #define TEST_VAL1 0xaa5555aa
1591 #define TEST_VAL2 0x55aaaa55
1592 /* Save it for later restoring */
1593 orig_val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0);
1594
1595 /* Test 1 */
1596 MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, TEST_VAL1);
1597 val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0);
1598 if (val != TEST_VAL1) {
1599 aprint_error_dev(sc->sc_dev, "TEST1 failed [0x%08x]\n", val);
1600 return (ENXIO);
1601 }
1602
1603 /* Test 2 */
1604 MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, TEST_VAL2);
1605 val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0);
1606 if (val != TEST_VAL2) {
1607 aprint_error_dev(sc->sc_dev, "TEST2 failed [0x%08x]\n", val);
1608 return (ENXIO);
1609 }
1610
1611 /* Restore to the original value */
1612 MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, orig_val);
1613
1614 val = CSR_READ_4(sc, BWI_MAC_STATUS);
1615 if ((val & ~BWI_MAC_STATUS_PHYLNK) != BWI_MAC_STATUS_IHREN) {
1616 aprint_error_dev(sc->sc_dev, "%s failed, MAC status 0x%08x\n",
1617 __func__, val);
1618 return (ENXIO);
1619 }
1620
1621 val = CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
1622 if (val != 0) {
1623 aprint_error_dev(sc->sc_dev, "%s failed, intr status %08x\n",
1624 __func__, val);
1625 return (ENXIO);
1626 }
1627 #undef TEST_VAL2
1628 #undef TEST_VAL1
1629
1630 return (0);
1631 }
1632
1633 static void
1634 bwi_mac_setup_tpctl(struct bwi_mac *mac)
1635 {
1636 struct bwi_softc *sc = mac->mac_sc;
1637 struct bwi_rf *rf = &mac->mac_rf;
1638 struct bwi_phy *phy = &mac->mac_phy;
1639 struct bwi_tpctl *tpctl = &mac->mac_tpctl;
1640
1641 /* Calc BBP attenuation */
1642 if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev < 6)
1643 tpctl->bbp_atten = 0;
1644 else
1645 tpctl->bbp_atten = 2;
1646
1647 /* Calc TX power CTRL1?? */
1648 tpctl->tp_ctrl1 = 0;
1649 if (rf->rf_type == BWI_RF_T_BCM2050) {
1650 if (rf->rf_rev == 1)
1651 tpctl->tp_ctrl1 = 3;
1652 else if (rf->rf_rev < 6)
1653 tpctl->tp_ctrl1 = 2;
1654 else if (rf->rf_rev == 8)
1655 tpctl->tp_ctrl1 = 1;
1656 }
1657
1658 /* Empty TX power CTRL2?? */
1659 tpctl->tp_ctrl2 = 0xffff;
1660
1661 /*
1662 * Calc RF attenuation
1663 */
1664 if (phy->phy_mode == IEEE80211_MODE_11A) {
1665 tpctl->rf_atten = 0x60;
1666 goto back;
1667 }
1668
1669 if (BWI_IS_BRCM_BCM4309G(sc) && sc->sc_pci_revid < 0x51) {
1670 tpctl->rf_atten = sc->sc_pci_revid < 0x43 ? 2 : 3;
1671 goto back;
1672 }
1673
1674 tpctl->rf_atten = 5;
1675
1676 if (rf->rf_type != BWI_RF_T_BCM2050) {
1677 if (rf->rf_type == BWI_RF_T_BCM2053 && rf->rf_rev == 1)
1678 tpctl->rf_atten = 6;
1679 goto back;
1680 }
1681
1682 /*
1683 * NB: If we reaches here and the card is BRCM_BCM4309G,
1684 * then the card's PCI revision must >= 0x51
1685 */
1686
1687 /* BCM2050 RF */
1688 switch (rf->rf_rev) {
1689 case 1:
1690 if (phy->phy_mode == IEEE80211_MODE_11G) {
1691 if (BWI_IS_BRCM_BCM4309G(sc) || BWI_IS_BRCM_BU4306(sc))
1692 tpctl->rf_atten = 3;
1693 else
1694 tpctl->rf_atten = 1;
1695 } else {
1696 if (BWI_IS_BRCM_BCM4309G(sc))
1697 tpctl->rf_atten = 7;
1698 else
1699 tpctl->rf_atten = 6;
1700 }
1701 break;
1702 case 2:
1703 if (phy->phy_mode == IEEE80211_MODE_11G) {
1704 /*
1705 * NOTE: Order of following conditions is critical
1706 */
1707 if (BWI_IS_BRCM_BCM4309G(sc))
1708 tpctl->rf_atten = 3;
1709 else if (BWI_IS_BRCM_BU4306(sc))
1710 tpctl->rf_atten = 5;
1711 else if (sc->sc_bbp_id == BWI_BBPID_BCM4320)
1712 tpctl->rf_atten = 4;
1713 else
1714 tpctl->rf_atten = 3;
1715 } else {
1716 tpctl->rf_atten = 6;
1717 }
1718 break;
1719 case 4:
1720 case 5:
1721 tpctl->rf_atten = 1;
1722 break;
1723 case 8:
1724 tpctl->rf_atten = 0x1a;
1725 break;
1726 }
1727 back:
1728 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_TXPOWER,
1729 "bbp atten: %u, rf atten: %u, ctrl1: %u, ctrl2: %u\n",
1730 tpctl->bbp_atten, tpctl->rf_atten,
1731 tpctl->tp_ctrl1, tpctl->tp_ctrl2);
1732 }
1733
1734 static void
1735 bwi_mac_dummy_xmit(struct bwi_mac *mac)
1736 {
1737 #define PACKET_LEN 5
1738 static const uint32_t packet_11a[PACKET_LEN] =
1739 { 0x000201cc, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 };
1740 static const uint32_t packet_11bg[PACKET_LEN] =
1741 { 0x000b846e, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 };
1742
1743 struct bwi_softc *sc = mac->mac_sc;
1744 struct bwi_rf *rf = &mac->mac_rf;
1745 const uint32_t *packet;
1746 uint16_t val_50c;
1747 int wait_max, i;
1748
1749 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) {
1750 wait_max = 30;
1751 packet = packet_11a;
1752 val_50c = 1;
1753 } else {
1754 wait_max = 250;
1755 packet = packet_11bg;
1756 val_50c = 0;
1757 }
1758
1759 for (i = 0; i < PACKET_LEN; ++i)
1760 TMPLT_WRITE_4(mac, i * 4, packet[i]);
1761
1762 CSR_READ_4(sc, BWI_MAC_STATUS); /* dummy read */
1763
1764 CSR_WRITE_2(sc, 0x568, 0);
1765 CSR_WRITE_2(sc, 0x7c0, 0);
1766 CSR_WRITE_2(sc, 0x50c, val_50c);
1767 CSR_WRITE_2(sc, 0x508, 0);
1768 CSR_WRITE_2(sc, 0x50a, 0);
1769 CSR_WRITE_2(sc, 0x54c, 0);
1770 CSR_WRITE_2(sc, 0x56a, 0x14);
1771 CSR_WRITE_2(sc, 0x568, 0x826);
1772 CSR_WRITE_2(sc, 0x500, 0);
1773 CSR_WRITE_2(sc, 0x502, 0x30);
1774
1775 if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev <= 5)
1776 RF_WRITE(mac, 0x51, 0x17);
1777
1778 for (i = 0; i < wait_max; ++i) {
1779 if (CSR_READ_2(sc, 0x50e) & 0x80)
1780 break;
1781 DELAY(10);
1782 }
1783 for (i = 0; i < 10; ++i) {
1784 if (CSR_READ_2(sc, 0x50e) & 0x400)
1785 break;
1786 DELAY(10);
1787 }
1788 for (i = 0; i < 10; ++i) {
1789 if ((CSR_READ_2(sc, 0x690) & 0x100) == 0)
1790 break;
1791 DELAY(10);
1792 }
1793
1794 if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev <= 5)
1795 RF_WRITE(mac, 0x51, 0x37);
1796 #undef PACKET_LEN
1797 }
1798
1799 static void
1800 bwi_mac_init_tpctl_11bg(struct bwi_mac *mac)
1801 {
1802 struct bwi_softc *sc = mac->mac_sc;
1803 struct bwi_phy *phy = &mac->mac_phy;
1804 struct bwi_rf *rf = &mac->mac_rf;
1805 struct bwi_tpctl tpctl_orig;
1806 int restore_tpctl = 0;
1807
1808 KASSERT(phy->phy_mode != IEEE80211_MODE_11A);
1809
1810 if (BWI_IS_BRCM_BU4306(sc))
1811 return;
1812
1813 PHY_WRITE(mac, 0x28, 0x8018);
1814 CSR_CLRBITS_2(sc, BWI_BBP_ATTEN, 0x20);
1815
1816 if (phy->phy_mode == IEEE80211_MODE_11G) {
1817 if ((phy->phy_flags & BWI_PHY_F_LINKED) == 0)
1818 return;
1819 PHY_WRITE(mac, 0x47a, 0xc111);
1820 }
1821 if (mac->mac_flags & BWI_MAC_F_TPCTL_INITED)
1822 return;
1823
1824 if (phy->phy_mode == IEEE80211_MODE_11B && phy->phy_rev >= 2 &&
1825 rf->rf_type == BWI_RF_T_BCM2050) {
1826 RF_SETBITS(mac, 0x76, 0x84);
1827 } else {
1828 struct bwi_tpctl tpctl;
1829
1830 /* Backup original TX power control variables */
1831 memcpy(&tpctl_orig, &mac->mac_tpctl, sizeof(tpctl_orig));
1832 restore_tpctl = 1;
1833
1834 memcpy(&tpctl, &mac->mac_tpctl, sizeof(tpctl));
1835 tpctl.bbp_atten = 11;
1836 tpctl.tp_ctrl1 = 0;
1837 #ifdef notyet
1838 if (rf->rf_rev >= 6 && rf->rf_rev <= 8)
1839 tpctl.rf_atten = 31;
1840 else
1841 #endif
1842 tpctl.rf_atten = 9;
1843
1844 bwi_mac_set_tpctl_11bg(mac, &tpctl);
1845 }
1846
1847 bwi_mac_dummy_xmit(mac);
1848
1849 mac->mac_flags |= BWI_MAC_F_TPCTL_INITED;
1850 rf->rf_base_tssi = PHY_READ(mac, 0x29);
1851 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_TXPOWER,
1852 "base tssi %d\n", rf->rf_base_tssi);
1853
1854 if (abs(rf->rf_base_tssi - rf->rf_idle_tssi) >= 20) {
1855 aprint_error_dev(sc->sc_dev, "base tssi measure failed\n");
1856 mac->mac_flags |= BWI_MAC_F_TPCTL_ERROR;
1857 }
1858
1859 if (restore_tpctl)
1860 bwi_mac_set_tpctl_11bg(mac, &tpctl_orig);
1861 else
1862 RF_CLRBITS(mac, 0x76, 0x84);
1863
1864 bwi_rf_clear_tssi(mac);
1865 }
1866
1867 static void
1868 bwi_mac_detach(struct bwi_mac *mac)
1869 {
1870 bwi_mac_fw_free(mac);
1871 }
1872
1873 static int
1874 bwi_mac_fw_alloc(struct bwi_mac *mac)
1875 {
1876 struct bwi_softc *sc = mac->mac_sc;
1877 int idx, error;
1878
1879 error = bwi_mac_fw_image_alloc(mac, BWI_FW_UCODE_PREFIX,
1880 mac->mac_rev >= 5 ? 5 : mac->mac_rev, &mac->mac_ucode_fwi,
1881 BWI_FW_T_UCODE);
1882 if (error)
1883 goto fail_ucode;
1884
1885 error = bwi_mac_fw_image_alloc(mac, BWI_FW_PCM_PREFIX,
1886 mac->mac_rev >= 5 ? 5 : mac->mac_rev, &mac->mac_pcm_fwi,
1887 BWI_FW_T_PCM);
1888 if (error)
1889 goto fail_pcm;
1890
1891 /* TODO: 11A */
1892 if (mac->mac_rev == 2 || mac->mac_rev == 4)
1893 idx = 2;
1894 else if (mac->mac_rev >= 5 && mac->mac_rev <= 20)
1895 idx = 5;
1896 else {
1897 aprint_error_dev(sc->sc_dev,
1898 "no suitable IV for MAC rev %d\n", mac->mac_rev);
1899 error = ENODEV;
1900 goto fail_iv;
1901 }
1902
1903 error = bwi_mac_fw_image_alloc(mac, BWI_FW_IV_PREFIX, idx,
1904 &mac->mac_iv_fwi, BWI_FW_T_IV);
1905 if (error)
1906 goto fail_iv;
1907
1908 /* TODO: 11A */
1909 if (mac->mac_rev == 2 || mac->mac_rev == 4 ||
1910 mac->mac_rev >= 11)
1911 /* No extended IV */
1912 goto back;
1913 else if (mac->mac_rev >= 5 && mac->mac_rev <= 10)
1914 idx = 5;
1915 else {
1916 aprint_error_dev(sc->sc_dev,
1917 "no suitable ExtIV for MAC rev %d\n", mac->mac_rev);
1918 error = ENODEV;
1919 goto fail_iv_ext;
1920 }
1921
1922 error = bwi_mac_fw_image_alloc(mac, BWI_FW_IV_EXT_PREFIX, idx,
1923 &mac->mac_iv_ext_fwi, BWI_FW_T_IV);
1924 if (error)
1925 goto fail_iv_ext;
1926
1927 back: return (0);
1928
1929 fail_iv_ext:
1930 bwi_mac_fw_image_free(mac, &mac->mac_iv_fwi);
1931
1932 fail_iv:
1933 bwi_mac_fw_image_free(mac, &mac->mac_pcm_fwi);
1934
1935 fail_pcm:
1936 bwi_mac_fw_image_free(mac, &mac->mac_ucode_fwi);
1937
1938 fail_ucode:
1939 return (error);
1940 }
1941
1942 static void
1943 bwi_mac_fw_free(struct bwi_mac *mac)
1944 {
1945 bwi_mac_fw_image_free(mac, &mac->mac_ucode_fwi);
1946 bwi_mac_fw_image_free(mac, &mac->mac_pcm_fwi);
1947 bwi_mac_fw_image_free(mac, &mac->mac_iv_fwi);
1948 bwi_mac_fw_image_free(mac, &mac->mac_iv_ext_fwi);
1949 }
1950
1951 static int
1952 bwi_mac_fw_image_alloc(struct bwi_mac *mac, const char *prefix, int idx,
1953 struct bwi_fw_image *fwi, uint8_t fw_type)
1954 {
1955 struct bwi_softc *sc = mac->mac_sc;
1956 char *fw_name = fwi->fwi_name;
1957 size_t fw_name_size = sizeof(fwi->fwi_name);
1958 firmware_handle_t fwh;
1959 const struct bwi_fwhdr *hdr;
1960 int error;
1961
1962 /* [TRC: XXX ???] */
1963 if (fwi->fwi_data != NULL)
1964 return (0);
1965
1966 snprintf(fw_name, fw_name_size, BWI_FW_NAME_FORMAT, sc->sc_fw_version,
1967 prefix, idx);
1968
1969 DPRINTF(sc, BWI_DBG_FIRMWARE, "opening firmware %s\n", fw_name);
1970
1971 error = firmware_open("bwi", fw_name, &fwh);
1972 if (error) {
1973 aprint_error_dev(sc->sc_dev, "firmware_open failed on %s\n",
1974 fw_name);
1975 goto fail;
1976 }
1977
1978 fwi->fwi_size = firmware_get_size(fwh);
1979 if (fwi->fwi_size < sizeof(struct bwi_fwhdr)) {
1980 aprint_error_dev(sc->sc_dev,
1981 "firmware image %s has no header\n",
1982 fw_name);
1983 error = EIO;
1984 goto fail;
1985 }
1986
1987 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE,
1988 "firmware image %s, size %zx\n", fw_name, fwi->fwi_size);
1989
1990 fwi->fwi_data = firmware_malloc(fwi->fwi_size);
1991 if (fwi->fwi_data == NULL) {
1992 error = ENOMEM;
1993 firmware_close(fwh);
1994 goto fail;
1995 }
1996
1997 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE,
1998 "firmware image %s loaded at %p\n", fw_name, fwi->fwi_data);
1999
2000 fwi->fwi_data = firmware_malloc(fwi->fwi_size);
2001 error = firmware_read(fwh, 0, fwi->fwi_data, fwi->fwi_size);
2002 firmware_close(fwh);
2003 if (error)
2004 goto free_and_fail;
2005
2006 hdr = (const struct bwi_fwhdr *)fwi->fwi_data;
2007
2008 if (fw_type != BWI_FW_T_IV) {
2009 /*
2010 * Don't verify IV's size, it has different meaning
2011 */
2012 size_t fw_size = (size_t)be32toh(hdr->fw_size);
2013 if (fw_size != fwi->fwi_size - sizeof(*hdr)) {
2014 aprint_error_dev(sc->sc_dev, "firmware image %s"
2015 " size mismatch, fw %zx, real %zx\n", fw_name,
2016 fw_size, fwi->fwi_size - sizeof(*hdr));
2017 goto invalid;
2018 }
2019 }
2020
2021 if (hdr->fw_type != fw_type) {
2022 aprint_error_dev(sc->sc_dev, "firmware image %s"
2023 " type mismatch, fw `%c', target `%c'\n", fw_name,
2024 hdr->fw_type, fw_type);
2025 goto invalid;
2026 }
2027
2028 if (hdr->fw_gen != BWI_FW_GEN_1) {
2029 aprint_error_dev(sc->sc_dev, "firmware image %s"
2030 " generation mismatch, fw %d, target %d\n", fw_name,
2031 hdr->fw_gen, BWI_FW_GEN_1);
2032 goto invalid;
2033 }
2034
2035 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE,
2036 "firmware image %s loaded successfully\n", fw_name);
2037
2038 return (0);
2039
2040 invalid:
2041 error = EINVAL;
2042
2043 free_and_fail:
2044 firmware_free(fwi->fwi_data, fwi->fwi_size);
2045 fwi->fwi_data = NULL;
2046 fwi->fwi_size = 0;
2047
2048 fail:
2049 return (error);
2050 }
2051
2052 static void
2053 bwi_mac_fw_image_free(struct bwi_mac *mac, struct bwi_fw_image *fwi)
2054 {
2055 if (fwi->fwi_data != NULL) {
2056 DPRINTF(mac->mac_sc, BWI_DBG_FIRMWARE, "freeing firmware %s\n",
2057 fwi->fwi_name);
2058 firmware_free(fwi->fwi_data, fwi->fwi_size);
2059 fwi->fwi_data = NULL;
2060 fwi->fwi_size = 0;
2061 }
2062 }
2063
2064 static int
2065 bwi_mac_fw_load(struct bwi_mac *mac)
2066 {
2067 struct bwi_softc *sc = mac->mac_sc;
2068 const uint32_t *fw;
2069 uint16_t fw_rev;
2070 size_t fw_len, i;
2071
2072 /*
2073 * Load ucode image
2074 */
2075 fw = (const uint32_t *)(mac->mac_ucode + BWI_FWHDR_SZ);
2076 fw_len = (mac->mac_ucode_size - BWI_FWHDR_SZ) / sizeof(uint32_t);
2077
2078 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE,
2079 "loading ucode image at %p, length %zx\n",
2080 fw, fw_len);
2081
2082 CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
2083 BWI_MOBJ_CTRL_VAL(BWI_FW_UCODE_MOBJ | BWI_WR_MOBJ_AUTOINC, 0));
2084 for (i = 0; i < fw_len; ++i) {
2085 CSR_WRITE_4(sc, BWI_MOBJ_DATA, be32toh(fw[i]));
2086 DELAY(10);
2087 }
2088
2089 /*
2090 * Load PCM image
2091 */
2092 fw = (const uint32_t *)(mac->mac_pcm + BWI_FWHDR_SZ);
2093 fw_len = (mac->mac_pcm_size - BWI_FWHDR_SZ) / sizeof(uint32_t);
2094
2095 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE,
2096 "loading PCM image at %p, length %zx\n",
2097 fw, fw_len);
2098
2099 CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
2100 BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ, 0x01ea));
2101 CSR_WRITE_4(sc, BWI_MOBJ_DATA, 0x4000);
2102
2103 CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
2104 BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ, 0x01eb));
2105 for (i = 0; i < fw_len; ++i) {
2106 CSR_WRITE_4(sc, BWI_MOBJ_DATA, be32toh(fw[i]));
2107 DELAY(10);
2108 }
2109
2110 CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_ALL_INTRS);
2111 CSR_WRITE_4(sc, BWI_MAC_STATUS,
2112 BWI_MAC_STATUS_UCODE_START |
2113 BWI_MAC_STATUS_IHREN |
2114 BWI_MAC_STATUS_INFRA);
2115 #define NRETRY 200
2116 for (i = 0; i < NRETRY; ++i) {
2117 uint32_t intr_status;
2118
2119 intr_status = CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
2120 if (intr_status == BWI_INTR_READY)
2121 break;
2122 DELAY(10);
2123 }
2124 if (i == NRETRY) {
2125 aprint_error_dev(sc->sc_dev,
2126 "timeout loading ucode & pcm firmware\n");
2127 return (ETIMEDOUT);
2128 }
2129 #undef NRETRY
2130
2131 CSR_READ_4(sc, BWI_MAC_INTR_STATUS); /* dummy read */
2132
2133 fw_rev = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWREV);
2134 if (fw_rev > BWI_FW_VERSION3_REVMAX) {
2135 aprint_error_dev(sc->sc_dev,
2136 "firmware version 4 is not supported yet\n");
2137 return (ENODEV);
2138 }
2139
2140 if (fw_rev != sc->sc_fw_rev) {
2141 aprint_normal_dev(sc->sc_dev, "firmware rev 0x%04x,"
2142 " patch level 0x%04x\n", fw_rev,
2143 MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWPATCHLV));
2144 sc->sc_fw_rev = fw_rev;
2145 }
2146
2147 return (0);
2148 }
2149
2150 static int
2151 bwi_mac_gpio_init(struct bwi_mac *mac)
2152 {
2153 struct bwi_softc *sc = mac->mac_sc;
2154 struct bwi_regwin *old, *gpio_rw;
2155 uint32_t filt, bits;
2156 int error;
2157
2158 CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_GPOSEL_MASK);
2159 /* TODO: LED */
2160
2161 CSR_SETBITS_2(sc, BWI_MAC_GPIO_MASK, 0xf);
2162
2163 filt = 0x1f;
2164 bits = 0xf;
2165 if (sc->sc_bbp_id == BWI_BBPID_BCM4301) {
2166 filt |= 0x60;
2167 bits |= 0x60;
2168 }
2169 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) {
2170 CSR_SETBITS_2(sc, BWI_MAC_GPIO_MASK, 0x200);
2171 filt |= 0x200;
2172 bits |= 0x200;
2173 }
2174
2175 gpio_rw = BWI_GPIO_REGWIN(sc);
2176 error = bwi_regwin_switch(sc, gpio_rw, &old);
2177 if (error)
2178 return (error);
2179
2180 CSR_FILT_SETBITS_4(sc, BWI_GPIO_CTRL, filt, bits);
2181
2182 return (bwi_regwin_switch(sc, old, NULL));
2183 }
2184
2185 static int
2186 bwi_mac_gpio_fini(struct bwi_mac *mac)
2187 {
2188 struct bwi_softc *sc = mac->mac_sc;
2189 struct bwi_regwin *old, *gpio_rw;
2190 int error;
2191
2192 gpio_rw = BWI_GPIO_REGWIN(sc);
2193 error = bwi_regwin_switch(sc, gpio_rw, &old);
2194 if (error)
2195 return (error);
2196
2197 CSR_WRITE_4(sc, BWI_GPIO_CTRL, 0);
2198
2199 return (bwi_regwin_switch(sc, old, NULL));
2200 }
2201
2202 static int
2203 bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct bwi_fw_image *fwi)
2204 {
2205 struct bwi_softc *sc = mac->mac_sc;
2206 const struct bwi_fwhdr *hdr;
2207 const struct bwi_fw_iv *iv;
2208 size_t iv_img_size;
2209 int n, i;
2210
2211 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE,
2212 "loading %s at %p\n", fwi->fwi_name, fwi->fwi_data);
2213
2214 /* Get the number of IVs in the IV image */
2215 hdr = (const struct bwi_fwhdr *)fwi->fwi_data;
2216 n = be32toh(hdr->fw_iv_cnt);
2217 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE,
2218 "IV count %d\n", n);
2219
2220 /* Calculate the IV image size, for later sanity check */
2221 iv_img_size = fwi->fwi_size - sizeof(*hdr);
2222
2223 /* Locate the first IV */
2224 iv = (const struct bwi_fw_iv *)(fwi->fwi_data + sizeof(*hdr));
2225
2226 for (i = 0; i < n; ++i) {
2227 uint16_t iv_ofs, ofs;
2228 int sz = 0;
2229
2230 if (iv_img_size < sizeof(iv->iv_ofs)) {
2231 aprint_error_dev(sc->sc_dev,
2232 "invalid IV image, ofs\n");
2233 return (EINVAL);
2234 }
2235 iv_img_size -= sizeof(iv->iv_ofs);
2236 sz += sizeof(iv->iv_ofs);
2237
2238 iv_ofs = be16toh(iv->iv_ofs);
2239
2240 ofs = __SHIFTOUT(iv_ofs, BWI_FW_IV_OFS_MASK);
2241 if (ofs >= 0x1000) {
2242 aprint_error_dev(sc->sc_dev, "invalid ofs (0x%04x) "
2243 "for %dth iv\n", ofs, i);
2244 return (EINVAL);
2245 }
2246
2247 if (iv_ofs & BWI_FW_IV_IS_32BIT) {
2248 uint32_t val32;
2249
2250 if (iv_img_size < sizeof(iv->iv_val.val32)) {
2251 aprint_error_dev(sc->sc_dev,
2252 "invalid IV image, val32\n");
2253 return (EINVAL);
2254 }
2255 iv_img_size -= sizeof(iv->iv_val.val32);
2256 sz += sizeof(iv->iv_val.val32);
2257
2258 val32 = be32toh(iv->iv_val.val32);
2259 CSR_WRITE_4(sc, ofs, val32);
2260 } else {
2261 uint16_t val16;
2262
2263 if (iv_img_size < sizeof(iv->iv_val.val16)) {
2264 aprint_error_dev(sc->sc_dev,
2265 "invalid IV image, val16\n");
2266 return (EINVAL);
2267 }
2268 iv_img_size -= sizeof(iv->iv_val.val16);
2269 sz += sizeof(iv->iv_val.val16);
2270
2271 val16 = be16toh(iv->iv_val.val16);
2272 CSR_WRITE_2(sc, ofs, val16);
2273 }
2274
2275 iv = (const struct bwi_fw_iv *)((const uint8_t *)iv + sz);
2276 }
2277
2278 if (iv_img_size != 0) {
2279 aprint_error_dev(sc->sc_dev,
2280 "invalid IV image, size left %zx\n", iv_img_size);
2281 return (EINVAL);
2282 }
2283
2284 return (0);
2285 }
2286
2287 static int
2288 bwi_mac_fw_init(struct bwi_mac *mac)
2289 {
2290 struct bwi_softc *sc = mac->mac_sc;
2291 int error;
2292
2293 error = bwi_mac_fw_load_iv(mac, &mac->mac_iv_fwi);
2294 if (error) {
2295 aprint_error_dev(sc->sc_dev, "load IV failed\n");
2296 return (error);
2297 }
2298
2299 if (mac->mac_iv_ext != NULL) {
2300 error = bwi_mac_fw_load_iv(mac, &mac->mac_iv_ext_fwi);
2301 if (error)
2302 aprint_error_dev(sc->sc_dev, "load ExtIV failed\n");
2303 }
2304
2305 return (error);
2306 }
2307
2308 static void
2309 bwi_mac_opmode_init(struct bwi_mac *mac)
2310 {
2311 struct bwi_softc *sc = mac->mac_sc;
2312 struct ieee80211com *ic = &sc->sc_ic;
2313 uint32_t mac_status;
2314 uint16_t pre_tbtt;
2315
2316 CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_INFRA);
2317 CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_INFRA);
2318 CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PASS_BCN);
2319
2320 /* Set probe resp timeout to infinite */
2321 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_PROBE_RESP_TO, 0);
2322
2323 /*
2324 * TODO: factor out following part
2325 */
2326
2327 mac_status = CSR_READ_4(sc, BWI_MAC_STATUS);
2328 mac_status &= ~(BWI_MAC_STATUS_OPMODE_HOSTAP |
2329 BWI_MAC_STATUS_PASS_CTL |
2330 BWI_MAC_STATUS_PASS_BADPLCP |
2331 BWI_MAC_STATUS_PASS_BADFCS |
2332 BWI_MAC_STATUS_PROMISC);
2333 mac_status |= BWI_MAC_STATUS_INFRA;
2334
2335 /* Always turn on PROMISC on old hardware */
2336 if (mac->mac_rev < 5)
2337 mac_status |= BWI_MAC_STATUS_PROMISC;
2338
2339 switch (ic->ic_opmode) {
2340 case IEEE80211_M_IBSS:
2341 mac_status &= ~BWI_MAC_STATUS_INFRA;
2342 break;
2343 case IEEE80211_M_HOSTAP:
2344 mac_status |= BWI_MAC_STATUS_OPMODE_HOSTAP;
2345 break;
2346 case IEEE80211_M_MONITOR:
2347 #if 0
2348 /* Do you want data from your microwave oven? */
2349 mac_status |= BWI_MAC_STATUS_PASS_CTL |
2350 BWI_MAC_STATUS_PASS_BADPLCP |
2351 BWI_MAC_STATUS_PASS_BADFCS;
2352 #else
2353 mac_status |= BWI_MAC_STATUS_PASS_CTL;
2354 #endif
2355 /* Promisc? */
2356 break;
2357 default:
2358 break;
2359 }
2360
2361 if (sc->sc_if.if_flags & IFF_PROMISC)
2362 mac_status |= BWI_MAC_STATUS_PROMISC;
2363
2364 CSR_WRITE_4(sc, BWI_MAC_STATUS, mac_status);
2365
2366 if (ic->ic_opmode != IEEE80211_M_IBSS &&
2367 ic->ic_opmode != IEEE80211_M_HOSTAP) {
2368 if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_rev == 3)
2369 pre_tbtt = 100;
2370 else
2371 pre_tbtt = 50;
2372 } else
2373 pre_tbtt = 2;
2374 CSR_WRITE_2(sc, BWI_MAC_PRE_TBTT, pre_tbtt);
2375 }
2376
2377 static void
2378 bwi_mac_hostflags_init(struct bwi_mac *mac)
2379 {
2380 struct bwi_softc *sc = mac->mac_sc;
2381 struct bwi_phy *phy = &mac->mac_phy;
2382 struct bwi_rf *rf = &mac->mac_rf;
2383 uint64_t host_flags;
2384
2385 if (phy->phy_mode == IEEE80211_MODE_11A)
2386 return;
2387
2388 host_flags = HFLAGS_READ(mac);
2389 host_flags |= BWI_HFLAG_SYM_WA;
2390
2391 if (phy->phy_mode == IEEE80211_MODE_11G) {
2392 if (phy->phy_rev == 1)
2393 host_flags |= BWI_HFLAG_GDC_WA;
2394 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
2395 host_flags |= BWI_HFLAG_OFDM_PA;
2396 } else if (phy->phy_mode == IEEE80211_MODE_11B) {
2397 if (phy->phy_rev >= 2 && rf->rf_type == BWI_RF_T_BCM2050)
2398 host_flags &= ~BWI_HFLAG_GDC_WA;
2399 } else {
2400 panic("unknown PHY mode %u\n", phy->phy_mode);
2401 }
2402
2403 HFLAGS_WRITE(mac, host_flags);
2404 }
2405
2406 static void
2407 bwi_mac_bss_param_init(struct bwi_mac *mac)
2408 {
2409 struct bwi_softc *sc = mac->mac_sc;
2410 struct bwi_phy *phy = &mac->mac_phy;
2411 struct bwi_retry_lim lim;
2412 uint16_t cw_min;
2413
2414 /*
2415 * Set short/long retry limits
2416 */
2417 memset(&lim, 0, sizeof(lim));
2418 lim.shretry = BWI_SHRETRY;
2419 lim.shretry_fb = BWI_SHRETRY_FB;
2420 lim.lgretry = BWI_LGRETRY;
2421 lim.lgretry_fb = BWI_LGRETRY_FB;
2422 bwi_mac_set_retry_lim(mac, &lim);
2423
2424 /*
2425 * Implicitly prevent firmware from sending probe response
2426 * by setting its "probe response timeout" to 1us.
2427 */
2428 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_PROBE_RESP_TO, 1);
2429
2430 /*
2431 * XXX MAC level acknowledge and CW min/max should depend
2432 * on the char rateset of the IBSS/BSS to join.
2433 */
2434
2435 /*
2436 * Set MAC level acknowledge rates
2437 */
2438 bwi_mac_set_ackrates(mac, &sc->sc_ic.ic_sup_rates[phy->phy_mode]);
2439
2440 /*
2441 * Set CW min
2442 */
2443 if (phy->phy_mode == IEEE80211_MODE_11B)
2444 cw_min = IEEE80211_CW_MIN_0;
2445 else
2446 cw_min = IEEE80211_CW_MIN_1;
2447 MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_CWMIN, cw_min);
2448
2449 /*
2450 * Set CW max
2451 */
2452 MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_CWMAX,
2453 IEEE80211_CW_MAX);
2454 }
2455
2456 static void
2457 bwi_mac_set_retry_lim(struct bwi_mac *mac, const struct bwi_retry_lim *lim)
2458 {
2459 /* Short/Long retry limit */
2460 MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_SHRETRY,
2461 lim->shretry);
2462 MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_LGRETRY,
2463 lim->lgretry);
2464
2465 /* Short/Long retry fallback limit */
2466 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_SHRETRY_FB,
2467 lim->shretry_fb);
2468 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_LGRETEY_FB,
2469 lim->lgretry_fb);
2470 }
2471
2472 static void
2473 bwi_mac_set_ackrates(struct bwi_mac *mac, const struct ieee80211_rateset *rs)
2474 {
2475 int i;
2476
2477 /* XXX not standard conforming */
2478 for (i = 0; i < rs->rs_nrates; ++i) {
2479 enum bwi_ieee80211_modtype modtype;
2480 uint16_t ofs;
2481
2482 modtype = bwi_ieee80211_rate2modtype(rs->rs_rates[i]);
2483 switch (modtype) {
2484 case IEEE80211_MODTYPE_DS:
2485 ofs = 0x4c0;
2486 ofs += (bwi_ieee80211_rate2plcp(rs->rs_rates[i],
2487 IEEE80211_MODE_11B) & 0xf) * 2;
2488 break;
2489 case IEEE80211_MODTYPE_OFDM:
2490 ofs = 0x480;
2491 ofs += (bwi_ieee80211_rate2plcp(rs->rs_rates[i],
2492 IEEE80211_MODE_11G) & 0xf) * 2;
2493 break;
2494 default:
2495 panic("unsupported modtype %u\n", modtype);
2496 }
2497
2498 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, ofs + 0x20,
2499 MOBJ_READ_2(mac, BWI_COMM_MOBJ, ofs));
2500 }
2501 }
2502
2503 static int
2504 bwi_mac_start(struct bwi_mac *mac)
2505 {
2506 struct bwi_softc *sc = mac->mac_sc;
2507
2508 CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_ENABLE);
2509 CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_INTR_READY);
2510
2511 /* Flush pending bus writes */
2512 CSR_READ_4(sc, BWI_MAC_STATUS);
2513 CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
2514
2515 return (bwi_mac_config_ps(mac));
2516 }
2517
2518 static int
2519 bwi_mac_stop(struct bwi_mac *mac)
2520 {
2521 struct bwi_softc *sc = mac->mac_sc;
2522 int error, i;
2523
2524 error = bwi_mac_config_ps(mac);
2525 if (error)
2526 return (error);
2527
2528 CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_ENABLE);
2529
2530 /* Flush pending bus write */
2531 CSR_READ_4(sc, BWI_MAC_STATUS);
2532
2533 #define NRETRY 10000
2534 for (i = 0; i < NRETRY; ++i) {
2535 if (CSR_READ_4(sc, BWI_MAC_INTR_STATUS) & BWI_INTR_READY)
2536 break;
2537 DELAY(1);
2538 }
2539 if (i == NRETRY) {
2540 aprint_error_dev(sc->sc_dev, "can't stop MAC\n");
2541 return (ETIMEDOUT);
2542 }
2543 #undef NRETRY
2544
2545 return (0);
2546 }
2547
2548 static int
2549 bwi_mac_config_ps(struct bwi_mac *mac)
2550 {
2551 struct bwi_softc *sc = mac->mac_sc;
2552 uint32_t status;
2553
2554 status = CSR_READ_4(sc, BWI_MAC_STATUS);
2555
2556 status &= ~BWI_MAC_STATUS_HW_PS;
2557 status |= BWI_MAC_STATUS_WAKEUP;
2558 CSR_WRITE_4(sc, BWI_MAC_STATUS, status);
2559
2560 /* Flush pending bus write */
2561 CSR_READ_4(sc, BWI_MAC_STATUS);
2562
2563 if (mac->mac_rev >= 5) {
2564 int i;
2565
2566 #define NRETRY 100
2567 for (i = 0; i < NRETRY; ++i) {
2568 if (MOBJ_READ_2(mac, BWI_COMM_MOBJ,
2569 BWI_COMM_MOBJ_UCODE_STATE) != BWI_UCODE_STATE_PS)
2570 break;
2571 DELAY(10);
2572 }
2573 if (i == NRETRY) {
2574 aprint_error_dev(sc->sc_dev, "config PS failed\n");
2575 return (ETIMEDOUT);
2576 }
2577 #undef NRETRY
2578 }
2579 return (0);
2580 }
2581
2582 static void
2583 bwi_mac_reset_hwkeys(struct bwi_mac *mac)
2584 {
2585 /* TODO: firmware crypto */
2586 MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_KEYTABLE_OFS);
2587 }
2588
2589 static void
2590 bwi_mac_shutdown(struct bwi_mac *mac)
2591 {
2592 struct bwi_softc *sc = mac->mac_sc;
2593 int i;
2594
2595 if (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS)
2596 (sc->sc_free_txstats)(sc);
2597
2598 (sc->sc_free_rx_ring)(sc);
2599
2600 for (i = 0; i < BWI_TX_NRING; ++i)
2601 (sc->sc_free_tx_ring)(sc, i);
2602
2603 bwi_rf_off(mac);
2604
2605 /* TODO: LED */
2606
2607 bwi_mac_gpio_fini(mac);
2608
2609 bwi_rf_off(mac); /* XXX again */
2610 CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC);
2611 bwi_regwin_disable(sc, &mac->mac_regwin, 0);
2612
2613 mac->mac_flags &= ~BWI_MAC_F_INITED;
2614 }
2615
2616 static int
2617 bwi_mac_get_property(struct bwi_mac *mac)
2618 {
2619 struct bwi_softc *sc = mac->mac_sc;
2620 enum bwi_bus_space old_bus_space;
2621 uint32_t val;
2622
2623 /*
2624 * Byte swap
2625 */
2626 val = CSR_READ_4(sc, BWI_MAC_STATUS);
2627 if (BWI_IS_PIO(sc) && (val & BWI_MAC_STATUS_BSWAP)) {
2628 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "disable byte swap\n");
2629 val &= ~BWI_MAC_STATUS_BSWAP;
2630 CSR_WRITE_4(sc, BWI_MAC_STATUS, val);
2631 val = CSR_READ_4(sc, BWI_MAC_STATUS);
2632 }
2633 if (val & BWI_MAC_STATUS_BSWAP) {
2634 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "need byte swap\n");
2635 mac->mac_flags |= BWI_MAC_F_BSWAP;
2636 }
2637
2638 /*
2639 * DMA address space
2640 */
2641 old_bus_space = sc->sc_bus_space;
2642
2643 val = CSR_READ_4(sc, BWI_STATE_HI);
2644 if (__SHIFTOUT(val, BWI_STATE_HI_FLAGS_MASK) &
2645 BWI_STATE_HI_FLAG_64BIT) {
2646 /* 64bit address */
2647 sc->sc_bus_space = BWI_BUS_SPACE_64BIT;
2648 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "64bit bus space\n");
2649 } else {
2650 uint32_t txrx_reg = BWI_TXRX_CTRL_BASE + BWI_TX32_CTRL;
2651
2652 CSR_WRITE_4(sc, txrx_reg, BWI_TXRX32_CTRL_ADDRHI_MASK);
2653 if (CSR_READ_4(sc, txrx_reg) & BWI_TXRX32_CTRL_ADDRHI_MASK) {
2654 /* 32bit address */
2655 sc->sc_bus_space = BWI_BUS_SPACE_32BIT;
2656 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH,
2657 "32bit bus space\n");
2658 } else {
2659 /* 30bit address */
2660 sc->sc_bus_space = BWI_BUS_SPACE_30BIT;
2661 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH,
2662 "30bit bus space\n");
2663 }
2664 }
2665
2666 if (old_bus_space != 0 && old_bus_space != sc->sc_bus_space) {
2667 aprint_error_dev(sc->sc_dev, "MACs bus space mismatch!\n");
2668 return (ENXIO);
2669 }
2670
2671 return (0);
2672 }
2673
2674 static void
2675 bwi_mac_updateslot(struct bwi_mac *mac, int shslot)
2676 {
2677 uint16_t slot_time;
2678
2679 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11B)
2680 return;
2681
2682 if (shslot)
2683 slot_time = IEEE80211_DUR_SHSLOT;
2684 else
2685 slot_time = IEEE80211_DUR_SLOT;
2686
2687 CSR_WRITE_2(mac->mac_sc, BWI_MAC_SLOTTIME,
2688 slot_time + BWI_MAC_SLOTTIME_ADJUST);
2689 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_SLOTTIME, slot_time);
2690 }
2691
2692 static int
2693 bwi_mac_attach(struct bwi_softc *sc, int id, uint8_t rev)
2694 {
2695 struct bwi_mac *mac;
2696 int i;
2697
2698 KASSERT(sc->sc_nmac <= BWI_MAC_MAX && sc->sc_nmac >= 0);
2699
2700 if (sc->sc_nmac == BWI_MAC_MAX) {
2701 aprint_error_dev(sc->sc_dev, "too many MACs\n");
2702 return (0);
2703 }
2704
2705 /*
2706 * More than one MAC is only supported by BCM4309
2707 */
2708 if (sc->sc_nmac != 0 &&
2709 sc->sc_pci_did != PCI_PRODUCT_BROADCOM_BCM4309) {
2710 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH,
2711 "ignore %dth MAC\n", sc->sc_nmac);
2712 return (0);
2713 }
2714
2715 mac = &sc->sc_mac[sc->sc_nmac];
2716
2717 /* XXX will this happen? */
2718 if (BWI_REGWIN_EXIST(&mac->mac_regwin)) {
2719 aprint_error_dev(sc->sc_dev, "%dth MAC already attached\n",
2720 sc->sc_nmac);
2721 return (0);
2722 }
2723
2724 /*
2725 * Test whether the revision of this MAC is supported
2726 */
2727 for (i = 0; i < __arraycount(bwi_sup_macrev); ++i) {
2728 if (bwi_sup_macrev[i] == rev)
2729 break;
2730 }
2731 if (i == __arraycount(bwi_sup_macrev)) {
2732 aprint_error_dev(sc->sc_dev, "MAC rev %u is not supported\n",
2733 rev);
2734 return (ENXIO);
2735 }
2736
2737 BWI_CREATE_MAC(mac, sc, id, rev);
2738 sc->sc_nmac++;
2739
2740 if (mac->mac_rev < 5) {
2741 mac->mac_flags |= BWI_MAC_F_HAS_TXSTATS;
2742 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "has TX stats\n");
2743 } else {
2744 mac->mac_flags |= BWI_MAC_F_PHYE_RESET;
2745 }
2746
2747 aprint_normal_dev(sc->sc_dev, "MAC: rev %u\n", rev);
2748 return (0);
2749 }
2750
2751 static void
2752 bwi_mac_balance_atten(int *bbp_atten0, int *rf_atten0)
2753 {
2754 int bbp_atten, rf_atten, rf_atten_lim = -1;
2755
2756 bbp_atten = *bbp_atten0;
2757 rf_atten = *rf_atten0;
2758
2759 /*
2760 * RF attenuation affects TX power BWI_RF_ATTEN_FACTOR times
2761 * as much as BBP attenuation, so we try our best to keep RF
2762 * attenuation within range. BBP attenuation will be clamped
2763 * later if it is out of range during balancing.
2764 *
2765 * BWI_RF_ATTEN_MAX0 is used as RF attenuation upper limit.
2766 */
2767
2768 /*
2769 * Use BBP attenuation to balance RF attenuation
2770 */
2771 if (rf_atten < 0)
2772 rf_atten_lim = 0;
2773 else if (rf_atten > BWI_RF_ATTEN_MAX0)
2774 rf_atten_lim = BWI_RF_ATTEN_MAX0;
2775
2776 if (rf_atten_lim >= 0) {
2777 bbp_atten += (BWI_RF_ATTEN_FACTOR * (rf_atten - rf_atten_lim));
2778 rf_atten = rf_atten_lim;
2779 }
2780
2781 /*
2782 * If possible, use RF attenuation to balance BBP attenuation
2783 * NOTE: RF attenuation is still kept within range.
2784 */
2785 while (rf_atten < BWI_RF_ATTEN_MAX0 && bbp_atten > BWI_BBP_ATTEN_MAX) {
2786 bbp_atten -= BWI_RF_ATTEN_FACTOR;
2787 ++rf_atten;
2788 }
2789 while (rf_atten > 0 && bbp_atten < 0) {
2790 bbp_atten += BWI_RF_ATTEN_FACTOR;
2791 --rf_atten;
2792 }
2793
2794 /* RF attenuation MUST be within range */
2795 KASSERT(rf_atten >= 0 && rf_atten <= BWI_RF_ATTEN_MAX0);
2796
2797 /*
2798 * Clamp BBP attenuation
2799 */
2800 if (bbp_atten < 0)
2801 bbp_atten = 0;
2802 else if (bbp_atten > BWI_BBP_ATTEN_MAX)
2803 bbp_atten = BWI_BBP_ATTEN_MAX;
2804
2805 *rf_atten0 = rf_atten;
2806 *bbp_atten0 = bbp_atten;
2807 }
2808
2809 static void
2810 bwi_mac_adjust_tpctl(struct bwi_mac *mac, int rf_atten_adj, int bbp_atten_adj)
2811 {
2812 struct bwi_softc *sc = mac->mac_sc;
2813 struct bwi_rf *rf = &mac->mac_rf;
2814 struct bwi_tpctl tpctl;
2815 int bbp_atten, rf_atten, tp_ctrl1;
2816
2817 memcpy(&tpctl, &mac->mac_tpctl, sizeof(tpctl));
2818
2819 /* NOTE: Use signed value to do calulation */
2820 bbp_atten = tpctl.bbp_atten;
2821 rf_atten = tpctl.rf_atten;
2822 tp_ctrl1 = tpctl.tp_ctrl1;
2823
2824 bbp_atten += bbp_atten_adj;
2825 rf_atten += rf_atten_adj;
2826
2827 bwi_mac_balance_atten(&bbp_atten, &rf_atten);
2828
2829 if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 2) {
2830 if (rf_atten <= 1) {
2831 if (tp_ctrl1 == 0) {
2832 tp_ctrl1 = 3;
2833 bbp_atten += 2;
2834 rf_atten += 2;
2835 } else if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) {
2836 bbp_atten +=
2837 (BWI_RF_ATTEN_FACTOR * (rf_atten - 2));
2838 rf_atten = 2;
2839 }
2840 } else if (rf_atten > 4 && tp_ctrl1 != 0) {
2841 tp_ctrl1 = 0;
2842 if (bbp_atten < 3) {
2843 bbp_atten += 2;
2844 rf_atten -= 3;
2845 } else {
2846 bbp_atten -= 2;
2847 rf_atten -= 2;
2848 }
2849 }
2850 bwi_mac_balance_atten(&bbp_atten, &rf_atten);
2851 }
2852
2853 tpctl.bbp_atten = bbp_atten;
2854 tpctl.rf_atten = rf_atten;
2855 tpctl.tp_ctrl1 = tp_ctrl1;
2856
2857 bwi_mac_lock(mac);
2858 bwi_mac_set_tpctl_11bg(mac, &tpctl);
2859 bwi_mac_unlock(mac);
2860 }
2861
2862 /*
2863 * http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower
2864 */
2865 static void
2866 bwi_mac_calibrate_txpower(struct bwi_mac *mac, enum bwi_txpwrcb_type type)
2867 {
2868 struct bwi_softc *sc = mac->mac_sc;
2869 struct bwi_rf *rf = &mac->mac_rf;
2870 int8_t tssi[4], tssi_avg, cur_txpwr;
2871 int error, i, ofdm_tssi;
2872 int txpwr_diff, rf_atten_adj, bbp_atten_adj;
2873
2874 if (!sc->sc_txpwr_calib)
2875 return;
2876
2877 if (mac->mac_flags & BWI_MAC_F_TPCTL_ERROR) {
2878 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER,
2879 "tpctl error happened, can't set txpower\n");
2880 return;
2881 }
2882
2883 if (BWI_IS_BRCM_BU4306(sc)) {
2884 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER,
2885 "BU4306, can't set txpower\n");
2886 return;
2887 }
2888
2889 /*
2890 * Save latest TSSI and reset the related memory objects
2891 */
2892 ofdm_tssi = 0;
2893 error = bwi_rf_get_latest_tssi(mac, tssi, BWI_COMM_MOBJ_TSSI_DS);
2894 if (error) {
2895 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "no DS tssi\n");
2896
2897 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11B) {
2898 if (type == BWI_TXPWR_FORCE) {
2899 rf_atten_adj = 0;
2900 bbp_atten_adj = 1;
2901 goto calib;
2902 } else {
2903 return;
2904 }
2905 }
2906
2907 error = bwi_rf_get_latest_tssi(mac, tssi,
2908 BWI_COMM_MOBJ_TSSI_OFDM);
2909 if (error) {
2910 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER,
2911 "no OFDM tssi\n");
2912 if (type == BWI_TXPWR_FORCE) {
2913 rf_atten_adj = 0;
2914 bbp_atten_adj = 1;
2915 goto calib;
2916 } else {
2917 return;
2918 }
2919 }
2920
2921 for (i = 0; i < 4; ++i) {
2922 tssi[i] += 0x20;
2923 tssi[i] &= 0x3f;
2924 }
2925 ofdm_tssi = 1;
2926 }
2927 bwi_rf_clear_tssi(mac);
2928
2929 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER,
2930 "tssi0 %d, tssi1 %d, tssi2 %d, tssi3 %d\n",
2931 tssi[0], tssi[1], tssi[2], tssi[3]);
2932
2933 /*
2934 * Calculate RF/BBP attenuation adjustment based on
2935 * the difference between desired TX power and sampled
2936 * TX power.
2937 */
2938 /* +8 == "each incremented by 1/2" */
2939 tssi_avg = (tssi[0] + tssi[1] + tssi[2] + tssi[3] + 8) / 4;
2940 if (ofdm_tssi && (HFLAGS_READ(mac) & BWI_HFLAG_PWR_BOOST_DS))
2941 tssi_avg -= 13;
2942
2943 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "tssi avg %d\n", tssi_avg);
2944
2945 error = bwi_rf_tssi2dbm(mac, tssi_avg, &cur_txpwr);
2946 if (error)
2947 return;
2948 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "current txpower %d\n",
2949 cur_txpwr);
2950
2951 txpwr_diff = rf->rf_txpower_max - cur_txpwr; /* XXX ni_txpower */
2952
2953 rf_atten_adj = -howmany(txpwr_diff, 8);
2954
2955 if (type == BWI_TXPWR_INIT) {
2956 /*
2957 * Move toward EEPROM max TX power as fast as we can
2958 */
2959 bbp_atten_adj = -txpwr_diff;
2960 } else {
2961 bbp_atten_adj = -(txpwr_diff / 2);
2962 }
2963 bbp_atten_adj -= (BWI_RF_ATTEN_FACTOR * rf_atten_adj);
2964
2965 if (rf_atten_adj == 0 && bbp_atten_adj == 0) {
2966 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "%s\n",
2967 "no need to adjust RF/BBP attenuation");
2968 /* TODO: LO */
2969 return;
2970 }
2971
2972 calib:
2973 DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER,
2974 "rf atten adjust %d, bbp atten adjust %d\n",
2975 rf_atten_adj, bbp_atten_adj);
2976 bwi_mac_adjust_tpctl(mac, rf_atten_adj, bbp_atten_adj);
2977 /* TODO: LO */
2978 }
2979
2980 static void
2981 bwi_mac_lock(struct bwi_mac *mac)
2982 {
2983 struct bwi_softc *sc = mac->mac_sc;
2984 struct ieee80211com *ic = &sc->sc_ic;
2985
2986 KASSERT((mac->mac_flags & BWI_MAC_F_LOCKED) == 0);
2987
2988 if (mac->mac_rev < 3)
2989 bwi_mac_stop(mac);
2990 else if (ic->ic_opmode != IEEE80211_M_HOSTAP)
2991 bwi_mac_config_ps(mac);
2992
2993 CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_RFLOCK);
2994
2995 /* Flush pending bus write */
2996 CSR_READ_4(sc, BWI_MAC_STATUS);
2997 DELAY(10);
2998
2999 mac->mac_flags |= BWI_MAC_F_LOCKED;
3000 }
3001
3002 static void
3003 bwi_mac_unlock(struct bwi_mac *mac)
3004 {
3005 struct bwi_softc *sc = mac->mac_sc;
3006 struct ieee80211com *ic = &sc->sc_ic;
3007
3008 KASSERT(mac->mac_flags & BWI_MAC_F_LOCKED);
3009
3010 CSR_READ_2(sc, BWI_PHYINFO); /* dummy read */
3011
3012 CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_RFLOCK);
3013
3014 if (mac->mac_rev < 3)
3015 bwi_mac_start(mac);
3016 else if (ic->ic_opmode != IEEE80211_M_HOSTAP)
3017 bwi_mac_config_ps(mac);
3018
3019 mac->mac_flags &= ~BWI_MAC_F_LOCKED;
3020 }
3021
3022 static void
3023 bwi_mac_set_promisc(struct bwi_mac *mac, int promisc)
3024 {
3025 struct bwi_softc *sc = mac->mac_sc;
3026
3027 if (mac->mac_rev < 5) /* Promisc is always on */
3028 return;
3029
3030 if (promisc)
3031 CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PROMISC);
3032 else
3033 CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PROMISC);
3034 }
3035
3036 /* PHY */
3037
3038 static void
3039 bwi_phy_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
3040 {
3041 struct bwi_softc *sc = mac->mac_sc;
3042
3043 /* TODO: 11A */
3044 CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
3045 CSR_WRITE_2(sc, BWI_PHY_DATA, data);
3046 }
3047
3048 static uint16_t
3049 bwi_phy_read(struct bwi_mac *mac, uint16_t ctrl)
3050 {
3051 struct bwi_softc *sc = mac->mac_sc;
3052
3053 /* TODO: 11A */
3054 CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
3055 return (CSR_READ_2(sc, BWI_PHY_DATA));
3056 }
3057
3058 static int
3059 bwi_phy_attach(struct bwi_mac *mac)
3060 {
3061 struct bwi_softc *sc = mac->mac_sc;
3062 struct bwi_phy *phy = &mac->mac_phy;
3063 uint8_t phyrev, phytype, phyver;
3064 uint16_t val;
3065 int i;
3066
3067 /* Get PHY type/revision/version */
3068 val = CSR_READ_2(sc, BWI_PHYINFO);
3069 phyrev = __SHIFTOUT(val, BWI_PHYINFO_REV_MASK);
3070 phytype = __SHIFTOUT(val, BWI_PHYINFO_TYPE_MASK);
3071 phyver = __SHIFTOUT(val, BWI_PHYINFO_VER_MASK);
3072 aprint_normal_dev(sc->sc_dev, "PHY type %d, rev %d, ver %d\n",
3073 phytype, phyrev, phyver);
3074
3075 /*
3076 * Verify whether the revision of the PHY type is supported
3077 * Convert PHY type to ieee80211_phymode
3078 */
3079 switch (phytype) {
3080 case BWI_PHYINFO_TYPE_11A:
3081 if (phyrev >= 4) {
3082 aprint_error_dev(sc->sc_dev,
3083 "unsupported 11A PHY, rev %u\n",
3084 phyrev);
3085 return (ENXIO);
3086 }
3087 phy->phy_init = bwi_phy_init_11a;
3088 phy->phy_mode = IEEE80211_MODE_11A;
3089 phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11A;
3090 phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11A;
3091 phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11A;
3092 break;
3093 case BWI_PHYINFO_TYPE_11B:
3094 for (i = 0; i < __arraycount(bwi_sup_bphy); ++i) {
3095 if (phyrev == bwi_sup_bphy[i].rev) {
3096 phy->phy_init = bwi_sup_bphy[i].init;
3097 break;
3098 }
3099 }
3100 if (i == __arraycount(bwi_sup_bphy)) {
3101 aprint_error_dev(sc->sc_dev,
3102 "unsupported 11B PHY, rev %u\n",
3103 phyrev);
3104 return (ENXIO);
3105 }
3106 phy->phy_mode = IEEE80211_MODE_11B;
3107 break;
3108 case BWI_PHYINFO_TYPE_11G:
3109 if (phyrev > 8) {
3110 aprint_error_dev(sc->sc_dev,
3111 "unsupported 11G PHY, rev %u\n",
3112 phyrev);
3113 return (ENXIO);
3114 }
3115 phy->phy_init = bwi_phy_init_11g;
3116 phy->phy_mode = IEEE80211_MODE_11G;
3117 phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11G;
3118 phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11G;
3119 phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11G;
3120 break;
3121 default:
3122 aprint_error_dev(sc->sc_dev, "unsupported PHY type %d\n",
3123 phytype);
3124 return (ENXIO);
3125 }
3126 phy->phy_rev = phyrev;
3127 phy->phy_version = phyver;
3128
3129 return (0);
3130 }
3131
3132 static void
3133 bwi_phy_set_bbp_atten(struct bwi_mac *mac, uint16_t bbp_atten)
3134 {
3135 struct bwi_phy *phy = &mac->mac_phy;
3136 uint16_t mask = 0x000f;
3137
3138 if (phy->phy_version == 0) {
3139 CSR_FILT_SETBITS_2(mac->mac_sc, BWI_BBP_ATTEN, ~mask,
3140 __SHIFTIN(bbp_atten, mask));
3141 } else {
3142 if (phy->phy_version > 1)
3143 mask <<= 2;
3144 else
3145 mask <<= 3;
3146 PHY_FILT_SETBITS(mac, BWI_PHYR_BBP_ATTEN, ~mask,
3147 __SHIFTIN(bbp_atten, mask));
3148 }
3149 }
3150
3151 static int
3152 bwi_phy_calibrate(struct bwi_mac *mac)
3153 {
3154 struct bwi_phy *phy = &mac->mac_phy;
3155
3156 /* Dummy read */
3157 CSR_READ_4(mac->mac_sc, BWI_MAC_STATUS);
3158
3159 /* Don't re-init */
3160 if (phy->phy_flags & BWI_PHY_F_CALIBRATED)
3161 return (0);
3162
3163 if (phy->phy_mode == IEEE80211_MODE_11G && phy->phy_rev == 1) {
3164 bwi_mac_reset(mac, 0);
3165 bwi_phy_init_11g(mac);
3166 bwi_mac_reset(mac, 1);
3167 }
3168
3169 phy->phy_flags |= BWI_PHY_F_CALIBRATED;
3170
3171 return (0);
3172 }
3173
3174 static void
3175 bwi_tbl_write_2(struct bwi_mac *mac, uint16_t ofs, uint16_t data)
3176 {
3177 struct bwi_phy *phy = &mac->mac_phy;
3178
3179 KASSERT(phy->phy_tbl_ctrl != 0 && phy->phy_tbl_data_lo != 0);
3180 PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs);
3181 PHY_WRITE(mac, phy->phy_tbl_data_lo, data);
3182 }
3183
3184 static void
3185 bwi_tbl_write_4(struct bwi_mac *mac, uint16_t ofs, uint32_t data)
3186 {
3187 struct bwi_phy *phy = &mac->mac_phy;
3188
3189 KASSERT(phy->phy_tbl_data_lo != 0 && phy->phy_tbl_data_hi != 0 &&
3190 phy->phy_tbl_ctrl != 0);
3191
3192 PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs);
3193 PHY_WRITE(mac, phy->phy_tbl_data_hi, data >> 16);
3194 PHY_WRITE(mac, phy->phy_tbl_data_lo, data & 0xffff);
3195 }
3196
3197 static void
3198 bwi_nrssi_write(struct bwi_mac *mac, uint16_t ofs, int16_t data)
3199 {
3200 PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
3201 PHY_WRITE(mac, BWI_PHYR_NRSSI_DATA, (uint16_t)data);
3202 }
3203
3204 static int16_t
3205 bwi_nrssi_read(struct bwi_mac *mac, uint16_t ofs)
3206 {
3207 PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
3208 return ((int16_t)PHY_READ(mac, BWI_PHYR_NRSSI_DATA));
3209 }
3210
3211 static void
3212 bwi_phy_init_11a(struct bwi_mac *mac)
3213 {
3214 /* TODO: 11A */
3215 }
3216
3217 static void
3218 bwi_phy_init_11g(struct bwi_mac *mac)
3219 {
3220 struct bwi_softc *sc = mac->mac_sc;
3221 struct bwi_phy *phy = &mac->mac_phy;
3222 struct bwi_rf *rf = &mac->mac_rf;
3223 const struct bwi_tpctl *tpctl = &mac->mac_tpctl;
3224
3225 if (phy->phy_rev == 1)
3226 bwi_phy_init_11b_rev5(mac);
3227 else
3228 bwi_phy_init_11b_rev6(mac);
3229
3230 if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED))
3231 bwi_phy_config_11g(mac);
3232
3233 if (phy->phy_rev >= 2) {
3234 PHY_WRITE(mac, 0x814, 0);
3235 PHY_WRITE(mac, 0x815, 0);
3236
3237 if (phy->phy_rev == 2) {
3238 PHY_WRITE(mac, 0x811, 0);
3239 PHY_WRITE(mac, 0x15, 0xc0);
3240 } else if (phy->phy_rev > 5) {
3241 PHY_WRITE(mac, 0x811, 0x400);
3242 PHY_WRITE(mac, 0x15, 0xc0);
3243 }
3244 }
3245
3246 if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED)) {
3247 uint16_t val;
3248
3249 val = PHY_READ(mac, 0x400) & 0xff;
3250 if (val == 3 || val == 5) {
3251 PHY_WRITE(mac, 0x4c2, 0x1816);
3252 PHY_WRITE(mac, 0x4c3, 0x8006);
3253 if (val == 5) {
3254 PHY_FILT_SETBITS(mac, 0x4cc,
3255 0xff, 0x1f00);
3256 }
3257 }
3258 }
3259
3260 if ((phy->phy_rev <= 2 && (phy->phy_flags & BWI_PHY_F_LINKED)) ||
3261 phy->phy_rev >= 2)
3262 PHY_WRITE(mac, 0x47e, 0x78);
3263
3264 if (rf->rf_rev == 8) {
3265 PHY_SETBITS(mac, 0x801, 0x80);
3266 PHY_SETBITS(mac, 0x43e, 0x4);
3267 }
3268
3269 if (phy->phy_rev >= 2 && (phy->phy_flags & BWI_PHY_F_LINKED))
3270 bwi_rf_get_gains(mac);
3271
3272 if (rf->rf_rev != 8)
3273 bwi_rf_init(mac);
3274
3275 if (tpctl->tp_ctrl2 == 0xffff) {
3276 bwi_rf_lo_update(mac);
3277 } else {
3278 if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 8) {
3279 RF_WRITE(mac, 0x52,
3280 (tpctl->tp_ctrl1 << 4) | tpctl->tp_ctrl2);
3281 } else {
3282 RF_FILT_SETBITS(mac, 0x52, 0xfff0, tpctl->tp_ctrl2);
3283 }
3284
3285 if (phy->phy_rev >= 6) {
3286 PHY_FILT_SETBITS(mac, 0x36, 0xfff,
3287 tpctl->tp_ctrl2 << 12);
3288 }
3289
3290 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
3291 PHY_WRITE(mac, 0x2e, 0x8075);
3292 else
3293 PHY_WRITE(mac, 0x2e, 0x807f);
3294
3295 if (phy->phy_rev < 2)
3296 PHY_WRITE(mac, 0x2f, 0x101);
3297 else
3298 PHY_WRITE(mac, 0x2f, 0x202);
3299 }
3300
3301 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
3302 bwi_rf_lo_adjust(mac, tpctl);
3303 PHY_WRITE(mac, 0x80f, 0x8078);
3304 }
3305
3306 if ((sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) {
3307 bwi_rf_init_hw_nrssi_table(mac, 0xffff /* XXX */);
3308 bwi_rf_set_nrssi_thr(mac);
3309 } else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
3310 if (rf->rf_nrssi[0] == BWI_INVALID_NRSSI) {
3311 KASSERT(rf->rf_nrssi[1] == BWI_INVALID_NRSSI);
3312 bwi_rf_calc_nrssi_slope(mac);
3313 } else {
3314 KASSERT(rf->rf_nrssi[1] != BWI_INVALID_NRSSI);
3315 bwi_rf_set_nrssi_thr(mac);
3316 }
3317 }
3318
3319 if (rf->rf_rev == 8)
3320 PHY_WRITE(mac, 0x805, 0x3230);
3321
3322 bwi_mac_init_tpctl_11bg(mac);
3323
3324 if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_pkg == 2) {
3325 PHY_CLRBITS(mac, 0x429, 0x4000);
3326 PHY_CLRBITS(mac, 0x4c3, 0x8000);
3327 }
3328 }
3329
3330 static void
3331 bwi_phy_init_11b_rev2(struct bwi_mac *mac)
3332 {
3333 struct bwi_softc *sc;
3334
3335 sc = mac->mac_sc;
3336
3337 /* TODO: 11B */
3338 aprint_error_dev(sc->sc_dev, "%s is not implemented yet\n", __func__);
3339 }
3340
3341 static void
3342 bwi_phy_init_11b_rev4(struct bwi_mac *mac)
3343 {
3344 struct bwi_softc *sc = mac->mac_sc;
3345 struct bwi_rf *rf = &mac->mac_rf;
3346 uint16_t val, ofs;
3347 uint chan;
3348
3349 CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
3350
3351 PHY_WRITE(mac, 0x20, 0x301c);
3352 PHY_WRITE(mac, 0x26, 0);
3353 PHY_WRITE(mac, 0x30, 0xc6);
3354 PHY_WRITE(mac, 0x88, 0x3e00);
3355
3356 for (ofs = 0, val = 0x3c3d; ofs < 30; ++ofs, val -= 0x202)
3357 PHY_WRITE(mac, 0x89 + ofs, val);
3358
3359 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
3360
3361 chan = rf->rf_curchan;
3362 if (chan == IEEE80211_CHAN_ANY)
3363 chan = 6; /* Force to channel 6 */
3364 bwi_rf_set_chan(mac, chan, 0);
3365
3366 if (rf->rf_type != BWI_RF_T_BCM2050) {
3367 RF_WRITE(mac, 0x75, 0x80);
3368 RF_WRITE(mac, 0x79, 0x81);
3369 }
3370
3371 RF_WRITE(mac, 0x50, 0x20);
3372 RF_WRITE(mac, 0x50, 0x23);
3373
3374 if (rf->rf_type == BWI_RF_T_BCM2050) {
3375 RF_WRITE(mac, 0x50, 0x20);
3376 RF_WRITE(mac, 0x5a, 0x70);
3377 RF_WRITE(mac, 0x5b, 0x7b);
3378 RF_WRITE(mac, 0x5c, 0xb0);
3379 RF_WRITE(mac, 0x7a, 0xf);
3380 PHY_WRITE(mac, 0x38, 0x677);
3381 bwi_rf_init_bcm2050(mac);
3382 }
3383
3384 PHY_WRITE(mac, 0x14, 0x80);
3385 PHY_WRITE(mac, 0x32, 0xca);
3386 if (rf->rf_type == BWI_RF_T_BCM2050)
3387 PHY_WRITE(mac, 0x32, 0xe0);
3388 PHY_WRITE(mac, 0x35, 0x7c2);
3389
3390 bwi_rf_lo_update(mac);
3391
3392 PHY_WRITE(mac, 0x26, 0xcc00);
3393 if (rf->rf_type == BWI_RF_T_BCM2050)
3394 PHY_WRITE(mac, 0x26, 0xce00);
3395
3396 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0x1100);
3397
3398 PHY_WRITE(mac, 0x2a, 0x88a3);
3399 if (rf->rf_type == BWI_RF_T_BCM2050)
3400 PHY_WRITE(mac, 0x2a, 0x88c2);
3401
3402 bwi_mac_set_tpctl_11bg(mac, NULL);
3403 if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
3404 bwi_rf_calc_nrssi_slope(mac);
3405 bwi_rf_set_nrssi_thr(mac);
3406 }
3407 bwi_mac_init_tpctl_11bg(mac);
3408 }
3409
3410 static void
3411 bwi_phy_init_11b_rev5(struct bwi_mac *mac)
3412 {
3413 struct bwi_softc *sc = mac->mac_sc;
3414 struct bwi_rf *rf = &mac->mac_rf;
3415 struct bwi_phy *phy = &mac->mac_phy;
3416 uint orig_chan;
3417
3418 if (phy->phy_version == 1)
3419 RF_SETBITS(mac, 0x7a, 0x50);
3420
3421 if (sc->sc_pci_subvid != PCI_VENDOR_BROADCOM &&
3422 sc->sc_pci_subdid != BWI_PCI_SUBDEVICE_BU4306) {
3423 uint16_t ofs, val;
3424
3425 val = 0x2120;
3426 for (ofs = 0xa8; ofs < 0xc7; ++ofs) {
3427 PHY_WRITE(mac, ofs, val);
3428 val += 0x202;
3429 }
3430 }
3431
3432 PHY_FILT_SETBITS(mac, 0x35, 0xf0ff, 0x700);
3433
3434 if (rf->rf_type == BWI_RF_T_BCM2050)
3435 PHY_WRITE(mac, 0x38, 0x667);
3436
3437 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
3438 if (rf->rf_type == BWI_RF_T_BCM2050) {
3439 RF_SETBITS(mac, 0x7a, 0x20);
3440 RF_SETBITS(mac, 0x51, 0x4);
3441 }
3442
3443 CSR_WRITE_2(sc, BWI_RF_ANTDIV, 0);
3444
3445 PHY_SETBITS(mac, 0x802, 0x100);
3446 PHY_SETBITS(mac, 0x42b, 0x2000);
3447 PHY_WRITE(mac, 0x1c, 0x186a);
3448
3449 PHY_FILT_SETBITS(mac, 0x13, 0xff, 0x1900);
3450 PHY_FILT_SETBITS(mac, 0x35, 0xffc0, 0x64);
3451 PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0xa);
3452 }
3453
3454 /* TODO: bad_frame_preempt? */
3455
3456 if (phy->phy_version == 1) {
3457 PHY_WRITE(mac, 0x26, 0xce00);
3458 PHY_WRITE(mac, 0x21, 0x3763);
3459 PHY_WRITE(mac, 0x22, 0x1bc3);
3460 PHY_WRITE(mac, 0x23, 0x6f9);
3461 PHY_WRITE(mac, 0x24, 0x37e);
3462 } else
3463 PHY_WRITE(mac, 0x26, 0xcc00);
3464 PHY_WRITE(mac, 0x30, 0xc6);
3465
3466 CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
3467
3468 if (phy->phy_version == 1)
3469 PHY_WRITE(mac, 0x20, 0x3e1c);
3470 else
3471 PHY_WRITE(mac, 0x20, 0x301c);
3472
3473 if (phy->phy_version == 0)
3474 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
3475
3476 /* Force to channel 7 */
3477 orig_chan = rf->rf_curchan;
3478 bwi_rf_set_chan(mac, 7, 0);
3479
3480 if (rf->rf_type != BWI_RF_T_BCM2050) {
3481 RF_WRITE(mac, 0x75, 0x80);
3482 RF_WRITE(mac, 0x79, 0x81);
3483 }
3484
3485 RF_WRITE(mac, 0x50, 0x20);
3486 RF_WRITE(mac, 0x50, 0x23);
3487
3488 if (rf->rf_type == BWI_RF_T_BCM2050) {
3489 RF_WRITE(mac, 0x50, 0x20);
3490 RF_WRITE(mac, 0x5a, 0x70);
3491 }
3492
3493 RF_WRITE(mac, 0x5b, 0x7b);
3494 RF_WRITE(mac, 0x5c, 0xb0);
3495 RF_SETBITS(mac, 0x7a, 0x7);
3496
3497 bwi_rf_set_chan(mac, orig_chan, 0);
3498
3499 PHY_WRITE(mac, 0x14, 0x80);
3500 PHY_WRITE(mac, 0x32, 0xca);
3501 PHY_WRITE(mac, 0x2a, 0x88a3);
3502
3503 bwi_mac_set_tpctl_11bg(mac, NULL);
3504
3505 if (rf->rf_type == BWI_RF_T_BCM2050)
3506 RF_WRITE(mac, 0x5d, 0xd);
3507
3508 CSR_FILT_SETBITS_2(sc, BWI_PHY_MAGIC_REG1, 0xffc0, 0x4);
3509 }
3510
3511 static void
3512 bwi_phy_init_11b_rev6(struct bwi_mac *mac)
3513 {
3514 struct bwi_softc *sc = mac->mac_sc;
3515 struct bwi_rf *rf = &mac->mac_rf;
3516 struct bwi_phy *phy = &mac->mac_phy;
3517 uint16_t val, ofs;
3518 uint orig_chan;
3519
3520 PHY_WRITE(mac, 0x3e, 0x817a);
3521 RF_SETBITS(mac, 0x7a, 0x58);
3522
3523 if (rf->rf_rev == 4 || rf->rf_rev == 5) {
3524 RF_WRITE(mac, 0x51, 0x37);
3525 RF_WRITE(mac, 0x52, 0x70);
3526 RF_WRITE(mac, 0x53, 0xb3);
3527 RF_WRITE(mac, 0x54, 0x9b);
3528 RF_WRITE(mac, 0x5a, 0x88);
3529 RF_WRITE(mac, 0x5b, 0x88);
3530 RF_WRITE(mac, 0x5d, 0x88);
3531 RF_WRITE(mac, 0x5e, 0x88);
3532 RF_WRITE(mac, 0x7d, 0x88);
3533 HFLAGS_SETBITS(mac, BWI_HFLAG_MAGIC1);
3534 } else if (rf->rf_rev == 8) {
3535 RF_WRITE(mac, 0x51, 0);
3536 RF_WRITE(mac, 0x52, 0x40);
3537 RF_WRITE(mac, 0x53, 0xb7);
3538 RF_WRITE(mac, 0x54, 0x98);
3539 RF_WRITE(mac, 0x5a, 0x88);
3540 RF_WRITE(mac, 0x5b, 0x6b);
3541 RF_WRITE(mac, 0x5c, 0xf);
3542 if (sc->sc_card_flags & BWI_CARD_F_ALT_IQ) {
3543 RF_WRITE(mac, 0x5d, 0xfa);
3544 RF_WRITE(mac, 0x5e, 0xd8);
3545 } else {
3546 RF_WRITE(mac, 0x5d, 0xf5);
3547 RF_WRITE(mac, 0x5e, 0xb8);
3548 }
3549 RF_WRITE(mac, 0x73, 0x3);
3550 RF_WRITE(mac, 0x7d, 0xa8);
3551 RF_WRITE(mac, 0x7c, 0x1);
3552 RF_WRITE(mac, 0x7e, 0x8);
3553 }
3554
3555 val = 0x1e1f;
3556 for (ofs = 0x88; ofs < 0x98; ++ofs) {
3557 PHY_WRITE(mac, ofs, val);
3558 val -= 0x202;
3559 }
3560
3561 val = 0x3e3f;
3562 for (ofs = 0x98; ofs < 0xa8; ++ofs) {
3563 PHY_WRITE(mac, ofs, val);
3564 val -= 0x202;
3565 }
3566
3567 val = 0x2120;
3568 for (ofs = 0xa8; ofs < 0xc8; ++ofs) {
3569 PHY_WRITE(mac, ofs, (val & 0x3f3f));
3570 val += 0x202;
3571 }
3572
3573 if (phy->phy_mode == IEEE80211_MODE_11G) {
3574 RF_SETBITS(mac, 0x7a, 0x20);
3575 RF_SETBITS(mac, 0x51, 0x4);
3576 PHY_SETBITS(mac, 0x802, 0x100);
3577 PHY_SETBITS(mac, 0x42b, 0x2000);
3578 PHY_WRITE(mac, 0x5b, 0);
3579 PHY_WRITE(mac, 0x5c, 0);
3580 }
3581
3582 /* Force to channel 7 */
3583 orig_chan = rf->rf_curchan;
3584 if (orig_chan >= 8)
3585 bwi_rf_set_chan(mac, 1, 0);
3586 else
3587 bwi_rf_set_chan(mac, 13, 0);
3588
3589 RF_WRITE(mac, 0x50, 0x20);
3590 RF_WRITE(mac, 0x50, 0x23);
3591
3592 DELAY(40);
3593
3594 if (rf->rf_rev < 6 || rf->rf_rev == 8) {
3595 RF_SETBITS(mac, 0x7c, 0x2);
3596 RF_WRITE(mac, 0x50, 0x20);
3597 }
3598 if (rf->rf_rev <= 2) {
3599 RF_WRITE(mac, 0x7c, 0x20);
3600 RF_WRITE(mac, 0x5a, 0x70);
3601 RF_WRITE(mac, 0x5b, 0x7b);
3602 RF_WRITE(mac, 0x5c, 0xb0);
3603 }
3604
3605 RF_FILT_SETBITS(mac, 0x7a, 0xf8, 0x7);
3606
3607 bwi_rf_set_chan(mac, orig_chan, 0);
3608
3609 PHY_WRITE(mac, 0x14, 0x200);
3610 if (rf->rf_rev >= 6)
3611 PHY_WRITE(mac, 0x2a, 0x88c2);
3612 else
3613 PHY_WRITE(mac, 0x2a, 0x8ac0);
3614 PHY_WRITE(mac, 0x38, 0x668);
3615
3616 bwi_mac_set_tpctl_11bg(mac, NULL);
3617
3618 if (rf->rf_rev <= 5) {
3619 PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0x3);
3620 if (rf->rf_rev <= 2)
3621 RF_WRITE(mac, 0x5d, 0xd);
3622 }
3623
3624 if (phy->phy_version == 4) {
3625 CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL2);
3626 PHY_CLRBITS(mac, 0x61, 0xf000);
3627 } else {
3628 PHY_FILT_SETBITS(mac, 0x2, 0xffc0, 0x4);
3629 }
3630
3631 if (phy->phy_mode == IEEE80211_MODE_11B) {
3632 CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC2);
3633 PHY_WRITE(mac, 0x16, 0x410);
3634 PHY_WRITE(mac, 0x17, 0x820);
3635 PHY_WRITE(mac, 0x62, 0x7);
3636
3637 bwi_rf_init_bcm2050(mac);
3638 bwi_rf_lo_update(mac);
3639 if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
3640 bwi_rf_calc_nrssi_slope(mac);
3641 bwi_rf_set_nrssi_thr(mac);
3642 }
3643 bwi_mac_init_tpctl_11bg(mac);
3644 } else
3645 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
3646 }
3647
3648 static void
3649 bwi_phy_config_11g(struct bwi_mac *mac)
3650 {
3651 struct bwi_softc *sc = mac->mac_sc;
3652 struct bwi_phy *phy = &mac->mac_phy;
3653 const uint16_t *tbl;
3654 uint16_t wrd_ofs1, wrd_ofs2;
3655 int i, n;
3656
3657 if (phy->phy_rev == 1) {
3658 PHY_WRITE(mac, 0x406, 0x4f19);
3659 PHY_FILT_SETBITS(mac, 0x429, 0xfc3f, 0x340);
3660 PHY_WRITE(mac, 0x42c, 0x5a);
3661 PHY_WRITE(mac, 0x427, 0x1a);
3662
3663 /* Fill frequency table */
3664 for (i = 0; i < __arraycount(bwi_phy_freq_11g_rev1); ++i) {
3665 bwi_tbl_write_2(mac, BWI_PHYTBL_FREQ + i,
3666 bwi_phy_freq_11g_rev1[i]);
3667 }
3668
3669 /* Fill noise table */
3670 for (i = 0; i < __arraycount(bwi_phy_noise_11g_rev1); ++i) {
3671 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
3672 bwi_phy_noise_11g_rev1[i]);
3673 }
3674
3675 /* Fill rotor table */
3676 for (i = 0; i < __arraycount(bwi_phy_rotor_11g_rev1); ++i) {
3677 /* NB: data length is 4 bytes */
3678 bwi_tbl_write_4(mac, BWI_PHYTBL_ROTOR + i,
3679 bwi_phy_rotor_11g_rev1[i]);
3680 }
3681 } else {
3682 bwi_nrssi_write(mac, 0xba98, (int16_t)0x7654); /* XXX */
3683
3684 if (phy->phy_rev == 2) {
3685 PHY_WRITE(mac, 0x4c0, 0x1861);
3686 PHY_WRITE(mac, 0x4c1, 0x271);
3687 } else if (phy->phy_rev > 2) {
3688 PHY_WRITE(mac, 0x4c0, 0x98);
3689 PHY_WRITE(mac, 0x4c1, 0x70);
3690 PHY_WRITE(mac, 0x4c9, 0x80);
3691 }
3692 PHY_SETBITS(mac, 0x42b, 0x800);
3693
3694 /* Fill RSSI table */
3695 for (i = 0; i < 64; ++i)
3696 bwi_tbl_write_2(mac, BWI_PHYTBL_RSSI + i, i);
3697
3698 /* Fill noise table */
3699 for (i = 0; i < __arraycount(bwi_phy_noise_11g); ++i) {
3700 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
3701 bwi_phy_noise_11g[i]);
3702 }
3703 }
3704
3705 /*
3706 * Fill noise scale table
3707 */
3708 if (phy->phy_rev <= 2) {
3709 tbl = bwi_phy_noise_scale_11g_rev2;
3710 n = __arraycount(bwi_phy_noise_scale_11g_rev2);
3711 } else if (phy->phy_rev >= 7 && (PHY_READ(mac, 0x449) & 0x200)) {
3712 tbl = bwi_phy_noise_scale_11g_rev7;
3713 n = __arraycount(bwi_phy_noise_scale_11g_rev7);
3714 } else {
3715 tbl = bwi_phy_noise_scale_11g;
3716 n = __arraycount(bwi_phy_noise_scale_11g);
3717 }
3718 for (i = 0; i < n; ++i)
3719 bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE_SCALE + i, tbl[i]);
3720
3721 /*
3722 * Fill sigma square table
3723 */
3724 if (phy->phy_rev == 2) {
3725 tbl = bwi_phy_sigma_sq_11g_rev2;
3726 n = __arraycount(bwi_phy_sigma_sq_11g_rev2);
3727 } else if (phy->phy_rev > 2 && phy->phy_rev <= 8) {
3728 tbl = bwi_phy_sigma_sq_11g_rev7;
3729 n = __arraycount(bwi_phy_sigma_sq_11g_rev7);
3730 } else {
3731 tbl = NULL;
3732 n = 0;
3733 }
3734 for (i = 0; i < n; ++i)
3735 bwi_tbl_write_2(mac, BWI_PHYTBL_SIGMA_SQ + i, tbl[i]);
3736
3737 if (phy->phy_rev == 1) {
3738 /* Fill delay table */
3739 for (i = 0; i < __arraycount(bwi_phy_delay_11g_rev1); ++i) {
3740 bwi_tbl_write_4(mac, BWI_PHYTBL_DELAY + i,
3741 bwi_phy_delay_11g_rev1[i]);
3742 }
3743
3744 /* Fill WRSSI (Wide-Band RSSI) table */
3745 for (i = 4; i < 20; ++i)
3746 bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI_REV1 + i, 0x20);
3747
3748 bwi_phy_config_agc(mac);
3749
3750 wrd_ofs1 = 0x5001;
3751 wrd_ofs2 = 0x5002;
3752 } else {
3753 /* Fill WRSSI (Wide-Band RSSI) table */
3754 for (i = 0; i < 0x20; ++i)
3755 bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI + i, 0x820);
3756
3757 bwi_phy_config_agc(mac);
3758
3759 PHY_READ(mac, 0x400); /* Dummy read */
3760 PHY_WRITE(mac, 0x403, 0x1000);
3761 bwi_tbl_write_2(mac, 0x3c02, 0xf);
3762 bwi_tbl_write_2(mac, 0x3c03, 0x14);
3763
3764 wrd_ofs1 = 0x401;
3765 wrd_ofs2 = 0x402;
3766 }
3767
3768 if (!(BWI_IS_BRCM_BU4306(sc) && sc->sc_pci_revid == 0x17)) {
3769 bwi_tbl_write_2(mac, wrd_ofs1, 0x2);
3770 bwi_tbl_write_2(mac, wrd_ofs2, 0x1);
3771 }
3772
3773 /* phy->phy_flags & BWI_PHY_F_LINKED ? */
3774 if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
3775 PHY_WRITE(mac, 0x46e, 0x3cf);
3776 }
3777
3778 /*
3779 * Configure Automatic Gain Controller
3780 */
3781 static void
3782 bwi_phy_config_agc(struct bwi_mac *mac)
3783 {
3784 struct bwi_phy *phy = &mac->mac_phy;
3785 uint16_t ofs;
3786
3787 ofs = phy->phy_rev == 1 ? 0x4c00 : 0;
3788
3789 bwi_tbl_write_2(mac, ofs, 0xfe);
3790 bwi_tbl_write_2(mac, ofs + 1, 0xd);
3791 bwi_tbl_write_2(mac, ofs + 2, 0x13);
3792 bwi_tbl_write_2(mac, ofs + 3, 0x19);
3793
3794 if (phy->phy_rev == 1) {
3795 bwi_tbl_write_2(mac, 0x1800, 0x2710);
3796 bwi_tbl_write_2(mac, 0x1801, 0x9b83);
3797 bwi_tbl_write_2(mac, 0x1802, 0x9b83);
3798 bwi_tbl_write_2(mac, 0x1803, 0xf8d);
3799 PHY_WRITE(mac, 0x455, 0x4);
3800 }
3801
3802 PHY_FILT_SETBITS(mac, 0x4a5, 0xff, 0x5700);
3803 PHY_FILT_SETBITS(mac, 0x41a, 0xff80, 0xf);
3804 PHY_FILT_SETBITS(mac, 0x41a, 0xc07f, 0x2b80);
3805 PHY_FILT_SETBITS(mac, 0x48c, 0xf0ff, 0x300);
3806
3807 RF_SETBITS(mac, 0x7a, 0x8);
3808
3809 PHY_FILT_SETBITS(mac, 0x4a0, 0xfff0, 0x8);
3810 PHY_FILT_SETBITS(mac, 0x4a1, 0xf0ff, 0x600);
3811 PHY_FILT_SETBITS(mac, 0x4a2, 0xf0ff, 0x700);
3812 PHY_FILT_SETBITS(mac, 0x4a0, 0xf0ff, 0x100);
3813
3814 if (phy->phy_rev == 1)
3815 PHY_FILT_SETBITS(mac, 0x4a2, 0xfff0, 0x7);
3816
3817 PHY_FILT_SETBITS(mac, 0x488, 0xff00, 0x1c);
3818 PHY_FILT_SETBITS(mac, 0x488, 0xc0ff, 0x200);
3819 PHY_FILT_SETBITS(mac, 0x496, 0xff00, 0x1c);
3820 PHY_FILT_SETBITS(mac, 0x489, 0xff00, 0x20);
3821 PHY_FILT_SETBITS(mac, 0x489, 0xc0ff, 0x200);
3822 PHY_FILT_SETBITS(mac, 0x482, 0xff00, 0x2e);
3823 PHY_FILT_SETBITS(mac, 0x496, 0xff, 0x1a00);
3824 PHY_FILT_SETBITS(mac, 0x481, 0xff00, 0x28);
3825 PHY_FILT_SETBITS(mac, 0x481, 0xff, 0x2c00);
3826
3827 if (phy->phy_rev == 1) {
3828 PHY_WRITE(mac, 0x430, 0x92b);
3829 PHY_FILT_SETBITS(mac, 0x41b, 0xffe1, 0x2);
3830 } else {
3831 PHY_CLRBITS(mac, 0x41b, 0x1e);
3832 PHY_WRITE(mac, 0x41f, 0x287a);
3833 PHY_FILT_SETBITS(mac, 0x420, 0xfff0, 0x4);
3834
3835 if (phy->phy_rev >= 6) {
3836 PHY_WRITE(mac, 0x422, 0x287a);
3837 PHY_FILT_SETBITS(mac, 0x420, 0xfff, 0x3000);
3838 }
3839 }
3840
3841 PHY_FILT_SETBITS(mac, 0x4a8, 0x8080, 0x7874);
3842 PHY_WRITE(mac, 0x48e, 0x1c00);
3843
3844 if (phy->phy_rev == 1) {
3845 PHY_FILT_SETBITS(mac, 0x4ab, 0xf0ff, 0x600);
3846 PHY_WRITE(mac, 0x48b, 0x5e);
3847 PHY_FILT_SETBITS(mac, 0x48c, 0xff00, 0x1e);
3848 PHY_WRITE(mac, 0x48d, 0x2);
3849 }
3850
3851 bwi_tbl_write_2(mac, ofs + 0x800, 0);
3852 bwi_tbl_write_2(mac, ofs + 0x801, 7);
3853 bwi_tbl_write_2(mac, ofs + 0x802, 16);
3854 bwi_tbl_write_2(mac, ofs + 0x803, 28);
3855
3856 if (phy->phy_rev >= 6) {
3857 PHY_CLRBITS(mac, 0x426, 0x3);
3858 PHY_CLRBITS(mac, 0x426, 0x1000);
3859 }
3860 }
3861
3862 static void
3863 bwi_set_gains(struct bwi_mac *mac, const struct bwi_gains *gains)
3864 {
3865 struct bwi_phy *phy = &mac->mac_phy;
3866 uint16_t tbl_gain_ofs1, tbl_gain_ofs2, tbl_gain;
3867 int i;
3868
3869 if (phy->phy_rev <= 1) {
3870 tbl_gain_ofs1 = 0x5000;
3871 tbl_gain_ofs2 = tbl_gain_ofs1 + 16;
3872 } else {
3873 tbl_gain_ofs1 = 0x400;
3874 tbl_gain_ofs2 = tbl_gain_ofs1 + 8;
3875 }
3876
3877 for (i = 0; i < 4; ++i) {
3878 if (gains != NULL) {
3879 tbl_gain = gains->tbl_gain1;
3880 } else {
3881 /* Bit swap */
3882 tbl_gain = (i & 0x1) << 1;
3883 tbl_gain |= (i & 0x2) >> 1;
3884 }
3885 bwi_tbl_write_2(mac, tbl_gain_ofs1 + i, tbl_gain);
3886 }
3887
3888 for (i = 0; i < 16; ++i) {
3889 if (gains != NULL)
3890 tbl_gain = gains->tbl_gain2;
3891 else
3892 tbl_gain = i;
3893 bwi_tbl_write_2(mac, tbl_gain_ofs2 + i, tbl_gain);
3894 }
3895
3896 if (gains == NULL || gains->phy_gain != -1) {
3897 uint16_t phy_gain1, phy_gain2;
3898
3899 if (gains != NULL) {
3900 phy_gain1 =
3901 ((uint16_t)gains->phy_gain << 14) |
3902 ((uint16_t)gains->phy_gain << 6);
3903 phy_gain2 = phy_gain1;
3904 } else {
3905 phy_gain1 = 0x4040;
3906 phy_gain2 = 0x4000;
3907 }
3908 PHY_FILT_SETBITS(mac, 0x4a0, 0xbfbf, phy_gain1);
3909 PHY_FILT_SETBITS(mac, 0x4a1, 0xbfbf, phy_gain1);
3910 PHY_FILT_SETBITS(mac, 0x4a2, 0xbfbf, phy_gain2);
3911 }
3912 bwi_mac_dummy_xmit(mac);
3913 }
3914
3915 static void
3916 bwi_phy_clear_state(struct bwi_phy *phy)
3917 {
3918 phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS;
3919 }
3920
3921 /* RF */
3922
3923 static int16_t
3924 bwi_nrssi_11g(struct bwi_mac *mac)
3925 {
3926 int16_t val;
3927
3928 #define NRSSI_11G_MASK 0x3f00
3929 val = (int16_t)__SHIFTOUT(PHY_READ(mac, 0x47f), NRSSI_11G_MASK);
3930 if (val >= 32)
3931 val -= 64;
3932
3933 return (val);
3934 #undef NRSSI_11G_MASK
3935 }
3936
3937 static struct bwi_rf_lo *
3938 bwi_get_rf_lo(struct bwi_mac *mac, uint16_t rf_atten, uint16_t bbp_atten)
3939 {
3940 int n;
3941
3942 n = rf_atten + (14 * (bbp_atten / 2));
3943 KASSERT(n < BWI_RFLO_MAX);
3944
3945 return (&mac->mac_rf.rf_lo[n]);
3946 }
3947
3948 static int
3949 bwi_rf_lo_isused(struct bwi_mac *mac, const struct bwi_rf_lo *lo)
3950 {
3951 struct bwi_rf *rf = &mac->mac_rf;
3952 int idx;
3953
3954 idx = lo - rf->rf_lo;
3955 KASSERT(idx >= 0 && idx < BWI_RFLO_MAX);
3956
3957 return (isset(rf->rf_lo_used, idx));
3958 }
3959
3960 static void
3961 bwi_rf_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
3962 {
3963 struct bwi_softc *sc = mac->mac_sc;
3964
3965 CSR_WRITE_2(sc, BWI_RF_CTRL, ctrl);
3966 CSR_WRITE_2(sc, BWI_RF_DATA_LO, data);
3967 }
3968
3969 static uint16_t
3970 bwi_rf_read(struct bwi_mac *mac, uint16_t ctrl)
3971 {
3972 struct bwi_rf *rf = &mac->mac_rf;
3973 struct bwi_softc *sc = mac->mac_sc;
3974
3975 ctrl |= rf->rf_ctrl_rd;
3976 if (rf->rf_ctrl_adj) {
3977 /* XXX */
3978 if (ctrl < 0x70)
3979 ctrl += 0x80;
3980 else if (ctrl < 0x80)
3981 ctrl += 0x70;
3982 }
3983
3984 CSR_WRITE_2(sc, BWI_RF_CTRL, ctrl);
3985 return (CSR_READ_2(sc, BWI_RF_DATA_LO));
3986 }
3987
3988 static int
3989 bwi_rf_attach(struct bwi_mac *mac)
3990 {
3991 struct bwi_softc *sc = mac->mac_sc;
3992 struct bwi_phy *phy = &mac->mac_phy;
3993 struct bwi_rf *rf = &mac->mac_rf;
3994 uint16_t type, manu;
3995 uint8_t rev;
3996
3997 /*
3998 * Get RF manufacture/type/revision
3999 */
4000 if (sc->sc_bbp_id == BWI_BBPID_BCM4317) {
4001 /*
4002 * Fake a BCM2050 RF
4003 */
4004 manu = BWI_RF_MANUFACT_BCM;
4005 type = BWI_RF_T_BCM2050;
4006 if (sc->sc_bbp_rev == 0)
4007 rev = 3;
4008 else if (sc->sc_bbp_rev == 1)
4009 rev = 4;
4010 else
4011 rev = 5;
4012 } else {
4013 uint32_t val;
4014
4015 CSR_WRITE_2(sc, BWI_RF_CTRL, BWI_RF_CTRL_RFINFO);
4016 val = CSR_READ_2(sc, BWI_RF_DATA_HI);
4017 val <<= 16;
4018
4019 CSR_WRITE_2(sc, BWI_RF_CTRL, BWI_RF_CTRL_RFINFO);
4020 val |= CSR_READ_2(sc, BWI_RF_DATA_LO);
4021
4022 manu = __SHIFTOUT(val, BWI_RFINFO_MANUFACT_MASK);
4023 type = __SHIFTOUT(val, BWI_RFINFO_TYPE_MASK);
4024 rev = __SHIFTOUT(val, BWI_RFINFO_REV_MASK);
4025 }
4026 aprint_normal_dev(sc->sc_dev, "RF manu 0x%03x, type 0x%04x, rev %u\n",
4027 manu, type, rev);
4028
4029 /*
4030 * Verify whether the RF is supported
4031 */
4032 rf->rf_ctrl_rd = 0;
4033 rf->rf_ctrl_adj = 0;
4034 switch (phy->phy_mode) {
4035 case IEEE80211_MODE_11A:
4036 if (manu != BWI_RF_MANUFACT_BCM ||
4037 type != BWI_RF_T_BCM2060 ||
4038 rev != 1) {
4039 aprint_error_dev(sc->sc_dev,
4040 "only BCM2060 rev 1 RF is supported for"
4041 " 11A PHY\n");
4042 return (ENXIO);
4043 }
4044 rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11A;
4045 rf->rf_on = bwi_rf_on_11a;
4046 rf->rf_off = bwi_rf_off_11a;
4047 rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2060;
4048 break;
4049 case IEEE80211_MODE_11B:
4050 if (type == BWI_RF_T_BCM2050) {
4051 rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11BG;
4052 rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2050;
4053 } else if (type == BWI_RF_T_BCM2053) {
4054 rf->rf_ctrl_adj = 1;
4055 rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2053;
4056 } else {
4057 aprint_error_dev(sc->sc_dev,
4058 "only BCM2050/BCM2053 RF is supported for"
4059 " 11B phy\n");
4060 return (ENXIO);
4061 }
4062 rf->rf_on = bwi_rf_on_11bg;
4063 rf->rf_off = bwi_rf_off_11bg;
4064 rf->rf_calc_nrssi_slope = bwi_rf_calc_nrssi_slope_11b;
4065 rf->rf_set_nrssi_thr = bwi_rf_set_nrssi_thr_11b;
4066 if (phy->phy_rev == 6)
4067 rf->rf_lo_update = bwi_rf_lo_update_11g;
4068 else
4069 rf->rf_lo_update = bwi_rf_lo_update_11b;
4070 break;
4071 case IEEE80211_MODE_11G:
4072 if (type != BWI_RF_T_BCM2050) {
4073 aprint_error_dev(sc->sc_dev,
4074 "only BCM2050 RF is supported for"
4075 " 11G PHY\n");
4076 return (ENXIO);
4077 }
4078 rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11BG;
4079 rf->rf_on = bwi_rf_on_11bg;
4080 if (mac->mac_rev >= 5)
4081 rf->rf_off = bwi_rf_off_11g_rev5;
4082 else
4083 rf->rf_off = bwi_rf_off_11bg;
4084 rf->rf_calc_nrssi_slope = bwi_rf_calc_nrssi_slope_11g;
4085 rf->rf_set_nrssi_thr = bwi_rf_set_nrssi_thr_11g;
4086 rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2050;
4087 rf->rf_lo_update = bwi_rf_lo_update_11g;
4088 break;
4089 default:
4090 aprint_error_dev(sc->sc_dev, "unsupported PHY mode\n");
4091 return (ENXIO);
4092 }
4093
4094 rf->rf_type = type;
4095 rf->rf_rev = rev;
4096 rf->rf_manu = manu;
4097 rf->rf_curchan = IEEE80211_CHAN_ANY;
4098 rf->rf_ant_mode = BWI_ANT_MODE_AUTO;
4099
4100 return (0);
4101 }
4102
4103 static void
4104 bwi_rf_set_chan(struct bwi_mac *mac, uint chan, int work_around)
4105 {
4106 struct bwi_softc *sc = mac->mac_sc;
4107
4108 if (chan == IEEE80211_CHAN_ANY)
4109 return;
4110
4111 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_CHAN, chan);
4112
4113 /* TODO: 11A */
4114
4115 if (work_around)
4116 bwi_rf_workaround(mac, chan);
4117
4118 CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan));
4119
4120 if (chan == 14) {
4121 if (sc->sc_locale == BWI_SPROM_LOCALE_JAPAN)
4122 HFLAGS_CLRBITS(mac, BWI_HFLAG_NOT_JAPAN);
4123 else
4124 HFLAGS_SETBITS(mac, BWI_HFLAG_NOT_JAPAN);
4125 CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, (1 << 11)); /* XXX */
4126 } else {
4127 CSR_CLRBITS_2(sc, BWI_RF_CHAN_EX, 0x840); /* XXX */
4128 }
4129 DELAY(8000); /* DELAY(2000); */
4130
4131 mac->mac_rf.rf_curchan = chan;
4132 }
4133
4134 static void
4135 bwi_rf_get_gains(struct bwi_mac *mac)
4136 {
4137 #define SAVE_PHY_MAX 15
4138 #define SAVE_RF_MAX 3
4139 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
4140 { 0x52, 0x43, 0x7a };
4141 static const uint16_t save_phy_regs[SAVE_PHY_MAX] = {
4142 0x0429, 0x0001, 0x0811, 0x0812,
4143 0x0814, 0x0815, 0x005a, 0x0059,
4144 0x0058, 0x000a, 0x0003, 0x080f,
4145 0x0810, 0x002b, 0x0015
4146 };
4147
4148 struct bwi_phy *phy = &mac->mac_phy;
4149 struct bwi_rf *rf = &mac->mac_rf;
4150 uint16_t save_phy[SAVE_PHY_MAX];
4151 uint16_t save_rf[SAVE_RF_MAX];
4152 uint16_t trsw;
4153 int i, j, loop1_max, loop1, loop2;
4154
4155 /*
4156 * Save PHY/RF registers for later restoration
4157 */
4158 for (i = 0; i < SAVE_PHY_MAX; ++i)
4159 save_phy[i] = PHY_READ(mac, save_phy_regs[i]);
4160 PHY_READ(mac, 0x2d); /* dummy read */
4161
4162 for (i = 0; i < SAVE_RF_MAX; ++i)
4163 save_rf[i] = RF_READ(mac, save_rf_regs[i]);
4164
4165 PHY_CLRBITS(mac, 0x429, 0xc000);
4166 PHY_SETBITS(mac, 0x1, 0x8000);
4167
4168 PHY_SETBITS(mac, 0x811, 0x2);
4169 PHY_CLRBITS(mac, 0x812, 0x2);
4170 PHY_SETBITS(mac, 0x811, 0x1);
4171 PHY_CLRBITS(mac, 0x812, 0x1);
4172
4173 PHY_SETBITS(mac, 0x814, 0x1);
4174 PHY_CLRBITS(mac, 0x815, 0x1);
4175 PHY_SETBITS(mac, 0x814, 0x2);
4176 PHY_CLRBITS(mac, 0x815, 0x2);
4177
4178 PHY_SETBITS(mac, 0x811, 0xc);
4179 PHY_SETBITS(mac, 0x812, 0xc);
4180 PHY_SETBITS(mac, 0x811, 0x30);
4181 PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x10);
4182
4183 PHY_WRITE(mac, 0x5a, 0x780);
4184 PHY_WRITE(mac, 0x59, 0xc810);
4185 PHY_WRITE(mac, 0x58, 0xd);
4186 PHY_SETBITS(mac, 0xa, 0x2000);
4187
4188 PHY_SETBITS(mac, 0x814, 0x4);
4189 PHY_CLRBITS(mac, 0x815, 0x4);
4190
4191 PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
4192
4193 if (rf->rf_rev == 8) {
4194 loop1_max = 15;
4195 RF_WRITE(mac, 0x43, loop1_max);
4196 } else {
4197 loop1_max = 9;
4198 RF_WRITE(mac, 0x52, 0x0);
4199 RF_FILT_SETBITS(mac, 0x43, 0xfff0, loop1_max);
4200 }
4201
4202 bwi_phy_set_bbp_atten(mac, 11);
4203
4204 if (phy->phy_rev >= 3)
4205 PHY_WRITE(mac, 0x80f, 0xc020);
4206 else
4207 PHY_WRITE(mac, 0x80f, 0x8020);
4208 PHY_WRITE(mac, 0x810, 0);
4209
4210 PHY_FILT_SETBITS(mac, 0x2b, 0xffc0, 0x1);
4211 PHY_FILT_SETBITS(mac, 0x2b, 0xc0ff, 0x800);
4212 PHY_SETBITS(mac, 0x811, 0x100);
4213 PHY_CLRBITS(mac, 0x812, 0x3000);
4214
4215 if ((mac->mac_sc->sc_card_flags & BWI_CARD_F_EXT_LNA) &&
4216 phy->phy_rev >= 7) {
4217 PHY_SETBITS(mac, 0x811, 0x800);
4218 PHY_SETBITS(mac, 0x812, 0x8000);
4219 }
4220 RF_CLRBITS(mac, 0x7a, 0xff08);
4221
4222 /*
4223 * Find out 'loop1/loop2', which will be used to calculate
4224 * max loopback gain later
4225 */
4226 j = 0;
4227 for (i = 0; i < loop1_max; ++i) {
4228 for (j = 0; j < 16; ++j) {
4229 RF_WRITE(mac, 0x43, i);
4230
4231 if (bwi_rf_gain_max_reached(mac, j))
4232 goto loop1_exit;
4233 }
4234 }
4235 loop1_exit:
4236 loop1 = i;
4237 loop2 = j;
4238
4239 /*
4240 * Find out 'trsw', which will be used to calculate
4241 * TRSW(TX/RX switch) RX gain later
4242 */
4243 if (loop2 >= 8) {
4244 PHY_SETBITS(mac, 0x812, 0x30);
4245 trsw = 0x1b;
4246 for (i = loop2 - 8; i < 16; ++i) {
4247 trsw -= 3;
4248 if (bwi_rf_gain_max_reached(mac, i))
4249 break;
4250 }
4251 } else {
4252 trsw = 0x18;
4253 }
4254
4255 /*
4256 * Restore saved PHY/RF registers
4257 */
4258 /* First 4 saved PHY registers need special processing */
4259 for (i = 4; i < SAVE_PHY_MAX; ++i)
4260 PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
4261
4262 bwi_phy_set_bbp_atten(mac, mac->mac_tpctl.bbp_atten);
4263
4264 for (i = 0; i < SAVE_RF_MAX; ++i)
4265 RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
4266
4267 PHY_WRITE(mac, save_phy_regs[2], save_phy[2] | 0x3);
4268 DELAY(10);
4269 PHY_WRITE(mac, save_phy_regs[2], save_phy[2]);
4270 PHY_WRITE(mac, save_phy_regs[3], save_phy[3]);
4271 PHY_WRITE(mac, save_phy_regs[0], save_phy[0]);
4272 PHY_WRITE(mac, save_phy_regs[1], save_phy[1]);
4273
4274 /*
4275 * Calculate gains
4276 */
4277 rf->rf_lo_gain = (loop2 * 6) - (loop1 * 4) - 11;
4278 rf->rf_rx_gain = trsw * 2;
4279 DPRINTF(mac->mac_sc, BWI_DBG_RF | BWI_DBG_INIT,
4280 "lo gain: %u, rx gain: %u\n",
4281 rf->rf_lo_gain, rf->rf_rx_gain);
4282
4283 #undef SAVE_RF_MAX
4284 #undef SAVE_PHY_MAX
4285 }
4286
4287 static void
4288 bwi_rf_init(struct bwi_mac *mac)
4289 {
4290 struct bwi_rf *rf = &mac->mac_rf;
4291
4292 if (rf->rf_type == BWI_RF_T_BCM2060) {
4293 /* TODO: 11A */
4294 } else {
4295 if (rf->rf_flags & BWI_RF_F_INITED)
4296 RF_WRITE(mac, 0x78, rf->rf_calib);
4297 else
4298 bwi_rf_init_bcm2050(mac);
4299 }
4300 }
4301
4302 static void
4303 bwi_rf_off_11a(struct bwi_mac *mac)
4304 {
4305 RF_WRITE(mac, 0x4, 0xff);
4306 RF_WRITE(mac, 0x5, 0xfb);
4307
4308 PHY_SETBITS(mac, 0x10, 0x8);
4309 PHY_SETBITS(mac, 0x11, 0x8);
4310
4311 PHY_WRITE(mac, 0x15, 0xaa00);
4312 }
4313
4314 static void
4315 bwi_rf_off_11bg(struct bwi_mac *mac)
4316 {
4317 PHY_WRITE(mac, 0x15, 0xaa00);
4318 }
4319
4320 static void
4321 bwi_rf_off_11g_rev5(struct bwi_mac *mac)
4322 {
4323 PHY_SETBITS(mac, 0x811, 0x8c);
4324 PHY_CLRBITS(mac, 0x812, 0x8c);
4325 }
4326
4327 static void
4328 bwi_rf_workaround(struct bwi_mac *mac, uint chan)
4329 {
4330 struct bwi_softc *sc = mac->mac_sc;
4331 struct bwi_rf *rf = &mac->mac_rf;
4332
4333 if (chan == IEEE80211_CHAN_ANY) {
4334 aprint_error_dev(sc->sc_dev, "%s invalid channel!\n",
4335 __func__);
4336 return;
4337 }
4338
4339 if (rf->rf_type != BWI_RF_T_BCM2050 || rf->rf_rev >= 6)
4340 return;
4341
4342 if (chan <= 10)
4343 CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan + 4));
4344 else
4345 CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(1));
4346 DELAY(1000);
4347 CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan));
4348 }
4349
4350 static struct bwi_rf_lo *
4351 bwi_rf_lo_find(struct bwi_mac *mac, const struct bwi_tpctl *tpctl)
4352 {
4353 uint16_t rf_atten, bbp_atten;
4354 int remap_rf_atten;
4355
4356 remap_rf_atten = 1;
4357 if (tpctl == NULL) {
4358 bbp_atten = 2;
4359 rf_atten = 3;
4360 } else {
4361 if (tpctl->tp_ctrl1 == 3)
4362 remap_rf_atten = 0;
4363
4364 bbp_atten = tpctl->bbp_atten;
4365 rf_atten = tpctl->rf_atten;
4366
4367 if (bbp_atten > 6)
4368 bbp_atten = 6;
4369 }
4370
4371 if (remap_rf_atten) {
4372 #define MAP_MAX 10
4373 static const uint16_t map[MAP_MAX] =
4374 { 11, 10, 11, 12, 13, 12, 13, 12, 13, 12 };
4375 #if 0
4376 KASSERT(rf_atten < MAP_MAX);
4377 rf_atten = map[rf_atten];
4378 #else
4379 if (rf_atten >= MAP_MAX) {
4380 rf_atten = 0; /* XXX */
4381 } else {
4382 rf_atten = map[rf_atten];
4383 }
4384 #endif
4385 #undef MAP_MAX
4386 }
4387
4388 return (bwi_get_rf_lo(mac, rf_atten, bbp_atten));
4389 }
4390
4391 static void
4392 bwi_rf_lo_adjust(struct bwi_mac *mac, const struct bwi_tpctl *tpctl)
4393 {
4394 const struct bwi_rf_lo *lo;
4395
4396 lo = bwi_rf_lo_find(mac, tpctl);
4397 RF_LO_WRITE(mac, lo);
4398 }
4399
4400 static void
4401 bwi_rf_lo_write(struct bwi_mac *mac, const struct bwi_rf_lo *lo)
4402 {
4403 uint16_t val;
4404
4405 val = (uint8_t)lo->ctrl_lo;
4406 val |= ((uint8_t)lo->ctrl_hi) << 8;
4407
4408 PHY_WRITE(mac, BWI_PHYR_RF_LO, val);
4409 }
4410
4411 static int
4412 bwi_rf_gain_max_reached(struct bwi_mac *mac, int idx)
4413 {
4414 PHY_FILT_SETBITS(mac, 0x812, 0xf0ff, idx << 8);
4415 PHY_FILT_SETBITS(mac, 0x15, 0xfff, 0xa000);
4416 PHY_SETBITS(mac, 0x15, 0xf000);
4417
4418 DELAY(20);
4419
4420 return ((PHY_READ(mac, 0x2d) >= 0xdfc));
4421 }
4422
4423 /* XXX use bitmap array */
4424 static uint16_t
4425 bwi_bitswap4(uint16_t val)
4426 {
4427 uint16_t ret;
4428
4429 ret = (val & 0x8) >> 3;
4430 ret |= (val & 0x4) >> 1;
4431 ret |= (val & 0x2) << 1;
4432 ret |= (val & 0x1) << 3;
4433
4434 return (ret);
4435 }
4436
4437 static uint16_t
4438 bwi_phy812_value(struct bwi_mac *mac, uint16_t lpd)
4439 {
4440 struct bwi_softc *sc = mac->mac_sc;
4441 struct bwi_phy *phy = &mac->mac_phy;
4442 struct bwi_rf *rf = &mac->mac_rf;
4443 uint16_t lo_gain, ext_lna, loop;
4444
4445 if ((phy->phy_flags & BWI_PHY_F_LINKED) == 0)
4446 return (0);
4447
4448 lo_gain = rf->rf_lo_gain;
4449 if (rf->rf_rev == 8)
4450 lo_gain += 0x3e;
4451 else
4452 lo_gain += 0x26;
4453
4454 if (lo_gain >= 0x46) {
4455 lo_gain -= 0x46;
4456 ext_lna = 0x3000;
4457 } else if (lo_gain >= 0x3a) {
4458 lo_gain -= 0x3a;
4459 ext_lna = 0x1000;
4460 } else if (lo_gain >= 0x2e) {
4461 lo_gain -= 0x2e;
4462 ext_lna = 0x2000;
4463 } else {
4464 lo_gain -= 0x10;
4465 ext_lna = 0;
4466 }
4467
4468 for (loop = 0; loop < 16; ++loop) {
4469 lo_gain -= (6 * loop);
4470 if (lo_gain < 6)
4471 break;
4472 }
4473
4474 if (phy->phy_rev >= 7 && (sc->sc_card_flags & BWI_CARD_F_EXT_LNA)) {
4475 if (ext_lna)
4476 ext_lna |= 0x8000;
4477 ext_lna |= (loop << 8);
4478 switch (lpd) {
4479 case 0x011:
4480 return (0x8f92);
4481 case 0x001:
4482 return (0x8092 | ext_lna);
4483 case 0x101:
4484 return (0x2092 | ext_lna);
4485 case 0x100:
4486 return (0x2093 | ext_lna);
4487 default:
4488 panic("unsupported lpd\n");
4489 }
4490 } else {
4491 ext_lna |= (loop << 8);
4492 switch (lpd) {
4493 case 0x011:
4494 return (0xf92);
4495 case 0x001:
4496 case 0x101:
4497 return (0x92 | ext_lna);
4498 case 0x100:
4499 return (0x93 | ext_lna);
4500 default:
4501 panic("unsupported lpd\n");
4502 }
4503 }
4504
4505 panic("never reached\n");
4506 return (0);
4507 }
4508
4509 static void
4510 bwi_rf_init_bcm2050(struct bwi_mac *mac)
4511 {
4512 #define SAVE_RF_MAX 3
4513 #define SAVE_PHY_COMM_MAX 4
4514 #define SAVE_PHY_11G_MAX 6
4515 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
4516 { 0x0043, 0x0051, 0x0052 };
4517 static const uint16_t save_phy_regs_comm[SAVE_PHY_COMM_MAX] =
4518 { 0x0015, 0x005a, 0x0059, 0x0058 };
4519 static const uint16_t save_phy_regs_11g[SAVE_PHY_11G_MAX] =
4520 { 0x0811, 0x0812, 0x0814, 0x0815, 0x0429, 0x0802 };
4521
4522 uint16_t save_rf[SAVE_RF_MAX];
4523 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
4524 uint16_t save_phy_11g[SAVE_PHY_11G_MAX];
4525 uint16_t phyr_35, phyr_30 = 0, rfr_78, phyr_80f = 0, phyr_810 = 0;
4526 uint16_t bphy_ctrl = 0, bbp_atten, rf_chan_ex;
4527 uint16_t phy812_val;
4528 uint16_t calib;
4529 uint32_t test_lim, test;
4530 struct bwi_softc *sc = mac->mac_sc;
4531 struct bwi_phy *phy = &mac->mac_phy;
4532 struct bwi_rf *rf = &mac->mac_rf;
4533 int i;
4534
4535 /*
4536 * Save registers for later restoring
4537 */
4538 for (i = 0; i < SAVE_RF_MAX; ++i)
4539 save_rf[i] = RF_READ(mac, save_rf_regs[i]);
4540 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
4541 save_phy_comm[i] = PHY_READ(mac, save_phy_regs_comm[i]);
4542
4543 if (phy->phy_mode == IEEE80211_MODE_11B) {
4544 phyr_30 = PHY_READ(mac, 0x30);
4545 bphy_ctrl = CSR_READ_2(sc, BWI_BPHY_CTRL);
4546
4547 PHY_WRITE(mac, 0x30, 0xff);
4548 CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x3f3f);
4549 } else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4550 for (i = 0; i < SAVE_PHY_11G_MAX; ++i) {
4551 save_phy_11g[i] = PHY_READ(mac, save_phy_regs_11g[i]);
4552 }
4553
4554 PHY_SETBITS(mac, 0x814, 0x3);
4555 PHY_CLRBITS(mac, 0x815, 0x3);
4556 PHY_CLRBITS(mac, 0x429, 0x8000);
4557 PHY_CLRBITS(mac, 0x802, 0x3);
4558
4559 phyr_80f = PHY_READ(mac, 0x80f);
4560 phyr_810 = PHY_READ(mac, 0x810);
4561
4562 if (phy->phy_rev >= 3)
4563 PHY_WRITE(mac, 0x80f, 0xc020);
4564 else
4565 PHY_WRITE(mac, 0x80f, 0x8020);
4566 PHY_WRITE(mac, 0x810, 0);
4567
4568 phy812_val = bwi_phy812_value(mac, 0x011);
4569 PHY_WRITE(mac, 0x812, phy812_val);
4570 if (phy->phy_rev < 7 ||
4571 (sc->sc_card_flags & BWI_CARD_F_EXT_LNA) == 0)
4572 PHY_WRITE(mac, 0x811, 0x1b3);
4573 else
4574 PHY_WRITE(mac, 0x811, 0x9b3);
4575 }
4576 CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
4577
4578 phyr_35 = PHY_READ(mac, 0x35);
4579 PHY_CLRBITS(mac, 0x35, 0x80);
4580
4581 bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN);
4582 rf_chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
4583
4584 if (phy->phy_version == 0) {
4585 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122);
4586 } else {
4587 if (phy->phy_version >= 2)
4588 PHY_FILT_SETBITS(mac, 0x3, 0xffbf, 0x40);
4589 CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000);
4590 }
4591
4592 calib = bwi_rf_calibval(mac);
4593
4594 if (phy->phy_mode == IEEE80211_MODE_11B)
4595 RF_WRITE(mac, 0x78, 0x26);
4596
4597 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4598 phy812_val = bwi_phy812_value(mac, 0x011);
4599 PHY_WRITE(mac, 0x812, phy812_val);
4600 }
4601
4602 PHY_WRITE(mac, 0x15, 0xbfaf);
4603 PHY_WRITE(mac, 0x2b, 0x1403);
4604
4605 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4606 phy812_val = bwi_phy812_value(mac, 0x001);
4607 PHY_WRITE(mac, 0x812, phy812_val);
4608 }
4609
4610 PHY_WRITE(mac, 0x15, 0xbfa0);
4611
4612 RF_SETBITS(mac, 0x51, 0x4);
4613 if (rf->rf_rev == 8)
4614 RF_WRITE(mac, 0x43, 0x1f);
4615 else {
4616 RF_WRITE(mac, 0x52, 0);
4617 RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9);
4618 }
4619
4620 test_lim = 0;
4621 PHY_WRITE(mac, 0x58, 0);
4622 for (i = 0; i < 16; ++i) {
4623 PHY_WRITE(mac, 0x5a, 0x480);
4624 PHY_WRITE(mac, 0x59, 0xc810);
4625
4626 PHY_WRITE(mac, 0x58, 0xd);
4627 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4628 phy812_val = bwi_phy812_value(mac, 0x101);
4629 PHY_WRITE(mac, 0x812, phy812_val);
4630 }
4631 PHY_WRITE(mac, 0x15, 0xafb0);
4632 DELAY(10);
4633
4634 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4635 phy812_val = bwi_phy812_value(mac, 0x101);
4636 PHY_WRITE(mac, 0x812, phy812_val);
4637 }
4638 PHY_WRITE(mac, 0x15, 0xefb0);
4639 DELAY(10);
4640
4641 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4642 phy812_val = bwi_phy812_value(mac, 0x100);
4643 PHY_WRITE(mac, 0x812, phy812_val);
4644 }
4645 PHY_WRITE(mac, 0x15, 0xfff0);
4646 DELAY(20);
4647
4648 test_lim += PHY_READ(mac, 0x2d);
4649
4650 PHY_WRITE(mac, 0x58, 0);
4651 if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4652 phy812_val = bwi_phy812_value(mac, 0x101);
4653 PHY_WRITE(mac, 0x812, phy812_val);
4654 }
4655 PHY_WRITE(mac, 0x15, 0xafb0);
4656 }
4657 ++test_lim;
4658 test_lim >>= 9;
4659
4660 DELAY(10);
4661
4662 test = 0;
4663 PHY_WRITE(mac, 0x58, 0);
4664 for (i = 0; i < 16; ++i) {
4665 int j;
4666
4667 rfr_78 = (bwi_bitswap4(i) << 1) | 0x20;
4668 RF_WRITE(mac, 0x78, rfr_78);
4669 DELAY(10);
4670
4671 /* NB: This block is slight different than the above one */
4672 for (j = 0; j < 16; ++j) {
4673 PHY_WRITE(mac, 0x5a, 0xd80);
4674 PHY_WRITE(mac, 0x59, 0xc810);
4675
4676 PHY_WRITE(mac, 0x58, 0xd);
4677 if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
4678 phy->phy_rev >= 2) {
4679 phy812_val = bwi_phy812_value(mac, 0x101);
4680 PHY_WRITE(mac, 0x812, phy812_val);
4681 }
4682 PHY_WRITE(mac, 0x15, 0xafb0);
4683 DELAY(10);
4684
4685 if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
4686 phy->phy_rev >= 2) {
4687 phy812_val = bwi_phy812_value(mac, 0x101);
4688 PHY_WRITE(mac, 0x812, phy812_val);
4689 }
4690 PHY_WRITE(mac, 0x15, 0xefb0);
4691 DELAY(10);
4692
4693 if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
4694 phy->phy_rev >= 2) {
4695 phy812_val = bwi_phy812_value(mac, 0x100);
4696 PHY_WRITE(mac, 0x812, phy812_val);
4697 }
4698 PHY_WRITE(mac, 0x15, 0xfff0);
4699 DELAY(10);
4700
4701 test += PHY_READ(mac, 0x2d);
4702
4703 PHY_WRITE(mac, 0x58, 0);
4704 if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
4705 phy->phy_rev >= 2) {
4706 phy812_val = bwi_phy812_value(mac, 0x101);
4707 PHY_WRITE(mac, 0x812, phy812_val);
4708 }
4709 PHY_WRITE(mac, 0x15, 0xafb0);
4710 }
4711
4712 ++test;
4713 test >>= 8;
4714
4715 if (test > test_lim)
4716 break;
4717 }
4718 if (i > 15)
4719 rf->rf_calib = rfr_78;
4720 else
4721 rf->rf_calib = calib;
4722 if (rf->rf_calib != 0xffff) {
4723 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_INIT,
4724 "RF calibration value: 0x%04x\n", rf->rf_calib);
4725 rf->rf_flags |= BWI_RF_F_INITED;
4726 }
4727
4728 /*
4729 * Restore trashes registers
4730 */
4731 PHY_WRITE(mac, save_phy_regs_comm[0], save_phy_comm[0]);
4732
4733 for (i = 0; i < SAVE_RF_MAX; ++i) {
4734 int pos = (i + 1) % SAVE_RF_MAX;
4735
4736 RF_WRITE(mac, save_rf_regs[pos], save_rf[pos]);
4737 }
4738 for (i = 1; i < SAVE_PHY_COMM_MAX; ++i)
4739 PHY_WRITE(mac, save_phy_regs_comm[i], save_phy_comm[i]);
4740
4741 CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten);
4742 if (phy->phy_version != 0)
4743 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, rf_chan_ex);
4744
4745 PHY_WRITE(mac, 0x35, phyr_35);
4746 bwi_rf_workaround(mac, rf->rf_curchan);
4747
4748 if (phy->phy_mode == IEEE80211_MODE_11B) {
4749 PHY_WRITE(mac, 0x30, phyr_30);
4750 CSR_WRITE_2(sc, BWI_BPHY_CTRL, bphy_ctrl);
4751 } else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4752 /* XXX Spec only says when PHY is linked (gmode) */
4753 CSR_CLRBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
4754
4755 for (i = 0; i < SAVE_PHY_11G_MAX; ++i) {
4756 PHY_WRITE(mac, save_phy_regs_11g[i],
4757 save_phy_11g[i]);
4758 }
4759
4760 PHY_WRITE(mac, 0x80f, phyr_80f);
4761 PHY_WRITE(mac, 0x810, phyr_810);
4762 }
4763
4764 #undef SAVE_PHY_11G_MAX
4765 #undef SAVE_PHY_COMM_MAX
4766 #undef SAVE_RF_MAX
4767 }
4768
4769 static uint16_t
4770 bwi_rf_calibval(struct bwi_mac *mac)
4771 {
4772 /* http://bcm-specs.sipsolutions.net/RCCTable */
4773 static const uint16_t rf_calibvals[] = {
4774 0x2, 0x3, 0x1, 0xf, 0x6, 0x7, 0x5, 0xf,
4775 0xa, 0xb, 0x9, 0xf, 0xe, 0xf, 0xd, 0xf
4776 };
4777
4778 uint16_t val, calib;
4779 int idx;
4780
4781 val = RF_READ(mac, BWI_RFR_BBP_ATTEN);
4782 idx = __SHIFTOUT(val, BWI_RFR_BBP_ATTEN_CALIB_IDX);
4783 KASSERT(idx < (int)(sizeof(rf_calibvals) / sizeof(rf_calibvals[0])));
4784
4785 calib = rf_calibvals[idx] << 1;
4786 if (val & BWI_RFR_BBP_ATTEN_CALIB_BIT)
4787 calib |= 0x1;
4788 calib |= 0x20;
4789
4790 return (calib);
4791 }
4792
4793 static int32_t
4794 _bwi_adjust_devide(int32_t num, int32_t den)
4795 {
4796 if (num < 0)
4797 return (num / den);
4798 else
4799 return ((num + den / 2) / den);
4800 }
4801
4802 /*
4803 * http://bcm-specs.sipsolutions.net/TSSI_to_DBM_Table
4804 * "calculating table entries"
4805 */
4806 static int
4807 bwi_rf_calc_txpower(int8_t *txpwr, uint8_t idx, const int16_t pa_params[])
4808 {
4809 int32_t m1, m2, f, dbm;
4810 int i;
4811
4812 m1 = _bwi_adjust_devide(16 * pa_params[0] + idx * pa_params[1], 32);
4813 m2 = imax(_bwi_adjust_devide(32768 + idx * pa_params[2], 256), 1);
4814
4815 #define ITER_MAX 16
4816 f = 256;
4817 for (i = 0; i < ITER_MAX; ++i) {
4818 int32_t q, d;
4819
4820 q = _bwi_adjust_devide(
4821 f * 4096 - _bwi_adjust_devide(m2 * f, 16) * f, 2048);
4822 d = abs(q - f);
4823 f = q;
4824
4825 if (d < 2)
4826 break;
4827 }
4828 if (i == ITER_MAX)
4829 return (EINVAL);
4830 #undef ITER_MAX
4831
4832 dbm = _bwi_adjust_devide(m1 * f, 8192);
4833 if (dbm < -127)
4834 dbm = -127;
4835 else if (dbm > 128)
4836 dbm = 128;
4837
4838 *txpwr = dbm;
4839
4840 return (0);
4841 }
4842
4843 static int
4844 bwi_rf_map_txpower(struct bwi_mac *mac)
4845 {
4846 struct bwi_softc *sc = mac->mac_sc;
4847 struct bwi_rf *rf = &mac->mac_rf;
4848 struct bwi_phy *phy = &mac->mac_phy;
4849 uint16_t sprom_ofs, val, mask;
4850 int16_t pa_params[3];
4851 int error = 0, i, ant_gain, reg_txpower_max;
4852 #ifdef BWI_DEBUG
4853 int debug = sc->sc_debug &
4854 (BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH);
4855 #endif
4856
4857 /*
4858 * Find out max TX power
4859 */
4860 val = bwi_read_sprom(sc, BWI_SPROM_MAX_TXPWR);
4861 if (phy->phy_mode == IEEE80211_MODE_11A) {
4862 rf->rf_txpower_max = __SHIFTOUT(val,
4863 BWI_SPROM_MAX_TXPWR_MASK_11A);
4864 } else {
4865 rf->rf_txpower_max = __SHIFTOUT(val,
4866 BWI_SPROM_MAX_TXPWR_MASK_11BG);
4867
4868 if ((sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) &&
4869 phy->phy_mode == IEEE80211_MODE_11G)
4870 rf->rf_txpower_max -= 3;
4871 }
4872 if (rf->rf_txpower_max <= 0) {
4873 aprint_error_dev(sc->sc_dev,
4874 "invalid max txpower in sprom\n");
4875 rf->rf_txpower_max = 74;
4876 }
4877 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
4878 "max txpower from sprom: %d dBm\n", rf->rf_txpower_max);
4879
4880 /*
4881 * Find out region/domain max TX power, which is adjusted
4882 * by antenna gain and 1.5 dBm fluctuation as mentioned
4883 * in v3 spec.
4884 */
4885 val = bwi_read_sprom(sc, BWI_SPROM_ANT_GAIN);
4886 if (phy->phy_mode == IEEE80211_MODE_11A)
4887 ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11A);
4888 else
4889 ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11BG);
4890 if (ant_gain == 0xff) {
4891 /* XXX why this always invalid? */
4892 aprint_error_dev(sc->sc_dev,
4893 "invalid antenna gain in sprom\n");
4894 ant_gain = 2;
4895 }
4896 ant_gain *= 4;
4897 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
4898 "ant gain %d dBm\n", ant_gain);
4899
4900 reg_txpower_max = 90 - ant_gain - 6; /* XXX magic number */
4901 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
4902 "region/domain max txpower %d dBm\n", reg_txpower_max);
4903
4904 /*
4905 * Force max TX power within region/domain TX power limit
4906 */
4907 if (rf->rf_txpower_max > reg_txpower_max)
4908 rf->rf_txpower_max = reg_txpower_max;
4909 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
4910 "max txpower %d dBm\n", rf->rf_txpower_max);
4911
4912 /*
4913 * Create TSSI to TX power mapping
4914 */
4915
4916 if (sc->sc_bbp_id == BWI_BBPID_BCM4301 &&
4917 rf->rf_type != BWI_RF_T_BCM2050) {
4918 rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI;
4919 memcpy(rf->rf_txpower_map0, bwi_txpower_map_11b,
4920 sizeof(rf->rf_txpower_map0));
4921 goto back;
4922 }
4923
4924 #define IS_VALID_PA_PARAM(p) ((p) != 0 && (p) != -1)
4925 /*
4926 * Extract PA parameters
4927 */
4928 if (phy->phy_mode == IEEE80211_MODE_11A)
4929 sprom_ofs = BWI_SPROM_PA_PARAM_11A;
4930 else
4931 sprom_ofs = BWI_SPROM_PA_PARAM_11BG;
4932 for (i = 0; i < __arraycount(pa_params); ++i)
4933 pa_params[i] = (int16_t)bwi_read_sprom(sc, sprom_ofs + (i * 2));
4934
4935 for (i = 0; i < __arraycount(pa_params); ++i) {
4936 /*
4937 * If one of the PA parameters from SPROM is not valid,
4938 * fall back to the default values, if there are any.
4939 */
4940 if (!IS_VALID_PA_PARAM(pa_params[i])) {
4941 const int8_t *txpower_map;
4942
4943 if (phy->phy_mode == IEEE80211_MODE_11A) {
4944 aprint_error_dev(sc->sc_dev,
4945 "no tssi2dbm table for 11a PHY\n");
4946 return (ENXIO);
4947 }
4948
4949 if (phy->phy_mode == IEEE80211_MODE_11G) {
4950 DPRINTF(sc,
4951 BWI_DBG_RF | BWI_DBG_TXPOWER |
4952 BWI_DBG_ATTACH,
4953 "use default 11g TSSI map\n");
4954 txpower_map = bwi_txpower_map_11g;
4955 } else {
4956 DPRINTF(sc,
4957 BWI_DBG_RF | BWI_DBG_TXPOWER |
4958 BWI_DBG_ATTACH,
4959 "use default 11b TSSI map\n");
4960 txpower_map = bwi_txpower_map_11b;
4961 }
4962
4963 rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI;
4964 memcpy(rf->rf_txpower_map0, txpower_map,
4965 sizeof(rf->rf_txpower_map0));
4966 goto back;
4967 }
4968 }
4969
4970 /*
4971 * All of the PA parameters from SPROM are valid.
4972 */
4973
4974 /*
4975 * Extract idle TSSI from SPROM.
4976 */
4977 val = bwi_read_sprom(sc, BWI_SPROM_IDLE_TSSI);
4978 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
4979 "sprom idle tssi: 0x%04x\n", val);
4980
4981 if (phy->phy_mode == IEEE80211_MODE_11A)
4982 mask = BWI_SPROM_IDLE_TSSI_MASK_11A;
4983 else
4984 mask = BWI_SPROM_IDLE_TSSI_MASK_11BG;
4985
4986 rf->rf_idle_tssi0 = (int)__SHIFTOUT(val, mask);
4987 if (!IS_VALID_PA_PARAM(rf->rf_idle_tssi0))
4988 rf->rf_idle_tssi0 = 62;
4989
4990 #undef IS_VALID_PA_PARAM
4991
4992 /*
4993 * Calculate TX power map, which is indexed by TSSI
4994 */
4995 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
4996 "TSSI-TX power map:\n");
4997 for (i = 0; i < BWI_TSSI_MAX; ++i) {
4998 error = bwi_rf_calc_txpower(&rf->rf_txpower_map0[i], i,
4999 pa_params);
5000 if (error) {
5001 aprint_error_dev(sc->sc_dev,
5002 "bwi_rf_calc_txpower failed\n");
5003 break;
5004 }
5005 #ifdef BWI_DEBUG
5006 if (debug) {
5007 if (i % 8 == 0) {
5008 if (i != 0)
5009 aprint_debug("\n");
5010 aprint_debug_dev(sc->sc_dev, "");
5011 }
5012 aprint_debug(" %d", rf->rf_txpower_map0[i]);
5013 }
5014 #endif
5015 }
5016 #ifdef BWI_DEBUG
5017 if (debug)
5018 aprint_debug("\n");
5019 #endif
5020 back:
5021 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
5022 "idle tssi0: %d\n", rf->rf_idle_tssi0);
5023
5024 return (error);
5025 }
5026
5027 static void
5028 bwi_rf_lo_update_11g(struct bwi_mac *mac)
5029 {
5030 struct bwi_softc *sc = mac->mac_sc;
5031 struct ifnet *ifp = &sc->sc_if;
5032 struct bwi_rf *rf = &mac->mac_rf;
5033 struct bwi_phy *phy = &mac->mac_phy;
5034 struct bwi_tpctl *tpctl = &mac->mac_tpctl;
5035 struct rf_saveregs regs;
5036 uint16_t ant_div, chan_ex;
5037 uint8_t devi_ctrl;
5038 uint orig_chan;
5039
5040 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_INIT, "%s enter\n", __func__);
5041
5042 /*
5043 * Save RF/PHY registers for later restoration
5044 */
5045 orig_chan = rf->rf_curchan;
5046 memset(®s, 0, sizeof(regs));
5047
5048 if (phy->phy_flags & BWI_PHY_F_LINKED) {
5049 SAVE_PHY_REG(mac, ®s, 429);
5050 SAVE_PHY_REG(mac, ®s, 802);
5051
5052 PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff);
5053 PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc);
5054 }
5055
5056 ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
5057 CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div | 0x8000);
5058 chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
5059
5060 SAVE_PHY_REG(mac, ®s, 15);
5061 SAVE_PHY_REG(mac, ®s, 2a);
5062 SAVE_PHY_REG(mac, ®s, 35);
5063 SAVE_PHY_REG(mac, ®s, 60);
5064 SAVE_RF_REG(mac, ®s, 43);
5065 SAVE_RF_REG(mac, ®s, 7a);
5066 SAVE_RF_REG(mac, ®s, 52);
5067 if (phy->phy_flags & BWI_PHY_F_LINKED) {
5068 SAVE_PHY_REG(mac, ®s, 811);
5069 SAVE_PHY_REG(mac, ®s, 812);
5070 SAVE_PHY_REG(mac, ®s, 814);
5071 SAVE_PHY_REG(mac, ®s, 815);
5072 }
5073
5074 /* Force to channel 6 */
5075 bwi_rf_set_chan(mac, 6, 0);
5076
5077 if (phy->phy_flags & BWI_PHY_F_LINKED) {
5078 PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff);
5079 PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc);
5080 bwi_mac_dummy_xmit(mac);
5081 }
5082 RF_WRITE(mac, 0x43, 0x6);
5083
5084 bwi_phy_set_bbp_atten(mac, 2);
5085
5086 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0);
5087
5088 PHY_WRITE(mac, 0x2e, 0x7f);
5089 PHY_WRITE(mac, 0x80f, 0x78);
5090 PHY_WRITE(mac, 0x35, regs.phy_35 & 0xff7f);
5091 RF_WRITE(mac, 0x7a, regs.rf_7a & 0xfff0);
5092 PHY_WRITE(mac, 0x2b, 0x203);
5093 PHY_WRITE(mac, 0x2a, 0x8a3);
5094
5095 if (phy->phy_flags & BWI_PHY_F_LINKED) {
5096 PHY_WRITE(mac, 0x814, regs.phy_814 | 0x3);
5097 PHY_WRITE(mac, 0x815, regs.phy_815 & 0xfffc);
5098 PHY_WRITE(mac, 0x811, 0x1b3);
5099 PHY_WRITE(mac, 0x812, 0xb2);
5100 }
5101
5102 if ((ifp->if_flags & IFF_RUNNING) == 0)
5103 tpctl->tp_ctrl2 = bwi_rf_get_tp_ctrl2(mac);
5104 PHY_WRITE(mac, 0x80f, 0x8078);
5105
5106 /*
5107 * Measure all RF LO
5108 */
5109 devi_ctrl = _bwi_rf_lo_update_11g(mac, regs.rf_7a);
5110
5111 /*
5112 * Restore saved RF/PHY registers
5113 */
5114 if (phy->phy_flags & BWI_PHY_F_LINKED) {
5115 PHY_WRITE(mac, 0x15, 0xe300);
5116 PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa0);
5117 DELAY(5);
5118 PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa2);
5119 DELAY(2);
5120 PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa3);
5121 } else
5122 PHY_WRITE(mac, 0x15, devi_ctrl | 0xefa0);
5123
5124 if ((ifp->if_flags & IFF_RUNNING) == 0)
5125 tpctl = NULL;
5126 bwi_rf_lo_adjust(mac, tpctl);
5127
5128 PHY_WRITE(mac, 0x2e, 0x807f);
5129 if (phy->phy_flags & BWI_PHY_F_LINKED)
5130 PHY_WRITE(mac, 0x2f, 0x202);
5131 else
5132 PHY_WRITE(mac, 0x2f, 0x101);
5133
5134 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
5135
5136 RESTORE_PHY_REG(mac, ®s, 15);
5137 RESTORE_PHY_REG(mac, ®s, 2a);
5138 RESTORE_PHY_REG(mac, ®s, 35);
5139 RESTORE_PHY_REG(mac, ®s, 60);
5140
5141 RESTORE_RF_REG(mac, ®s, 43);
5142 RESTORE_RF_REG(mac, ®s, 7a);
5143
5144 regs.rf_52 &= 0xf0;
5145 regs.rf_52 |= (RF_READ(mac, 0x52) & 0xf);
5146 RF_WRITE(mac, 0x52, regs.rf_52);
5147
5148 CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
5149
5150 if (phy->phy_flags & BWI_PHY_F_LINKED) {
5151 RESTORE_PHY_REG(mac, ®s, 811);
5152 RESTORE_PHY_REG(mac, ®s, 812);
5153 RESTORE_PHY_REG(mac, ®s, 814);
5154 RESTORE_PHY_REG(mac, ®s, 815);
5155 RESTORE_PHY_REG(mac, ®s, 429);
5156 RESTORE_PHY_REG(mac, ®s, 802);
5157 }
5158
5159 bwi_rf_set_chan(mac, orig_chan, 1);
5160 }
5161
5162 static uint32_t
5163 bwi_rf_lo_devi_measure(struct bwi_mac *mac, uint16_t ctrl)
5164 {
5165 struct bwi_phy *phy = &mac->mac_phy;
5166 uint32_t devi = 0;
5167 int i;
5168
5169 if (phy->phy_flags & BWI_PHY_F_LINKED)
5170 ctrl <<= 8;
5171
5172 for (i = 0; i < 8; ++i) {
5173 if (phy->phy_flags & BWI_PHY_F_LINKED) {
5174 PHY_WRITE(mac, 0x15, 0xe300);
5175 PHY_WRITE(mac, 0x812, ctrl | 0xb0);
5176 DELAY(5);
5177 PHY_WRITE(mac, 0x812, ctrl | 0xb2);
5178 DELAY(2);
5179 PHY_WRITE(mac, 0x812, ctrl | 0xb3);
5180 DELAY(4);
5181 PHY_WRITE(mac, 0x15, 0xf300);
5182 } else {
5183 PHY_WRITE(mac, 0x15, ctrl | 0xefa0);
5184 DELAY(2);
5185 PHY_WRITE(mac, 0x15, ctrl | 0xefe0);
5186 DELAY(4);
5187 PHY_WRITE(mac, 0x15, ctrl | 0xffe0);
5188 }
5189 DELAY(8);
5190 devi += PHY_READ(mac, 0x2d);
5191 }
5192
5193 return (devi);
5194 }
5195
5196 static uint16_t
5197 bwi_rf_get_tp_ctrl2(struct bwi_mac *mac)
5198 {
5199 uint32_t devi_min;
5200 uint16_t tp_ctrl2 = 0;
5201 int i;
5202
5203 RF_WRITE(mac, 0x52, 0);
5204 DELAY(10);
5205 devi_min = bwi_rf_lo_devi_measure(mac, 0);
5206
5207 for (i = 0; i < 16; ++i) {
5208 uint32_t devi;
5209
5210 RF_WRITE(mac, 0x52, i);
5211 DELAY(10);
5212 devi = bwi_rf_lo_devi_measure(mac, 0);
5213
5214 if (devi < devi_min) {
5215 devi_min = devi;
5216 tp_ctrl2 = i;
5217 }
5218 }
5219
5220 return (tp_ctrl2);
5221 }
5222
5223 static uint8_t
5224 _bwi_rf_lo_update_11g(struct bwi_mac *mac, uint16_t orig_rf7a)
5225 {
5226 #define RF_ATTEN_LISTSZ 14
5227 #define BBP_ATTEN_MAX 4 /* half */
5228 static const int rf_atten_list[RF_ATTEN_LISTSZ] =
5229 { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 1, 2, 3, 4 };
5230 static const int rf_atten_init_list[RF_ATTEN_LISTSZ] =
5231 { 0, 3, 1, 5, 7, 3, 2, 0, 4, 6, -1, -1, -1, -1 };
5232 static const int rf_lo_measure_order[RF_ATTEN_LISTSZ] =
5233 { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 10, 11, 12, 13 };
5234
5235 struct ifnet *ifp = &mac->mac_sc->sc_if;
5236 struct bwi_rf_lo lo_save, *lo;
5237 uint8_t devi_ctrl = 0;
5238 int idx, adj_rf7a = 0;
5239
5240 memset(&lo_save, 0, sizeof(lo_save));
5241 for (idx = 0; idx < RF_ATTEN_LISTSZ; ++idx) {
5242 int init_rf_atten = rf_atten_init_list[idx];
5243 int rf_atten = rf_atten_list[idx];
5244 int bbp_atten;
5245
5246 for (bbp_atten = 0; bbp_atten < BBP_ATTEN_MAX; ++bbp_atten) {
5247 uint16_t tp_ctrl2, rf7a;
5248
5249 if ((ifp->if_flags & IFF_RUNNING) == 0) {
5250 if (idx == 0) {
5251 memset(&lo_save, 0, sizeof(lo_save));
5252 } else if (init_rf_atten < 0) {
5253 lo = bwi_get_rf_lo(mac,
5254 rf_atten, 2 * bbp_atten);
5255 memcpy(&lo_save, lo, sizeof(lo_save));
5256 } else {
5257 lo = bwi_get_rf_lo(mac,
5258 init_rf_atten, 0);
5259 memcpy(&lo_save, lo, sizeof(lo_save));
5260 }
5261
5262 devi_ctrl = 0;
5263 adj_rf7a = 0;
5264
5265 /*
5266 * XXX
5267 * Linux driver overflows 'val'
5268 */
5269 if (init_rf_atten >= 0) {
5270 int val;
5271
5272 val = rf_atten * 2 + bbp_atten;
5273 if (val > 14) {
5274 adj_rf7a = 1;
5275 if (val > 17)
5276 devi_ctrl = 1;
5277 if (val > 19)
5278 devi_ctrl = 2;
5279 }
5280 }
5281 } else {
5282 lo = bwi_get_rf_lo(mac,
5283 rf_atten, 2 * bbp_atten);
5284 if (!bwi_rf_lo_isused(mac, lo))
5285 continue;
5286 memcpy(&lo_save, lo, sizeof(lo_save));
5287
5288 devi_ctrl = 3;
5289 adj_rf7a = 0;
5290 }
5291
5292 RF_WRITE(mac, BWI_RFR_ATTEN, rf_atten);
5293
5294 tp_ctrl2 = mac->mac_tpctl.tp_ctrl2;
5295 if (init_rf_atten < 0)
5296 tp_ctrl2 |= (3 << 4);
5297 RF_WRITE(mac, BWI_RFR_TXPWR, tp_ctrl2);
5298
5299 DELAY(10);
5300
5301 bwi_phy_set_bbp_atten(mac, bbp_atten * 2);
5302
5303 rf7a = orig_rf7a & 0xfff0;
5304 if (adj_rf7a)
5305 rf7a |= 0x8;
5306 RF_WRITE(mac, 0x7a, rf7a);
5307
5308 lo = bwi_get_rf_lo(mac,
5309 rf_lo_measure_order[idx], bbp_atten * 2);
5310 bwi_rf_lo_measure_11g(mac, &lo_save, lo, devi_ctrl);
5311 }
5312 }
5313
5314 return (devi_ctrl);
5315
5316 #undef RF_ATTEN_LISTSZ
5317 #undef BBP_ATTEN_MAX
5318 }
5319
5320 static void
5321 bwi_rf_lo_measure_11g(struct bwi_mac *mac, const struct bwi_rf_lo *src_lo,
5322 struct bwi_rf_lo *dst_lo, uint8_t devi_ctrl)
5323 {
5324 #define LO_ADJUST_MIN 1
5325 #define LO_ADJUST_MAX 8
5326 #define LO_ADJUST(hi, lo) { .ctrl_hi = hi, .ctrl_lo = lo }
5327 static const struct bwi_rf_lo rf_lo_adjust[LO_ADJUST_MAX] = {
5328 LO_ADJUST(1, 1),
5329 LO_ADJUST(1, 0),
5330 LO_ADJUST(1, -1),
5331 LO_ADJUST(0, -1),
5332 LO_ADJUST(-1, -1),
5333 LO_ADJUST(-1, 0),
5334 LO_ADJUST(-1, 1),
5335 LO_ADJUST(0, 1)
5336 };
5337 #undef LO_ADJUST
5338
5339 struct bwi_rf_lo lo_min;
5340 uint32_t devi_min;
5341 int found, loop_count, adjust_state;
5342
5343 memcpy(&lo_min, src_lo, sizeof(lo_min));
5344 RF_LO_WRITE(mac, &lo_min);
5345 devi_min = bwi_rf_lo_devi_measure(mac, devi_ctrl);
5346
5347 loop_count = 12; /* XXX */
5348 adjust_state = 0;
5349 do {
5350 struct bwi_rf_lo lo_base;
5351 int i, fin;
5352
5353 found = 0;
5354 if (adjust_state == 0) {
5355 i = LO_ADJUST_MIN;
5356 fin = LO_ADJUST_MAX;
5357 } else if (adjust_state % 2 == 0) {
5358 i = adjust_state - 1;
5359 fin = adjust_state + 1;
5360 } else {
5361 i = adjust_state - 2;
5362 fin = adjust_state + 2;
5363 }
5364
5365 if (i < LO_ADJUST_MIN)
5366 i += LO_ADJUST_MAX;
5367 KASSERT(i <= LO_ADJUST_MAX && i >= LO_ADJUST_MIN);
5368
5369 if (fin > LO_ADJUST_MAX)
5370 fin -= LO_ADJUST_MAX;
5371 KASSERT(fin <= LO_ADJUST_MAX && fin >= LO_ADJUST_MIN);
5372
5373 memcpy(&lo_base, &lo_min, sizeof(lo_base));
5374 for (;;) {
5375 struct bwi_rf_lo lo;
5376
5377 lo.ctrl_hi = lo_base.ctrl_hi +
5378 rf_lo_adjust[i - 1].ctrl_hi;
5379 lo.ctrl_lo = lo_base.ctrl_lo +
5380 rf_lo_adjust[i - 1].ctrl_lo;
5381
5382 if (abs(lo.ctrl_lo) < 9 && abs(lo.ctrl_hi) < 9) {
5383 uint32_t devi;
5384
5385 RF_LO_WRITE(mac, &lo);
5386 devi = bwi_rf_lo_devi_measure(mac, devi_ctrl);
5387 if (devi < devi_min) {
5388 devi_min = devi;
5389 adjust_state = i;
5390 found = 1;
5391 memcpy(&lo_min, &lo, sizeof(lo_min));
5392 }
5393 }
5394 if (i == fin)
5395 break;
5396 if (i == LO_ADJUST_MAX)
5397 i = LO_ADJUST_MIN;
5398 else
5399 ++i;
5400 }
5401 } while (loop_count-- && found);
5402
5403 memcpy(dst_lo, &lo_min, sizeof(*dst_lo));
5404
5405 #undef LO_ADJUST_MIN
5406 #undef LO_ADJUST_MAX
5407 }
5408
5409 static void
5410 bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *mac)
5411 {
5412 #define SAVE_RF_MAX 3
5413 #define SAVE_PHY_MAX 8
5414 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
5415 { 0x7a, 0x52, 0x43 };
5416 static const uint16_t save_phy_regs[SAVE_PHY_MAX] =
5417 { 0x30, 0x26, 0x15, 0x2a, 0x20, 0x5a, 0x59, 0x58 };
5418
5419 struct bwi_softc *sc = mac->mac_sc;
5420 struct bwi_rf *rf = &mac->mac_rf;
5421 struct bwi_phy *phy = &mac->mac_phy;
5422 uint16_t save_rf[SAVE_RF_MAX];
5423 uint16_t save_phy[SAVE_PHY_MAX];
5424 uint16_t ant_div, chan_ex;
5425 int16_t nrssi[2];
5426 int i;
5427
5428 /*
5429 * Save RF/PHY registers for later restoration
5430 */
5431 for (i = 0; i < SAVE_RF_MAX; ++i)
5432 save_rf[i] = RF_READ(mac, save_rf_regs[i]);
5433 for (i = 0; i < SAVE_PHY_MAX; ++i)
5434 save_phy[i] = PHY_READ(mac, save_phy_regs[i]);
5435
5436 ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
5437 (void)CSR_READ_2(sc, BWI_BBP_ATTEN);
5438 chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
5439
5440 /*
5441 * Calculate nrssi0
5442 */
5443 if (phy->phy_rev >= 5)
5444 RF_CLRBITS(mac, 0x7a, 0xff80);
5445 else
5446 RF_CLRBITS(mac, 0x7a, 0xfff0);
5447 PHY_WRITE(mac, 0x30, 0xff);
5448
5449 CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x7f7f);
5450
5451 PHY_WRITE(mac, 0x26, 0);
5452 PHY_SETBITS(mac, 0x15, 0x20);
5453 PHY_WRITE(mac, 0x2a, 0x8a3);
5454 RF_SETBITS(mac, 0x7a, 0x80);
5455
5456 nrssi[0] = (int16_t)PHY_READ(mac, 0x27);
5457
5458 /*
5459 * Calculate nrssi1
5460 */
5461 RF_CLRBITS(mac, 0x7a, 0xff80);
5462 if (phy->phy_version >= 2)
5463 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x40);
5464 else if (phy->phy_version == 0)
5465 CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122);
5466 else
5467 CSR_CLRBITS_2(sc, BWI_RF_CHAN_EX, 0xdfff);
5468
5469 PHY_WRITE(mac, 0x20, 0x3f3f);
5470 PHY_WRITE(mac, 0x15, 0xf330);
5471
5472 RF_WRITE(mac, 0x5a, 0x60);
5473 RF_CLRBITS(mac, 0x43, 0xff0f);
5474
5475 PHY_WRITE(mac, 0x5a, 0x480);
5476 PHY_WRITE(mac, 0x59, 0x810);
5477 PHY_WRITE(mac, 0x58, 0xd);
5478
5479 DELAY(20);
5480
5481 nrssi[1] = (int16_t)PHY_READ(mac, 0x27);
5482
5483 /*
5484 * Restore saved RF/PHY registers
5485 */
5486 PHY_WRITE(mac, save_phy_regs[0], save_phy[0]);
5487 RF_WRITE(mac, save_rf_regs[0], save_rf[0]);
5488
5489 CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
5490
5491 for (i = 1; i < 4; ++i)
5492 PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
5493
5494 bwi_rf_workaround(mac, rf->rf_curchan);
5495
5496 if (phy->phy_version != 0)
5497 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
5498
5499 for (; i < SAVE_PHY_MAX; ++i)
5500 PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
5501
5502 for (i = 1; i < SAVE_RF_MAX; ++i)
5503 RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
5504
5505 /*
5506 * Install calculated narrow RSSI values
5507 */
5508 if (nrssi[0] == nrssi[1])
5509 rf->rf_nrssi_slope = 0x10000;
5510 else
5511 rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]);
5512 if (nrssi[0] <= -4) {
5513 rf->rf_nrssi[0] = nrssi[0];
5514 rf->rf_nrssi[1] = nrssi[1];
5515 }
5516
5517 #undef SAVE_RF_MAX
5518 #undef SAVE_PHY_MAX
5519 }
5520
5521 static void
5522 bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *mac)
5523 {
5524 #define SAVE_RF_MAX 2
5525 #define SAVE_PHY_COMM_MAX 10
5526 #define SAVE_PHY6_MAX 8
5527 static const uint16_t save_rf_regs[SAVE_RF_MAX] = { 0x7a, 0x43 };
5528 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
5529 0x0001, 0x0811, 0x0812, 0x0814,
5530 0x0815, 0x005a, 0x0059, 0x0058,
5531 0x000a, 0x0003
5532 };
5533 static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
5534 0x002e, 0x002f, 0x080f, 0x0810,
5535 0x0801, 0x0060, 0x0014, 0x0478
5536 };
5537
5538 struct bwi_phy *phy = &mac->mac_phy;
5539 uint16_t save_rf[SAVE_RF_MAX];
5540 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
5541 uint16_t save_phy6[SAVE_PHY6_MAX];
5542 uint16_t rf7b = 0xffff;
5543 int16_t nrssi;
5544 int i, phy6_idx = 0;
5545
5546 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
5547 save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i]);
5548 for (i = 0; i < SAVE_RF_MAX; ++i)
5549 save_rf[i] = RF_READ(mac, save_rf_regs[i]);
5550
5551 PHY_CLRBITS(mac, 0x429, 0x8000);
5552 PHY_FILT_SETBITS(mac, 0x1, 0x3fff, 0x4000);
5553 PHY_SETBITS(mac, 0x811, 0xc);
5554 PHY_FILT_SETBITS(mac, 0x812, 0xfff3, 0x4);
5555 PHY_CLRBITS(mac, 0x802, 0x3);
5556
5557 if (phy->phy_rev >= 6) {
5558 for (i = 0; i < SAVE_PHY6_MAX; ++i)
5559 save_phy6[i] = PHY_READ(mac, save_phy6_regs[i]);
5560
5561 PHY_WRITE(mac, 0x2e, 0);
5562 PHY_WRITE(mac, 0x2f, 0);
5563 PHY_WRITE(mac, 0x80f, 0);
5564 PHY_WRITE(mac, 0x810, 0);
5565 PHY_SETBITS(mac, 0x478, 0x100);
5566 PHY_SETBITS(mac, 0x801, 0x40);
5567 PHY_SETBITS(mac, 0x60, 0x40);
5568 PHY_SETBITS(mac, 0x14, 0x200);
5569 }
5570
5571 RF_SETBITS(mac, 0x7a, 0x70);
5572 RF_SETBITS(mac, 0x7a, 0x80);
5573
5574 DELAY(30);
5575
5576 nrssi = bwi_nrssi_11g(mac);
5577 if (nrssi == 31) {
5578 for (i = 7; i >= 4; --i) {
5579 RF_WRITE(mac, 0x7b, i);
5580 DELAY(20);
5581 nrssi = bwi_nrssi_11g(mac);
5582 if (nrssi < 31 && rf7b == 0xffff)
5583 rf7b = i;
5584 }
5585 if (rf7b == 0xffff)
5586 rf7b = 4;
5587 } else {
5588 struct bwi_gains gains;
5589
5590 RF_CLRBITS(mac, 0x7a, 0xff80);
5591
5592 PHY_SETBITS(mac, 0x814, 0x1);
5593 PHY_CLRBITS(mac, 0x815, 0x1);
5594 PHY_SETBITS(mac, 0x811, 0xc);
5595 PHY_SETBITS(mac, 0x812, 0xc);
5596 PHY_SETBITS(mac, 0x811, 0x30);
5597 PHY_SETBITS(mac, 0x812, 0x30);
5598 PHY_WRITE(mac, 0x5a, 0x480);
5599 PHY_WRITE(mac, 0x59, 0x810);
5600 PHY_WRITE(mac, 0x58, 0xd);
5601 if (phy->phy_version == 0)
5602 PHY_WRITE(mac, 0x3, 0x122);
5603 else
5604 PHY_SETBITS(mac, 0xa, 0x2000);
5605 PHY_SETBITS(mac, 0x814, 0x4);
5606 PHY_CLRBITS(mac, 0x815, 0x4);
5607 PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
5608 RF_SETBITS(mac, 0x7a, 0xf);
5609
5610 memset(&gains, 0, sizeof(gains));
5611 gains.tbl_gain1 = 3;
5612 gains.tbl_gain2 = 0;
5613 gains.phy_gain = 1;
5614 bwi_set_gains(mac, &gains);
5615
5616 RF_FILT_SETBITS(mac, 0x43, 0xf0, 0xf);
5617 DELAY(30);
5618
5619 nrssi = bwi_nrssi_11g(mac);
5620 if (nrssi == -32) {
5621 for (i = 0; i < 4; ++i) {
5622 RF_WRITE(mac, 0x7b, i);
5623 DELAY(20);
5624 nrssi = bwi_nrssi_11g(mac);
5625 if (nrssi > -31 && rf7b == 0xffff)
5626 rf7b = i;
5627 }
5628 if (rf7b == 0xffff)
5629 rf7b = 3;
5630 } else {
5631 rf7b = 0;
5632 }
5633 }
5634 RF_WRITE(mac, 0x7b, rf7b);
5635
5636 /*
5637 * Restore saved RF/PHY registers
5638 */
5639 if (phy->phy_rev >= 6) {
5640 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
5641 PHY_WRITE(mac, save_phy6_regs[phy6_idx],
5642 save_phy6[phy6_idx]);
5643 }
5644 }
5645
5646 /* Saved PHY registers 0, 1, 2 are handled later */
5647 for (i = 3; i < SAVE_PHY_COMM_MAX; ++i)
5648 PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
5649
5650 for (i = SAVE_RF_MAX - 1; i >= 0; --i)
5651 RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
5652
5653 PHY_SETBITS(mac, 0x802, 0x3);
5654 PHY_SETBITS(mac, 0x429, 0x8000);
5655
5656 bwi_set_gains(mac, NULL);
5657
5658 if (phy->phy_rev >= 6) {
5659 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
5660 PHY_WRITE(mac, save_phy6_regs[phy6_idx],
5661 save_phy6[phy6_idx]);
5662 }
5663 }
5664
5665 PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
5666 PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
5667 PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
5668
5669 #undef SAVE_RF_MAX
5670 #undef SAVE_PHY_COMM_MAX
5671 #undef SAVE_PHY6_MAX
5672 }
5673
5674 static void
5675 bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *mac)
5676 {
5677 #define SAVE_RF_MAX 3
5678 #define SAVE_PHY_COMM_MAX 4
5679 #define SAVE_PHY3_MAX 8
5680 static const uint16_t save_rf_regs[SAVE_RF_MAX] =
5681 { 0x7a, 0x52, 0x43 };
5682 static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
5683 { 0x15, 0x5a, 0x59, 0x58 };
5684 static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
5685 0x002e, 0x002f, 0x080f, 0x0810,
5686 0x0801, 0x0060, 0x0014, 0x0478
5687 };
5688
5689 struct bwi_softc *sc = mac->mac_sc;
5690 struct bwi_phy *phy = &mac->mac_phy;
5691 struct bwi_rf *rf = &mac->mac_rf;
5692 uint16_t save_rf[SAVE_RF_MAX];
5693 uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
5694 uint16_t save_phy3[SAVE_PHY3_MAX];
5695 uint16_t ant_div, bbp_atten, chan_ex;
5696 struct bwi_gains gains;
5697 int16_t nrssi[2];
5698 int i, phy3_idx = 0;
5699
5700 if (rf->rf_rev >= 9)
5701 return;
5702 else if (rf->rf_rev == 8)
5703 bwi_rf_set_nrssi_ofs_11g(mac);
5704
5705 PHY_CLRBITS(mac, 0x429, 0x8000);
5706 PHY_CLRBITS(mac, 0x802, 0x3);
5707
5708 /*
5709 * Save RF/PHY registers for later restoration
5710 */
5711 ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
5712 CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
5713
5714 for (i = 0; i < SAVE_RF_MAX; ++i)
5715 save_rf[i] = RF_READ(mac, save_rf_regs[i]);
5716 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
5717 save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i]);
5718
5719 bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN);
5720 chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
5721
5722 if (phy->phy_rev >= 3) {
5723 for (i = 0; i < SAVE_PHY3_MAX; ++i)
5724 save_phy3[i] = PHY_READ(mac, save_phy3_regs[i]);
5725
5726 PHY_WRITE(mac, 0x2e, 0);
5727 PHY_WRITE(mac, 0x810, 0);
5728
5729 if (phy->phy_rev == 4 || phy->phy_rev == 6 ||
5730 phy->phy_rev == 7) {
5731 PHY_SETBITS(mac, 0x478, 0x100);
5732 PHY_SETBITS(mac, 0x810, 0x40);
5733 } else if (phy->phy_rev == 3 || phy->phy_rev == 5)
5734 PHY_CLRBITS(mac, 0x810, 0x40);
5735
5736 PHY_SETBITS(mac, 0x60, 0x40);
5737 PHY_SETBITS(mac, 0x14, 0x200);
5738 }
5739
5740 /*
5741 * Calculate nrssi0
5742 */
5743 RF_SETBITS(mac, 0x7a, 0x70);
5744
5745 memset(&gains, 0, sizeof(gains));
5746 gains.tbl_gain1 = 0;
5747 gains.tbl_gain2 = 8;
5748 gains.phy_gain = 0;
5749 bwi_set_gains(mac, &gains);
5750
5751 RF_CLRBITS(mac, 0x7a, 0xff08);
5752 if (phy->phy_rev >= 2) {
5753 PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x30);
5754 PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x10);
5755 }
5756
5757 RF_SETBITS(mac, 0x7a, 0x80);
5758 DELAY(20);
5759 nrssi[0] = bwi_nrssi_11g(mac);
5760
5761 /*
5762 * Calculate nrssi1
5763 */
5764 RF_CLRBITS(mac, 0x7a, 0xff80);
5765 if (phy->phy_version >= 2)
5766 PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
5767 CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000);
5768
5769 RF_SETBITS(mac, 0x7a, 0xf);
5770 PHY_WRITE(mac, 0x15, 0xf330);
5771 if (phy->phy_rev >= 2) {
5772 PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x20);
5773 PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x20);
5774 }
5775
5776 memset(&gains, 0, sizeof(gains));
5777 gains.tbl_gain1 = 3;
5778 gains.tbl_gain2 = 0;
5779 gains.phy_gain = 1;
5780 bwi_set_gains(mac, &gains);
5781
5782 if (rf->rf_rev == 8) {
5783 RF_WRITE(mac, 0x43, 0x1f);
5784 } else {
5785 RF_FILT_SETBITS(mac, 0x52, 0xff0f, 0x60);
5786 RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9);
5787 }
5788 PHY_WRITE(mac, 0x5a, 0x480);
5789 PHY_WRITE(mac, 0x59, 0x810);
5790 PHY_WRITE(mac, 0x58, 0xd);
5791 DELAY(20);
5792
5793 nrssi[1] = bwi_nrssi_11g(mac);
5794
5795 /*
5796 * Install calculated narrow RSSI values
5797 */
5798 if (nrssi[1] == nrssi[0])
5799 rf->rf_nrssi_slope = 0x10000;
5800 else
5801 rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]);
5802 if (nrssi[0] >= -4) {
5803 rf->rf_nrssi[0] = nrssi[1];
5804 rf->rf_nrssi[1] = nrssi[0];
5805 }
5806
5807 /*
5808 * Restore saved RF/PHY registers
5809 */
5810 if (phy->phy_rev >= 3) {
5811 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
5812 PHY_WRITE(mac, save_phy3_regs[phy3_idx],
5813 save_phy3[phy3_idx]);
5814 }
5815 }
5816 if (phy->phy_rev >= 2) {
5817 PHY_CLRBITS(mac, 0x812, 0x30);
5818 PHY_CLRBITS(mac, 0x811, 0x30);
5819 }
5820
5821 for (i = 0; i < SAVE_RF_MAX; ++i)
5822 RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
5823
5824 CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
5825 CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten);
5826 CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
5827
5828 for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
5829 PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
5830
5831 bwi_rf_workaround(mac, rf->rf_curchan);
5832 PHY_SETBITS(mac, 0x802, 0x3);
5833 bwi_set_gains(mac, NULL);
5834 PHY_SETBITS(mac, 0x429, 0x8000);
5835
5836 if (phy->phy_rev >= 3) {
5837 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
5838 PHY_WRITE(mac, save_phy3_regs[phy3_idx],
5839 save_phy3[phy3_idx]);
5840 }
5841 }
5842
5843 bwi_rf_init_sw_nrssi_table(mac);
5844 bwi_rf_set_nrssi_thr_11g(mac);
5845
5846 #undef SAVE_RF_MAX
5847 #undef SAVE_PHY_COMM_MAX
5848 #undef SAVE_PHY3_MAX
5849 }
5850
5851 static void
5852 bwi_rf_init_sw_nrssi_table(struct bwi_mac *mac)
5853 {
5854 struct bwi_rf *rf = &mac->mac_rf;
5855 int d, i;
5856
5857 d = 0x1f - rf->rf_nrssi[0];
5858 for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) {
5859 int val;
5860
5861 val = (((i - d) * rf->rf_nrssi_slope) / 0x10000) + 0x3a;
5862 if (val < 0)
5863 val = 0;
5864 else if (val > 0x3f)
5865 val = 0x3f;
5866
5867 rf->rf_nrssi_table[i] = val;
5868 }
5869 }
5870
5871 static void
5872 bwi_rf_init_hw_nrssi_table(struct bwi_mac *mac, uint16_t adjust)
5873 {
5874 int i;
5875
5876 for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) {
5877 int16_t val;
5878
5879 val = bwi_nrssi_read(mac, i);
5880
5881 val -= adjust;
5882 if (val < -32)
5883 val = -32;
5884 else if (val > 31)
5885 val = 31;
5886
5887 bwi_nrssi_write(mac, i, val);
5888 }
5889 }
5890
5891 static void
5892 bwi_rf_set_nrssi_thr_11b(struct bwi_mac *mac)
5893 {
5894 struct bwi_rf *rf = &mac->mac_rf;
5895 int32_t thr;
5896
5897 if (rf->rf_type != BWI_RF_T_BCM2050 ||
5898 (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0)
5899 return;
5900
5901 /*
5902 * Calculate nrssi threshold
5903 */
5904 if (rf->rf_rev >= 6) {
5905 thr = (rf->rf_nrssi[1] - rf->rf_nrssi[0]) * 32;
5906 thr += 20 * (rf->rf_nrssi[0] + 1);
5907 thr /= 40;
5908 } else {
5909 thr = rf->rf_nrssi[1] - 5;
5910 }
5911 if (thr < 0)
5912 thr = 0;
5913 else if (thr > 0x3e)
5914 thr = 0x3e;
5915
5916 PHY_READ(mac, BWI_PHYR_NRSSI_THR_11B); /* dummy read */
5917 PHY_WRITE(mac, BWI_PHYR_NRSSI_THR_11B, (((uint16_t)thr) << 8) | 0x1c);
5918
5919 if (rf->rf_rev >= 6) {
5920 PHY_WRITE(mac, 0x87, 0xe0d);
5921 PHY_WRITE(mac, 0x86, 0xc0b);
5922 PHY_WRITE(mac, 0x85, 0xa09);
5923 PHY_WRITE(mac, 0x84, 0x808);
5924 PHY_WRITE(mac, 0x83, 0x808);
5925 PHY_WRITE(mac, 0x82, 0x604);
5926 PHY_WRITE(mac, 0x81, 0x302);
5927 PHY_WRITE(mac, 0x80, 0x100);
5928 }
5929 }
5930
5931 static int32_t
5932 _nrssi_threshold(const struct bwi_rf *rf, int32_t val)
5933 {
5934 val *= (rf->rf_nrssi[1] - rf->rf_nrssi[0]);
5935 val += (rf->rf_nrssi[0] << 6);
5936 if (val < 32)
5937 val += 31;
5938 else
5939 val += 32;
5940 val >>= 6;
5941 if (val < -31)
5942 val = -31;
5943 else if (val > 31)
5944 val = 31;
5945
5946 return (val);
5947 }
5948
5949 static void
5950 bwi_rf_set_nrssi_thr_11g(struct bwi_mac *mac)
5951 {
5952 int32_t thr1, thr2;
5953 uint16_t thr;
5954
5955 /*
5956 * Find the two nrssi thresholds
5957 */
5958 if ((mac->mac_phy.phy_flags & BWI_PHY_F_LINKED) == 0 ||
5959 (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) {
5960 int16_t nrssi;
5961
5962 nrssi = bwi_nrssi_read(mac, 0x20);
5963 if (nrssi >= 32)
5964 nrssi -= 64;
5965
5966 if (nrssi < 3) {
5967 thr1 = 0x2b;
5968 thr2 = 0x27;
5969 } else {
5970 thr1 = 0x2d;
5971 thr2 = 0x2b;
5972 }
5973 } else {
5974 /* TODO Interfere mode */
5975 thr1 = _nrssi_threshold(&mac->mac_rf, 0x11);
5976 thr2 = _nrssi_threshold(&mac->mac_rf, 0xe);
5977 }
5978
5979 #define NRSSI_THR1_MASK 0x003f
5980 #define NRSSI_THR2_MASK 0x0fc0
5981 thr = __SHIFTIN((uint32_t)thr1, NRSSI_THR1_MASK) |
5982 __SHIFTIN((uint32_t)thr2, NRSSI_THR2_MASK);
5983 PHY_FILT_SETBITS(mac, BWI_PHYR_NRSSI_THR_11G, 0xf000, thr);
5984 #undef NRSSI_THR1_MASK
5985 #undef NRSSI_THR2_MASK
5986 }
5987
5988 static void
5989 bwi_rf_clear_tssi(struct bwi_mac *mac)
5990 {
5991 /* XXX use function pointer */
5992 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) {
5993 /* TODO: 11A */
5994 } else {
5995 uint16_t val;
5996 int i;
5997
5998 val = __SHIFTIN(BWI_INVALID_TSSI, BWI_LO_TSSI_MASK) |
5999 __SHIFTIN(BWI_INVALID_TSSI, BWI_HI_TSSI_MASK);
6000
6001 for (i = 0; i < 2; ++i) {
6002 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ,
6003 BWI_COMM_MOBJ_TSSI_DS + (i * 2), val);
6004 }
6005
6006 for (i = 0; i < 2; ++i) {
6007 MOBJ_WRITE_2(mac, BWI_COMM_MOBJ,
6008 BWI_COMM_MOBJ_TSSI_OFDM + (i * 2), val);
6009 }
6010 }
6011 }
6012
6013 static void
6014 bwi_rf_clear_state(struct bwi_rf *rf)
6015 {
6016 int i;
6017
6018 rf->rf_flags &= ~BWI_RF_CLEAR_FLAGS;
6019 memset(rf->rf_lo, 0, sizeof(rf->rf_lo));
6020 memset(rf->rf_lo_used, 0, sizeof(rf->rf_lo_used));
6021
6022 rf->rf_nrssi_slope = 0;
6023 rf->rf_nrssi[0] = BWI_INVALID_NRSSI;
6024 rf->rf_nrssi[1] = BWI_INVALID_NRSSI;
6025
6026 for (i = 0; i < BWI_NRSSI_TBLSZ; ++i)
6027 rf->rf_nrssi_table[i] = i;
6028
6029 rf->rf_lo_gain = 0;
6030 rf->rf_rx_gain = 0;
6031
6032 memcpy(rf->rf_txpower_map, rf->rf_txpower_map0,
6033 sizeof(rf->rf_txpower_map));
6034 rf->rf_idle_tssi = rf->rf_idle_tssi0;
6035 }
6036
6037 static void
6038 bwi_rf_on_11a(struct bwi_mac *mac)
6039 {
6040 /* TODO: 11A */
6041 }
6042
6043 static void
6044 bwi_rf_on_11bg(struct bwi_mac *mac)
6045 {
6046 struct bwi_phy *phy = &mac->mac_phy;
6047
6048 PHY_WRITE(mac, 0x15, 0x8000);
6049 PHY_WRITE(mac, 0x15, 0xcc00);
6050 if (phy->phy_flags & BWI_PHY_F_LINKED)
6051 PHY_WRITE(mac, 0x15, 0xc0);
6052 else
6053 PHY_WRITE(mac, 0x15, 0);
6054
6055 bwi_rf_set_chan(mac, 6 /* XXX */, 1);
6056 }
6057
6058 static void
6059 bwi_rf_set_ant_mode(struct bwi_mac *mac, int ant_mode)
6060 {
6061 struct bwi_softc *sc = mac->mac_sc;
6062 struct bwi_phy *phy = &mac->mac_phy;
6063 uint16_t val;
6064
6065 KASSERT(ant_mode == BWI_ANT_MODE_0 ||
6066 ant_mode == BWI_ANT_MODE_1 ||
6067 ant_mode == BWI_ANT_MODE_AUTO);
6068
6069 HFLAGS_CLRBITS(mac, BWI_HFLAG_AUTO_ANTDIV);
6070
6071 if (phy->phy_mode == IEEE80211_MODE_11B) {
6072 /* NOTE: v4/v3 conflicts, take v3 */
6073 if (mac->mac_rev == 2)
6074 val = BWI_ANT_MODE_AUTO;
6075 else
6076 val = ant_mode;
6077 val <<= 7;
6078 PHY_FILT_SETBITS(mac, 0x3e2, 0xfe7f, val);
6079 } else { /* 11a/g */
6080 /* XXX reg/value naming */
6081 val = ant_mode << 7;
6082 PHY_FILT_SETBITS(mac, 0x401, 0x7e7f, val);
6083
6084 if (ant_mode == BWI_ANT_MODE_AUTO)
6085 PHY_CLRBITS(mac, 0x42b, 0x100);
6086
6087 if (phy->phy_mode == IEEE80211_MODE_11A) {
6088 /* TODO: 11A */
6089 } else { /* 11g */
6090 if (ant_mode == BWI_ANT_MODE_AUTO)
6091 PHY_SETBITS(mac, 0x48c, 0x2000);
6092 else
6093 PHY_CLRBITS(mac, 0x48c, 0x2000);
6094
6095 if (phy->phy_rev >= 2) {
6096 PHY_SETBITS(mac, 0x461, 0x10);
6097 PHY_FILT_SETBITS(mac, 0x4ad, 0xff00, 0x15);
6098 if (phy->phy_rev == 2) {
6099 PHY_WRITE(mac, 0x427, 0x8);
6100 } else {
6101 PHY_FILT_SETBITS(mac, 0x427,
6102 0xff00, 0x8);
6103 }
6104
6105 if (phy->phy_rev >= 6)
6106 PHY_WRITE(mac, 0x49b, 0xdc);
6107 }
6108 }
6109 }
6110
6111 /* XXX v4 set AUTO_ANTDIV unconditionally */
6112 if (ant_mode == BWI_ANT_MODE_AUTO)
6113 HFLAGS_SETBITS(mac, BWI_HFLAG_AUTO_ANTDIV);
6114
6115 val = ant_mode << 8;
6116 MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_BEACON,
6117 0xfc3f, val);
6118 MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_ACK,
6119 0xfc3f, val);
6120 MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_PROBE_RESP,
6121 0xfc3f, val);
6122
6123 /* XXX what's these */
6124 if (phy->phy_mode == IEEE80211_MODE_11B)
6125 CSR_SETBITS_2(sc, 0x5e, 0x4);
6126
6127 CSR_WRITE_4(sc, 0x100, 0x1000000);
6128 if (mac->mac_rev < 5)
6129 CSR_WRITE_4(sc, 0x10c, 0x1000000);
6130
6131 mac->mac_rf.rf_ant_mode = ant_mode;
6132 }
6133
6134 static int
6135 bwi_rf_get_latest_tssi(struct bwi_mac *mac, int8_t tssi[], uint16_t ofs)
6136 {
6137 int i;
6138
6139 for (i = 0; i < 4; ) {
6140 uint16_t val;
6141
6142 val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, ofs + i);
6143 tssi[i++] = (int8_t)__SHIFTOUT(val, BWI_LO_TSSI_MASK);
6144 tssi[i++] = (int8_t)__SHIFTOUT(val, BWI_HI_TSSI_MASK);
6145 }
6146
6147 for (i = 0; i < 4; ++i) {
6148 if (tssi[i] == BWI_INVALID_TSSI)
6149 return (EINVAL);
6150 }
6151
6152 return (0);
6153 }
6154
6155 static int
6156 bwi_rf_tssi2dbm(struct bwi_mac *mac, int8_t tssi, int8_t *txpwr)
6157 {
6158 struct bwi_rf *rf = &mac->mac_rf;
6159 int pwr_idx;
6160
6161 pwr_idx = rf->rf_idle_tssi + (int)tssi - rf->rf_base_tssi;
6162 #if 0
6163 if (pwr_idx < 0 || pwr_idx >= BWI_TSSI_MAX)
6164 return (EINVAL);
6165 #else
6166 if (pwr_idx < 0)
6167 pwr_idx = 0;
6168 else if (pwr_idx >= BWI_TSSI_MAX)
6169 pwr_idx = BWI_TSSI_MAX - 1;
6170 #endif
6171 *txpwr = rf->rf_txpower_map[pwr_idx];
6172
6173 return (0);
6174 }
6175
6176 static int
6177 bwi_rf_calc_rssi_bcm2050(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr)
6178 {
6179 uint16_t flags1, flags3;
6180 int rssi, lna_gain;
6181
6182 rssi = hdr->rxh_rssi;
6183 flags1 = le16toh(hdr->rxh_flags1);
6184 flags3 = le16toh(hdr->rxh_flags3);
6185
6186 #define NEW_BCM2050_RSSI
6187 #ifdef NEW_BCM2050_RSSI
6188 if (flags1 & BWI_RXH_F1_OFDM) {
6189 if (rssi > 127)
6190 rssi -= 256;
6191 if (flags3 & BWI_RXH_F3_BCM2050_RSSI)
6192 rssi += 17;
6193 else
6194 rssi -= 4;
6195 return (rssi);
6196 }
6197
6198 if (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
6199 struct bwi_rf *rf = &mac->mac_rf;
6200
6201 if (rssi >= BWI_NRSSI_TBLSZ)
6202 rssi = BWI_NRSSI_TBLSZ - 1;
6203
6204 rssi = ((31 - (int)rf->rf_nrssi_table[rssi]) * -131) / 128;
6205 rssi -= 67;
6206 } else {
6207 rssi = ((31 - rssi) * -149) / 128;
6208 rssi -= 68;
6209 }
6210
6211 if (mac->mac_phy.phy_mode != IEEE80211_MODE_11G)
6212 return (rssi);
6213
6214 if (flags3 & BWI_RXH_F3_BCM2050_RSSI)
6215 rssi += 20;
6216
6217 lna_gain = __SHIFTOUT(le16toh(hdr->rxh_phyinfo),
6218 BWI_RXH_PHYINFO_LNAGAIN);
6219 /* [TRC: XXX This causes some seriously verbose output. I hope it
6220 just verbose and not actually a symptom of a problem.]
6221
6222 DPRINTF(mac->mac_sc, BWI_DBG_RF | BWI_DBG_RX,
6223 "lna_gain %d, phyinfo 0x%04x\n",
6224 lna_gain, le16toh(hdr->rxh_phyinfo));
6225 */
6226 switch (lna_gain) {
6227 case 0:
6228 rssi += 27;
6229 break;
6230 case 1:
6231 rssi += 6;
6232 break;
6233 case 2:
6234 rssi += 12;
6235 break;
6236 case 3:
6237 /*
6238 * XXX
6239 * According to v3 spec, we should do _nothing_ here,
6240 * but it seems that the result RSSI will be too low
6241 * (relative to what ath(4) says). Raise it a little
6242 * bit.
6243 */
6244 rssi += 5;
6245 break;
6246 default:
6247 panic("impossible lna gain %d", lna_gain);
6248 }
6249 #else /* !NEW_BCM2050_RSSI */
6250 lna_gain = 0; /* shut up gcc warning */
6251
6252 if (flags1 & BWI_RXH_F1_OFDM) {
6253 if (rssi > 127)
6254 rssi -= 256;
6255 rssi = (rssi * 73) / 64;
6256
6257 if (flags3 & BWI_RXH_F3_BCM2050_RSSI)
6258 rssi += 25;
6259 else
6260 rssi -= 3;
6261 return (rssi);
6262 }
6263
6264 if (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
6265 struct bwi_rf *rf = &mac->mac_rf;
6266
6267 if (rssi >= BWI_NRSSI_TBLSZ)
6268 rssi = BWI_NRSSI_TBLSZ - 1;
6269
6270 rssi = ((31 - (int)rf->rf_nrssi_table[rssi]) * -131) / 128;
6271 rssi -= 57;
6272 } else {
6273 rssi = ((31 - rssi) * -149) / 128;
6274 rssi -= 68;
6275 }
6276
6277 if (mac->mac_phy.phy_mode != IEEE80211_MODE_11G)
6278 return (rssi);
6279
6280 if (flags3 & BWI_RXH_F3_BCM2050_RSSI)
6281 rssi += 25;
6282 #endif /* NEW_BCM2050_RSSI */
6283 return (rssi);
6284 }
6285
6286 static int
6287 bwi_rf_calc_rssi_bcm2053(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr)
6288 {
6289 uint16_t flags1;
6290 int rssi;
6291
6292 rssi = (((int)hdr->rxh_rssi - 11) * 103) / 64;
6293
6294 flags1 = le16toh(hdr->rxh_flags1);
6295 if (flags1 & BWI_RXH_F1_BCM2053_RSSI)
6296 rssi -= 109;
6297 else
6298 rssi -= 83;
6299
6300 return (rssi);
6301 }
6302
6303 static int
6304 bwi_rf_calc_rssi_bcm2060(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr)
6305 {
6306 int rssi;
6307
6308 rssi = hdr->rxh_rssi;
6309 if (rssi > 127)
6310 rssi -= 256;
6311
6312 return (rssi);
6313 }
6314
6315 static uint16_t
6316 bwi_rf_lo_measure_11b(struct bwi_mac *mac)
6317 {
6318 uint16_t val;
6319 int i;
6320
6321 val = 0;
6322 for (i = 0; i < 10; ++i) {
6323 PHY_WRITE(mac, 0x15, 0xafa0);
6324 DELAY(1);
6325 PHY_WRITE(mac, 0x15, 0xefa0);
6326 DELAY(10);
6327 PHY_WRITE(mac, 0x15, 0xffa0);
6328 DELAY(40);
6329
6330 val += PHY_READ(mac, 0x2c);
6331 }
6332
6333 return (val);
6334 }
6335
6336 static void
6337 bwi_rf_lo_update_11b(struct bwi_mac *mac)
6338 {
6339 struct bwi_softc *sc = mac->mac_sc;
6340 struct bwi_rf *rf = &mac->mac_rf;
6341 struct rf_saveregs regs;
6342 uint16_t rf_val, phy_val, min_val, val;
6343 uint16_t rf52, bphy_ctrl;
6344 int i;
6345
6346 DPRINTF(sc, BWI_DBG_RF | BWI_DBG_INIT, "%s enter\n", __func__);
6347
6348 memset(®s, 0, sizeof(regs));
6349 bphy_ctrl = 0;
6350
6351 /*
6352 * Save RF/PHY registers for later restoration
6353 */
6354 SAVE_PHY_REG(mac, ®s, 15);
6355 rf52 = RF_READ(mac, 0x52) & 0xfff0;
6356 if (rf->rf_type == BWI_RF_T_BCM2050) {
6357 SAVE_PHY_REG(mac, ®s, 0a);
6358 SAVE_PHY_REG(mac, ®s, 2a);
6359 SAVE_PHY_REG(mac, ®s, 35);
6360 SAVE_PHY_REG(mac, ®s, 03);
6361 SAVE_PHY_REG(mac, ®s, 01);
6362 SAVE_PHY_REG(mac, ®s, 30);
6363
6364 SAVE_RF_REG(mac, ®s, 43);
6365 SAVE_RF_REG(mac, ®s, 7a);
6366
6367 bphy_ctrl = CSR_READ_2(sc, BWI_BPHY_CTRL);
6368
6369 SAVE_RF_REG(mac, ®s, 52);
6370 regs.rf_52 &= 0xf0;
6371
6372 PHY_WRITE(mac, 0x30, 0xff);
6373 CSR_WRITE_2(sc, BWI_PHY_CTRL, 0x3f3f);
6374 PHY_WRITE(mac, 0x35, regs.phy_35 & 0xff7f);
6375 RF_WRITE(mac, 0x7a, regs.rf_7a & 0xfff0);
6376 }
6377
6378 PHY_WRITE(mac, 0x15, 0xb000);
6379
6380 if (rf->rf_type == BWI_RF_T_BCM2050) {
6381 PHY_WRITE(mac, 0x2b, 0x203);
6382 PHY_WRITE(mac, 0x2a, 0x8a3);
6383 } else {
6384 PHY_WRITE(mac, 0x2b, 0x1402);
6385 }
6386
6387 /*
6388 * Setup RF signal
6389 */
6390 rf_val = 0;
6391 min_val = UINT16_MAX;
6392
6393 for (i = 0; i < 4; ++i) {
6394 RF_WRITE(mac, 0x52, rf52 | i);
6395 bwi_rf_lo_measure_11b(mac); /* Ignore return value */
6396 }
6397 for (i = 0; i < 10; ++i) {
6398 RF_WRITE(mac, 0x52, rf52 | i);
6399
6400 val = bwi_rf_lo_measure_11b(mac) / 10;
6401 if (val < min_val) {
6402 min_val = val;
6403 rf_val = i;
6404 }
6405 }
6406 RF_WRITE(mac, 0x52, rf52 | rf_val);
6407
6408 /*
6409 * Setup PHY signal
6410 */
6411 phy_val = 0;
6412 min_val = UINT16_MAX;
6413
6414 for (i = -4; i < 5; i += 2) {
6415 int j;
6416
6417 for (j = -4; j < 5; j += 2) {
6418 uint16_t phy2f;
6419
6420 phy2f = (0x100 * i) + j;
6421 if (j < 0)
6422 phy2f += 0x100;
6423 PHY_WRITE(mac, 0x2f, phy2f);
6424
6425 val = bwi_rf_lo_measure_11b(mac) / 10;
6426 if (val < min_val) {
6427 min_val = val;
6428 phy_val = phy2f;
6429 }
6430 }
6431 }
6432 PHY_WRITE(mac, 0x2f, phy_val + 0x101);
6433
6434 /*
6435 * Restore saved RF/PHY registers
6436 */
6437 if (rf->rf_type == BWI_RF_T_BCM2050) {
6438 RESTORE_PHY_REG(mac, ®s, 0a);
6439 RESTORE_PHY_REG(mac, ®s, 2a);
6440 RESTORE_PHY_REG(mac, ®s, 35);
6441 RESTORE_PHY_REG(mac, ®s, 03);
6442 RESTORE_PHY_REG(mac, ®s, 01);
6443 RESTORE_PHY_REG(mac, ®s, 30);
6444
6445 RESTORE_RF_REG(mac, ®s, 43);
6446 RESTORE_RF_REG(mac, ®s, 7a);
6447
6448 RF_FILT_SETBITS(mac, 0x52, 0xf, regs.rf_52);
6449
6450 CSR_WRITE_2(sc, BWI_BPHY_CTRL, bphy_ctrl);
6451 }
6452 RESTORE_PHY_REG(mac, ®s, 15);
6453
6454 bwi_rf_workaround(mac, rf->rf_curchan);
6455 }
6456
6457 /* INTERFACE */
6458
6459 static uint16_t
6460 bwi_read_sprom(struct bwi_softc *sc, uint16_t ofs)
6461 {
6462 return (CSR_READ_2(sc, ofs + BWI_SPROM_START));
6463 }
6464
6465 static void
6466 bwi_setup_desc32(struct bwi_softc *sc, struct bwi_desc32 *desc_array,
6467 int ndesc, int desc_idx, bus_addr_t paddr, int buf_len, int tx)
6468 {
6469 struct bwi_desc32 *desc = &desc_array[desc_idx];
6470 uint32_t ctrl, addr, addr_hi, addr_lo;
6471
6472 addr_lo = __SHIFTOUT(paddr, BWI_DESC32_A_ADDR_MASK);
6473 addr_hi = __SHIFTOUT(paddr, BWI_DESC32_A_FUNC_MASK);
6474
6475 addr = __SHIFTIN(addr_lo, BWI_DESC32_A_ADDR_MASK) |
6476 __SHIFTIN(BWI_DESC32_A_FUNC_TXRX, BWI_DESC32_A_FUNC_MASK);
6477
6478 ctrl = __SHIFTIN(buf_len, BWI_DESC32_C_BUFLEN_MASK) |
6479 __SHIFTIN(addr_hi, BWI_DESC32_C_ADDRHI_MASK);
6480 if (desc_idx == ndesc - 1)
6481 ctrl |= BWI_DESC32_C_EOR;
6482 if (tx) {
6483 /* XXX */
6484 ctrl |= BWI_DESC32_C_FRAME_START |
6485 BWI_DESC32_C_FRAME_END |
6486 BWI_DESC32_C_INTR;
6487 }
6488
6489 desc->addr = htole32(addr);
6490 desc->ctrl = htole32(ctrl);
6491 }
6492
6493 static void
6494 bwi_power_on(struct bwi_softc *sc, int with_pll)
6495 {
6496 uint32_t gpio_in, gpio_out, gpio_en, status;
6497
6498 DPRINTF(sc, BWI_DBG_MISC, "%s\n", __func__);
6499
6500 if (BWI_IS_SDIO(sc)) {
6501 return;
6502 }
6503
6504 gpio_in = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_IN);
6505 if (gpio_in & BWI_PCIM_GPIO_PWR_ON)
6506 goto back;
6507
6508 gpio_out = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT);
6509 gpio_en = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_ENABLE);
6510
6511 gpio_out |= BWI_PCIM_GPIO_PWR_ON;
6512 gpio_en |= BWI_PCIM_GPIO_PWR_ON;
6513 if (with_pll) {
6514 /* Turn off PLL first */
6515 gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF;
6516 gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF;
6517 }
6518
6519 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out);
6520 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_ENABLE, gpio_en);
6521 DELAY(1000);
6522
6523 if (with_pll) {
6524 /* Turn on PLL */
6525 gpio_out &= ~BWI_PCIM_GPIO_PLL_PWR_OFF;
6526 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out);
6527 DELAY(5000);
6528 }
6529
6530 back:
6531 /* [TRC: XXX This looks totally wrong -- what's PCI doing in here?] */
6532 /* Clear "Signaled Target Abort" */
6533 status = (sc->sc_conf_read)(sc, PCI_COMMAND_STATUS_REG);
6534 status &= ~PCI_STATUS_TARGET_TARGET_ABORT;
6535 (sc->sc_conf_write)(sc, PCI_COMMAND_STATUS_REG, status);
6536 }
6537
6538 static int
6539 bwi_power_off(struct bwi_softc *sc, int with_pll)
6540 {
6541 uint32_t gpio_out, gpio_en;
6542
6543 DPRINTF(sc, BWI_DBG_MISC, "%s\n", __func__);
6544
6545 if (BWI_IS_SDIO(sc)) {
6546 return (0);
6547 }
6548
6549 (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_IN); /* dummy read */
6550 gpio_out = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT);
6551 gpio_en = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_ENABLE);
6552
6553 gpio_out &= ~BWI_PCIM_GPIO_PWR_ON;
6554 gpio_en |= BWI_PCIM_GPIO_PWR_ON;
6555 if (with_pll) {
6556 gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF;
6557 gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF;
6558 }
6559
6560 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out);
6561 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_ENABLE, gpio_en);
6562
6563 return (0);
6564 }
6565
6566 static int
6567 bwi_regwin_switch(struct bwi_softc *sc, struct bwi_regwin *rw,
6568 struct bwi_regwin **old_rw)
6569 {
6570 int error;
6571
6572 if (old_rw != NULL)
6573 *old_rw = NULL;
6574
6575 if (!BWI_REGWIN_EXIST(rw))
6576 return (EINVAL);
6577
6578 if (sc->sc_cur_regwin != rw) {
6579 error = bwi_regwin_select(sc, rw->rw_id);
6580 if (error) {
6581 aprint_error_dev(sc->sc_dev,
6582 "can't select regwin %d\n", rw->rw_id);
6583 return (error);
6584 }
6585 }
6586
6587 if (old_rw != NULL)
6588 *old_rw = sc->sc_cur_regwin;
6589 sc->sc_cur_regwin = rw;
6590
6591 return (0);
6592 }
6593
6594 static int
6595 bwi_regwin_select(struct bwi_softc *sc, int id)
6596 {
6597 uint32_t win = BWI_PCIM_REGWIN(id);
6598 int i;
6599
6600 #define RETRY_MAX 50
6601 for (i = 0; i < RETRY_MAX; ++i) {
6602 (sc->sc_conf_write)(sc, BWI_PCIR_SEL_REGWIN, win);
6603 if ((sc->sc_conf_read)(sc, BWI_PCIR_SEL_REGWIN) == win)
6604 return (0);
6605 DELAY(10);
6606 }
6607 #undef RETRY_MAX
6608
6609 return (ENXIO);
6610 }
6611
6612 static void
6613 bwi_regwin_info(struct bwi_softc *sc, uint16_t *type, uint8_t *rev)
6614 {
6615 uint32_t val;
6616
6617 val = CSR_READ_4(sc, BWI_ID_HI);
6618 *type = BWI_ID_HI_REGWIN_TYPE(val);
6619 *rev = BWI_ID_HI_REGWIN_REV(val);
6620
6621 DPRINTF(sc, BWI_DBG_ATTACH, "regwin: type 0x%03x, rev %d,"
6622 " vendor 0x%04x\n", *type, *rev,
6623 __SHIFTOUT(val, BWI_ID_HI_REGWIN_VENDOR_MASK));
6624 }
6625
6626 static void
6627 bwi_led_attach(struct bwi_softc *sc)
6628 {
6629 const uint8_t *led_act = NULL;
6630 uint16_t gpio, val[BWI_LED_MAX];
6631 int i;
6632
6633 for (i = 0; i < __arraycount(bwi_vendor_led_act); ++i) {
6634 if (sc->sc_pci_subvid == bwi_vendor_led_act[i].vid) {
6635 led_act = bwi_vendor_led_act[i].led_act;
6636 break;
6637 }
6638 }
6639 if (led_act == NULL)
6640 led_act = bwi_default_led_act;
6641
6642 gpio = bwi_read_sprom(sc, BWI_SPROM_GPIO01);
6643 val[0] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_0);
6644 val[1] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_1);
6645
6646 gpio = bwi_read_sprom(sc, BWI_SPROM_GPIO23);
6647 val[2] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_2);
6648 val[3] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_3);
6649
6650 for (i = 0; i < BWI_LED_MAX; ++i) {
6651 struct bwi_led *led = &sc->sc_leds[i];
6652
6653 if (val[i] == 0xff) {
6654 led->l_act = led_act[i];
6655 } else {
6656 if (val[i] & BWI_LED_ACT_LOW)
6657 led->l_flags |= BWI_LED_F_ACTLOW;
6658 led->l_act = __SHIFTOUT(val[i], BWI_LED_ACT_MASK);
6659 }
6660 led->l_mask = (1 << i);
6661
6662 if (led->l_act == BWI_LED_ACT_BLINK_SLOW ||
6663 led->l_act == BWI_LED_ACT_BLINK_POLL ||
6664 led->l_act == BWI_LED_ACT_BLINK) {
6665 led->l_flags |= BWI_LED_F_BLINK;
6666 if (led->l_act == BWI_LED_ACT_BLINK_POLL)
6667 led->l_flags |= BWI_LED_F_POLLABLE;
6668 else if (led->l_act == BWI_LED_ACT_BLINK_SLOW)
6669 led->l_flags |= BWI_LED_F_SLOW;
6670
6671 if (sc->sc_blink_led == NULL) {
6672 sc->sc_blink_led = led;
6673 if (led->l_flags & BWI_LED_F_SLOW)
6674 BWI_LED_SLOWDOWN(sc->sc_led_idle);
6675 }
6676 }
6677
6678 DPRINTF(sc, BWI_DBG_LED | BWI_DBG_ATTACH,
6679 "%dth led, act %d, lowact %d\n", i, led->l_act,
6680 led->l_flags & BWI_LED_F_ACTLOW);
6681 }
6682 callout_init(&sc->sc_led_blink_ch, 0);
6683 }
6684
6685 static uint16_t
6686 bwi_led_onoff(const struct bwi_led *led, uint16_t val, int on)
6687 {
6688 if (led->l_flags & BWI_LED_F_ACTLOW)
6689 on = !on;
6690 if (on)
6691 val |= led->l_mask;
6692 else
6693 val &= ~led->l_mask;
6694
6695 return (val);
6696 }
6697
6698 static void
6699 bwi_led_newstate(struct bwi_softc *sc, enum ieee80211_state nstate)
6700 {
6701 struct ieee80211com *ic = &sc->sc_ic;
6702 struct ifnet *ifp = &sc->sc_if;
6703 uint16_t val;
6704 int i;
6705
6706 if (nstate == IEEE80211_S_INIT) {
6707 callout_stop(&sc->sc_led_blink_ch);
6708 sc->sc_led_blinking = 0;
6709 }
6710
6711 if ((ifp->if_flags & IFF_RUNNING) == 0)
6712 return;
6713
6714 val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL);
6715 for (i = 0; i < BWI_LED_MAX; ++i) {
6716 struct bwi_led *led = &sc->sc_leds[i];
6717 int on;
6718
6719 if (led->l_act == BWI_LED_ACT_UNKN ||
6720 led->l_act == BWI_LED_ACT_NULL)
6721 continue;
6722
6723 if ((led->l_flags & BWI_LED_F_BLINK) &&
6724 nstate != IEEE80211_S_INIT)
6725 continue;
6726
6727 switch (led->l_act) {
6728 case BWI_LED_ACT_ON: /* Always on */
6729 on = 1;
6730 break;
6731 case BWI_LED_ACT_OFF: /* Always off */
6732 case BWI_LED_ACT_5GHZ: /* TODO: 11A */
6733 on = 0;
6734 break;
6735 default:
6736 on = 1;
6737 switch (nstate) {
6738 case IEEE80211_S_INIT:
6739 on = 0;
6740 break;
6741 case IEEE80211_S_RUN:
6742 if (led->l_act == BWI_LED_ACT_11G &&
6743 ic->ic_curmode != IEEE80211_MODE_11G)
6744 on = 0;
6745 break;
6746 default:
6747 if (led->l_act == BWI_LED_ACT_ASSOC)
6748 on = 0;
6749 break;
6750 }
6751 break;
6752 }
6753
6754 val = bwi_led_onoff(led, val, on);
6755 }
6756 CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val);
6757 }
6758
6759 static void
6760 bwi_led_event(struct bwi_softc *sc, int event)
6761 {
6762 struct bwi_led *led = sc->sc_blink_led;
6763 int rate;
6764
6765 if (event == BWI_LED_EVENT_POLL) {
6766 if ((led->l_flags & BWI_LED_F_POLLABLE) == 0)
6767 return;
6768 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
6769 return;
6770 }
6771
6772 sc->sc_led_ticks = ticks;
6773 if (sc->sc_led_blinking)
6774 return;
6775
6776 switch (event) {
6777 case BWI_LED_EVENT_RX:
6778 rate = sc->sc_rx_rate;
6779 break;
6780 case BWI_LED_EVENT_TX:
6781 rate = sc->sc_tx_rate;
6782 break;
6783 case BWI_LED_EVENT_POLL:
6784 rate = 0;
6785 break;
6786 default:
6787 panic("unknown LED event %d\n", event);
6788 break;
6789 }
6790 bwi_led_blink_start(sc, bwi_led_duration[rate].on_dur,
6791 bwi_led_duration[rate].off_dur);
6792 }
6793
6794 static void
6795 bwi_led_blink_start(struct bwi_softc *sc, int on_dur, int off_dur)
6796 {
6797 struct bwi_led *led = sc->sc_blink_led;
6798 uint16_t val;
6799
6800 val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL);
6801 val = bwi_led_onoff(led, val, 1);
6802 CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val);
6803
6804 if (led->l_flags & BWI_LED_F_SLOW) {
6805 BWI_LED_SLOWDOWN(on_dur);
6806 BWI_LED_SLOWDOWN(off_dur);
6807 }
6808
6809 sc->sc_led_blinking = 1;
6810 sc->sc_led_blink_offdur = off_dur;
6811
6812 callout_reset(&sc->sc_led_blink_ch, on_dur, bwi_led_blink_next, sc);
6813 }
6814
6815 static void
6816 bwi_led_blink_next(void *xsc)
6817 {
6818 struct bwi_softc *sc = xsc;
6819 uint16_t val;
6820
6821 val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL);
6822 val = bwi_led_onoff(sc->sc_blink_led, val, 0);
6823 CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val);
6824
6825 callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
6826 bwi_led_blink_end, sc);
6827 }
6828
6829 static void
6830 bwi_led_blink_end(void *xsc)
6831 {
6832 struct bwi_softc *sc = xsc;
6833
6834 sc->sc_led_blinking = 0;
6835 }
6836
6837 static int
6838 bwi_bbp_attach(struct bwi_softc *sc)
6839 {
6840 uint16_t bbp_id, rw_type;
6841 uint8_t rw_rev;
6842 uint32_t info;
6843 int error, nregwin, i, nretry = 0;
6844
6845 /*
6846 * Get 0th regwin information
6847 * NOTE: 0th regwin should exist
6848 */
6849 retry_com:
6850 error = bwi_regwin_select(sc, 0);
6851 if (error) {
6852 aprint_error_dev(sc->sc_dev, "can't select regwin 0\n");
6853 return (error);
6854 }
6855 bwi_regwin_info(sc, &rw_type, &rw_rev);
6856
6857 /* Sometimes it takes a few tries to read SDIO common regwin. */
6858 if (rw_type != BWI_REGWIN_T_COM &&
6859 BWI_IS_SDIO(sc) && nretry++ < 5) {
6860 goto retry_com;
6861 }
6862
6863 /*
6864 * Find out BBP id
6865 */
6866 bbp_id = 0;
6867 info = 0;
6868 if (rw_type == BWI_REGWIN_T_COM) {
6869 info = CSR_READ_4(sc, BWI_INFO);
6870 bbp_id = __SHIFTOUT(info, BWI_INFO_BBPID_MASK);
6871
6872 BWI_CREATE_REGWIN(&sc->sc_com_regwin, 0, rw_type, rw_rev);
6873
6874 sc->sc_cap = CSR_READ_4(sc, BWI_CAPABILITY);
6875 } else {
6876 uint16_t did = sc->sc_pci_did;
6877 uint8_t revid = sc->sc_pci_revid;
6878
6879 for (i = 0; i < __arraycount(bwi_bbpid_map); ++i) {
6880 if (did >= bwi_bbpid_map[i].did_min &&
6881 did <= bwi_bbpid_map[i].did_max) {
6882 bbp_id = bwi_bbpid_map[i].bbp_id;
6883 break;
6884 }
6885 }
6886 if (bbp_id == 0) {
6887 aprint_error_dev(sc->sc_dev, "no BBP id for device id"
6888 " 0x%04x\n", did);
6889 return (ENXIO);
6890 }
6891
6892 info = __SHIFTIN(revid, BWI_INFO_BBPREV_MASK) |
6893 __SHIFTIN(0, BWI_INFO_BBPPKG_MASK);
6894 }
6895
6896 /*
6897 * Find out number of regwins
6898 */
6899 nregwin = 0;
6900 if (rw_type == BWI_REGWIN_T_COM && rw_rev >= 4) {
6901 nregwin = __SHIFTOUT(info, BWI_INFO_NREGWIN_MASK);
6902 } else {
6903 for (i = 0; i < __arraycount(bwi_regwin_count); ++i) {
6904 if (bwi_regwin_count[i].bbp_id == bbp_id) {
6905 nregwin = bwi_regwin_count[i].nregwin;
6906 break;
6907 }
6908 }
6909 if (nregwin == 0) {
6910 aprint_error_dev(sc->sc_dev, "no number of win for"
6911 " BBP id 0x%04x\n", bbp_id);
6912 return (ENXIO);
6913 }
6914 }
6915
6916 /* Record BBP id/rev for later using */
6917 sc->sc_bbp_id = bbp_id;
6918 sc->sc_bbp_rev = __SHIFTOUT(info, BWI_INFO_BBPREV_MASK);
6919 sc->sc_bbp_pkg = __SHIFTOUT(info, BWI_INFO_BBPPKG_MASK);
6920 aprint_normal_dev(sc->sc_dev,
6921 "BBP id 0x%04x, BBP rev 0x%x, BBP pkg %d\n",
6922 sc->sc_bbp_id, sc->sc_bbp_rev, sc->sc_bbp_pkg);
6923 DPRINTF(sc, BWI_DBG_ATTACH, "nregwin %d, cap 0x%08x\n",
6924 nregwin, sc->sc_cap);
6925
6926 /*
6927 * Create rest of the regwins
6928 */
6929
6930 /* Don't re-create common regwin, if it is already created */
6931 i = BWI_REGWIN_EXIST(&sc->sc_com_regwin) ? 1 : 0;
6932
6933 for (; i < nregwin; ++i) {
6934 /*
6935 * Get regwin information
6936 */
6937 error = bwi_regwin_select(sc, i);
6938 if (error) {
6939 aprint_error_dev(sc->sc_dev, "can't select regwin"
6940 " %d\n", i);
6941 return (error);
6942 }
6943 bwi_regwin_info(sc, &rw_type, &rw_rev);
6944
6945 /*
6946 * Try attach:
6947 * 1) Bus (PCI/PCIE) regwin
6948 * 2) MAC regwin
6949 * Ignore rest types of regwin
6950 */
6951 if (rw_type == BWI_REGWIN_T_BUSPCI ||
6952 rw_type == BWI_REGWIN_T_BUSPCIE) {
6953 if (BWI_REGWIN_EXIST(&sc->sc_bus_regwin)) {
6954 aprint_error_dev(sc->sc_dev,
6955 "bus regwin already exists\n");
6956 } else {
6957 BWI_CREATE_REGWIN(&sc->sc_bus_regwin, i,
6958 rw_type, rw_rev);
6959 }
6960 } else if (rw_type == BWI_REGWIN_T_MAC) {
6961 /* XXX ignore return value */
6962 bwi_mac_attach(sc, i, rw_rev);
6963 }
6964 }
6965
6966 /* At least one MAC shold exist */
6967 if (!BWI_REGWIN_EXIST(&sc->sc_mac[0].mac_regwin)) {
6968 aprint_error_dev(sc->sc_dev, "no MAC was found\n");
6969 return (ENXIO);
6970 }
6971 KASSERT(sc->sc_nmac > 0);
6972
6973 /* Bus regwin must exist */
6974 if (!BWI_REGWIN_EXIST(&sc->sc_bus_regwin)) {
6975 aprint_error_dev(sc->sc_dev, "no bus regwin was found\n");
6976 return (ENXIO);
6977 }
6978
6979 /* Start with first MAC */
6980 error = bwi_regwin_switch(sc, &sc->sc_mac[0].mac_regwin, NULL);
6981 if (error)
6982 return (error);
6983
6984 return (0);
6985 }
6986
6987 static int
6988 bwi_bus_init(struct bwi_softc *sc, struct bwi_mac *mac)
6989 {
6990 struct bwi_regwin *old, *bus;
6991 uint32_t val;
6992 int error;
6993
6994 bus = &sc->sc_bus_regwin;
6995 KASSERT(sc->sc_cur_regwin == &mac->mac_regwin);
6996
6997 if (BWI_IS_SDIO(sc)) {
6998 sc->sc_flags |= BWI_F_BUS_INITED;
6999 return (0);
7000 }
7001
7002 /*
7003 * Tell bus to generate requested interrupts (PCI and Cardbus only).
7004 */
7005 if (bus->rw_rev < 6 && bus->rw_type == BWI_REGWIN_T_BUSPCI) {
7006 /*
7007 * NOTE: Read BWI_FLAGS from MAC regwin
7008 */
7009 val = CSR_READ_4(sc, BWI_FLAGS);
7010
7011 error = bwi_regwin_switch(sc, bus, &old);
7012 if (error)
7013 return (error);
7014
7015 CSR_SETBITS_4(sc, BWI_INTRVEC, (val & BWI_FLAGS_INTR_MASK));
7016 } else {
7017 uint32_t mac_mask;
7018
7019 mac_mask = 1 << mac->mac_id;
7020
7021 error = bwi_regwin_switch(sc, bus, &old);
7022 if (error)
7023 return (error);
7024
7025 val = (sc->sc_conf_read)(sc, BWI_PCIR_INTCTL);
7026 val |= mac_mask << 8;
7027 (sc->sc_conf_write)(sc, BWI_PCIR_INTCTL, val);
7028 }
7029
7030 if (sc->sc_flags & BWI_F_BUS_INITED)
7031 goto back;
7032
7033 if (bus->rw_type == BWI_REGWIN_T_BUSPCI) {
7034 /*
7035 * Enable prefetch and burst
7036 */
7037 CSR_SETBITS_4(sc, BWI_BUS_CONFIG,
7038 BWI_BUS_CONFIG_PREFETCH | BWI_BUS_CONFIG_BURST);
7039
7040 if (bus->rw_rev < 5) {
7041 struct bwi_regwin *com = &sc->sc_com_regwin;
7042
7043 /*
7044 * Configure timeouts for bus operation
7045 */
7046
7047 /*
7048 * Set service timeout and request timeout
7049 */
7050 CSR_SETBITS_4(sc, BWI_CONF_LO,
7051 __SHIFTIN(BWI_CONF_LO_SERVTO,
7052 BWI_CONF_LO_SERVTO_MASK) |
7053 __SHIFTIN(BWI_CONF_LO_REQTO,
7054 BWI_CONF_LO_REQTO_MASK));
7055
7056 /*
7057 * If there is common regwin, we switch to that regwin
7058 * and switch back to bus regwin once we have done.
7059 */
7060 if (BWI_REGWIN_EXIST(com)) {
7061 error = bwi_regwin_switch(sc, com, NULL);
7062 if (error)
7063 return (error);
7064 }
7065
7066 /* Let bus know what we have changed */
7067 CSR_WRITE_4(sc, BWI_BUS_ADDR, BWI_BUS_ADDR_MAGIC);
7068 CSR_READ_4(sc, BWI_BUS_ADDR); /* Flush */
7069 CSR_WRITE_4(sc, BWI_BUS_DATA, 0);
7070 CSR_READ_4(sc, BWI_BUS_DATA); /* Flush */
7071
7072 if (BWI_REGWIN_EXIST(com)) {
7073 error = bwi_regwin_switch(sc, bus, NULL);
7074 if (error)
7075 return (error);
7076 }
7077 } else if (bus->rw_rev >= 11) {
7078 /*
7079 * Enable memory read multiple
7080 */
7081 CSR_SETBITS_4(sc, BWI_BUS_CONFIG, BWI_BUS_CONFIG_MRM);
7082 }
7083 } else {
7084 /* TODO: PCIE */
7085 }
7086
7087 sc->sc_flags |= BWI_F_BUS_INITED;
7088 back:
7089 return (bwi_regwin_switch(sc, old, NULL));
7090 }
7091
7092 static void
7093 bwi_get_card_flags(struct bwi_softc *sc)
7094 {
7095 sc->sc_card_flags = bwi_read_sprom(sc, BWI_SPROM_CARD_FLAGS);
7096 if (sc->sc_card_flags == 0xffff)
7097 sc->sc_card_flags = 0;
7098
7099 if (sc->sc_pci_subvid == PCI_VENDOR_APPLE &&
7100 sc->sc_pci_subdid == 0x4e && /* XXX */
7101 sc->sc_pci_revid > 0x40)
7102 sc->sc_card_flags |= BWI_CARD_F_PA_GPIO9;
7103
7104 DPRINTF(sc, BWI_DBG_ATTACH, "card flags 0x%04x\n", sc->sc_card_flags);
7105 }
7106
7107 static void
7108 bwi_get_eaddr(struct bwi_softc *sc, uint16_t eaddr_ofs, uint8_t *eaddr)
7109 {
7110 int i;
7111
7112 for (i = 0; i < 3; ++i) {
7113 *((uint16_t *)eaddr + i) =
7114 htobe16(bwi_read_sprom(sc, eaddr_ofs + 2 * i));
7115 }
7116 }
7117
7118 static void
7119 bwi_get_clock_freq(struct bwi_softc *sc, struct bwi_clock_freq *freq)
7120 {
7121 struct bwi_regwin *com;
7122 uint32_t val;
7123 uint div;
7124 int src;
7125
7126 memset(freq, 0, sizeof(*freq));
7127 com = &sc->sc_com_regwin;
7128
7129 KASSERT(BWI_REGWIN_EXIST(com));
7130 KASSERT(sc->sc_cur_regwin == com);
7131 KASSERT(sc->sc_cap & BWI_CAP_CLKMODE);
7132
7133 /*
7134 * Calculate clock frequency
7135 */
7136 src = -1;
7137 div = 0;
7138 if (com->rw_rev < 6) {
7139 val = BWI_IS_SDIO(sc) ?
7140 0 : (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT);
7141 if (val & BWI_PCIM_GPIO_OUT_CLKSRC) {
7142 src = BWI_CLKSRC_PCI;
7143 div = 64;
7144 } else {
7145 src = BWI_CLKSRC_CS_OSC;
7146 div = 32;
7147 }
7148 } else if (com->rw_rev < 10) {
7149 val = CSR_READ_4(sc, BWI_CLOCK_CTRL);
7150
7151 src = __SHIFTOUT(val, BWI_CLOCK_CTRL_CLKSRC);
7152 if (src == BWI_CLKSRC_LP_OSC)
7153 div = 1;
7154 else {
7155 div = (__SHIFTOUT(val, BWI_CLOCK_CTRL_FDIV) + 1) << 2;
7156
7157 /* Unknown source */
7158 if (src >= BWI_CLKSRC_MAX)
7159 src = BWI_CLKSRC_CS_OSC;
7160 }
7161 } else {
7162 val = CSR_READ_4(sc, BWI_CLOCK_INFO);
7163
7164 src = BWI_CLKSRC_CS_OSC;
7165 div = (__SHIFTOUT(val, BWI_CLOCK_INFO_FDIV) + 1) << 2;
7166 }
7167
7168 KASSERT(src >= 0 && src < BWI_CLKSRC_MAX);
7169 KASSERT(div != 0);
7170
7171 DPRINTF(sc, BWI_DBG_ATTACH, "clksrc %s\n",
7172 src == BWI_CLKSRC_PCI ? "PCI" :
7173 (src == BWI_CLKSRC_LP_OSC ? "LP_OSC" : "CS_OSC"));
7174
7175 freq->clkfreq_min = bwi_clkfreq[src].freq_min / div;
7176 freq->clkfreq_max = bwi_clkfreq[src].freq_max / div;
7177
7178 DPRINTF(sc, BWI_DBG_ATTACH, "clkfreq min %u, max %u\n",
7179 freq->clkfreq_min, freq->clkfreq_max);
7180 }
7181
7182 static int
7183 bwi_set_clock_mode(struct bwi_softc *sc, enum bwi_clock_mode clk_mode)
7184 {
7185 struct bwi_regwin *old, *com;
7186 uint32_t clk_ctrl, clk_src;
7187 int error, pwr_off = 0;
7188
7189 com = &sc->sc_com_regwin;
7190 if (!BWI_REGWIN_EXIST(com))
7191 return (0);
7192
7193 if (com->rw_rev >= 10 || com->rw_rev < 6)
7194 return (0);
7195
7196 /*
7197 * For common regwin whose rev is [6, 10), the chip
7198 * must be capable to change clock mode.
7199 */
7200 if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0)
7201 return (0);
7202
7203 error = bwi_regwin_switch(sc, com, &old);
7204 if (error)
7205 return (error);
7206
7207 if (clk_mode == BWI_CLOCK_MODE_FAST)
7208 bwi_power_on(sc, 0); /* Don't turn on PLL */
7209
7210 clk_ctrl = CSR_READ_4(sc, BWI_CLOCK_CTRL);
7211 clk_src = __SHIFTOUT(clk_ctrl, BWI_CLOCK_CTRL_CLKSRC);
7212
7213 switch (clk_mode) {
7214 case BWI_CLOCK_MODE_FAST:
7215 clk_ctrl &= ~BWI_CLOCK_CTRL_SLOW;
7216 clk_ctrl |= BWI_CLOCK_CTRL_IGNPLL;
7217 break;
7218 case BWI_CLOCK_MODE_SLOW:
7219 clk_ctrl |= BWI_CLOCK_CTRL_SLOW;
7220 break;
7221 case BWI_CLOCK_MODE_DYN:
7222 clk_ctrl &= ~(BWI_CLOCK_CTRL_SLOW |
7223 BWI_CLOCK_CTRL_IGNPLL |
7224 BWI_CLOCK_CTRL_NODYN);
7225 if (clk_src != BWI_CLKSRC_CS_OSC) {
7226 clk_ctrl |= BWI_CLOCK_CTRL_NODYN;
7227 pwr_off = 1;
7228 }
7229 break;
7230 }
7231 CSR_WRITE_4(sc, BWI_CLOCK_CTRL, clk_ctrl);
7232
7233 if (pwr_off)
7234 bwi_power_off(sc, 0); /* Leave PLL as it is */
7235
7236 return (bwi_regwin_switch(sc, old, NULL));
7237 }
7238
7239 static int
7240 bwi_set_clock_delay(struct bwi_softc *sc)
7241 {
7242 struct bwi_regwin *old, *com;
7243 int error;
7244
7245 com = &sc->sc_com_regwin;
7246 if (!BWI_REGWIN_EXIST(com))
7247 return (0);
7248
7249 error = bwi_regwin_switch(sc, com, &old);
7250 if (error)
7251 return (error);
7252
7253 if (sc->sc_bbp_id == BWI_BBPID_BCM4321) {
7254 if (sc->sc_bbp_rev == 0)
7255 CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC0);
7256 else if (sc->sc_bbp_rev == 1)
7257 CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC1);
7258 }
7259
7260 if (sc->sc_cap & BWI_CAP_CLKMODE) {
7261 if (com->rw_rev >= 10)
7262 CSR_FILT_SETBITS_4(sc, BWI_CLOCK_INFO, 0xffff, 0x40000);
7263 else {
7264 struct bwi_clock_freq freq;
7265
7266 bwi_get_clock_freq(sc, &freq);
7267 CSR_WRITE_4(sc, BWI_PLL_ON_DELAY,
7268 howmany(freq.clkfreq_max * 150, 1000000));
7269 CSR_WRITE_4(sc, BWI_FREQ_SEL_DELAY,
7270 howmany(freq.clkfreq_max * 15, 1000000));
7271 }
7272 }
7273
7274 return (bwi_regwin_switch(sc, old, NULL));
7275 }
7276
7277 static int
7278 bwi_init(struct ifnet *ifp)
7279 {
7280 struct bwi_softc *sc = ifp->if_softc;
7281
7282 bwi_init_statechg(sc, 1);
7283
7284 return (0);
7285 }
7286
7287 static void
7288 bwi_init_statechg(struct bwi_softc *sc, int statechg)
7289 {
7290 struct ieee80211com *ic = &sc->sc_ic;
7291 struct ifnet *ifp = &sc->sc_if;
7292 struct bwi_mac *mac;
7293 int error;
7294
7295 DPRINTF(sc, BWI_DBG_MISC, "%s\n", __func__);
7296
7297 bwi_stop(ifp, statechg);
7298
7299 /* power on cardbus socket */
7300 if (sc->sc_enable != NULL)
7301 (sc->sc_enable)(sc, 0);
7302
7303 bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST);
7304
7305 /* TODO: 2 MAC */
7306
7307 mac = &sc->sc_mac[0];
7308 error = bwi_regwin_switch(sc, &mac->mac_regwin, NULL);
7309 if (error)
7310 goto back;
7311
7312 error = bwi_mac_init(mac);
7313 if (error)
7314 goto back;
7315
7316 bwi_bbp_power_on(sc, BWI_CLOCK_MODE_DYN);
7317
7318 IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
7319
7320 bwi_set_bssid(sc, bwi_zero_addr); /* Clear BSSID */
7321 bwi_set_addr_filter(sc, BWI_ADDR_FILTER_MYADDR, ic->ic_myaddr);
7322
7323 bwi_mac_reset_hwkeys(mac);
7324
7325 if ((mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) == 0) {
7326 int i;
7327
7328 #define NRETRY 1000
7329 /*
7330 * Drain any possible pending TX status
7331 */
7332 for (i = 0; i < NRETRY; ++i) {
7333 if ((CSR_READ_4(sc, BWI_TXSTATUS_0) &
7334 BWI_TXSTATUS_0_MORE) == 0)
7335 break;
7336 CSR_READ_4(sc, BWI_TXSTATUS_1);
7337 }
7338 if (i == NRETRY)
7339 aprint_error_dev(sc->sc_dev,
7340 "can't drain TX status\n");
7341 #undef NRETRY
7342 }
7343
7344 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11G)
7345 bwi_mac_updateslot(mac, 1);
7346
7347 /* Start MAC */
7348 error = bwi_mac_start(mac);
7349 if (error)
7350 goto back;
7351
7352 ifp->if_flags |= IFF_RUNNING;
7353 ifp->if_flags &= ~IFF_OACTIVE;
7354
7355 /* Enable intrs */
7356 bwi_enable_intrs(sc, BWI_INIT_INTRS);
7357
7358 if (statechg) {
7359 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
7360 /* [TRC: XXX OpenBSD omits this conditional.] */
7361 if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
7362 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
7363 } else {
7364 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
7365 }
7366 } else {
7367 ieee80211_new_state(ic, ic->ic_state, -1);
7368 }
7369
7370 back:
7371 if (error)
7372 bwi_stop(ifp, 1);
7373 else
7374 /* [TRC: XXX DragonFlyBD uses ifp->if_start(ifp).] */
7375 bwi_start(ifp);
7376
7377 DPRINTF(sc, BWI_DBG_MISC, "%s done\n", __func__);
7378 }
7379
7380 static int
7381 bwi_ioctl(struct ifnet *ifp, u_long cmd, void *data)
7382 {
7383 struct bwi_softc *sc = ifp->if_softc;
7384 struct ieee80211com *ic = &sc->sc_ic;
7385 int s, error = 0;
7386
7387 /* [TRC: XXX Superstitiously cargo-culted from wi(4).] */
7388 if (!device_is_active(sc->sc_dev))
7389 return (ENXIO);
7390
7391 s = splnet();
7392
7393 switch (cmd) {
7394 case SIOCSIFFLAGS:
7395 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
7396 break;
7397 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
7398 (IFF_UP | IFF_RUNNING)) {
7399 struct bwi_mac *mac;
7400 int promisc = -1;
7401
7402 KASSERT(sc->sc_cur_regwin->rw_type ==
7403 BWI_REGWIN_T_MAC);
7404 mac = (struct bwi_mac *)sc->sc_cur_regwin;
7405
7406 if ((ifp->if_flags & IFF_PROMISC) &&
7407 (sc->sc_flags & BWI_F_PROMISC) == 0) {
7408 promisc = 1;
7409 sc->sc_flags |= BWI_F_PROMISC;
7410 } else if ((ifp->if_flags & IFF_PROMISC) == 0 &&
7411 (sc->sc_flags & BWI_F_PROMISC)) {
7412 promisc = 0;
7413 sc->sc_flags &= ~BWI_F_PROMISC;
7414 }
7415
7416 if (promisc >= 0)
7417 bwi_mac_set_promisc(mac, promisc);
7418 }
7419
7420 if (ifp->if_flags & IFF_UP) {
7421 if (!(ifp->if_flags & IFF_RUNNING))
7422 bwi_init(ifp);
7423 } else {
7424 if (ifp->if_flags & IFF_RUNNING)
7425 bwi_stop(ifp, 1);
7426 }
7427 break;
7428
7429 case SIOCADDMULTI:
7430 case SIOCDELMULTI:
7431 /* [TRC: Several other drivers appear to have this
7432 copied & pasted, so I'm following suit.] */
7433 /* XXX no h/w multicast filter? --dyoung */
7434 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
7435 /* setup multicast filter, etc */
7436 error = 0;
7437 }
7438 break;
7439
7440 case SIOCS80211CHANNEL:
7441 /* [TRC: Pilfered from OpenBSD. No clue whether it works.] */
7442 /* allow fast channel switching in monitor mode */
7443 error = ieee80211_ioctl(ic, cmd, data);
7444 if (error == ENETRESET &&
7445 ic->ic_opmode == IEEE80211_M_MONITOR) {
7446 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
7447 (IFF_UP | IFF_RUNNING)) {
7448 /* [TRC: XXX ????] */
7449 ic->ic_bss->ni_chan = ic->ic_ibss_chan;
7450 ic->ic_curchan = ic->ic_ibss_chan;
7451 bwi_set_chan(sc, ic->ic_bss->ni_chan);
7452 }
7453 error = 0;
7454 }
7455 break;
7456
7457 default:
7458 error = ieee80211_ioctl(ic, cmd, data);
7459 break;
7460 }
7461
7462 if (error == ENETRESET) {
7463 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
7464 (IFF_UP | IFF_RUNNING) &&
7465 /* [TRC: XXX Superstitiously cargo-culted from iwi(4). */
7466 (ic->ic_roaming != IEEE80211_ROAMING_MANUAL))
7467 bwi_init(ifp);
7468 error = 0;
7469 }
7470
7471 splx(s);
7472
7473 return (error);
7474 }
7475
7476 static void
7477 bwi_start(struct ifnet *ifp)
7478 {
7479 struct bwi_softc *sc = ifp->if_softc;
7480 struct ieee80211com *ic = &sc->sc_ic;
7481 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
7482 int trans, idx;
7483
7484 /* [TRC: XXX I'm not sure under which conditions we're actually
7485 supposed to refuse to start, so I'm copying what OpenBSD and
7486 DragonFlyBSD do, even if no one else on NetBSD does it. */
7487 if ((ifp->if_flags & IFF_OACTIVE) ||
7488 (ifp->if_flags & IFF_RUNNING) == 0)
7489 return;
7490
7491 trans = 0;
7492 idx = tbd->tbd_idx;
7493
7494 while (tbd->tbd_buf[idx].tb_mbuf == NULL) {
7495 struct ieee80211_frame *wh;
7496 struct ieee80211_node *ni;
7497 struct mbuf *m;
7498 int mgt_pkt = 0;
7499
7500 IF_DEQUEUE(&ic->ic_mgtq, m);
7501 if (m != NULL) {
7502 ni = M_GETCTX(m, struct ieee80211_node *);
7503 M_CLEARCTX(m);
7504
7505 mgt_pkt = 1;
7506 } else {
7507 struct ether_header *eh;
7508
7509 if (ic->ic_state != IEEE80211_S_RUN)
7510 break;
7511
7512 IFQ_DEQUEUE(&ifp->if_snd, m);
7513 if (m == NULL)
7514 break;
7515
7516 if (m->m_len < sizeof(*eh)) {
7517 m = m_pullup(m, sizeof(*eh));
7518 if (m == NULL) {
7519 if_statinc(ifp, if_oerrors);
7520 continue;
7521 }
7522 }
7523 eh = mtod(m, struct ether_header *);
7524
7525 ni = ieee80211_find_txnode(ic, eh->ether_dhost);
7526 if (ni == NULL) {
7527 if_statinc(ifp, if_oerrors);
7528 m_freem(m);
7529 continue;
7530 }
7531
7532 /* [TRC: XXX Superstitiously cargo-culted from
7533 ath(4) and wi(4).] */
7534 if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
7535 (m->m_flags & M_PWR_SAV) == 0) {
7536 ieee80211_pwrsave(ic, ni, m);
7537 ieee80211_free_node(ni);
7538 continue;
7539 }
7540
7541 /* [TRC: XXX I *think* we're supposed to do
7542 this, but honestly I have no clue. We don't
7543 use M_WME_GETAC, so...] */
7544 if (ieee80211_classify(ic, m, ni)) {
7545 /* [TRC: XXX What debug flag?] */
7546 DPRINTF(sc, BWI_DBG_MISC,
7547 "%s: discard, classification failure\n",
7548 __func__);
7549 if_statinc(ifp, if_oerrors);
7550 m_freem(m);
7551 ieee80211_free_node(ni);
7552 continue;
7553 }
7554
7555 /* [TRC: XXX wi(4) and awi(4) do this; iwi(4)
7556 doesn't.] */
7557 if_statinc(ifp, if_opackets);
7558
7559 /* [TRC: XXX When should the packet be
7560 filtered? Different drivers appear to do it
7561 at different times.] */
7562 /* TODO: PS */
7563 bpf_mtap(ifp, m, BPF_D_OUT);
7564 m = ieee80211_encap(ic, m, ni);
7565 if (m == NULL) {
7566 if_statinc(ifp, if_oerrors);
7567 ieee80211_free_node(ni);
7568 continue;
7569 }
7570 }
7571 bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT);
7572
7573 wh = mtod(m, struct ieee80211_frame *);
7574 /* [TRC: XXX What about ic->ic_flags & IEEE80211_F_PRIVACY?] */
7575 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
7576 if (ieee80211_crypto_encap(ic, ni, m) == NULL) {
7577 if_statinc(ifp, if_oerrors);
7578 m_freem(m);
7579 ieee80211_free_node(ni);
7580 continue;
7581 }
7582 }
7583 wh = NULL; /* [TRC: XXX Huh?] */
7584
7585 if (bwi_encap(sc, idx, m, &ni, mgt_pkt) != 0) {
7586 /* 'm' is freed in bwi_encap() if we reach here */
7587 if_statinc(ifp, if_oerrors);
7588 if (ni != NULL)
7589 ieee80211_free_node(ni);
7590 continue;
7591 }
7592
7593 trans = 1;
7594 tbd->tbd_used++;
7595 idx = (idx + 1) % BWI_TX_NDESC;
7596
7597 if (tbd->tbd_used + BWI_TX_NSPRDESC >=
7598 (BWI_IS_SDIO(sc) ? 32 : BWI_TX_NDESC)) {
7599 ifp->if_flags |= IFF_OACTIVE;
7600 break;
7601 }
7602 }
7603 tbd->tbd_idx = idx;
7604
7605 if (trans)
7606 sc->sc_tx_timer = 5;
7607 ifp->if_timer = 1;
7608
7609 if (BWI_IS_PIO(sc)) {
7610 mutex_enter(&sc->sc_pio_txlock);
7611 if (!STAILQ_EMPTY(&sc->sc_pio_txpend)) {
7612 struct bwi_task *t;
7613
7614 t = pool_cache_get(sc->sc_freetask, PR_NOWAIT);
7615 if (t == NULL) {
7616 device_printf(sc->sc_dev, "no free tasks\n");
7617 } else {
7618 t->t_ic = &sc->sc_ic;
7619 t->t_cmd = BWI_TASK_TX;
7620 workqueue_enqueue(sc->sc_taskq, &t->t_work,
7621 NULL);
7622 }
7623 }
7624 mutex_exit(&sc->sc_pio_txlock);
7625 }
7626 }
7627
7628 static void
7629 bwi_watchdog(struct ifnet *ifp)
7630 {
7631 struct bwi_softc *sc = ifp->if_softc;
7632
7633 ifp->if_timer = 0;
7634
7635 if ((ifp->if_flags & IFF_RUNNING) == 0 ||
7636 !device_is_active(sc->sc_dev))
7637 return;
7638
7639 if (sc->sc_tx_timer) {
7640 if (--sc->sc_tx_timer == 0) {
7641 aprint_error_dev(sc->sc_dev, "device timeout\n");
7642 if_statinc(ifp, if_oerrors);
7643 /* TODO */
7644 /* [TRC: XXX TODO what? Stop the device?
7645 Bring it down? iwi(4) does this.] */
7646 } else
7647 ifp->if_timer = 1;
7648 }
7649
7650 ieee80211_watchdog(&sc->sc_ic);
7651 }
7652
7653 static void
7654 bwi_stop(struct ifnet *ifp, int state_chg)
7655 {
7656 struct bwi_softc *sc = ifp->if_softc;
7657 struct ieee80211com *ic = &sc->sc_ic;
7658 struct bwi_mac *mac;
7659 int i, error, pwr_off = 0;
7660
7661 DPRINTF(sc, BWI_DBG_MISC, "%s\n", __func__);
7662
7663 if (state_chg)
7664 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
7665 else
7666 bwi_newstate_begin(sc, IEEE80211_S_INIT);
7667
7668 if (ifp->if_flags & IFF_RUNNING) {
7669 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
7670 mac = (struct bwi_mac *)sc->sc_cur_regwin;
7671
7672 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
7673
7674 bwi_disable_intrs(sc, BWI_ALL_INTRS);
7675 CSR_READ_4(sc, BWI_MAC_INTR_MASK);
7676 bwi_mac_stop(mac);
7677 }
7678
7679 for (i = 0; i < sc->sc_nmac; ++i) {
7680 struct bwi_regwin *old_rw;
7681
7682 mac = &sc->sc_mac[i];
7683 if ((mac->mac_flags & BWI_MAC_F_INITED) == 0)
7684 continue;
7685
7686 error = bwi_regwin_switch(sc, &mac->mac_regwin, &old_rw);
7687 if (error)
7688 continue;
7689
7690 bwi_mac_shutdown(mac);
7691 pwr_off = 1;
7692
7693 bwi_regwin_switch(sc, old_rw, NULL);
7694 }
7695
7696 if (pwr_off)
7697 bwi_bbp_power_off(sc);
7698
7699 sc->sc_tx_timer = 0;
7700 ifp->if_timer = 0;
7701 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
7702
7703 /* power off cardbus socket */
7704 if (sc->sc_disable != NULL)
7705 (sc->sc_disable)(sc, 0);
7706
7707 return;
7708 }
7709
7710 static void
7711 bwi_newstate_begin(struct bwi_softc *sc, enum ieee80211_state nstate)
7712 {
7713 callout_stop(&sc->sc_scan_ch);
7714 callout_stop(&sc->sc_calib_ch);
7715
7716 bwi_led_newstate(sc, nstate);
7717
7718 if (nstate == IEEE80211_S_INIT)
7719 sc->sc_txpwrcb_type = BWI_TXPWR_INIT;
7720 }
7721
7722 static int
7723 bwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
7724 {
7725 struct bwi_softc *sc = ic->ic_ifp->if_softc;
7726 struct ieee80211_node *ni;
7727 int error;
7728
7729 /* [TRC: XXX amrr] */
7730 callout_stop(&sc->sc_amrr_ch);
7731
7732 bwi_newstate_begin(sc, nstate);
7733
7734 if (nstate == IEEE80211_S_INIT)
7735 goto back;
7736
7737 /* [TRC: XXX What channel do we set this to? */
7738 error = bwi_set_chan(sc, ic->ic_curchan);
7739 if (error) {
7740 aprint_error_dev(sc->sc_dev, "can't set channel to %u\n",
7741 ieee80211_chan2ieee(ic, ic->ic_curchan));
7742 return (error);
7743 }
7744
7745 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
7746 /* Nothing to do */
7747 } else if (nstate == IEEE80211_S_RUN) {
7748 struct bwi_mac *mac;
7749
7750 ni = ic->ic_bss;
7751
7752 bwi_set_bssid(sc, ic->ic_bss->ni_bssid);
7753
7754 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
7755 mac = (struct bwi_mac *)sc->sc_cur_regwin;
7756
7757 /* Initial TX power calibration */
7758 bwi_mac_calibrate_txpower(mac, BWI_TXPWR_INIT);
7759 #ifdef notyet
7760 sc->sc_txpwrcb_type = BWI_TXPWR_FORCE;
7761 #else
7762 sc->sc_txpwrcb_type = BWI_TXPWR_CALIB;
7763 #endif
7764 /* [TRC: XXX amrr] */
7765 if (ic->ic_opmode == IEEE80211_M_STA) {
7766 /* fake a join to init the tx rate */
7767 bwi_newassoc(ni, 1);
7768 }
7769
7770 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
7771 /* start automatic rate control timer */
7772 if (ic->ic_fixed_rate == -1)
7773 callout_schedule(&sc->sc_amrr_ch, hz / 2);
7774 }
7775 } else
7776 bwi_set_bssid(sc, bwi_zero_addr);
7777
7778 back:
7779 error = (sc->sc_newstate)(ic, nstate, arg);
7780
7781 if (nstate == IEEE80211_S_SCAN) {
7782 callout_schedule(&sc->sc_scan_ch,
7783 (sc->sc_dwell_time * hz) / 1000);
7784 } else if (nstate == IEEE80211_S_RUN) {
7785 /* XXX 15 seconds */
7786 callout_schedule(&sc->sc_calib_ch, hz);
7787 }
7788
7789 return (error);
7790 }
7791
7792 static int
7793 bwi_newstate_sdio(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
7794 {
7795 struct bwi_softc *sc = ic->ic_ifp->if_softc;
7796 struct bwi_task *t;
7797
7798 t = pool_cache_get(sc->sc_freetask, PR_NOWAIT);
7799 if (t == NULL) {
7800 device_printf(sc->sc_dev, "no free tasks\n");
7801 return EIO;
7802 }
7803
7804 t->t_ic = ic;
7805 t->t_cmd = BWI_TASK_NEWSTATE;
7806 t->t_newstate.state = nstate;
7807 t->t_newstate.arg = arg;
7808 workqueue_enqueue(sc->sc_taskq, &t->t_work, NULL);
7809
7810 return 0;
7811 }
7812
7813 static inline bool
7814 bwi_tx_fifo_pkt_valid(struct bwi_softc *sc, u_int len)
7815 {
7816 return len >= sizeof(uint32_t) && len <= sc->sc_pio_fifolen;
7817 }
7818
7819 static inline bool
7820 bwi_tx_fifo_avail(struct bwi_softc *sc, u_int len)
7821 {
7822 return len <= sc->sc_pio_fifoavail;
7823 }
7824
7825 static void
7826 bwi_tx_frame_data_pio(struct bwi_softc *sc, u_int idx, uint32_t *ctl,
7827 uint8_t *buf, u_int buflen)
7828 {
7829 size_t count;
7830
7831 *ctl |= BWI_PIO_TXCTL_VALID_BYTES(4);
7832 CSR_WRITE_4(sc, BWI_PIO_TXCTL(idx), *ctl);
7833
7834 count = buflen / sizeof(uint32_t);
7835 CSR_WRITE_MULTI_4(sc, BWI_PIO_TXDATA(idx), (uint32_t *)buf, count);
7836 buf += count * sizeof(uint32_t);
7837 buflen -= count * sizeof(uint32_t);
7838 if (buflen != 0) {
7839 uint32_t data = 0;
7840
7841 *ctl &= ~BWI_PIO_TXCTL_VALID;
7842 *ctl |= BWI_PIO_TXCTL_VALID_BYTES(buflen);
7843 CSR_WRITE_4(sc, BWI_PIO_TXCTL(idx), *ctl);
7844
7845 memcpy(&data, buf, buflen);
7846 CSR_WRITE_MULTI_4(sc, BWI_PIO_TXDATA(idx), &data, 1);
7847 }
7848 }
7849
7850 static void
7851 bwi_tx_frame_pio(struct bwi_softc *sc, struct bwi_txbuf *tb)
7852 {
7853 struct mbuf *m = tb->tb_mbuf;
7854 const u_int idx = BWI_TX_DATA_RING;
7855 uint32_t ctl;
7856 uint8_t *txbuf = sc->sc_pio_databuf;
7857 u_int pktlen = m_length(m);
7858
7859 m_copydata(m, 0, pktlen, txbuf);
7860
7861 ctl = CSR_READ_4(sc, BWI_PIO_TXCTL(idx));
7862 ctl |= BWI_PIO_TXCTL_FREADY;
7863 ctl &= ~BWI_PIO_TXCTL_EOF;
7864
7865 bwi_tx_frame_data_pio(sc, idx, &ctl, txbuf, pktlen);
7866
7867 ctl |= BWI_PIO_TXCTL_EOF;
7868 CSR_WRITE_4(sc, BWI_PIO_TXCTL(idx), ctl);
7869 }
7870
7871 static void
7872 bwi_tx_pending(struct bwi_softc *sc)
7873 {
7874 struct ifnet *ifp = &sc->sc_if;
7875 struct bwi_txbuf *tb;
7876
7877 mutex_enter(&sc->sc_pio_txlock);
7878 while ((tb = STAILQ_FIRST(&sc->sc_pio_txpend)) != NULL) {
7879 const u_int pktlen = m_length(tb->tb_mbuf);
7880
7881 if (!bwi_tx_fifo_pkt_valid(sc, pktlen)) {
7882 device_printf(sc->sc_dev,
7883 "dropping large packet (%u bytes)\n", pktlen);
7884
7885 STAILQ_REMOVE_HEAD(&sc->sc_pio_txpend, tb_entry);
7886 if_statinc(ifp, if_oerrors);
7887 m_freem(tb->tb_mbuf);
7888 tb->tb_mbuf = NULL;
7889 continue;
7890 }
7891
7892 if (!bwi_tx_fifo_avail(sc, pktlen)) {
7893 break;
7894 }
7895
7896 STAILQ_REMOVE_HEAD(&sc->sc_pio_txpend, tb_entry);
7897
7898 sc->sc_pio_fifoavail -= roundup(pktlen, 4);
7899 mutex_exit(&sc->sc_pio_txlock);
7900
7901 bwi_tx_frame_pio(sc, tb);
7902
7903 mutex_enter(&sc->sc_pio_txlock);
7904 }
7905 mutex_exit(&sc->sc_pio_txlock);
7906 }
7907
7908 static void
7909 bwi_task(struct work *wk, void *arg)
7910 {
7911 struct bwi_task *t = (struct bwi_task *)wk;
7912 struct ieee80211com *ic = t->t_ic;
7913 struct bwi_softc *sc = ic->ic_ifp->if_softc;
7914
7915 switch (t->t_cmd) {
7916 case BWI_TASK_NEWSTATE:
7917 bwi_newstate(ic, t->t_newstate.state, t->t_newstate.arg);
7918 break;
7919 case BWI_TASK_UPDATESLOT:
7920 bwi_updateslot(ic->ic_ifp);
7921 break;
7922 case BWI_TASK_TX:
7923 bwi_tx_pending(sc);
7924 break;
7925 case BWI_TASK_INIT:
7926 bwi_init(ic->ic_ifp);
7927 break;
7928 case BWI_TASK_CALIBRATE:
7929 bwi_do_calibrate(sc);
7930 break;
7931 default:
7932 panic("bwi: unknown task command %d", t->t_cmd);
7933 }
7934
7935 pool_cache_put(sc->sc_freetask, t);
7936 }
7937
7938 static int
7939 bwi_media_change(struct ifnet *ifp)
7940 {
7941 struct bwi_softc *sc = ifp->if_softc;
7942 int error;
7943
7944 error = ieee80211_media_change(ifp);
7945 if (error != ENETRESET)
7946 return (error);
7947
7948 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) {
7949 if (BWI_IS_SDIO(sc)) {
7950 struct bwi_task *t;
7951
7952 t = pool_cache_get(sc->sc_freetask, PR_NOWAIT);
7953 if (t == NULL) {
7954 device_printf(sc->sc_dev, "no free tasks\n");
7955 return (ENOBUFS);
7956 }
7957
7958 t->t_ic = &sc->sc_ic;
7959 t->t_cmd = BWI_TASK_INIT;
7960 workqueue_enqueue(sc->sc_taskq, &t->t_work, NULL);
7961 } else {
7962 bwi_init(ifp);
7963 }
7964 }
7965
7966 return (0);
7967 }
7968
7969 /* [TRC: XXX amrr] */
7970 static void
7971 bwi_iter_func(void *arg, struct ieee80211_node *ni)
7972 {
7973 struct bwi_softc *sc = arg;
7974 struct bwi_node *bn = (struct bwi_node *)ni;
7975
7976 ieee80211_amrr_choose(&sc->sc_amrr, ni, &bn->amn);
7977 }
7978
7979 static void
7980 bwi_amrr_timeout(void *arg)
7981 {
7982 struct bwi_softc *sc = arg;
7983 struct ieee80211com *ic = &sc->sc_ic;
7984 int s;
7985
7986 s = splnet();
7987 if (ic->ic_opmode == IEEE80211_M_STA)
7988 bwi_iter_func(sc, ic->ic_bss);
7989 else
7990 /* [TRC: XXX I'm making a wild guess about what to
7991 supply for the node table.] */
7992 ieee80211_iterate_nodes(&ic->ic_sta, bwi_iter_func, sc);
7993
7994 callout_schedule(&sc->sc_amrr_ch, hz / 2);
7995 splx(s);
7996 }
7997
7998 static void
7999 bwi_newassoc(struct ieee80211_node *ni, int isnew)
8000 {
8001 struct ieee80211com *ic = ni->ni_ic;
8002 struct bwi_softc *sc = ic->ic_ifp->if_softc;
8003 int i;
8004
8005 DPRINTF(sc, BWI_DBG_STATION, "%s\n", __func__);
8006
8007 ieee80211_amrr_node_init(&sc->sc_amrr, &((struct bwi_node *)ni)->amn);
8008
8009 /* set rate to some reasonable initial value */
8010 for (i = ni->ni_rates.rs_nrates - 1;
8011 i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72;
8012 i--);
8013
8014 ni->ni_txrate = i;
8015 }
8016
8017 static struct ieee80211_node *
8018 bwi_node_alloc(struct ieee80211_node_table *nt)
8019 {
8020 struct bwi_node *bn;
8021
8022 bn = malloc(sizeof(struct bwi_node), M_80211_NODE, M_NOWAIT | M_ZERO);
8023
8024 return ((struct ieee80211_node *)bn);
8025 }
8026 /* [TRC: XXX amrr end] */
8027
8028 static int
8029 bwi_pio_alloc(struct bwi_softc *sc)
8030 {
8031 struct bwi_mac *mac = &sc->sc_mac[0];
8032 int i, j, has_txstats;
8033
8034 KASSERT(BWI_IS_PIO(sc));
8035
8036 if (mac->mac_rev < 8) {
8037 aprint_error_dev(sc->sc_dev,
8038 "driver does not support MAC rev %u in PIO mode\n",
8039 mac->mac_rev);
8040 return EINVAL;
8041 }
8042
8043 has_txstats = (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) != 0;
8044
8045 sc->sc_init_tx_ring = bwi_init_tx_ring_pio;
8046 sc->sc_free_tx_ring = bwi_free_tx_ring_pio;
8047 sc->sc_init_rx_ring = bwi_init_rx_ring_pio;
8048 sc->sc_free_rx_ring = bwi_free_rx_ring_pio;
8049 sc->sc_setup_rxdesc = bwi_setup_rx_desc_pio;
8050 sc->sc_setup_txdesc = bwi_setup_tx_desc_pio;
8051 sc->sc_rxeof = bwi_rxeof_pio;
8052 sc->sc_start_tx = bwi_start_tx_pio;
8053 if (has_txstats) {
8054 sc->sc_init_txstats = bwi_init_txstats_pio;
8055 sc->sc_free_txstats = bwi_free_txstats_pio;
8056 sc->sc_txeof_status = bwi_txeof_status_pio;
8057 }
8058
8059 mutex_init(&sc->sc_pio_txlock, MUTEX_DEFAULT, IPL_SOFTNET);
8060 STAILQ_INIT(&sc->sc_pio_txpend);
8061
8062 sc->sc_pio_fifolen = 2000 - 80;
8063 sc->sc_pio_fifoavail = sc->sc_pio_fifolen;
8064
8065 sc->sc_pio_databuf = kmem_alloc(sc->sc_pio_fifolen, KM_SLEEP);
8066
8067 for (i = 0; i < BWI_TX_NRING; ++i) {
8068 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
8069 for (j = 0; j < BWI_TX_NDESC; ++j) {
8070 tbd->tbd_buf[j].tb_data = tbd;
8071 }
8072 }
8073
8074 return 0;
8075 }
8076
8077 static void
8078 bwi_pio_free(struct bwi_softc *sc)
8079 {
8080 KASSERT(BWI_IS_PIO(sc));
8081
8082 kmem_free(sc->sc_pio_databuf, sc->sc_pio_fifolen);
8083 mutex_destroy(&sc->sc_pio_txlock);
8084 }
8085
8086 static int
8087 bwi_dma_alloc(struct bwi_softc *sc)
8088 {
8089 int error, i, has_txstats;
8090 /* [TRC: XXX DragonFlyBSD adjusts the low address for different
8091 bus spaces. Should we?] */
8092 bus_size_t tx_ring_sz, rx_ring_sz, desc_sz = 0;
8093 uint32_t txrx_ctrl_step = 0;
8094
8095 KASSERT(!BWI_IS_PIO(sc));
8096
8097 has_txstats = 0;
8098 for (i = 0; i < sc->sc_nmac; ++i) {
8099 if (sc->sc_mac[i].mac_flags & BWI_MAC_F_HAS_TXSTATS) {
8100 has_txstats = 1;
8101 break;
8102 }
8103 }
8104
8105 switch (sc->sc_bus_space) {
8106 case BWI_BUS_SPACE_30BIT:
8107 case BWI_BUS_SPACE_32BIT:
8108 desc_sz = sizeof(struct bwi_desc32);
8109 txrx_ctrl_step = 0x20;
8110
8111 sc->sc_init_tx_ring = bwi_init_tx_ring32;
8112 sc->sc_free_tx_ring = bwi_free_tx_ring32;
8113 sc->sc_init_rx_ring = bwi_init_rx_ring32;
8114 sc->sc_free_rx_ring = bwi_free_rx_ring32;
8115 sc->sc_setup_rxdesc = bwi_setup_rx_desc32;
8116 sc->sc_setup_txdesc = bwi_setup_tx_desc32;
8117 sc->sc_rxeof = bwi_rxeof32;
8118 sc->sc_start_tx = bwi_start_tx32;
8119 if (has_txstats) {
8120 sc->sc_init_txstats = bwi_init_txstats32;
8121 sc->sc_free_txstats = bwi_free_txstats32;
8122 sc->sc_txeof_status = bwi_txeof_status32;
8123 }
8124 break;
8125
8126 case BWI_BUS_SPACE_64BIT:
8127 desc_sz = sizeof(struct bwi_desc64);
8128 txrx_ctrl_step = 0x40;
8129
8130 sc->sc_init_tx_ring = bwi_init_tx_ring64;
8131 sc->sc_free_tx_ring = bwi_free_tx_ring64;
8132 sc->sc_init_rx_ring = bwi_init_rx_ring64;
8133 sc->sc_free_rx_ring = bwi_free_rx_ring64;
8134 sc->sc_setup_rxdesc = bwi_setup_rx_desc64;
8135 sc->sc_setup_txdesc = bwi_setup_tx_desc64;
8136 sc->sc_rxeof = bwi_rxeof64;
8137 sc->sc_start_tx = bwi_start_tx64;
8138 if (has_txstats) {
8139 sc->sc_init_txstats = bwi_init_txstats64;
8140 sc->sc_free_txstats = bwi_free_txstats64;
8141 sc->sc_txeof_status = bwi_txeof_status64;
8142 }
8143 break;
8144 }
8145
8146 KASSERT(desc_sz != 0);
8147 KASSERT(txrx_ctrl_step != 0);
8148
8149 tx_ring_sz = roundup(desc_sz * BWI_TX_NDESC, BWI_RING_ALIGN);
8150 rx_ring_sz = roundup(desc_sz * BWI_RX_NDESC, BWI_RING_ALIGN);
8151
8152 /* [TRC: XXX Using OpenBSD's code, which is rather different
8153 from DragonFlyBSD's.] */
8154 #define TXRX_CTRL(idx) (BWI_TXRX_CTRL_BASE + (idx) * txrx_ctrl_step)
8155 /*
8156 * Create TX ring DMA stuffs
8157 */
8158 for (i = 0; i < BWI_TX_NRING; ++i) {
8159 error = bus_dmamap_create(sc->sc_dmat, tx_ring_sz, 1,
8160 tx_ring_sz, 0, BUS_DMA_NOWAIT,
8161 &sc->sc_tx_rdata[i].rdata_dmap);
8162 if (error) {
8163 aprint_error_dev(sc->sc_dev,
8164 "%dth TX ring DMA create failed\n", i);
8165 return (error);
8166 }
8167 error = bwi_dma_ring_alloc(sc,
8168 &sc->sc_tx_rdata[i], tx_ring_sz, TXRX_CTRL(i));
8169 if (error) {
8170 aprint_error_dev(sc->sc_dev,
8171 "%dth TX ring DMA alloc failed\n", i);
8172 return (error);
8173 }
8174 }
8175
8176 /*
8177 * Create RX ring DMA stuffs
8178 */
8179 error = bus_dmamap_create(sc->sc_dmat, rx_ring_sz, 1,
8180 rx_ring_sz, 0, BUS_DMA_NOWAIT,
8181 &sc->sc_rx_rdata.rdata_dmap);
8182 if (error) {
8183 aprint_error_dev(sc->sc_dev, "RX ring DMA create failed\n");
8184 return (error);
8185 }
8186
8187 error = bwi_dma_ring_alloc(sc, &sc->sc_rx_rdata,
8188 rx_ring_sz, TXRX_CTRL(0));
8189 if (error) {
8190 aprint_error_dev(sc->sc_dev, "RX ring DMA alloc failed\n");
8191 return (error);
8192 }
8193
8194 if (has_txstats) {
8195 error = bwi_dma_txstats_alloc(sc, TXRX_CTRL(3), desc_sz);
8196 if (error) {
8197 aprint_error_dev(sc->sc_dev,
8198 "TX stats DMA alloc failed\n");
8199 return (error);
8200 }
8201 }
8202 #undef TXRX_CTRL
8203
8204 return (bwi_dma_mbuf_create(sc));
8205 }
8206
8207 static void
8208 bwi_dma_free(struct bwi_softc *sc)
8209 {
8210 int i;
8211
8212 KASSERT(!BWI_IS_PIO(sc));
8213
8214 for (i = 0; i < BWI_TX_NRING; ++i)
8215 bwi_ring_data_free(&sc->sc_tx_rdata[i], sc);
8216
8217 bwi_ring_data_free(&sc->sc_rx_rdata, sc);
8218 bwi_dma_txstats_free(sc);
8219 bwi_dma_mbuf_destroy(sc, BWI_TX_NRING, 1);
8220 }
8221
8222 static void
8223 bwi_ring_data_free(struct bwi_ring_data *rd, struct bwi_softc *sc)
8224 {
8225 if (rd->rdata_desc != NULL) {
8226 bus_dmamap_unload(sc->sc_dmat, rd->rdata_dmap);
8227 bus_dmamem_free(sc->sc_dmat, &rd->rdata_seg, 1);
8228 }
8229 }
8230
8231 static int
8232 bwi_dma_ring_alloc(struct bwi_softc *sc,
8233 struct bwi_ring_data *rd, bus_size_t size, uint32_t txrx_ctrl)
8234 {
8235 int error, nsegs;
8236
8237 error = bus_dmamem_alloc(sc->sc_dmat, size, BWI_ALIGN, 0,
8238 &rd->rdata_seg, 1, &nsegs, BUS_DMA_NOWAIT);
8239 if (error) {
8240 aprint_error_dev(sc->sc_dev, "can't allocate DMA mem\n");
8241 return (error);
8242 }
8243
8244 error = bus_dmamem_map(sc->sc_dmat, &rd->rdata_seg, nsegs,
8245 size, (void **)&rd->rdata_desc, BUS_DMA_NOWAIT);
8246 if (error) {
8247 aprint_error_dev(sc->sc_dev, "can't map DMA mem\n");
8248 return (error);
8249 }
8250
8251 error = bus_dmamap_load(sc->sc_dmat, rd->rdata_dmap, rd->rdata_desc,
8252 size, NULL, BUS_DMA_WAITOK);
8253 if (error) {
8254 aprint_error_dev(sc->sc_dev, "can't load DMA mem\n");
8255 bus_dmamem_free(sc->sc_dmat, &rd->rdata_seg, nsegs);
8256 rd->rdata_desc = NULL;
8257 return (error);
8258 }
8259
8260 rd->rdata_paddr = rd->rdata_dmap->dm_segs[0].ds_addr;
8261 rd->rdata_txrx_ctrl = txrx_ctrl;
8262
8263 return (0);
8264 }
8265
8266 static int
8267 bwi_dma_txstats_alloc(struct bwi_softc *sc, uint32_t ctrl_base,
8268 bus_size_t desc_sz)
8269 {
8270 struct bwi_txstats_data *st;
8271 bus_size_t dma_size;
8272 int error, nsegs;
8273
8274 st = malloc(sizeof(*st), M_DEVBUF, M_WAITOK | M_ZERO);
8275 sc->sc_txstats = st;
8276
8277 /*
8278 * Create TX stats descriptor DMA stuffs
8279 */
8280 dma_size = roundup(desc_sz * BWI_TXSTATS_NDESC, BWI_RING_ALIGN);
8281
8282 error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0,
8283 BUS_DMA_NOWAIT, &st->stats_ring_dmap);
8284 if (error) {
8285 aprint_error_dev(sc->sc_dev,
8286 "can't create txstats ring DMA mem\n");
8287 return (error);
8288 }
8289
8290 error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_RING_ALIGN, 0,
8291 &st->stats_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT);
8292 if (error) {
8293 aprint_error_dev(sc->sc_dev,
8294 "can't allocate txstats ring DMA mem\n");
8295 return (error);
8296 }
8297
8298 error = bus_dmamem_map(sc->sc_dmat, &st->stats_ring_seg, nsegs,
8299 dma_size, (void **)&st->stats_ring, BUS_DMA_NOWAIT);
8300 if (error) {
8301 aprint_error_dev(sc->sc_dev,
8302 "can't map txstats ring DMA mem\n");
8303 return (error);
8304 }
8305
8306 error = bus_dmamap_load(sc->sc_dmat, st->stats_ring_dmap,
8307 st->stats_ring, dma_size, NULL, BUS_DMA_WAITOK);
8308 if (error) {
8309 aprint_error_dev(sc->sc_dev,
8310 "can't load txstats ring DMA mem\n");
8311 bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, nsegs);
8312 return (error);
8313 }
8314
8315 memset(st->stats_ring, 0, dma_size);
8316 st->stats_ring_paddr = st->stats_ring_dmap->dm_segs[0].ds_addr;
8317
8318 /*
8319 * Create TX stats DMA stuffs
8320 */
8321 dma_size = roundup(sizeof(struct bwi_txstats) * BWI_TXSTATS_NDESC,
8322 BWI_ALIGN);
8323
8324 error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0,
8325 BUS_DMA_NOWAIT, &st->stats_dmap);
8326 if (error) {
8327 aprint_error_dev(sc->sc_dev,
8328 "can't create txstats ring DMA mem\n");
8329 return (error);
8330 }
8331
8332 error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_ALIGN, 0,
8333 &st->stats_seg, 1, &nsegs, BUS_DMA_NOWAIT);
8334 if (error) {
8335 aprint_error_dev(sc->sc_dev,
8336 "can't allocate txstats DMA mem\n");
8337 return (error);
8338 }
8339
8340 error = bus_dmamem_map(sc->sc_dmat, &st->stats_seg, nsegs,
8341 dma_size, (void **)&st->stats, BUS_DMA_NOWAIT);
8342 if (error) {
8343 aprint_error_dev(sc->sc_dev, "can't map txstats DMA mem\n");
8344 return (error);
8345 }
8346
8347 error = bus_dmamap_load(sc->sc_dmat, st->stats_dmap, st->stats,
8348 dma_size, NULL, BUS_DMA_WAITOK);
8349 if (error) {
8350 aprint_error_dev(sc->sc_dev, "can't load txstats DMA mem\n");
8351 bus_dmamem_free(sc->sc_dmat, &st->stats_seg, nsegs);
8352 return (error);
8353 }
8354
8355 memset(st->stats, 0, dma_size);
8356 st->stats_paddr = st->stats_dmap->dm_segs[0].ds_addr;
8357 st->stats_ctrl_base = ctrl_base;
8358
8359 return (0);
8360 }
8361
8362 static void
8363 bwi_dma_txstats_free(struct bwi_softc *sc)
8364 {
8365 struct bwi_txstats_data *st;
8366
8367 if (sc->sc_txstats == NULL)
8368 return;
8369 st = sc->sc_txstats;
8370
8371 bus_dmamap_unload(sc->sc_dmat, st->stats_ring_dmap);
8372 bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, 1);
8373
8374 bus_dmamap_unload(sc->sc_dmat, st->stats_dmap);
8375 bus_dmamem_free(sc->sc_dmat, &st->stats_seg, 1);
8376
8377 free(st, M_DEVBUF);
8378 }
8379
8380 static int
8381 bwi_dma_mbuf_create(struct bwi_softc *sc)
8382 {
8383 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8384 int i, j, k, ntx, error;
8385
8386 ntx = 0;
8387
8388 /*
8389 * Create TX mbuf DMA map
8390 */
8391 for (i = 0; i < BWI_TX_NRING; ++i) {
8392 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
8393
8394 for (j = 0; j < BWI_TX_NDESC; ++j) {
8395 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
8396 0, BUS_DMA_NOWAIT, &tbd->tbd_buf[j].tb_dmap);
8397 if (error) {
8398 aprint_error_dev(sc->sc_dev,
8399 "can't create %dth tbd, %dth DMA map\n",
8400 i, j);
8401 ntx = i;
8402 for (k = 0; k < j; ++k) {
8403 bus_dmamap_destroy(sc->sc_dmat,
8404 tbd->tbd_buf[k].tb_dmap);
8405 }
8406 goto fail;
8407 }
8408 }
8409 }
8410 ntx = BWI_TX_NRING;
8411
8412 /*
8413 * Create RX mbuf DMA map and a spare DMA map
8414 */
8415 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0,
8416 BUS_DMA_NOWAIT, &rbd->rbd_tmp_dmap);
8417 if (error) {
8418 aprint_error_dev(sc->sc_dev,
8419 "can't create spare RX buf DMA map\n");
8420 goto fail;
8421 }
8422
8423 for (j = 0; j < BWI_RX_NDESC; ++j) {
8424 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0,
8425 BUS_DMA_NOWAIT, &rbd->rbd_buf[j].rb_dmap);
8426 if (error) {
8427 aprint_error_dev(sc->sc_dev,
8428 "can't create %dth RX buf DMA map\n", j);
8429
8430 for (k = 0; k < j; ++k) {
8431 bus_dmamap_destroy(sc->sc_dmat,
8432 rbd->rbd_buf[j].rb_dmap);
8433 }
8434 bus_dmamap_destroy(sc->sc_dmat,
8435 rbd->rbd_tmp_dmap);
8436 goto fail;
8437 }
8438 }
8439
8440 return (0);
8441 fail:
8442 bwi_dma_mbuf_destroy(sc, ntx, 0);
8443
8444 return (error);
8445 }
8446
8447 static void
8448 bwi_dma_mbuf_destroy(struct bwi_softc *sc, int ntx, int nrx)
8449 {
8450 int i, j;
8451
8452 for (i = 0; i < ntx; ++i) {
8453 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
8454
8455 for (j = 0; j < BWI_TX_NDESC; ++j) {
8456 struct bwi_txbuf *tb = &tbd->tbd_buf[j];
8457
8458 if (tb->tb_mbuf != NULL) {
8459 bus_dmamap_unload(sc->sc_dmat,
8460 tb->tb_dmap);
8461 m_freem(tb->tb_mbuf);
8462 }
8463 if (tb->tb_ni != NULL)
8464 ieee80211_free_node(tb->tb_ni);
8465 bus_dmamap_destroy(sc->sc_dmat, tb->tb_dmap);
8466 }
8467 }
8468
8469 if (nrx) {
8470 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8471
8472 bus_dmamap_destroy(sc->sc_dmat, rbd->rbd_tmp_dmap);
8473 for (j = 0; j < BWI_RX_NDESC; ++j) {
8474 struct bwi_rxbuf *rb = &rbd->rbd_buf[j];
8475
8476 if (rb->rb_mbuf != NULL) {
8477 bus_dmamap_unload(sc->sc_dmat,
8478 rb->rb_dmap);
8479 m_freem(rb->rb_mbuf);
8480 }
8481 bus_dmamap_destroy(sc->sc_dmat, rb->rb_dmap);
8482 }
8483 }
8484 }
8485
8486 static void
8487 bwi_enable_intrs(struct bwi_softc *sc, uint32_t enable_intrs)
8488 {
8489 DPRINTF(sc, BWI_DBG_INTR, "enable_intrs 0x%08x\n", enable_intrs);
8490 CSR_SETBITS_4(sc, BWI_MAC_INTR_MASK, enable_intrs);
8491 }
8492
8493 static void
8494 bwi_disable_intrs(struct bwi_softc *sc, uint32_t disable_intrs)
8495 {
8496 DPRINTF(sc, BWI_DBG_INTR, "disable_intrs 0x%08x\n", disable_intrs);
8497 CSR_CLRBITS_4(sc, BWI_MAC_INTR_MASK, disable_intrs);
8498 }
8499
8500 static int
8501 bwi_init_tx_ring_pio(struct bwi_softc *sc, int ring_idx)
8502 {
8503 return (0);
8504 }
8505
8506 static int
8507 bwi_init_rx_ring_pio(struct bwi_softc *sc)
8508 {
8509 uint32_t ctrl_base = BWI_TXRX_CTRL_BASE;
8510 uint32_t val;
8511 int error;
8512
8513 val = CSR_READ_4(sc, ctrl_base + BWI_RX32_CTRL);
8514 val |= BWI_TXRX32_CTRL_ENABLE |
8515 BWI_RX32_CTRL_DIRECT_FIFO;
8516 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_CTRL, val);
8517
8518 error = bwi_newbuf(sc, 0, 1);
8519 if (error) {
8520 aprint_error_dev(sc->sc_dev,
8521 "can't allocate RX buffer\n");
8522 return (error);
8523 }
8524
8525 return (0);
8526 }
8527
8528 static int
8529 bwi_init_txstats_pio(struct bwi_softc *sc)
8530 {
8531 return (0);
8532 }
8533
8534 static void
8535 bwi_setup_rx_desc_pio(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr,
8536 int buf_len)
8537 {
8538 }
8539
8540 static void
8541 bwi_setup_tx_desc_pio(struct bwi_softc *sc, struct bwi_ring_data *rd,
8542 int buf_idx, bus_addr_t paddr, int buf_len)
8543 {
8544 }
8545
8546 static int
8547 bwi_init_tx_ring32(struct bwi_softc *sc, int ring_idx)
8548 {
8549 struct bwi_ring_data *rd;
8550 struct bwi_txbuf_data *tbd;
8551 uint32_t val, addr_hi, addr_lo;
8552
8553 KASSERT(ring_idx < BWI_TX_NRING);
8554 rd = &sc->sc_tx_rdata[ring_idx];
8555 tbd = &sc->sc_tx_bdata[ring_idx];
8556
8557 tbd->tbd_idx = 0;
8558 tbd->tbd_used = 0;
8559
8560 memset(rd->rdata_desc, 0, sizeof(struct bwi_desc32) * BWI_TX_NDESC);
8561 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
8562 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8563
8564 addr_lo = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_ADDR_MASK);
8565 addr_hi = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_FUNC_MASK);
8566
8567 val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) |
8568 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX,
8569 BWI_TXRX32_RINGINFO_FUNC_MASK);
8570 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, val);
8571
8572 val = __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) |
8573 BWI_TXRX32_CTRL_ENABLE;
8574 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, val);
8575
8576 return (0);
8577 }
8578
8579 static void
8580 bwi_init_rxdesc_ring32(struct bwi_softc *sc, uint32_t ctrl_base,
8581 bus_addr_t paddr, int hdr_size, int ndesc)
8582 {
8583 uint32_t val, addr_hi, addr_lo;
8584
8585 addr_lo = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_ADDR_MASK);
8586 addr_hi = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_FUNC_MASK);
8587
8588 val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) |
8589 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX,
8590 BWI_TXRX32_RINGINFO_FUNC_MASK);
8591 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_RINGINFO, val);
8592
8593 val = __SHIFTIN(hdr_size, BWI_RX32_CTRL_HDRSZ_MASK) |
8594 __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) |
8595 BWI_TXRX32_CTRL_ENABLE;
8596 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_CTRL, val);
8597
8598 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX,
8599 (ndesc - 1) * sizeof(struct bwi_desc32));
8600 }
8601
8602 static int
8603 bwi_init_rx_ring32(struct bwi_softc *sc)
8604 {
8605 struct bwi_ring_data *rd = &sc->sc_rx_rdata;
8606 int i, error;
8607
8608 sc->sc_rx_bdata.rbd_idx = 0;
8609
8610 for (i = 0; i < BWI_RX_NDESC; ++i) {
8611 error = bwi_newbuf(sc, i, 1);
8612 if (error) {
8613 aprint_error_dev(sc->sc_dev,
8614 "can't allocate %dth RX buffer\n", i);
8615 return (error);
8616 }
8617 }
8618 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
8619 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8620
8621 bwi_init_rxdesc_ring32(sc, rd->rdata_txrx_ctrl, rd->rdata_paddr,
8622 sizeof(struct bwi_rxbuf_hdr), BWI_RX_NDESC);
8623 return (0);
8624 }
8625
8626 static int
8627 bwi_init_txstats32(struct bwi_softc *sc)
8628 {
8629 struct bwi_txstats_data *st = sc->sc_txstats;
8630 bus_addr_t stats_paddr;
8631 int i;
8632
8633 memset(st->stats, 0, BWI_TXSTATS_NDESC * sizeof(struct bwi_txstats));
8634 bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0,
8635 st->stats_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8636
8637 st->stats_idx = 0;
8638
8639 stats_paddr = st->stats_paddr;
8640 for (i = 0; i < BWI_TXSTATS_NDESC; ++i) {
8641 bwi_setup_desc32(sc, st->stats_ring, BWI_TXSTATS_NDESC, i,
8642 stats_paddr, sizeof(struct bwi_txstats), 0);
8643 stats_paddr += sizeof(struct bwi_txstats);
8644 }
8645 bus_dmamap_sync(sc->sc_dmat, st->stats_ring_dmap, 0,
8646 st->stats_ring_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8647
8648 bwi_init_rxdesc_ring32(sc, st->stats_ctrl_base,
8649 st->stats_ring_paddr, 0, BWI_TXSTATS_NDESC);
8650
8651 return (0);
8652 }
8653
8654 static void
8655 bwi_setup_rx_desc32(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr,
8656 int buf_len)
8657 {
8658 struct bwi_ring_data *rd = &sc->sc_rx_rdata;
8659
8660 KASSERT(buf_idx < BWI_RX_NDESC);
8661 bwi_setup_desc32(sc, rd->rdata_desc, BWI_RX_NDESC, buf_idx,
8662 paddr, buf_len, 0);
8663 }
8664
8665 static void
8666 bwi_setup_tx_desc32(struct bwi_softc *sc, struct bwi_ring_data *rd,
8667 int buf_idx, bus_addr_t paddr, int buf_len)
8668 {
8669 KASSERT(buf_idx < BWI_TX_NDESC);
8670 bwi_setup_desc32(sc, rd->rdata_desc, BWI_TX_NDESC, buf_idx,
8671 paddr, buf_len, 1);
8672 }
8673 static int
8674 bwi_init_tx_ring64(struct bwi_softc *sc, int ring_idx)
8675 {
8676 /* TODO: 64 */
8677 return (EOPNOTSUPP);
8678 }
8679
8680 static int
8681 bwi_init_rx_ring64(struct bwi_softc *sc)
8682 {
8683 /* TODO: 64 */
8684 return (EOPNOTSUPP);
8685 }
8686
8687 static int
8688 bwi_init_txstats64(struct bwi_softc *sc)
8689 {
8690 /* TODO: 64 */
8691 return (EOPNOTSUPP);
8692 }
8693
8694 static void
8695 bwi_setup_rx_desc64(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr,
8696 int buf_len)
8697 {
8698 /* TODO: 64 */
8699 }
8700
8701 static void
8702 bwi_setup_tx_desc64(struct bwi_softc *sc, struct bwi_ring_data *rd,
8703 int buf_idx, bus_addr_t paddr, int buf_len)
8704 {
8705 /* TODO: 64 */
8706 }
8707
8708 static int
8709 bwi_newbuf(struct bwi_softc *sc, int buf_idx, int init)
8710 {
8711 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8712 struct bwi_rxbuf *rxbuf = &rbd->rbd_buf[buf_idx];
8713 struct bwi_rxbuf_hdr *hdr;
8714 bus_dmamap_t map;
8715 bus_addr_t paddr;
8716 struct mbuf *m;
8717 int error = 0;
8718
8719 KASSERT(buf_idx < BWI_RX_NDESC);
8720
8721 MGETHDR(m, init ? M_WAITOK : M_DONTWAIT, MT_DATA);
8722 if (m == NULL)
8723 return (ENOBUFS);
8724 MCLGET(m, init ? M_WAITOK : M_DONTWAIT);
8725 if ((m->m_flags & M_EXT) == 0) {
8726 error = ENOBUFS;
8727
8728 /*
8729 * If the NIC is up and running, we need to:
8730 * - Clear RX buffer's header.
8731 * - Restore RX descriptor settings.
8732 */
8733 if (init)
8734 return error;
8735 else
8736 goto back;
8737 }
8738 m->m_len = m->m_pkthdr.len = MCLBYTES;
8739
8740 if (!BWI_IS_PIO(sc)) {
8741 /*
8742 * Try to load RX buf into temporary DMA map
8743 */
8744 error = bus_dmamap_load_mbuf(sc->sc_dmat, rbd->rbd_tmp_dmap, m,
8745 init ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT);
8746 if (error) {
8747 m_freem(m);
8748
8749 /*
8750 * See the comment above
8751 */
8752 if (init)
8753 return error;
8754 else
8755 goto back;
8756 }
8757
8758 if (!init)
8759 bus_dmamap_unload(sc->sc_dmat, rxbuf->rb_dmap);
8760 }
8761 rxbuf->rb_mbuf = m;
8762
8763 if (!BWI_IS_PIO(sc)) {
8764 /*
8765 * Swap RX buf's DMA map with the loaded temporary one
8766 */
8767 map = rxbuf->rb_dmap;
8768 rxbuf->rb_dmap = rbd->rbd_tmp_dmap;
8769 rbd->rbd_tmp_dmap = map;
8770 paddr = rxbuf->rb_dmap->dm_segs[0].ds_addr;
8771 rxbuf->rb_paddr = paddr;
8772 }
8773
8774 back:
8775 /*
8776 * Clear RX buf header
8777 */
8778 hdr = mtod(rxbuf->rb_mbuf, struct bwi_rxbuf_hdr *);
8779 memset(hdr, 0, sizeof(*hdr));
8780 if (!BWI_IS_PIO(sc)) {
8781 bus_dmamap_sync(sc->sc_dmat, rxbuf->rb_dmap, 0,
8782 rxbuf->rb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8783 }
8784
8785 /*
8786 * Setup RX buf descriptor
8787 */
8788 (sc->sc_setup_rxdesc)(sc, buf_idx, rxbuf->rb_paddr,
8789 rxbuf->rb_mbuf->m_len - sizeof(*hdr));
8790 return error;
8791 }
8792
8793 static void
8794 bwi_set_addr_filter(struct bwi_softc *sc, uint16_t addr_ofs,
8795 const uint8_t *addr)
8796 {
8797 int i;
8798
8799 CSR_WRITE_2(sc, BWI_ADDR_FILTER_CTRL,
8800 BWI_ADDR_FILTER_CTRL_SET | addr_ofs);
8801
8802 for (i = 0; i < (IEEE80211_ADDR_LEN / 2); ++i) {
8803 uint16_t addr_val;
8804
8805 addr_val = (uint16_t)addr[i * 2] |
8806 (((uint16_t)addr[(i * 2) + 1]) << 8);
8807 CSR_WRITE_2(sc, BWI_ADDR_FILTER_DATA, addr_val);
8808 }
8809 }
8810
8811 static int
8812 bwi_set_chan(struct bwi_softc *sc, struct ieee80211_channel *c)
8813 {
8814 struct ieee80211com *ic = &sc->sc_ic;
8815 struct bwi_mac *mac;
8816 /* uint16_t flags; */ /* [TRC: XXX See below.] */
8817 uint chan;
8818
8819 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
8820 mac = (struct bwi_mac *)sc->sc_cur_regwin;
8821
8822 chan = ieee80211_chan2ieee(ic, c);
8823
8824 bwi_rf_set_chan(mac, chan, 0);
8825
8826 /* [TRC: XXX DragonFlyBSD sets up radio tap channel frequency
8827 and flags here. OpenBSD does not, and appears to do so
8828 later (in bwi_rxeof and bwi_encap).] */
8829
8830 return (0);
8831 }
8832
8833 static void
8834 bwi_next_scan(void *xsc)
8835 {
8836 struct bwi_softc *sc = xsc;
8837 struct ieee80211com *ic = &sc->sc_ic;
8838 int s;
8839
8840 s = splnet();
8841
8842 if (ic->ic_state == IEEE80211_S_SCAN)
8843 ieee80211_next_scan(ic);
8844
8845 splx(s);
8846 }
8847
8848 static int
8849 bwi_rxeof(struct bwi_softc *sc, int end_idx)
8850 {
8851 struct bwi_ring_data *rd = &sc->sc_rx_rdata;
8852 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8853 struct ieee80211com *ic = &sc->sc_ic;
8854 struct ifnet *ifp = &sc->sc_if;
8855 int s, idx, rx_data = 0;
8856
8857 idx = rbd->rbd_idx;
8858 while (idx != end_idx) {
8859 struct bwi_rxbuf *rb = &rbd->rbd_buf[idx];
8860 struct bwi_rxbuf_hdr *hdr;
8861 struct ieee80211_frame_min *wh;
8862 struct ieee80211_node *ni;
8863 struct mbuf *m;
8864 const void *plcp;
8865 uint16_t flags2;
8866 int buflen, wh_ofs, hdr_extra, rssi, type, rate;
8867
8868 m = rb->rb_mbuf;
8869 bus_dmamap_sync(sc->sc_dmat, rb->rb_dmap, 0,
8870 rb->rb_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
8871
8872 if (bwi_newbuf(sc, idx, 0)) {
8873 if_statinc(ifp, if_ierrors);
8874 goto next;
8875 }
8876
8877 hdr = mtod(m, struct bwi_rxbuf_hdr *);
8878 flags2 = le16toh(hdr->rxh_flags2);
8879
8880 hdr_extra = 0;
8881 if (flags2 & BWI_RXH_F2_TYPE2FRAME)
8882 hdr_extra = 2;
8883 wh_ofs = hdr_extra + 6; /* XXX magic number */
8884
8885 buflen = le16toh(hdr->rxh_buflen);
8886 if (buflen < BWI_FRAME_MIN_LEN(wh_ofs)) {
8887 aprint_error_dev(sc->sc_dev, "short frame %d,"
8888 " hdr_extra %d\n", buflen, hdr_extra);
8889 if_statinc(ifp, if_ierrors);
8890 m_freem(m);
8891 goto next;
8892 }
8893
8894 plcp = ((const uint8_t *)(hdr + 1) + hdr_extra);
8895 rssi = bwi_calc_rssi(sc, hdr);
8896
8897 m_set_rcvif(m, ifp);
8898 m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr);
8899 m_adj(m, sizeof(*hdr) + wh_ofs);
8900
8901 if (htole16(hdr->rxh_flags1) & BWI_RXH_F1_OFDM)
8902 rate = bwi_ofdm_plcp2rate(plcp);
8903 else
8904 rate = bwi_ds_plcp2rate(plcp);
8905
8906 s = splnet();
8907
8908 /* RX radio tap */
8909 if (sc->sc_drvbpf != NULL) {
8910 struct mbuf mb;
8911 struct bwi_rx_radiotap_hdr *tap = &sc->sc_rxtap;
8912
8913 tap->wr_tsf = hdr->rxh_tsf;
8914 tap->wr_flags = 0;
8915 tap->wr_rate = rate;
8916 tap->wr_chan_freq =
8917 htole16(ic->ic_bss->ni_chan->ic_freq);
8918 tap->wr_chan_flags =
8919 htole16(ic->ic_bss->ni_chan->ic_flags);
8920 tap->wr_antsignal = rssi;
8921 tap->wr_antnoise = BWI_NOISE_FLOOR;
8922
8923 mb.m_data = (void *)tap;
8924 mb.m_len = sc->sc_rxtap_len;
8925 mb.m_next = m;
8926 mb.m_nextpkt = NULL;
8927 mb.m_owner = NULL;
8928 mb.m_type = 0;
8929 mb.m_flags = 0;
8930 bpf_mtap3(sc->sc_drvbpf, &mb, BPF_D_IN);
8931 }
8932
8933 m_adj(m, -IEEE80211_CRC_LEN);
8934
8935 wh = mtod(m, struct ieee80211_frame_min *);
8936 ni = ieee80211_find_rxnode(ic, wh);
8937 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
8938
8939 ieee80211_input(ic, m, ni, hdr->rxh_rssi,
8940 le16toh(hdr->rxh_tsf));
8941
8942 ieee80211_free_node(ni);
8943
8944 if (type == IEEE80211_FC0_TYPE_DATA) {
8945 rx_data = 1;
8946 sc->sc_rx_rate = rate;
8947 }
8948
8949 splx(s);
8950 next:
8951 idx = (idx + 1) % BWI_RX_NDESC;
8952 }
8953
8954 rbd->rbd_idx = idx;
8955 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
8956 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8957
8958 return (rx_data);
8959 }
8960
8961 static void
8962 bwi_rx_frame_data_pio(struct bwi_softc *sc, struct bwi_rxbuf_hdr *hdr, int qid)
8963 {
8964 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8965 struct bwi_rxbuf *rb = &rbd->rbd_buf[0];
8966 struct ieee80211_frame_min *wh;
8967 struct ieee80211_node *ni;
8968 struct ifnet *ifp = &sc->sc_if;
8969 struct ieee80211com *ic = &sc->sc_ic;
8970 struct mbuf *m;
8971 const void *plcp;
8972 uint16_t flags2;
8973 int buflen, hdr_extra, rssi, type, rate;
8974 int s;
8975
8976 m = rb->rb_mbuf;
8977
8978 if (bwi_newbuf(sc, 0, 0)) {
8979 device_printf(sc->sc_dev, "couldn't create mbuf\n");
8980 if_statinc(ifp, if_ierrors);
8981 return;
8982 }
8983
8984 flags2 = le16toh(hdr->rxh_flags2);
8985
8986 hdr_extra = 0;
8987 if (flags2 & BWI_RXH_F2_TYPE2FRAME)
8988 hdr_extra = 2;
8989
8990 buflen = le16toh(hdr->rxh_buflen);
8991
8992 /* Read the packet data into the mbuf */
8993 CSR_READ_MULTI_4(sc, BWI_PIO_RXDATA(qid), mtod(m, uint32_t *),
8994 buflen / sizeof(uint32_t));
8995 if (buflen & 0x3) {
8996 uint8_t data[4];
8997 uint8_t *ppkt;
8998 u_int resid;
8999 u_int n;
9000
9001 resid = buflen & 0x3;
9002 ppkt = mtod(m, uint8_t *) + (buflen & ~0x3);
9003 CSR_READ_MULTI_4(sc, BWI_PIO_RXDATA(qid), (uint32_t *)&data, 1);
9004 for (n = 0; n < resid; n++, ppkt++) {
9005 *ppkt = data[n];
9006 }
9007 }
9008
9009 plcp = mtod(m, uint8_t *) + hdr_extra;
9010 rssi = bwi_calc_rssi(sc, hdr);
9011
9012 m_set_rcvif(m, ifp);
9013 m->m_len = m->m_pkthdr.len = buflen + hdr_extra;
9014 m_adj(m, hdr_extra + 6);
9015
9016 if (htole16(hdr->rxh_flags1) & BWI_RXH_F1_OFDM)
9017 rate = bwi_ofdm_plcp2rate(plcp);
9018 else
9019 rate = bwi_ds_plcp2rate(plcp);
9020
9021 s = splnet();
9022
9023 /* RX radio tap */
9024 if (sc->sc_drvbpf != NULL) {
9025 struct mbuf mb;
9026 struct bwi_rx_radiotap_hdr *tap = &sc->sc_rxtap;
9027
9028 tap->wr_tsf = hdr->rxh_tsf;
9029 tap->wr_flags = 0;
9030 tap->wr_rate = rate;
9031 tap->wr_chan_freq =
9032 htole16(ic->ic_bss->ni_chan->ic_freq);
9033 tap->wr_chan_flags =
9034 htole16(ic->ic_bss->ni_chan->ic_flags);
9035 tap->wr_antsignal = rssi;
9036 tap->wr_antnoise = BWI_NOISE_FLOOR;
9037
9038 mb.m_data = (void *)tap;
9039 mb.m_len = sc->sc_rxtap_len;
9040 mb.m_next = m;
9041 mb.m_nextpkt = NULL;
9042 mb.m_owner = NULL;
9043 mb.m_type = 0;
9044 mb.m_flags = 0;
9045 bpf_mtap3(sc->sc_drvbpf, &mb, BPF_D_IN);
9046 }
9047
9048 m_adj(m, -IEEE80211_CRC_LEN);
9049
9050 wh = mtod(m, struct ieee80211_frame_min *);
9051 ni = ieee80211_find_rxnode(ic, wh);
9052 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
9053
9054 ieee80211_input(ic, m, ni, hdr->rxh_rssi,
9055 le16toh(hdr->rxh_tsf));
9056
9057 ieee80211_free_node(ni);
9058
9059 if (type == IEEE80211_FC0_TYPE_DATA) {
9060 sc->sc_rx_rate = rate;
9061 }
9062
9063 splx(s);
9064 }
9065
9066 static int
9067 bwi_rx_frame_pio(struct bwi_softc *sc)
9068 {
9069 struct bwi_rxbuf_hdr rxh;
9070 struct ifnet *ifp = &sc->sc_if;
9071 const u_int qid = 0;
9072 const size_t pio_hdrlen = 20;
9073 struct timeval start, diff;
9074 uint32_t val;
9075 uint16_t pktlen;
9076 uint16_t flags2;
9077
9078 /* Check for frame ready bit and acknowledge it */
9079 val = CSR_READ_4(sc, BWI_PIO_RXCTL(qid));
9080 if ((val & BWI_PIO_RXCTL_FRAMERDY) == 0) {
9081 return 0;
9082 }
9083 CSR_WRITE_4(sc, BWI_PIO_RXCTL(qid), BWI_PIO_RXCTL_FRAMERDY);
9084
9085 /* Wait for up to 100us for data ready */
9086 microuptime(&start);
9087 for (;;) {
9088 val = CSR_READ_4(sc, BWI_PIO_RXCTL(qid));
9089 if ((val & BWI_PIO_RXCTL_DATARDY) != 0) {
9090 break;
9091 }
9092 microuptime(&diff);
9093 timersub(&diff, &start, &diff);
9094 if (diff.tv_sec != 0 || diff.tv_usec > 100) {
9095 device_printf(sc->sc_dev, "RX timeout\n");
9096 if_statinc(ifp, if_ierrors);
9097 goto ack;
9098 }
9099 }
9100
9101 /* Read 20 bytes of the packet RX header from the FIFO... */
9102 CSR_READ_MULTI_4(sc, BWI_PIO_RXDATA(qid), (uint32_t *)&rxh,
9103 pio_hdrlen / sizeof(uint32_t));
9104 /* ... and zero the rest of it. */
9105 memset(((uint8_t *)&rxh) + pio_hdrlen, 0, sizeof(rxh) - pio_hdrlen);
9106
9107 /* Validate packet */
9108 pktlen = le16toh(rxh.rxh_buflen);
9109 if (pktlen > 0x700 || pktlen == 0) {
9110 device_printf(sc->sc_dev, "RX error (length %#x)\n", pktlen);
9111 if_statinc(ifp, if_ierrors);
9112 goto ack;
9113 }
9114 flags2 = le16toh(rxh.rxh_flags2);
9115 if ((flags2 & BWI_RXH_F2_INVALID) != 0) {
9116 device_printf(sc->sc_dev, "RX frame invalid\n");
9117 if_statinc(ifp, if_ierrors);
9118 goto ack;
9119 }
9120
9121 /* Process frame data */
9122 bwi_rx_frame_data_pio(sc, &rxh, qid);
9123
9124 ack:
9125 CSR_WRITE_4(sc, BWI_PIO_RXCTL(qid), BWI_PIO_RXCTL_DATARDY);
9126 return 1;
9127 }
9128
9129 static int
9130 bwi_rxeof_pio(struct bwi_softc *sc)
9131 {
9132 unsigned npkt = 0;
9133
9134 while (bwi_rx_frame_pio(sc) && npkt++ < 1000) {
9135 preempt_point();
9136 }
9137
9138 return (npkt != 0);
9139 }
9140
9141 static int
9142 bwi_rxeof32(struct bwi_softc *sc)
9143 {
9144 uint32_t val, rx_ctrl;
9145 int end_idx, rx_data;
9146
9147 rx_ctrl = sc->sc_rx_rdata.rdata_txrx_ctrl;
9148
9149 val = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS);
9150 end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) /
9151 sizeof(struct bwi_desc32);
9152
9153 rx_data = bwi_rxeof(sc, end_idx);
9154
9155 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_INDEX,
9156 end_idx * sizeof(struct bwi_desc32));
9157
9158 return (rx_data);
9159 }
9160
9161 static int
9162 bwi_rxeof64(struct bwi_softc *sc)
9163 {
9164 /* TODO: 64 */
9165 return (0);
9166 }
9167
9168 static void
9169 bwi_reset_rx_ring32(struct bwi_softc *sc, uint32_t rx_ctrl)
9170 {
9171 int i;
9172
9173 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_CTRL, 0);
9174
9175 #define NRETRY 10
9176 for (i = 0; i < NRETRY; ++i) {
9177 uint32_t status;
9178
9179 status = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS);
9180 if (__SHIFTOUT(status, BWI_RX32_STATUS_STATE_MASK) ==
9181 BWI_RX32_STATUS_STATE_DISABLED)
9182 break;
9183
9184 DELAY(1000);
9185 }
9186 if (i == NRETRY)
9187 aprint_error_dev(sc->sc_dev, "reset rx ring timedout\n");
9188 #undef NRETRY
9189
9190 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_RINGINFO, 0);
9191 }
9192
9193 static void
9194 bwi_free_txstats_pio(struct bwi_softc *sc)
9195 {
9196 }
9197
9198 static void
9199 bwi_free_txstats32(struct bwi_softc *sc)
9200 {
9201 bwi_reset_rx_ring32(sc, sc->sc_txstats->stats_ctrl_base);
9202 }
9203
9204 static void
9205 bwi_free_rx_ring_pio(struct bwi_softc *sc)
9206 {
9207 }
9208
9209 static void
9210 bwi_free_tx_ring_pio(struct bwi_softc *sc, int ring_idx)
9211 {
9212 bwi_free_tx_ring32(sc, ring_idx);
9213 }
9214
9215 static void
9216 bwi_free_rx_ring32(struct bwi_softc *sc)
9217 {
9218 struct bwi_ring_data *rd = &sc->sc_rx_rdata;
9219 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
9220 int i;
9221
9222 bwi_reset_rx_ring32(sc, rd->rdata_txrx_ctrl);
9223
9224 for (i = 0; i < BWI_RX_NDESC; ++i) {
9225 struct bwi_rxbuf *rb = &rbd->rbd_buf[i];
9226
9227 if (rb->rb_mbuf != NULL) {
9228 bus_dmamap_unload(sc->sc_dmat, rb->rb_dmap);
9229 m_freem(rb->rb_mbuf);
9230 rb->rb_mbuf = NULL;
9231 }
9232 }
9233 }
9234
9235 static void
9236 bwi_free_tx_ring32(struct bwi_softc *sc, int ring_idx)
9237 {
9238 struct bwi_ring_data *rd;
9239 struct bwi_txbuf_data *tbd;
9240 uint32_t state, val;
9241 int i;
9242
9243 KASSERT(ring_idx < BWI_TX_NRING);
9244 rd = &sc->sc_tx_rdata[ring_idx];
9245 tbd = &sc->sc_tx_bdata[ring_idx];
9246
9247 #define NRETRY 10
9248 for (i = 0; i < NRETRY; ++i) {
9249 val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS);
9250 state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK);
9251 if (state == BWI_TX32_STATUS_STATE_DISABLED ||
9252 state == BWI_TX32_STATUS_STATE_IDLE ||
9253 state == BWI_TX32_STATUS_STATE_STOPPED)
9254 break;
9255
9256 DELAY(1000);
9257 }
9258 if (i == NRETRY)
9259 aprint_error_dev(sc->sc_dev,
9260 "wait for TX ring(%d) stable timed out\n", ring_idx);
9261
9262 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, 0);
9263 for (i = 0; i < NRETRY; ++i) {
9264 val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS);
9265 state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK);
9266 if (state == BWI_TX32_STATUS_STATE_DISABLED)
9267 break;
9268
9269 DELAY(1000);
9270 }
9271 if (i == NRETRY)
9272 aprint_error_dev(sc->sc_dev, "reset TX ring (%d) timed out\n",
9273 ring_idx);
9274 #undef NRETRY
9275
9276 DELAY(1000);
9277
9278 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, 0);
9279
9280 for (i = 0; i < BWI_TX_NDESC; ++i) {
9281 struct bwi_txbuf *tb = &tbd->tbd_buf[i];
9282
9283 if (tb->tb_mbuf != NULL) {
9284 if (!BWI_IS_PIO(sc)) {
9285 bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap);
9286 }
9287 m_freem(tb->tb_mbuf);
9288 tb->tb_mbuf = NULL;
9289 }
9290 if (tb->tb_ni != NULL) {
9291 ieee80211_free_node(tb->tb_ni);
9292 tb->tb_ni = NULL;
9293 }
9294 }
9295 }
9296
9297 static void
9298 bwi_free_txstats64(struct bwi_softc *sc)
9299 {
9300 /* TODO: 64 */
9301 }
9302
9303 static void
9304 bwi_free_rx_ring64(struct bwi_softc *sc)
9305 {
9306 /* TODO: 64 */
9307 }
9308
9309 static void
9310 bwi_free_tx_ring64(struct bwi_softc *sc, int ring_idx)
9311 {
9312 /* TODO: 64 */
9313 }
9314
9315 /* XXX does not belong here */
9316 /* [TRC: Begin pilferage from OpenBSD.] */
9317
9318 /*
9319 * Convert bit rate (in 0.5Mbps units) to PLCP signal (R4-R1) and vice versa.
9320 */
9321 uint8_t
9322 bwi_ieee80211_rate2plcp(u_int8_t rate, enum ieee80211_phymode mode)
9323 {
9324 rate &= IEEE80211_RATE_VAL;
9325
9326 if (mode == IEEE80211_MODE_11B) {
9327 /* IEEE Std 802.11b-1999 page 15, subclause 18.2.3.3 */
9328 switch (rate) {
9329 case 2: return 10;
9330 case 4: return 20;
9331 case 11: return 55;
9332 case 22: return 110;
9333 /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */
9334 case 44: return 220;
9335 }
9336 } else if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11A) {
9337 /* IEEE Std 802.11a-1999 page 14, subclause 17.3.4.1 */
9338 switch (rate) {
9339 case 12: return 0x0b;
9340 case 18: return 0x0f;
9341 case 24: return 0x0a;
9342 case 36: return 0x0e;
9343 case 48: return 0x09;
9344 case 72: return 0x0d;
9345 case 96: return 0x08;
9346 case 108: return 0x0c;
9347 }
9348 } else
9349 panic("Unexpected mode %u", mode);
9350
9351 return 0;
9352 }
9353
9354 static uint8_t
9355 bwi_ieee80211_plcp2rate(uint8_t plcp, enum ieee80211_phymode mode)
9356 {
9357 if (mode == IEEE80211_MODE_11B) {
9358 /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */
9359 switch (plcp) {
9360 case 10: return 2;
9361 case 20: return 4;
9362 case 55: return 11;
9363 case 110: return 22;
9364 /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */
9365 case 220: return 44;
9366 }
9367 } else if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11A) {
9368 /* IEEE Std 802.11a-1999 page 14, subclause 17.3.4.1 */
9369 switch (plcp) {
9370 case 0x0b: return 12;
9371 case 0x0f: return 18;
9372 case 0x0a: return 24;
9373 case 0x0e: return 36;
9374 case 0x09: return 48;
9375 case 0x0d: return 72;
9376 case 0x08: return 96;
9377 case 0x0c: return 108;
9378 }
9379 } else
9380 panic("Unexpected mode %u", mode);
9381
9382 return 0;
9383 }
9384 /* [TRC: End pilferage from OpenBSD.] */
9385
9386 static enum bwi_ieee80211_modtype
9387 bwi_ieee80211_rate2modtype(uint8_t rate)
9388 {
9389 rate &= IEEE80211_RATE_VAL;
9390
9391 if (rate == 44)
9392 return (IEEE80211_MODTYPE_PBCC);
9393 else if (rate == 22 || rate < 12)
9394 return (IEEE80211_MODTYPE_DS);
9395 else
9396 return (IEEE80211_MODTYPE_OFDM);
9397 }
9398
9399 static uint8_t
9400 bwi_ofdm_plcp2rate(const void *plcp0)
9401 {
9402 uint32_t plcp;
9403 uint8_t plcp_rate;
9404
9405 /* plcp0 may not be 32-bit aligned. */
9406 plcp = le32dec(plcp0);
9407 plcp_rate = __SHIFTOUT(plcp, IEEE80211_OFDM_PLCP_RATE_MASK);
9408
9409 return (bwi_ieee80211_plcp2rate(plcp_rate, IEEE80211_MODE_11G));
9410 }
9411
9412 static uint8_t
9413 bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *hdr)
9414 {
9415 return (bwi_ieee80211_plcp2rate(hdr->i_signal, IEEE80211_MODE_11B));
9416 }
9417
9418 static void
9419 bwi_ofdm_plcp_header(uint32_t *plcp0, int pkt_len, uint8_t rate)
9420 {
9421 uint32_t plcp;
9422
9423 plcp = __SHIFTIN(bwi_ieee80211_rate2plcp(rate, IEEE80211_MODE_11G),
9424 IEEE80211_OFDM_PLCP_RATE_MASK) |
9425 __SHIFTIN(pkt_len, IEEE80211_OFDM_PLCP_LEN_MASK);
9426 *plcp0 = htole32(plcp);
9427 }
9428
9429 static void
9430 bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *plcp, int pkt_len,
9431 uint8_t rate)
9432 {
9433 int len, service, pkt_bitlen;
9434
9435 pkt_bitlen = pkt_len * NBBY;
9436 len = howmany(pkt_bitlen * 2, rate);
9437
9438 service = IEEE80211_DS_PLCP_SERVICE_LOCKED;
9439 if (rate == (11 * 2)) {
9440 int pkt_bitlen1;
9441
9442 /*
9443 * PLCP service field needs to be adjusted,
9444 * if TX rate is 11Mbytes/s
9445 */
9446 pkt_bitlen1 = len * 11;
9447 if (pkt_bitlen1 - pkt_bitlen >= NBBY)
9448 service |= IEEE80211_DS_PLCP_SERVICE_LENEXT7;
9449 }
9450
9451 plcp->i_signal = bwi_ieee80211_rate2plcp(rate, IEEE80211_MODE_11B);
9452 plcp->i_service = service;
9453 plcp->i_length = htole16(len);
9454 /* NOTE: do NOT touch i_crc */
9455 }
9456
9457 static void
9458 bwi_plcp_header(void *plcp, int pkt_len, uint8_t rate)
9459 {
9460 enum bwi_ieee80211_modtype modtype;
9461
9462 /*
9463 * Assume caller has zeroed 'plcp'
9464 */
9465
9466 modtype = bwi_ieee80211_rate2modtype(rate);
9467 if (modtype == IEEE80211_MODTYPE_OFDM)
9468 bwi_ofdm_plcp_header(plcp, pkt_len, rate);
9469 else if (modtype == IEEE80211_MODTYPE_DS)
9470 bwi_ds_plcp_header(plcp, pkt_len, rate);
9471 else
9472 panic("unsupport modulation type %u\n", modtype);
9473 }
9474
9475 static uint8_t
9476 bwi_ieee80211_ack_rate(struct ieee80211_node *ni, uint8_t rate)
9477 {
9478 const struct ieee80211_rateset *rs = &ni->ni_rates;
9479 uint8_t ack_rate = 0;
9480 enum bwi_ieee80211_modtype modtype;
9481 int i;
9482
9483 rate &= IEEE80211_RATE_VAL;
9484
9485 modtype = bwi_ieee80211_rate2modtype(rate);
9486
9487 for (i = 0; i < rs->rs_nrates; ++i) {
9488 uint8_t rate1 = rs->rs_rates[i] & IEEE80211_RATE_VAL;
9489
9490 if (rate1 > rate) {
9491 if (ack_rate != 0)
9492 return (ack_rate);
9493 else
9494 break;
9495 }
9496
9497 if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) &&
9498 bwi_ieee80211_rate2modtype(rate1) == modtype)
9499 ack_rate = rate1;
9500 }
9501
9502 switch (rate) {
9503 /* CCK */
9504 case 2:
9505 case 4:
9506 case 11:
9507 case 22:
9508 ack_rate = rate;
9509 break;
9510 /* PBCC */
9511 case 44:
9512 ack_rate = 22;
9513 break;
9514
9515 /* OFDM */
9516 case 12:
9517 case 18:
9518 ack_rate = 12;
9519 break;
9520 case 24:
9521 case 36:
9522 ack_rate = 24;
9523 break;
9524 case 48:
9525 case 72:
9526 case 96:
9527 case 108:
9528 ack_rate = 48;
9529 break;
9530 default:
9531 panic("unsupported rate %d\n", rate);
9532 }
9533 return (ack_rate);
9534 }
9535
9536 /* [TRC: XXX does not belong here] */
9537
9538 #define IEEE80211_OFDM_TXTIME(kbps, frmlen) \
9539 (IEEE80211_OFDM_PREAMBLE_TIME + \
9540 IEEE80211_OFDM_SIGNAL_TIME + \
9541 (IEEE80211_OFDM_NSYMS((kbps), (frmlen)) * IEEE80211_OFDM_SYM_TIME))
9542
9543 #define IEEE80211_OFDM_SYM_TIME 4
9544 #define IEEE80211_OFDM_PREAMBLE_TIME 16
9545 #define IEEE80211_OFDM_SIGNAL_EXT_TIME 6
9546 #define IEEE80211_OFDM_SIGNAL_TIME 4
9547
9548 #define IEEE80211_OFDM_PLCP_SERVICE_NBITS 16
9549 #define IEEE80211_OFDM_TAIL_NBITS 6
9550
9551 #define IEEE80211_OFDM_NBITS(frmlen) \
9552 (IEEE80211_OFDM_PLCP_SERVICE_NBITS + \
9553 ((frmlen) * NBBY) + \
9554 IEEE80211_OFDM_TAIL_NBITS)
9555
9556 #define IEEE80211_OFDM_NBITS_PER_SYM(kbps) \
9557 (((kbps) * IEEE80211_OFDM_SYM_TIME) / 1000)
9558
9559 #define IEEE80211_OFDM_NSYMS(kbps, frmlen) \
9560 howmany(IEEE80211_OFDM_NBITS((frmlen)), \
9561 IEEE80211_OFDM_NBITS_PER_SYM((kbps)))
9562
9563 #define IEEE80211_CCK_TXTIME(kbps, frmlen) \
9564 (((IEEE80211_CCK_NBITS((frmlen)) * 1000) + (kbps) - 1) / (kbps))
9565
9566 #define IEEE80211_CCK_PREAMBLE_LEN 144
9567 #define IEEE80211_CCK_PLCP_HDR_TIME 48
9568 #define IEEE80211_CCK_SHPREAMBLE_LEN 72
9569 #define IEEE80211_CCK_SHPLCP_HDR_TIME 24
9570
9571 #define IEEE80211_CCK_NBITS(frmlen) ((frmlen) * NBBY)
9572
9573 static uint16_t
9574 bwi_ieee80211_txtime(struct ieee80211com *ic, struct ieee80211_node *ni,
9575 uint len, uint8_t rs_rate, uint32_t flags)
9576 {
9577 enum bwi_ieee80211_modtype modtype;
9578 uint16_t txtime;
9579 int rate;
9580
9581 rs_rate &= IEEE80211_RATE_VAL;
9582
9583 rate = rs_rate * 500; /* ieee80211 rate -> kbps */
9584
9585 modtype = bwi_ieee80211_rate2modtype(rs_rate);
9586 if (modtype == IEEE80211_MODTYPE_OFDM) {
9587 /*
9588 * IEEE Std 802.11a-1999, page 37, equation (29)
9589 * IEEE Std 802.11g-2003, page 44, equation (42)
9590 */
9591 txtime = IEEE80211_OFDM_TXTIME(rate, len);
9592 if (ic->ic_curmode == IEEE80211_MODE_11G)
9593 txtime += IEEE80211_OFDM_SIGNAL_EXT_TIME;
9594 } else {
9595 /*
9596 * IEEE Std 802.11b-1999, page 28, subclause 18.3.4
9597 * IEEE Std 802.11g-2003, page 45, equation (43)
9598 */
9599 if (modtype == IEEE80211_MODTYPE_PBCC)
9600 ++len;
9601 txtime = IEEE80211_CCK_TXTIME(rate, len);
9602
9603 /*
9604 * Short preamble is not applicable for DS 1Mbits/s
9605 */
9606 if (rs_rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) {
9607 txtime += IEEE80211_CCK_SHPREAMBLE_LEN +
9608 IEEE80211_CCK_SHPLCP_HDR_TIME;
9609 } else {
9610 txtime += IEEE80211_CCK_PREAMBLE_LEN +
9611 IEEE80211_CCK_PLCP_HDR_TIME;
9612 }
9613 }
9614 return (txtime);
9615 }
9616
9617 static int
9618 bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
9619 struct ieee80211_node **nip, int mgt_pkt)
9620 {
9621 struct ieee80211com *ic = &sc->sc_ic;
9622 struct ieee80211_node *ni = *nip;
9623 struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING];
9624 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
9625 struct bwi_txbuf *tb = &tbd->tbd_buf[idx];
9626 struct bwi_mac *mac;
9627 struct bwi_txbuf_hdr *hdr;
9628 struct ieee80211_frame *wh;
9629 uint8_t rate; /* [TRC: XXX Use a fallback rate?] */
9630 uint32_t mac_ctrl;
9631 uint16_t phy_ctrl;
9632 bus_addr_t paddr;
9633 int pkt_len, error, mcast_pkt = 0;
9634 #if 0
9635 const uint8_t *p;
9636 int i;
9637 #endif
9638
9639 KASSERT(ni != NULL);
9640 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
9641 mac = (struct bwi_mac *)sc->sc_cur_regwin;
9642
9643 wh = mtod(m, struct ieee80211_frame *);
9644
9645 /* Get 802.11 frame len before prepending TX header */
9646 pkt_len = m->m_pkthdr.len + IEEE80211_CRC_LEN;
9647
9648 /*
9649 * Find TX rate
9650 */
9651 memset(tb->tb_rate_idx, 0, sizeof(tb->tb_rate_idx));
9652 if (!mgt_pkt) {
9653 if (ic->ic_fixed_rate != -1) {
9654 rate = ic->ic_sup_rates[ic->ic_curmode].
9655 rs_rates[ic->ic_fixed_rate];
9656 /* [TRC: XXX Set fallback rate.] */
9657 } else {
9658 /* AMRR rate control */
9659 rate = ni->ni_rates.rs_rates[ni->ni_txrate];
9660 }
9661 } else {
9662 /* Fixed at 1Mbits/s for mgt frames */
9663 /* [TRC: XXX Set fallback rate.] */
9664 rate = (1 * 2);
9665 }
9666
9667 rate &= IEEE80211_RATE_VAL;
9668
9669 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
9670 /* [TRC: XXX Set fallback rate.] */
9671 rate = ic->ic_mcast_rate;
9672 mcast_pkt = 1;
9673 }
9674
9675 /* [TRC: XXX Check fallback rate.] */
9676 if (rate == 0) {
9677 aprint_error_dev(sc->sc_dev, "invalid rate %u", rate);
9678 /* [TRC: In the margin of the following line,
9679 DragonFlyBSD writes `Force 1Mbits/s', whereas
9680 OpenBSD writes `Force 1Mbytes/s'.] */
9681 rate = (1 * 2);
9682 /* [TRC: XXX Set fallback rate.] */
9683 }
9684 sc->sc_tx_rate = rate;
9685
9686 /* TX radio tap */
9687 if (sc->sc_drvbpf != NULL) {
9688 struct mbuf mb;
9689 struct bwi_tx_radiotap_hdr *tap = &sc->sc_txtap;
9690
9691 tap->wt_flags = 0;
9692 tap->wt_rate = rate;
9693 tap->wt_chan_freq =
9694 htole16(ic->ic_bss->ni_chan->ic_freq);
9695 tap->wt_chan_flags =
9696 htole16(ic->ic_bss->ni_chan->ic_flags);
9697
9698 mb.m_data = (void *)tap;
9699 mb.m_len = sc->sc_txtap_len;
9700 mb.m_next = m;
9701 mb.m_nextpkt = NULL;
9702 mb.m_type = 0;
9703 mb.m_flags = 0;
9704 bpf_mtap3(sc->sc_drvbpf, &mb, BPF_D_OUT);
9705 }
9706
9707 /*
9708 * Setup the embedded TX header
9709 */
9710 M_PREPEND(m, sizeof(*hdr), M_DONTWAIT);
9711 if (m == NULL) {
9712 aprint_error_dev(sc->sc_dev, "prepend TX header failed\n");
9713 return (ENOBUFS);
9714 }
9715 hdr = mtod(m, struct bwi_txbuf_hdr *);
9716
9717 memset(hdr, 0, sizeof(*hdr));
9718
9719 memcpy(hdr->txh_fc, wh->i_fc, sizeof(hdr->txh_fc));
9720 memcpy(hdr->txh_addr1, wh->i_addr1, sizeof(hdr->txh_addr1));
9721
9722 if (!mcast_pkt) {
9723 uint16_t dur;
9724 uint8_t ack_rate;
9725
9726 /* [TRC: XXX Set fallback rate.] */
9727 ack_rate = bwi_ieee80211_ack_rate(ni, rate);
9728 dur = bwi_ieee80211_txtime(ic, ni,
9729 sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN,
9730 ack_rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE);
9731
9732 hdr->txh_fb_duration = htole16(dur);
9733 }
9734
9735 hdr->txh_id = htole16(
9736 __SHIFTIN(BWI_TX_DATA_RING, BWI_TXH_ID_RING_MASK) |
9737 __SHIFTIN(idx, BWI_TXH_ID_IDX_MASK));
9738
9739 bwi_plcp_header(hdr->txh_plcp, pkt_len, rate);
9740 /* [TRC: XXX Use fallback rate.] */
9741 bwi_plcp_header(hdr->txh_fb_plcp, pkt_len, rate);
9742
9743 phy_ctrl = __SHIFTIN(mac->mac_rf.rf_ant_mode,
9744 BWI_TXH_PHY_C_ANTMODE_MASK);
9745 if (bwi_ieee80211_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM)
9746 phy_ctrl |= BWI_TXH_PHY_C_OFDM;
9747 else if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && rate != (2 * 1))
9748 phy_ctrl |= BWI_TXH_PHY_C_SHPREAMBLE;
9749
9750 mac_ctrl = BWI_TXH_MAC_C_HWSEQ | BWI_TXH_MAC_C_FIRST_FRAG;
9751 if (!IEEE80211_IS_MULTICAST(wh->i_addr1))
9752 mac_ctrl |= BWI_TXH_MAC_C_ACK;
9753 if (bwi_ieee80211_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM)
9754 mac_ctrl |= BWI_TXH_MAC_C_FB_OFDM;
9755
9756 hdr->txh_mac_ctrl = htole32(mac_ctrl);
9757 hdr->txh_phy_ctrl = htole16(phy_ctrl);
9758
9759 /* Catch any further usage */
9760 hdr = NULL;
9761 wh = NULL;
9762
9763 if (BWI_IS_PIO(sc)) {
9764 error = 0;
9765 } else {
9766 /* DMA load */
9767 error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m,
9768 BUS_DMA_NOWAIT);
9769 if (error && error != EFBIG) {
9770 aprint_error_dev(sc->sc_dev,
9771 "can't load TX buffer (1) %d\n", error);
9772 goto back;
9773 }
9774 }
9775
9776 if (error) { /* error == EFBIG */
9777 struct mbuf *m_new;
9778
9779 KASSERT(!BWI_IS_PIO(sc));
9780
9781 error = 0;
9782
9783 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
9784 if (m_new == NULL) {
9785 error = ENOBUFS;
9786 aprint_error_dev(sc->sc_dev,
9787 "can't defrag TX buffer (1)\n");
9788 goto back;
9789 }
9790
9791 m_copy_pkthdr(m_new, m);
9792 if (m->m_pkthdr.len > MHLEN) {
9793 MCLGET(m_new, M_DONTWAIT);
9794 if (!(m_new->m_flags & M_EXT)) {
9795 m_freem(m_new);
9796 error = ENOBUFS;
9797 }
9798 }
9799
9800 if (error) {
9801 aprint_error_dev(sc->sc_dev,
9802 "can't defrag TX buffer (2)\n");
9803 goto back;
9804 }
9805
9806 m_copydata(m, 0, m->m_pkthdr.len, mtod(m_new, void *));
9807 m_freem(m);
9808 m_new->m_len = m_new->m_pkthdr.len;
9809 m = m_new;
9810
9811 error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m,
9812 BUS_DMA_NOWAIT);
9813 if (error) {
9814 aprint_error_dev(sc->sc_dev,
9815 "can't load TX buffer (2) %d\n", error);
9816 goto back;
9817 }
9818 }
9819 error = 0;
9820
9821 if (!BWI_IS_PIO(sc)) {
9822 bus_dmamap_sync(sc->sc_dmat, tb->tb_dmap, 0,
9823 tb->tb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
9824 }
9825
9826 if (mgt_pkt || mcast_pkt) {
9827 /* Don't involve mcast/mgt packets into TX rate control */
9828 ieee80211_free_node(ni);
9829 *nip = ni = NULL;
9830 }
9831
9832 tb->tb_mbuf = m;
9833 tb->tb_ni = ni;
9834
9835 #if 0
9836 p = mtod(m, const uint8_t *);
9837 for (i = 0; i < m->m_pkthdr.len; ++i) {
9838 if (i % 8 == 0) {
9839 if (i != 0)
9840 aprint_debug("\n");
9841 aprint_debug_dev(sc->sc_dev, "");
9842 }
9843 aprint_debug(" %02x", p[i]);
9844 }
9845 aprint_debug("\n");
9846 #endif
9847
9848 DPRINTF(sc, BWI_DBG_TX, "idx %d, pkt_len %d, buflen %d\n",
9849 idx, pkt_len, m->m_pkthdr.len);
9850
9851 if (!BWI_IS_PIO(sc)) {
9852 /* Setup TX descriptor */
9853 paddr = tb->tb_dmap->dm_segs[0].ds_addr;
9854 (sc->sc_setup_txdesc)(sc, rd, idx, paddr, m->m_pkthdr.len);
9855 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
9856 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
9857 }
9858
9859 /* Kick start */
9860 (sc->sc_start_tx)(sc, rd->rdata_txrx_ctrl, idx);
9861
9862 back:
9863 if (error)
9864 m_freem(m);
9865 return (error);
9866 }
9867
9868 static void
9869 bwi_start_tx_pio(struct bwi_softc *sc, uint32_t tx_ctrl, int idx)
9870 {
9871 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
9872 struct bwi_txbuf *tb = &tbd->tbd_buf[idx];
9873
9874 mutex_enter(&sc->sc_pio_txlock);
9875 STAILQ_INSERT_TAIL(&sc->sc_pio_txpend, tb, tb_entry);
9876 mutex_exit(&sc->sc_pio_txlock);
9877 }
9878
9879 static void
9880 bwi_start_tx32(struct bwi_softc *sc, uint32_t tx_ctrl, int idx)
9881 {
9882 idx = (idx + 1) % BWI_TX_NDESC;
9883 CSR_WRITE_4(sc, tx_ctrl + BWI_TX32_INDEX,
9884 idx * sizeof(struct bwi_desc32));
9885 }
9886
9887 static void
9888 bwi_start_tx64(struct bwi_softc *sc, uint32_t tx_ctrl, int idx)
9889 {
9890 /* TODO: 64 */
9891 }
9892
9893 static void
9894 bwi_txeof_status_pio(struct bwi_softc *sc)
9895 {
9896 /* TODO: PIO */
9897 }
9898
9899 static void
9900 bwi_txeof_status32(struct bwi_softc *sc)
9901 {
9902 struct ifnet *ifp = &sc->sc_if;
9903 uint32_t val, ctrl_base;
9904 int end_idx, s;
9905
9906 s = splnet();
9907
9908 ctrl_base = sc->sc_txstats->stats_ctrl_base;
9909
9910 val = CSR_READ_4(sc, ctrl_base + BWI_RX32_STATUS);
9911 end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) /
9912 sizeof(struct bwi_desc32);
9913
9914 bwi_txeof_status(sc, end_idx);
9915
9916 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX,
9917 end_idx * sizeof(struct bwi_desc32));
9918
9919 if ((ifp->if_flags & IFF_OACTIVE) == 0)
9920 ifp->if_start(ifp); /* [TRC: XXX Why not bwi_start?] */
9921
9922 splx(s);
9923 }
9924
9925 static void
9926 bwi_txeof_status64(struct bwi_softc *sc)
9927 {
9928 /* TODO: 64 */
9929 }
9930
9931 static void
9932 _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, uint8_t retry_cnt)
9933 {
9934 struct ifnet *ifp = &sc->sc_if;
9935 struct bwi_txbuf_data *tbd;
9936 struct bwi_txbuf *tb;
9937 int ring_idx, buf_idx;
9938
9939 if (tx_id == 0) {
9940 /* [TRC: XXX What is the severity of this message?] */
9941 aprint_normal_dev(sc->sc_dev, "zero tx id\n");
9942 return;
9943 }
9944
9945 ring_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_RING_MASK);
9946 buf_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_IDX_MASK);
9947
9948 KASSERT(ring_idx == BWI_TX_DATA_RING);
9949 KASSERT(buf_idx < BWI_TX_NDESC);
9950 tbd = &sc->sc_tx_bdata[ring_idx];
9951 KASSERT(tbd->tbd_used > 0);
9952 tbd->tbd_used--;
9953
9954 tb = &tbd->tbd_buf[buf_idx];
9955
9956 if (BWI_IS_PIO(sc)) {
9957 mutex_enter(&sc->sc_pio_txlock);
9958 const u_int pktlen = m_length(tb->tb_mbuf);
9959 sc->sc_pio_fifoavail += roundup(pktlen, sizeof(uint32_t));
9960 KASSERT(sc->sc_pio_fifoavail <= sc->sc_pio_fifolen);
9961 mutex_exit(&sc->sc_pio_txlock);
9962 } else {
9963 bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap);
9964 }
9965 m_freem(tb->tb_mbuf);
9966 tb->tb_mbuf = NULL;
9967
9968 if (tb->tb_ni != NULL) {
9969 struct bwi_node *bn = (struct bwi_node *)tb->tb_ni;
9970
9971 /* Update rate control statistics for the node. */
9972 bn->amn.amn_txcnt++;
9973 if (retry_cnt) {
9974 bn->amn.amn_retrycnt++;
9975 }
9976
9977 ieee80211_free_node(tb->tb_ni);
9978 tb->tb_ni = NULL;
9979 }
9980
9981 if (tbd->tbd_used == 0)
9982 sc->sc_tx_timer = 0;
9983
9984 ifp->if_flags &= ~IFF_OACTIVE;
9985 }
9986
9987 static void
9988 bwi_txeof_status(struct bwi_softc *sc, int end_idx)
9989 {
9990 struct bwi_txstats_data *st = sc->sc_txstats;
9991 int idx;
9992
9993 if (!BWI_IS_PIO(sc)) {
9994 bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0,
9995 st->stats_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
9996 }
9997
9998 idx = st->stats_idx;
9999 while (idx != end_idx) {
10000 /* [TRC: XXX Filter this out if it is not pending; see
10001 DragonFlyBSD's revision 1.5. */
10002 _bwi_txeof(sc, le16toh(st->stats[idx].txs_id),
10003 st->stats[idx].txs_retry_cnt);
10004 idx = (idx + 1) % BWI_TXSTATS_NDESC;
10005 }
10006 st->stats_idx = idx;
10007 }
10008
10009 static void
10010 bwi_txeof(struct bwi_softc *sc)
10011 {
10012 struct ifnet *ifp = &sc->sc_if;
10013 int s;
10014
10015 s = splnet();
10016
10017 for (;;) {
10018 uint32_t tx_status0;
10019 uint16_t tx_id;
10020 uint8_t tx_cnt;
10021
10022 tx_status0 = CSR_READ_4(sc, BWI_TXSTATUS_0);
10023 if ((tx_status0 & BWI_TXSTATUS_0_MORE) == 0)
10024 break;
10025 (void)CSR_READ_4(sc, BWI_TXSTATUS_1);
10026
10027 tx_id = __SHIFTOUT(tx_status0, BWI_TXSTATUS_0_TXID_MASK);
10028 tx_cnt = __SHIFTOUT(tx_status0, BWI_TXSTATUS_0_DATA_TXCNT_MASK);
10029
10030 if ((tx_status0 &
10031 (BWI_TXSTATUS_0_PENDING | BWI_TXSTATUS_0_AMPDU)) != 0) {
10032 continue;
10033 }
10034
10035 _bwi_txeof(sc, tx_id, tx_cnt != 1);
10036
10037 if_statinc(ifp, if_opackets);
10038 if (tx_cnt == 0) {
10039 if_statinc(ifp, if_oerrors);
10040 }
10041 }
10042
10043 if ((ifp->if_flags & IFF_OACTIVE) == 0)
10044 ifp->if_start(ifp);
10045
10046 splx(s);
10047 }
10048
10049 static int
10050 bwi_bbp_power_on(struct bwi_softc *sc, enum bwi_clock_mode clk_mode)
10051 {
10052 bwi_power_on(sc, 1);
10053
10054 return (bwi_set_clock_mode(sc, clk_mode));
10055 }
10056
10057 static void
10058 bwi_bbp_power_off(struct bwi_softc *sc)
10059 {
10060 bwi_set_clock_mode(sc, BWI_CLOCK_MODE_SLOW);
10061 bwi_power_off(sc, 1);
10062 }
10063
10064 static int
10065 bwi_get_pwron_delay(struct bwi_softc *sc)
10066 {
10067 struct bwi_regwin *com, *old;
10068 struct bwi_clock_freq freq;
10069 uint32_t val;
10070 int error;
10071
10072 com = &sc->sc_com_regwin;
10073 KASSERT(BWI_REGWIN_EXIST(com));
10074
10075 if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0)
10076 return (0);
10077
10078 error = bwi_regwin_switch(sc, com, &old);
10079 if (error)
10080 return (error);
10081
10082 bwi_get_clock_freq(sc, &freq);
10083
10084 val = CSR_READ_4(sc, BWI_PLL_ON_DELAY);
10085 sc->sc_pwron_delay = howmany((val + 2) * 1000000, freq.clkfreq_min);
10086 DPRINTF(sc, BWI_DBG_ATTACH, "power on delay %u\n", sc->sc_pwron_delay);
10087
10088 return (bwi_regwin_switch(sc, old, NULL));
10089 }
10090
10091 static int
10092 bwi_bus_attach(struct bwi_softc *sc)
10093 {
10094 struct bwi_regwin *bus, *old;
10095 int error;
10096
10097 bus = &sc->sc_bus_regwin;
10098
10099 error = bwi_regwin_switch(sc, bus, &old);
10100 if (error)
10101 return (error);
10102
10103 if (!bwi_regwin_is_enabled(sc, bus))
10104 bwi_regwin_enable(sc, bus, 0);
10105
10106 /* Disable interripts */
10107 CSR_WRITE_4(sc, BWI_INTRVEC, 0);
10108
10109 return (bwi_regwin_switch(sc, old, NULL));
10110 }
10111
10112 static const char *
10113 bwi_regwin_name(const struct bwi_regwin *rw)
10114 {
10115 switch (rw->rw_type) {
10116 case BWI_REGWIN_T_COM:
10117 return ("COM");
10118 case BWI_REGWIN_T_BUSPCI:
10119 return ("PCI");
10120 case BWI_REGWIN_T_MAC:
10121 return ("MAC");
10122 case BWI_REGWIN_T_BUSPCIE:
10123 return ("PCIE");
10124 }
10125 panic("unknown regwin type 0x%04x\n", rw->rw_type);
10126
10127 return (NULL);
10128 }
10129
10130 static uint32_t
10131 bwi_regwin_disable_bits(struct bwi_softc *sc)
10132 {
10133 uint32_t busrev;
10134
10135 /* XXX cache this */
10136 busrev = __SHIFTOUT(CSR_READ_4(sc, BWI_ID_LO), BWI_ID_LO_BUSREV_MASK);
10137 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT | BWI_DBG_MISC,
10138 "bus rev %u\n", busrev);
10139
10140 if (busrev == BWI_BUSREV_0)
10141 return (BWI_STATE_LO_DISABLE1);
10142 else if (busrev == BWI_BUSREV_1)
10143 return (BWI_STATE_LO_DISABLE2);
10144 else
10145 return (BWI_STATE_LO_DISABLE1 | BWI_STATE_LO_DISABLE2);
10146 }
10147
10148 static int
10149 bwi_regwin_is_enabled(struct bwi_softc *sc, struct bwi_regwin *rw)
10150 {
10151 uint32_t val, disable_bits;
10152
10153 disable_bits = bwi_regwin_disable_bits(sc);
10154 val = CSR_READ_4(sc, BWI_STATE_LO);
10155
10156 if ((val & (BWI_STATE_LO_CLOCK |
10157 BWI_STATE_LO_RESET |
10158 disable_bits)) == BWI_STATE_LO_CLOCK) {
10159 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT, "%s is enabled\n",
10160 bwi_regwin_name(rw));
10161 return (1);
10162 } else {
10163 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT, "%s is disabled\n",
10164 bwi_regwin_name(rw));
10165 return (0);
10166 }
10167 }
10168
10169 static void
10170 bwi_regwin_disable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags)
10171 {
10172 uint32_t state_lo, disable_bits;
10173 int i;
10174
10175 state_lo = CSR_READ_4(sc, BWI_STATE_LO);
10176
10177 /*
10178 * If current regwin is in 'reset' state, it was already disabled.
10179 */
10180 if (state_lo & BWI_STATE_LO_RESET) {
10181 DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT,
10182 "%s was already disabled\n", bwi_regwin_name(rw));
10183 return;
10184 }
10185
10186 disable_bits = bwi_regwin_disable_bits(sc);
10187
10188 /*
10189 * Disable normal clock
10190 */
10191 state_lo = BWI_STATE_LO_CLOCK | disable_bits;
10192 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
10193
10194 /*
10195 * Wait until normal clock is disabled
10196 */
10197 #define NRETRY 1000
10198 for (i = 0; i < NRETRY; ++i) {
10199 state_lo = CSR_READ_4(sc, BWI_STATE_LO);
10200 if (state_lo & disable_bits)
10201 break;
10202 DELAY(10);
10203 }
10204 if (i == NRETRY) {
10205 aprint_error_dev(sc->sc_dev, "%s disable clock timeout\n",
10206 bwi_regwin_name(rw));
10207 }
10208
10209 for (i = 0; i < NRETRY; ++i) {
10210 uint32_t state_hi;
10211
10212 state_hi = CSR_READ_4(sc, BWI_STATE_HI);
10213 if ((state_hi & BWI_STATE_HI_BUSY) == 0)
10214 break;
10215 DELAY(10);
10216 }
10217 if (i == NRETRY) {
10218 aprint_error_dev(sc->sc_dev, "%s wait BUSY unset timeout\n",
10219 bwi_regwin_name(rw));
10220 }
10221 #undef NRETRY
10222
10223 /*
10224 * Reset and disable regwin with gated clock
10225 */
10226 state_lo = BWI_STATE_LO_RESET | disable_bits |
10227 BWI_STATE_LO_CLOCK | BWI_STATE_LO_GATED_CLOCK |
10228 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
10229 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
10230
10231 /* Flush pending bus write */
10232 CSR_READ_4(sc, BWI_STATE_LO);
10233 DELAY(1);
10234
10235 /* Reset and disable regwin */
10236 state_lo = BWI_STATE_LO_RESET | disable_bits |
10237 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
10238 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
10239
10240 /* Flush pending bus write */
10241 CSR_READ_4(sc, BWI_STATE_LO);
10242 DELAY(1);
10243 }
10244
10245 static void
10246 bwi_regwin_enable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags)
10247 {
10248 uint32_t state_lo, state_hi, imstate;
10249
10250 bwi_regwin_disable(sc, rw, flags);
10251
10252 /* Reset regwin with gated clock */
10253 state_lo = BWI_STATE_LO_RESET |
10254 BWI_STATE_LO_CLOCK |
10255 BWI_STATE_LO_GATED_CLOCK |
10256 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
10257 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
10258
10259 /* Flush pending bus write */
10260 CSR_READ_4(sc, BWI_STATE_LO);
10261 DELAY(1);
10262
10263 state_hi = CSR_READ_4(sc, BWI_STATE_HI);
10264 if (state_hi & BWI_STATE_HI_SERROR)
10265 CSR_WRITE_4(sc, BWI_STATE_HI, 0);
10266
10267 imstate = CSR_READ_4(sc, BWI_IMSTATE);
10268 if (imstate & (BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT)) {
10269 imstate &= ~(BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT);
10270 CSR_WRITE_4(sc, BWI_IMSTATE, imstate);
10271 }
10272
10273 /* Enable regwin with gated clock */
10274 state_lo = BWI_STATE_LO_CLOCK |
10275 BWI_STATE_LO_GATED_CLOCK |
10276 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
10277 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
10278
10279 /* Flush pending bus write */
10280 CSR_READ_4(sc, BWI_STATE_LO);
10281 DELAY(1);
10282
10283 /* Enable regwin with normal clock */
10284 state_lo = BWI_STATE_LO_CLOCK |
10285 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
10286 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
10287
10288 /* Flush pending bus write */
10289 CSR_READ_4(sc, BWI_STATE_LO);
10290 DELAY(1);
10291 }
10292
10293 static void
10294 bwi_set_bssid(struct bwi_softc *sc, const uint8_t *bssid)
10295 {
10296 struct ieee80211com *ic = &sc->sc_ic;
10297 struct bwi_mac *mac;
10298 struct bwi_myaddr_bssid buf;
10299 const uint8_t *p;
10300 uint32_t val;
10301 int n, i;
10302
10303 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
10304 mac = (struct bwi_mac *)sc->sc_cur_regwin;
10305
10306 bwi_set_addr_filter(sc, BWI_ADDR_FILTER_BSSID, bssid);
10307
10308 memcpy(buf.myaddr, ic->ic_myaddr, sizeof(buf.myaddr));
10309 memcpy(buf.bssid, bssid, sizeof(buf.bssid));
10310
10311 n = sizeof(buf) / sizeof(val);
10312 p = (const uint8_t *)&buf;
10313 for (i = 0; i < n; ++i) {
10314 int j;
10315
10316 val = 0;
10317 for (j = 0; j < sizeof(val); ++j)
10318 val |= ((uint32_t)(*p++)) << (j * 8);
10319
10320 TMPLT_WRITE_4(mac, 0x20 + (i * sizeof(val)), val);
10321 }
10322 }
10323
10324 static void
10325 bwi_updateslot(struct ifnet *ifp)
10326 {
10327 struct bwi_softc *sc = ifp->if_softc;
10328 struct ieee80211com *ic = &sc->sc_ic;
10329 struct bwi_mac *mac;
10330
10331 if ((ifp->if_flags & IFF_RUNNING) == 0)
10332 return;
10333
10334 DPRINTF(sc, BWI_DBG_80211, "%s\n", __func__);
10335
10336 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
10337 mac = (struct bwi_mac *)sc->sc_cur_regwin;
10338
10339 bwi_mac_updateslot(mac, (ic->ic_flags & IEEE80211_F_SHSLOT));
10340 }
10341
10342 static void
10343 bwi_updateslot_sdio(struct ifnet *ifp)
10344 {
10345 struct bwi_softc *sc = ifp->if_softc;
10346 struct bwi_task *t;
10347
10348 t = pool_cache_get(sc->sc_freetask, PR_NOWAIT);
10349 if (t == NULL) {
10350 device_printf(sc->sc_dev, "no free tasks\n");
10351 return;
10352 }
10353
10354 t->t_ic = &sc->sc_ic;
10355 t->t_cmd = BWI_TASK_UPDATESLOT;
10356 workqueue_enqueue(sc->sc_taskq, &t->t_work, NULL);
10357 }
10358
10359 static void
10360 bwi_do_calibrate(struct bwi_softc *sc)
10361 {
10362 struct bwi_mac *mac;
10363 struct ieee80211com *ic = &sc->sc_ic;
10364
10365 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
10366 mac = (struct bwi_mac *)sc->sc_cur_regwin;
10367
10368 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
10369 bwi_mac_calibrate_txpower(mac, sc->sc_txpwrcb_type);
10370 sc->sc_txpwrcb_type = BWI_TXPWR_CALIB;
10371 }
10372
10373 /* XXX 15 seconds */
10374 callout_schedule(&sc->sc_calib_ch, hz * 15);
10375 }
10376
10377 static void
10378 bwi_calibrate(void *xsc)
10379 {
10380 struct bwi_softc *sc = xsc;
10381 struct ieee80211com *ic = &sc->sc_ic;
10382 int s;
10383
10384 s = splnet();
10385
10386 if (ic->ic_state == IEEE80211_S_RUN) {
10387 if (BWI_IS_SDIO(sc)) {
10388 struct bwi_task *t;
10389
10390 t = pool_cache_get(sc->sc_freetask, PR_NOWAIT);
10391 if (t == NULL) {
10392 device_printf(sc->sc_dev, "no free tasks\n");
10393 callout_schedule(&sc->sc_calib_ch, hz * 15);
10394 } else {
10395 t->t_ic = &sc->sc_ic;
10396 t->t_cmd = BWI_TASK_CALIBRATE;
10397 workqueue_enqueue(sc->sc_taskq, &t->t_work,
10398 NULL);
10399 }
10400 } else {
10401 bwi_do_calibrate(sc);
10402 }
10403 }
10404
10405 splx(s);
10406 }
10407
10408 static int
10409 bwi_calc_rssi(struct bwi_softc *sc, const struct bwi_rxbuf_hdr *hdr)
10410 {
10411 struct bwi_mac *mac;
10412
10413 KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
10414 mac = (struct bwi_mac *)sc->sc_cur_regwin;
10415
10416 return (bwi_rf_calc_rssi(mac, hdr));
10417 }
10418
10419 bool
10420 bwi_suspend(device_t dv, const pmf_qual_t *qual)
10421 {
10422 struct bwi_softc *sc = device_private(dv);
10423
10424 bwi_power_off(sc, 0);
10425 if (sc->sc_disable != NULL)
10426 (sc->sc_disable)(sc, 1);
10427
10428 return true;
10429 }
10430
10431 bool
10432 bwi_resume(device_t dv, const pmf_qual_t *qual)
10433 {
10434 struct bwi_softc *sc = device_private(dv);
10435
10436 if (sc->sc_enable != NULL)
10437 (sc->sc_enable)(sc, 1);
10438 bwi_power_on(sc, 1);
10439
10440 return true;
10441 }
10442