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