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