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