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