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