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