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