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