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