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