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