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