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