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