1 /*	$NetBSD: wi.c,v 1.240 2016/06/10 13:27:14 ozaki-r Exp $	*/
2 
3 /*-
4  * Copyright (c) 2004 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Charles M. Hannum.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * Copyright (c) 1997, 1998, 1999
34  *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
35  *
36  * Redistribution and use in source and binary forms, with or without
37  * modification, are permitted provided that the following conditions
38  * are met:
39  * 1. Redistributions of source code must retain the above copyright
40  *    notice, this list of conditions and the following disclaimer.
41  * 2. Redistributions in binary form must reproduce the above copyright
42  *    notice, this list of conditions and the following disclaimer in the
43  *    documentation and/or other materials provided with the distribution.
44  * 3. All advertising materials mentioning features or use of this software
45  *    must display the following acknowledgement:
46  *	This product includes software developed by Bill Paul.
47  * 4. Neither the name of the author nor the names of any co-contributors
48  *    may be used to endorse or promote products derived from this software
49  *    without specific prior written permission.
50  *
51  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
52  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
55  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
56  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
57  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
58  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
59  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
61  * THE POSSIBILITY OF SUCH DAMAGE.
62  */
63 
64 /*
65  * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for NetBSD.
66  *
67  * Original FreeBSD driver written by Bill Paul <wpaul@ctr.columbia.edu>
68  * Electrical Engineering Department
69  * Columbia University, New York City
70  */
71 
72 /*
73  * The WaveLAN/IEEE adapter is the second generation of the WaveLAN
74  * from Lucent. Unlike the older cards, the new ones are programmed
75  * entirely via a firmware-driven controller called the Hermes.
76  * Unfortunately, Lucent will not release the Hermes programming manual
77  * without an NDA (if at all). What they do release is an API library
78  * called the HCF (Hardware Control Functions) which is supposed to
79  * do the device-specific operations of a device driver for you. The
80  * publically available version of the HCF library (the 'HCF Light') is
81  * a) extremely gross, b) lacks certain features, particularly support
82  * for 802.11 frames, and c) is contaminated by the GNU Public License.
83  *
84  * This driver does not use the HCF or HCF Light at all. Instead, it
85  * programs the Hermes controller directly, using information gleaned
86  * from the HCF Light code and corresponding documentation.
87  *
88  * This driver supports both the PCMCIA and ISA versions of the
89  * WaveLAN/IEEE cards. Note however that the ISA card isn't really
90  * anything of the sort: it's actually a PCMCIA bridge adapter
91  * that fits into an ISA slot, into which a PCMCIA WaveLAN card is
92  * inserted. Consequently, you need to use the pccard support for
93  * both the ISA and PCMCIA adapters.
94  */
95 
96 /*
97  * FreeBSD driver ported to NetBSD by Bill Sommerfeld in the back of the
98  * Oslo IETF plenary meeting.
99  */
100 
101 #include <sys/cdefs.h>
102 __KERNEL_RCSID(0, "$NetBSD: wi.c,v 1.240 2016/06/10 13:27:14 ozaki-r Exp $");
103 
104 #define WI_HERMES_AUTOINC_WAR	/* Work around data write autoinc bug. */
105 #define WI_HERMES_STATS_WAR	/* Work around stats counter bug. */
106 #undef WI_HISTOGRAM
107 #undef WI_RING_DEBUG
108 #define STATIC static
109 
110 
111 #include <sys/param.h>
112 #include <sys/sysctl.h>
113 #include <sys/systm.h>
114 #include <sys/callout.h>
115 #include <sys/device.h>
116 #include <sys/socket.h>
117 #include <sys/mbuf.h>
118 #include <sys/ioctl.h>
119 #include <sys/kernel.h>		/* for hz */
120 #include <sys/proc.h>
121 #include <sys/kauth.h>
122 
123 #include <net/if.h>
124 #include <net/if_dl.h>
125 #include <net/if_llc.h>
126 #include <net/if_media.h>
127 #include <net/if_ether.h>
128 #include <net/route.h>
129 
130 #include <net80211/ieee80211_netbsd.h>
131 #include <net80211/ieee80211_var.h>
132 #include <net80211/ieee80211_ioctl.h>
133 #include <net80211/ieee80211_radiotap.h>
134 #include <net80211/ieee80211_rssadapt.h>
135 
136 #include <net/bpf.h>
137 #include <net/bpfdesc.h>
138 
139 #include <sys/bus.h>
140 
141 #include <dev/ic/wi_ieee.h>
142 #include <dev/ic/wireg.h>
143 #include <dev/ic/wivar.h>
144 
145 STATIC int  wi_init(struct ifnet *);
146 STATIC void wi_stop(struct ifnet *, int);
147 STATIC void wi_start(struct ifnet *);
148 STATIC int  wi_reset(struct wi_softc *);
149 STATIC void wi_watchdog(struct ifnet *);
150 STATIC int  wi_ioctl(struct ifnet *, u_long, void *);
151 STATIC int  wi_media_change(struct ifnet *);
152 STATIC void wi_media_status(struct ifnet *, struct ifmediareq *);
153 
154 static void wi_ioctl_init(struct wi_softc *);
155 static int wi_ioctl_enter(struct wi_softc *);
156 static void wi_ioctl_exit(struct wi_softc *);
157 static void wi_ioctl_drain(struct wi_softc *);
158 
159 STATIC struct ieee80211_node *wi_node_alloc(struct ieee80211_node_table *);
160 STATIC void wi_node_free(struct ieee80211_node *);
161 
162 STATIC void wi_raise_rate(struct ieee80211com *, struct ieee80211_rssdesc *);
163 STATIC void wi_lower_rate(struct ieee80211com *, struct ieee80211_rssdesc *);
164 STATIC int wi_choose_rate(struct ieee80211com *, struct ieee80211_node *,
165     struct ieee80211_frame *, u_int);
166 STATIC void wi_rssadapt_updatestats_cb(void *, struct ieee80211_node *);
167 STATIC void wi_rssadapt_updatestats(void *);
168 STATIC void wi_rssdescs_init(struct wi_rssdesc (*)[], wi_rssdescq_t *);
169 STATIC void wi_rssdescs_reset(struct ieee80211com *, struct wi_rssdesc (*)[],
170     wi_rssdescq_t *, u_int8_t (*)[]);
171 STATIC void wi_sync_bssid(struct wi_softc *, u_int8_t new_bssid[]);
172 
173 STATIC void wi_rx_intr(struct wi_softc *);
174 STATIC void wi_txalloc_intr(struct wi_softc *);
175 STATIC void wi_cmd_intr(struct wi_softc *);
176 STATIC void wi_tx_intr(struct wi_softc *);
177 STATIC void wi_tx_ex_intr(struct wi_softc *);
178 STATIC void wi_info_intr(struct wi_softc *);
179 
180 STATIC int wi_key_delete(struct ieee80211com *, const struct ieee80211_key *);
181 STATIC int wi_key_set(struct ieee80211com *, const struct ieee80211_key *,
182     const u_int8_t[IEEE80211_ADDR_LEN]);
183 STATIC void wi_key_update_begin(struct ieee80211com *);
184 STATIC void wi_key_update_end(struct ieee80211com *);
185 
186 STATIC void wi_push_packet(struct wi_softc *);
187 STATIC int  wi_get_cfg(struct ifnet *, u_long, void *);
188 STATIC int  wi_set_cfg(struct ifnet *, u_long, void *);
189 STATIC int  wi_cfg_txrate(struct wi_softc *);
190 STATIC int  wi_write_txrate(struct wi_softc *, int);
191 STATIC int  wi_write_wep(struct wi_softc *);
192 STATIC int  wi_write_multi(struct wi_softc *);
193 STATIC int  wi_alloc_fid(struct wi_softc *, int, int *);
194 STATIC void wi_read_nicid(struct wi_softc *);
195 STATIC int  wi_write_ssid(struct wi_softc *, int, u_int8_t *, int);
196 
197 STATIC int  wi_cmd(struct wi_softc *, int, int, int, int);
198 STATIC int  wi_cmd_start(struct wi_softc *, int, int, int, int);
199 STATIC int  wi_cmd_wait(struct wi_softc *, int, int);
200 STATIC int  wi_seek_bap(struct wi_softc *, int, int);
201 STATIC int  wi_read_bap(struct wi_softc *, int, int, void *, int);
202 STATIC int  wi_write_bap(struct wi_softc *, int, int, void *, int);
203 STATIC int  wi_mwrite_bap(struct wi_softc *, int, int, struct mbuf *, int);
204 STATIC int  wi_read_rid(struct wi_softc *, int, void *, int *);
205 STATIC int  wi_write_rid(struct wi_softc *, int, void *, int);
206 
207 STATIC int  wi_newstate(struct ieee80211com *, enum ieee80211_state, int);
208 STATIC void  wi_set_tim(struct ieee80211_node *, int);
209 
210 STATIC int  wi_scan_ap(struct wi_softc *, u_int16_t, u_int16_t);
211 STATIC void wi_scan_result(struct wi_softc *, int, int);
212 
213 STATIC void wi_dump_pkt(struct wi_frame *, struct ieee80211_node *, int rssi);
214 STATIC void wi_mend_flags(struct wi_softc *, enum ieee80211_state);
215 
216 static inline int
wi_write_val(struct wi_softc * sc,int rid,u_int16_t val)217 wi_write_val(struct wi_softc *sc, int rid, u_int16_t val)
218 {
219 
220 	val = htole16(val);
221 	return wi_write_rid(sc, rid, &val, sizeof(val));
222 }
223 
224 static	struct timeval lasttxerror;	/* time of last tx error msg */
225 static	int curtxeps = 0;		/* current tx error msgs/sec */
226 static	int wi_txerate = 0;		/* tx error rate: max msgs/sec */
227 
228 #ifdef WI_DEBUG
229 #define	WI_DEBUG_MAX	2
230 int wi_debug = 0;
231 
232 #define	DPRINTF(X)	if (wi_debug) printf X
233 #define	DPRINTF2(X)	if (wi_debug > 1) printf X
234 #define	IFF_DUMPPKTS(_ifp) \
235 	(((_ifp)->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
236 static int wi_sysctl_verify_debug(SYSCTLFN_PROTO);
237 #else
238 #define	DPRINTF(X)
239 #define	DPRINTF2(X)
240 #define	IFF_DUMPPKTS(_ifp)	0
241 #endif
242 
243 #define WI_INTRS	(WI_EV_RX | WI_EV_ALLOC | WI_EV_INFO | \
244 			 WI_EV_TX | WI_EV_TX_EXC | WI_EV_CMD)
245 
246 struct wi_card_ident
247 wi_card_ident[] = {
248 	/* CARD_ID			CARD_NAME		FIRM_TYPE */
249 	{ WI_NIC_LUCENT_ID,		WI_NIC_LUCENT_STR,	WI_LUCENT },
250 	{ WI_NIC_SONY_ID,		WI_NIC_SONY_STR,	WI_LUCENT },
251 	{ WI_NIC_LUCENT_EMB_ID,		WI_NIC_LUCENT_EMB_STR,	WI_LUCENT },
252 	{ WI_NIC_EVB2_ID,		WI_NIC_EVB2_STR,	WI_INTERSIL },
253 	{ WI_NIC_HWB3763_ID,		WI_NIC_HWB3763_STR,	WI_INTERSIL },
254 	{ WI_NIC_HWB3163_ID,		WI_NIC_HWB3163_STR,	WI_INTERSIL },
255 	{ WI_NIC_HWB3163B_ID,		WI_NIC_HWB3163B_STR,	WI_INTERSIL },
256 	{ WI_NIC_EVB3_ID,		WI_NIC_EVB3_STR,	WI_INTERSIL },
257 	{ WI_NIC_HWB1153_ID,		WI_NIC_HWB1153_STR,	WI_INTERSIL },
258 	{ WI_NIC_P2_SST_ID,		WI_NIC_P2_SST_STR,	WI_INTERSIL },
259 	{ WI_NIC_EVB2_SST_ID,		WI_NIC_EVB2_SST_STR,	WI_INTERSIL },
260 	{ WI_NIC_3842_EVA_ID,		WI_NIC_3842_EVA_STR,	WI_INTERSIL },
261 	{ WI_NIC_3842_PCMCIA_AMD_ID,	WI_NIC_3842_PCMCIA_STR,	WI_INTERSIL },
262 	{ WI_NIC_3842_PCMCIA_SST_ID,	WI_NIC_3842_PCMCIA_STR,	WI_INTERSIL },
263 	{ WI_NIC_3842_PCMCIA_ATM_ID,	WI_NIC_3842_PCMCIA_STR,	WI_INTERSIL },
264 	{ WI_NIC_3842_MINI_AMD_ID,	WI_NIC_3842_MINI_STR,	WI_INTERSIL },
265 	{ WI_NIC_3842_MINI_SST_ID,	WI_NIC_3842_MINI_STR,	WI_INTERSIL },
266 	{ WI_NIC_3842_MINI_ATM_ID,	WI_NIC_3842_MINI_STR,	WI_INTERSIL },
267 	{ WI_NIC_3842_PCI_AMD_ID,	WI_NIC_3842_PCI_STR,	WI_INTERSIL },
268 	{ WI_NIC_3842_PCI_SST_ID,	WI_NIC_3842_PCI_STR,	WI_INTERSIL },
269 	{ WI_NIC_3842_PCI_ATM_ID,	WI_NIC_3842_PCI_STR,	WI_INTERSIL },
270 	{ WI_NIC_P3_PCMCIA_AMD_ID,	WI_NIC_P3_PCMCIA_STR,	WI_INTERSIL },
271 	{ WI_NIC_P3_PCMCIA_SST_ID,	WI_NIC_P3_PCMCIA_STR,	WI_INTERSIL },
272 	{ WI_NIC_P3_MINI_AMD_ID,	WI_NIC_P3_MINI_STR,	WI_INTERSIL },
273 	{ WI_NIC_P3_MINI_SST_ID,	WI_NIC_P3_MINI_STR,	WI_INTERSIL },
274 	{ 0,	NULL,	0 },
275 };
276 
277 #ifndef _MODULE
278 /*
279  * Setup sysctl(3) MIB, hw.wi.*
280  *
281  * TBD condition CTLFLAG_PERMANENT on being a module or not
282  */
283 SYSCTL_SETUP(sysctl_wi, "sysctl wi(4) subtree setup")
284 {
285 	int rc;
286 	const struct sysctlnode *rnode;
287 #ifdef WI_DEBUG
288 	const struct sysctlnode *cnode;
289 #endif /* WI_DEBUG */
290 
291 	if ((rc = sysctl_createv(clog, 0, NULL, &rnode,
292 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "wi",
293 	    "Lucent/Prism/Symbol 802.11 controls",
294 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0)
295 		goto err;
296 
297 #ifdef WI_DEBUG
298 	/* control debugging printfs */
299 	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
300 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
301 	    "debug", SYSCTL_DESCR("Enable debugging output"),
302 	    wi_sysctl_verify_debug, 0, &wi_debug, 0, CTL_CREATE, CTL_EOL)) != 0)
303 		goto err;
304 #endif /* WI_DEBUG */
305 	return;
306 err:
307 	printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
308 }
309 #endif
310 
311 #ifdef WI_DEBUG
312 static int
wi_sysctl_verify(SYSCTLFN_ARGS,int lower,int upper)313 wi_sysctl_verify(SYSCTLFN_ARGS, int lower, int upper)
314 {
315 	int error, t;
316 	struct sysctlnode node;
317 
318 	node = *rnode;
319 	t = *(int*)rnode->sysctl_data;
320 	node.sysctl_data = &t;
321 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
322 	if (error || newp == NULL)
323 		return (error);
324 
325 	if (t < lower || t > upper)
326 		return (EINVAL);
327 
328 	*(int*)rnode->sysctl_data = t;
329 
330 	return (0);
331 }
332 
333 static int
wi_sysctl_verify_debug(SYSCTLFN_ARGS)334 wi_sysctl_verify_debug(SYSCTLFN_ARGS)
335 {
336 	return wi_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)),
337 	    0, WI_DEBUG_MAX);
338 }
339 #endif /* WI_DEBUG */
340 
341 STATIC int
wi_read_xrid(struct wi_softc * sc,int rid,void * buf,int ebuflen)342 wi_read_xrid(struct wi_softc *sc, int rid, void *buf, int ebuflen)
343 {
344 	int buflen, rc;
345 
346 	buflen = ebuflen;
347 	if ((rc = wi_read_rid(sc, rid, buf, &buflen)) != 0)
348 		return rc;
349 
350 	if (buflen < ebuflen) {
351 #ifdef WI_DEBUG
352 		printf("%s: rid=%#04x read %d, expected %d\n", __func__,
353 		    rid, buflen, ebuflen);
354 #endif
355 		return -1;
356 	}
357 	return 0;
358 }
359 
360 int
wi_attach(struct wi_softc * sc,const u_int8_t * macaddr)361 wi_attach(struct wi_softc *sc, const u_int8_t *macaddr)
362 {
363 	struct ieee80211com *ic = &sc->sc_ic;
364 	struct ifnet *ifp = &sc->sc_if;
365 	int chan, nrate, buflen;
366 	u_int16_t val, chanavail;
367  	struct {
368  		u_int16_t nrates;
369  		char rates[IEEE80211_RATE_SIZE];
370  	} ratebuf;
371 	static const u_int8_t empty_macaddr[IEEE80211_ADDR_LEN] = {
372 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00
373 	};
374 	int s;
375 
376 	wi_ioctl_init(sc);
377 
378 	s = splnet();
379 
380 	/* Make sure interrupts are disabled. */
381 	CSR_WRITE_2(sc, WI_INT_EN, 0);
382 	CSR_WRITE_2(sc, WI_EVENT_ACK, ~0);
383 
384 	sc->sc_invalid = 0;
385 
386 	/* Reset the NIC. */
387 	if (wi_reset(sc) != 0) {
388 		sc->sc_invalid = 1;
389 		splx(s);
390 		return 1;
391 	}
392 
393 	if (wi_read_xrid(sc, WI_RID_MAC_NODE, ic->ic_myaddr,
394 			 IEEE80211_ADDR_LEN) != 0 ||
395 	    IEEE80211_ADDR_EQ(ic->ic_myaddr, empty_macaddr)) {
396 		if (macaddr != NULL)
397 			memcpy(ic->ic_myaddr, macaddr, IEEE80211_ADDR_LEN);
398 		else {
399 			printf(" could not get mac address, attach failed\n");
400 			splx(s);
401 			return 1;
402 		}
403 	}
404 
405 	printf(" 802.11 address %s\n", ether_sprintf(ic->ic_myaddr));
406 
407 	/* Read NIC identification */
408 	wi_read_nicid(sc);
409 
410 	memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
411 	ifp->if_softc = sc;
412 	ifp->if_start = wi_start;
413 	ifp->if_ioctl = wi_ioctl;
414 	ifp->if_watchdog = wi_watchdog;
415 	ifp->if_init = wi_init;
416 	ifp->if_stop = wi_stop;
417 	ifp->if_flags =
418 	    IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST | IFF_NOTRAILERS;
419 	IFQ_SET_READY(&ifp->if_snd);
420 
421 	ic->ic_ifp = ifp;
422 	ic->ic_phytype = IEEE80211_T_DS;
423 	ic->ic_opmode = IEEE80211_M_STA;
424 	ic->ic_caps = IEEE80211_C_AHDEMO;
425 	ic->ic_state = IEEE80211_S_INIT;
426 	ic->ic_max_aid = WI_MAX_AID;
427 
428 	/* Find available channel */
429 	if (wi_read_xrid(sc, WI_RID_CHANNEL_LIST, &chanavail,
430 	                 sizeof(chanavail)) != 0) {
431 		aprint_normal_dev(sc->sc_dev, "using default channel list\n");
432 		chanavail = htole16(0x1fff);	/* assume 1-13 */
433 	}
434 	for (chan = 16; chan > 0; chan--) {
435 		if (!isset((u_int8_t*)&chanavail, chan - 1))
436 			continue;
437 		ic->ic_ibss_chan = &ic->ic_channels[chan];
438 		ic->ic_channels[chan].ic_freq =
439 		    ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ);
440 		ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_B;
441 	}
442 
443 	/* Find default IBSS channel */
444 	if (wi_read_xrid(sc, WI_RID_OWN_CHNL, &val, sizeof(val)) == 0) {
445 		chan = le16toh(val);
446 		if (isset((u_int8_t*)&chanavail, chan - 1))
447 			ic->ic_ibss_chan = &ic->ic_channels[chan];
448 	}
449 	if (ic->ic_ibss_chan == NULL) {
450 		aprint_error_dev(sc->sc_dev, "no available channel\n");
451 		return 1;
452 	}
453 
454 	if (sc->sc_firmware_type == WI_LUCENT) {
455 		sc->sc_dbm_offset = WI_LUCENT_DBM_OFFSET;
456 	} else {
457 		if ((sc->sc_flags & WI_FLAGS_HAS_DBMADJUST) &&
458 		    wi_read_xrid(sc, WI_RID_DBM_ADJUST, &val, sizeof(val)) == 0)
459 			sc->sc_dbm_offset = le16toh(val);
460 		else
461 			sc->sc_dbm_offset = WI_PRISM_DBM_OFFSET;
462 	}
463 
464 	sc->sc_flags |= WI_FLAGS_RSSADAPTSTA;
465 
466 	/*
467 	 * Set flags based on firmware version.
468 	 */
469 	switch (sc->sc_firmware_type) {
470 	case WI_LUCENT:
471 		sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE;
472 #ifdef WI_HERMES_AUTOINC_WAR
473 		/* XXX: not confirmed, but never seen for recent firmware */
474 		if (sc->sc_sta_firmware_ver <  40000) {
475 			sc->sc_flags |= WI_FLAGS_BUG_AUTOINC;
476 		}
477 #endif
478 		if (sc->sc_sta_firmware_ver >= 60000)
479 			sc->sc_flags |= WI_FLAGS_HAS_MOR;
480 		if (sc->sc_sta_firmware_ver >= 60006) {
481 			ic->ic_caps |= IEEE80211_C_IBSS;
482 			ic->ic_caps |= IEEE80211_C_MONITOR;
483 		}
484 		ic->ic_caps |= IEEE80211_C_PMGT;
485 		sc->sc_ibss_port = 1;
486 		break;
487 
488 	case WI_INTERSIL:
489 		sc->sc_flags |= WI_FLAGS_HAS_FRAGTHR;
490 		sc->sc_flags |= WI_FLAGS_HAS_ROAMING;
491 		sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE;
492 		if (sc->sc_sta_firmware_ver > 10101)
493 			sc->sc_flags |= WI_FLAGS_HAS_DBMADJUST;
494 		if (sc->sc_sta_firmware_ver >= 800) {
495 			if (sc->sc_sta_firmware_ver != 10402)
496 				ic->ic_caps |= IEEE80211_C_HOSTAP;
497 			ic->ic_caps |= IEEE80211_C_IBSS;
498 			ic->ic_caps |= IEEE80211_C_MONITOR;
499 		}
500 		ic->ic_caps |= IEEE80211_C_PMGT;
501 		sc->sc_ibss_port = 0;
502 		sc->sc_alt_retry = 2;
503 		break;
504 
505 	case WI_SYMBOL:
506 		sc->sc_flags |= WI_FLAGS_HAS_DIVERSITY;
507 		if (sc->sc_sta_firmware_ver >= 20000)
508 			ic->ic_caps |= IEEE80211_C_IBSS;
509 		sc->sc_ibss_port = 4;
510 		break;
511 	}
512 
513 	/*
514 	 * Find out if we support WEP on this card.
515 	 */
516 	if (wi_read_xrid(sc, WI_RID_WEP_AVAIL, &val, sizeof(val)) == 0 &&
517 	    val != htole16(0))
518 		ic->ic_caps |= IEEE80211_C_WEP;
519 
520 	/* Find supported rates. */
521 	buflen = sizeof(ratebuf);
522 	if (wi_read_rid(sc, WI_RID_DATA_RATES, &ratebuf, &buflen) == 0 &&
523 	    buflen > 2) {
524 		nrate = le16toh(ratebuf.nrates);
525 		if (nrate > IEEE80211_RATE_SIZE)
526 			nrate = IEEE80211_RATE_SIZE;
527 		memcpy(ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates,
528 		    &ratebuf.rates[0], nrate);
529 		ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = nrate;
530 	} else {
531 		aprint_error_dev(sc->sc_dev, "no supported rate list\n");
532 		return 1;
533 	}
534 
535 	sc->sc_max_datalen = 2304;
536 	sc->sc_rts_thresh = 2347;
537 	sc->sc_frag_thresh = 2346;
538 	sc->sc_system_scale = 1;
539 	sc->sc_cnfauthmode = IEEE80211_AUTH_OPEN;
540 	sc->sc_roaming_mode = 1;
541 
542 	callout_init(&sc->sc_rssadapt_ch, 0);
543 
544 	/*
545 	 * Call MI attach routines.
546 	 */
547 	if_attach(ifp);
548 	ieee80211_ifattach(ic);
549 
550 	sc->sc_newstate = ic->ic_newstate;
551 	sc->sc_set_tim = ic->ic_set_tim;
552 	ic->ic_newstate = wi_newstate;
553 	ic->ic_node_alloc = wi_node_alloc;
554 	ic->ic_node_free = wi_node_free;
555 	ic->ic_set_tim = wi_set_tim;
556 
557 	ic->ic_crypto.cs_key_delete = wi_key_delete;
558 	ic->ic_crypto.cs_key_set = wi_key_set;
559 	ic->ic_crypto.cs_key_update_begin = wi_key_update_begin;
560 	ic->ic_crypto.cs_key_update_end = wi_key_update_end;
561 
562 	ieee80211_media_init(ic, wi_media_change, wi_media_status);
563 
564 	bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
565 	    sizeof(struct ieee80211_frame) + 64, &sc->sc_drvbpf);
566 
567 	memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu));
568 	sc->sc_rxtap.wr_ihdr.it_len = htole16(sizeof(sc->sc_rxtapu));
569 	sc->sc_rxtap.wr_ihdr.it_present = htole32(WI_RX_RADIOTAP_PRESENT);
570 
571 	memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu));
572 	sc->sc_txtap.wt_ihdr.it_len = htole16(sizeof(sc->sc_txtapu));
573 	sc->sc_txtap.wt_ihdr.it_present = htole32(WI_TX_RADIOTAP_PRESENT);
574 
575 	/* Attach is successful. */
576 	sc->sc_attached = 1;
577 
578 	splx(s);
579 	ieee80211_announce(ic);
580 	return 0;
581 }
582 
583 int
wi_detach(struct wi_softc * sc)584 wi_detach(struct wi_softc *sc)
585 {
586 	struct ifnet *ifp = &sc->sc_if;
587 	int s;
588 
589 	if (!sc->sc_attached)
590 		return 0;
591 
592 	sc->sc_invalid = 1;
593 	s = splnet();
594 
595 	wi_stop(ifp, 1);
596 
597 	ieee80211_ifdetach(&sc->sc_ic);
598 	if_detach(ifp);
599 	splx(s);
600 	wi_ioctl_drain(sc);
601 	return 0;
602 }
603 
604 int
wi_activate(device_t self,enum devact act)605 wi_activate(device_t self, enum devact act)
606 {
607 	struct wi_softc *sc = device_private(self);
608 
609 	switch (act) {
610 	case DVACT_DEACTIVATE:
611 		if_deactivate(&sc->sc_if);
612 		return 0;
613 	default:
614 		return EOPNOTSUPP;
615 	}
616 }
617 
618 int
wi_intr(void * arg)619 wi_intr(void *arg)
620 {
621 	int i;
622 	struct wi_softc	*sc = arg;
623 	struct ifnet *ifp = &sc->sc_if;
624 	u_int16_t status;
625 
626 	if (sc->sc_enabled == 0 ||
627 	    !device_is_active(sc->sc_dev) ||
628 	    (ifp->if_flags & IFF_RUNNING) == 0)
629 		return 0;
630 
631 	if ((ifp->if_flags & IFF_UP) == 0) {
632 		CSR_WRITE_2(sc, WI_INT_EN, 0);
633 		CSR_WRITE_2(sc, WI_EVENT_ACK, ~0);
634 		return 1;
635 	}
636 
637 	/* This is superfluous on Prism, but Lucent breaks if we
638 	 * do not disable interrupts.
639 	 */
640 	CSR_WRITE_2(sc, WI_INT_EN, 0);
641 
642 	/* maximum 10 loops per interrupt */
643 	for (i = 0; i < 10; i++) {
644 		status = CSR_READ_2(sc, WI_EVENT_STAT);
645 #ifdef WI_DEBUG
646 		if (wi_debug > 1) {
647 			printf("%s: iter %d status %#04x\n", __func__, i,
648 			    status);
649 		}
650 #endif /* WI_DEBUG */
651 		if ((status & WI_INTRS) == 0)
652 			break;
653 
654 		sc->sc_status = status;
655 
656 		if (status & WI_EV_RX)
657 			wi_rx_intr(sc);
658 
659 		if (status & WI_EV_ALLOC)
660 			wi_txalloc_intr(sc);
661 
662 		if (status & WI_EV_TX)
663 			wi_tx_intr(sc);
664 
665 		if (status & WI_EV_TX_EXC)
666 			wi_tx_ex_intr(sc);
667 
668 		if (status & WI_EV_INFO)
669 			wi_info_intr(sc);
670 
671 		CSR_WRITE_2(sc, WI_EVENT_ACK, sc->sc_status);
672 
673 		if (sc->sc_status & WI_EV_CMD)
674 			wi_cmd_intr(sc);
675 
676 		if ((ifp->if_flags & IFF_OACTIVE) == 0 &&
677 		    (sc->sc_flags & WI_FLAGS_OUTRANGE) == 0 &&
678 		    !IFQ_IS_EMPTY(&ifp->if_snd))
679 			wi_start(ifp);
680 
681 		sc->sc_status = 0;
682 	}
683 
684 	/* re-enable interrupts */
685 	CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
686 
687 	sc->sc_status = 0;
688 
689 	return 1;
690 }
691 
692 #define arraylen(a) (sizeof(a) / sizeof((a)[0]))
693 
694 STATIC void
wi_rssdescs_init(struct wi_rssdesc (* rssd)[WI_NTXRSS],wi_rssdescq_t * rssdfree)695 wi_rssdescs_init(struct wi_rssdesc (*rssd)[WI_NTXRSS], wi_rssdescq_t *rssdfree)
696 {
697 	int i;
698 	SLIST_INIT(rssdfree);
699 	for (i = 0; i < arraylen(*rssd); i++) {
700 		SLIST_INSERT_HEAD(rssdfree, &(*rssd)[i], rd_next);
701 	}
702 }
703 
704 STATIC void
wi_rssdescs_reset(struct ieee80211com * ic,struct wi_rssdesc (* rssd)[WI_NTXRSS],wi_rssdescq_t * rssdfree,u_int8_t (* txpending)[IEEE80211_RATE_MAXSIZE])705 wi_rssdescs_reset(struct ieee80211com *ic, struct wi_rssdesc (*rssd)[WI_NTXRSS],
706     wi_rssdescq_t *rssdfree, u_int8_t (*txpending)[IEEE80211_RATE_MAXSIZE])
707 {
708 	struct ieee80211_node *ni;
709 	int i;
710 	for (i = 0; i < arraylen(*rssd); i++) {
711 		ni = (*rssd)[i].rd_desc.id_node;
712 		(*rssd)[i].rd_desc.id_node = NULL;
713 		if (ni != NULL && (ic->ic_ifp->if_flags & IFF_DEBUG) != 0)
714 			printf("%s: cleaning outstanding rssadapt "
715 			    "descriptor for %s\n",
716 			    ic->ic_ifp->if_xname, ether_sprintf(ni->ni_macaddr));
717 		if (ni != NULL)
718 			ieee80211_free_node(ni);
719 	}
720 	memset(*txpending, 0, sizeof(*txpending));
721 	wi_rssdescs_init(rssd, rssdfree);
722 }
723 
724 STATIC int
wi_init(struct ifnet * ifp)725 wi_init(struct ifnet *ifp)
726 {
727 	struct wi_softc *sc = ifp->if_softc;
728 	struct ieee80211com *ic = &sc->sc_ic;
729 	struct wi_joinreq join;
730 	int i;
731 	int error = 0, wasenabled;
732 
733 	DPRINTF(("wi_init: enabled %d\n", sc->sc_enabled));
734 	wasenabled = sc->sc_enabled;
735 	if (!sc->sc_enabled) {
736 		if ((error = (*sc->sc_enable)(sc->sc_dev, 1)) != 0)
737 			goto out;
738 		sc->sc_enabled = 1;
739 	} else
740 		wi_stop(ifp, 0);
741 
742 	/* Symbol firmware cannot be initialized more than once */
743 	if (sc->sc_firmware_type != WI_SYMBOL || !wasenabled)
744 		if ((error = wi_reset(sc)) != 0)
745 			goto out;
746 
747 	/* common 802.11 configuration */
748 	ic->ic_flags &= ~IEEE80211_F_IBSSON;
749 	sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
750 	switch (ic->ic_opmode) {
751 	case IEEE80211_M_STA:
752 		wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_BSS);
753 		break;
754 	case IEEE80211_M_IBSS:
755 		wi_write_val(sc, WI_RID_PORTTYPE, sc->sc_ibss_port);
756 		ic->ic_flags |= IEEE80211_F_IBSSON;
757 		break;
758 	case IEEE80211_M_AHDEMO:
759 		wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_ADHOC);
760 		break;
761 	case IEEE80211_M_HOSTAP:
762 		wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_HOSTAP);
763 		break;
764 	case IEEE80211_M_MONITOR:
765 		if (sc->sc_firmware_type == WI_LUCENT)
766 			wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_ADHOC);
767 		wi_cmd(sc, WI_CMD_TEST | (WI_TEST_MONITOR << 8), 0, 0, 0);
768 		break;
769 	}
770 
771 	/* Intersil interprets this RID as joining ESS even in IBSS mode */
772 	if (sc->sc_firmware_type == WI_LUCENT &&
773 	    (ic->ic_flags & IEEE80211_F_IBSSON) && ic->ic_des_esslen > 0)
774 		wi_write_val(sc, WI_RID_CREATE_IBSS, 1);
775 	else
776 		wi_write_val(sc, WI_RID_CREATE_IBSS, 0);
777 	wi_write_val(sc, WI_RID_MAX_SLEEP, ic->ic_lintval);
778 	wi_write_ssid(sc, WI_RID_DESIRED_SSID, ic->ic_des_essid,
779 	    ic->ic_des_esslen);
780 	wi_write_val(sc, WI_RID_OWN_CHNL,
781 	    ieee80211_chan2ieee(ic, ic->ic_ibss_chan));
782 	wi_write_ssid(sc, WI_RID_OWN_SSID, ic->ic_des_essid, ic->ic_des_esslen);
783 	IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
784 	wi_write_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, IEEE80211_ADDR_LEN);
785 	if (ic->ic_caps & IEEE80211_C_PMGT)
786 		wi_write_val(sc, WI_RID_PM_ENABLED,
787 		    (ic->ic_flags & IEEE80211_F_PMGTON) ? 1 : 0);
788 
789 	/* not yet common 802.11 configuration */
790 	wi_write_val(sc, WI_RID_MAX_DATALEN, sc->sc_max_datalen);
791 	wi_write_val(sc, WI_RID_RTS_THRESH, sc->sc_rts_thresh);
792 	if (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR)
793 		wi_write_val(sc, WI_RID_FRAG_THRESH, sc->sc_frag_thresh);
794 
795 	/* driver specific 802.11 configuration */
796 	if (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE)
797 		wi_write_val(sc, WI_RID_SYSTEM_SCALE, sc->sc_system_scale);
798 	if (sc->sc_flags & WI_FLAGS_HAS_ROAMING)
799 		wi_write_val(sc, WI_RID_ROAMING_MODE, sc->sc_roaming_mode);
800 	if (sc->sc_flags & WI_FLAGS_HAS_MOR)
801 		wi_write_val(sc, WI_RID_MICROWAVE_OVEN, sc->sc_microwave_oven);
802 	wi_cfg_txrate(sc);
803 	wi_write_ssid(sc, WI_RID_NODENAME, sc->sc_nodename, sc->sc_nodelen);
804 
805 #ifndef	IEEE80211_NO_HOSTAP
806 	if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
807 	    sc->sc_firmware_type == WI_INTERSIL) {
808 		wi_write_val(sc, WI_RID_OWN_BEACON_INT, ic->ic_lintval);
809 		wi_write_val(sc, WI_RID_DTIM_PERIOD, 1);
810 	}
811 #endif /* !IEEE80211_NO_HOSTAP */
812 
813 	if (sc->sc_firmware_type == WI_INTERSIL) {
814 		struct ieee80211_rateset *rs =
815 		    &ic->ic_sup_rates[IEEE80211_MODE_11B];
816 		u_int16_t basic = 0, supported = 0, rate;
817 
818 		for (i = 0; i < rs->rs_nrates; i++) {
819 			switch (rs->rs_rates[i] & IEEE80211_RATE_VAL) {
820 			case 2:
821 				rate = 1;
822 				break;
823 			case 4:
824 				rate = 2;
825 				break;
826 			case 11:
827 				rate = 4;
828 				break;
829 			case 22:
830 				rate = 8;
831 				break;
832 			default:
833 				rate = 0;
834 				break;
835 			}
836 			if (rs->rs_rates[i] & IEEE80211_RATE_BASIC)
837 				basic |= rate;
838 			supported |= rate;
839 		}
840 		wi_write_val(sc, WI_RID_BASIC_RATE, basic);
841 		wi_write_val(sc, WI_RID_SUPPORT_RATE, supported);
842 		wi_write_val(sc, WI_RID_ALT_RETRY_COUNT, sc->sc_alt_retry);
843 	}
844 
845 	/*
846 	 * Initialize promisc mode.
847 	 *	Being in Host-AP mode causes a great
848 	 *	deal of pain if promiscuous mode is set.
849 	 *	Therefore we avoid confusing the firmware
850 	 *	and always reset promisc mode in Host-AP
851 	 *	mode.  Host-AP sees all the packets anyway.
852 	 */
853 	if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
854 	    (ifp->if_flags & IFF_PROMISC) != 0) {
855 		wi_write_val(sc, WI_RID_PROMISC, 1);
856 	} else {
857 		wi_write_val(sc, WI_RID_PROMISC, 0);
858 	}
859 
860 	/* Configure WEP. */
861 	if (ic->ic_caps & IEEE80211_C_WEP) {
862 		sc->sc_cnfauthmode = ic->ic_bss->ni_authmode;
863 		wi_write_wep(sc);
864 	}
865 
866 	/* Set multicast filter. */
867 	wi_write_multi(sc);
868 
869 	sc->sc_txalloc = 0;
870 	sc->sc_txalloced = 0;
871 	sc->sc_txqueue = 0;
872 	sc->sc_txqueued = 0;
873 	sc->sc_txstart = 0;
874 	sc->sc_txstarted = 0;
875 
876 	if (sc->sc_firmware_type != WI_SYMBOL || !wasenabled) {
877 		sc->sc_buflen = IEEE80211_MAX_LEN + sizeof(struct wi_frame);
878 		if (sc->sc_firmware_type == WI_SYMBOL)
879 			sc->sc_buflen = 1585;	/* XXX */
880 		for (i = 0; i < WI_NTXBUF; i++) {
881 			error = wi_alloc_fid(sc, sc->sc_buflen,
882 			    &sc->sc_txd[i].d_fid);
883 			if (error) {
884 				aprint_error_dev(sc->sc_dev,
885 				    "tx buffer allocation failed\n");
886 				goto out;
887 			}
888 			DPRINTF2(("wi_init: txbuf %d allocated %x\n", i,
889 			    sc->sc_txd[i].d_fid));
890 			++sc->sc_txalloced;
891 		}
892 	}
893 
894 	wi_rssdescs_init(&sc->sc_rssd, &sc->sc_rssdfree);
895 
896 	/* Enable desired port */
897 	wi_cmd(sc, WI_CMD_ENABLE | sc->sc_portnum, 0, 0, 0);
898 	ifp->if_flags |= IFF_RUNNING;
899 	ifp->if_flags &= ~IFF_OACTIVE;
900 	ic->ic_state = IEEE80211_S_INIT;
901 
902 	if (ic->ic_opmode == IEEE80211_M_AHDEMO ||
903 	    ic->ic_opmode == IEEE80211_M_IBSS ||
904 	    ic->ic_opmode == IEEE80211_M_MONITOR ||
905 	    ic->ic_opmode == IEEE80211_M_HOSTAP)
906 		ieee80211_create_ibss(ic, ic->ic_ibss_chan);
907 
908 	/* Enable interrupts */
909 	CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
910 
911 #ifndef	IEEE80211_NO_HOSTAP
912 	if (!wasenabled &&
913 	    ic->ic_opmode == IEEE80211_M_HOSTAP &&
914 	    sc->sc_firmware_type == WI_INTERSIL) {
915 		/* XXX: some card need to be re-enabled for hostap */
916 		wi_cmd(sc, WI_CMD_DISABLE | WI_PORT0, 0, 0, 0);
917 		wi_cmd(sc, WI_CMD_ENABLE | WI_PORT0, 0, 0, 0);
918 	}
919 #endif /* !IEEE80211_NO_HOSTAP */
920 
921 	if (ic->ic_opmode == IEEE80211_M_STA &&
922 	    ((ic->ic_flags & IEEE80211_F_DESBSSID) ||
923 	    ic->ic_des_chan != IEEE80211_CHAN_ANYC)) {
924 		memset(&join, 0, sizeof(join));
925 		if (ic->ic_flags & IEEE80211_F_DESBSSID)
926 			IEEE80211_ADDR_COPY(&join.wi_bssid, ic->ic_des_bssid);
927 		if (ic->ic_des_chan != IEEE80211_CHAN_ANYC)
928 			join.wi_chan =
929 			    htole16(ieee80211_chan2ieee(ic, ic->ic_des_chan));
930 		/* Lucent firmware does not support the JOIN RID. */
931 		if (sc->sc_firmware_type != WI_LUCENT)
932 			wi_write_rid(sc, WI_RID_JOIN_REQ, &join, sizeof(join));
933 	}
934 
935  out:
936 	if (error) {
937 		printf("%s: interface not running\n", device_xname(sc->sc_dev));
938 		wi_stop(ifp, 0);
939 	}
940 	DPRINTF(("wi_init: return %d\n", error));
941 	return error;
942 }
943 
944 STATIC void
wi_txcmd_wait(struct wi_softc * sc)945 wi_txcmd_wait(struct wi_softc *sc)
946 {
947 	KASSERT(sc->sc_txcmds == 1);
948 	if (sc->sc_status & WI_EV_CMD) {
949 		sc->sc_status &= ~WI_EV_CMD;
950 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
951 	} else
952 		(void)wi_cmd_wait(sc, WI_CMD_TX | WI_RECLAIM, 0);
953 }
954 
955 STATIC void
wi_stop(struct ifnet * ifp,int disable)956 wi_stop(struct ifnet *ifp, int disable)
957 {
958 	struct wi_softc	*sc = ifp->if_softc;
959 	struct ieee80211com *ic = &sc->sc_ic;
960 	int s;
961 
962 	if (!sc->sc_enabled)
963 		return;
964 
965 	s = splnet();
966 
967 	DPRINTF(("wi_stop: disable %d\n", disable));
968 
969 	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
970 
971 	/* wait for tx command completion (deassoc, deauth) */
972 	while (sc->sc_txcmds > 0) {
973 		wi_txcmd_wait(sc);
974 		wi_cmd_intr(sc);
975 	}
976 
977 	/* TBD wait for deassoc, deauth tx completion? */
978 
979 	if (!sc->sc_invalid) {
980 		CSR_WRITE_2(sc, WI_INT_EN, 0);
981 		wi_cmd(sc, WI_CMD_DISABLE | sc->sc_portnum, 0, 0, 0);
982 	}
983 
984 	wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree,
985 	    &sc->sc_txpending);
986 
987 	sc->sc_tx_timer = 0;
988 	sc->sc_scan_timer = 0;
989 	sc->sc_false_syns = 0;
990 	sc->sc_naps = 0;
991 	ifp->if_flags &= ~(IFF_OACTIVE | IFF_RUNNING);
992 	ifp->if_timer = 0;
993 
994 	if (disable) {
995 		(*sc->sc_enable)(sc->sc_dev, 0);
996 		sc->sc_enabled = 0;
997 	}
998 	splx(s);
999 }
1000 
1001 /*
1002  * Choose a data rate for a packet len bytes long that suits the packet
1003  * type and the wireless conditions.
1004  *
1005  * TBD Adapt fragmentation threshold.
1006  */
1007 STATIC int
wi_choose_rate(struct ieee80211com * ic,struct ieee80211_node * ni,struct ieee80211_frame * wh,u_int len)1008 wi_choose_rate(struct ieee80211com *ic, struct ieee80211_node *ni,
1009     struct ieee80211_frame *wh, u_int len)
1010 {
1011 	struct wi_softc	*sc = ic->ic_ifp->if_softc;
1012 	struct wi_node *wn = (void*)ni;
1013 	struct ieee80211_rssadapt *ra = &wn->wn_rssadapt;
1014 	int do_not_adapt, i, rateidx, s;
1015 
1016 	do_not_adapt = (ic->ic_opmode != IEEE80211_M_HOSTAP) &&
1017 	    (sc->sc_flags & WI_FLAGS_RSSADAPTSTA) == 0;
1018 
1019 	s = splnet();
1020 
1021 	rateidx = ieee80211_rssadapt_choose(ra, &ni->ni_rates, wh, len,
1022 	    ic->ic_fixed_rate,
1023 	    ((ic->ic_ifp->if_flags & IFF_DEBUG) == 0) ? NULL : ic->ic_ifp->if_xname,
1024 	    do_not_adapt);
1025 
1026 	ni->ni_txrate = rateidx;
1027 
1028 	if (ic->ic_opmode != IEEE80211_M_HOSTAP) {
1029 		/* choose the slowest pending rate so that we don't
1030 		 * accidentally send a packet on the MAC's queue
1031 		 * too fast. TBD find out if the MAC labels Tx
1032 		 * packets w/ rate when enqueued or dequeued.
1033 		 */
1034 		for (i = 0; i < rateidx && sc->sc_txpending[i] == 0; i++);
1035 		rateidx = i;
1036 	}
1037 
1038 	splx(s);
1039 	return (rateidx);
1040 }
1041 
1042 STATIC void
wi_raise_rate(struct ieee80211com * ic,struct ieee80211_rssdesc * id)1043 wi_raise_rate(struct ieee80211com *ic, struct ieee80211_rssdesc *id)
1044 {
1045 	struct wi_node *wn;
1046 	if (id->id_node == NULL)
1047 		return;
1048 
1049 	wn = (void*)id->id_node;
1050 	ieee80211_rssadapt_raise_rate(ic, &wn->wn_rssadapt, id);
1051 }
1052 
1053 STATIC void
wi_lower_rate(struct ieee80211com * ic,struct ieee80211_rssdesc * id)1054 wi_lower_rate(struct ieee80211com *ic, struct ieee80211_rssdesc *id)
1055 {
1056 	struct ieee80211_node *ni;
1057 	struct wi_node *wn;
1058 	int s;
1059 
1060 	s = splnet();
1061 
1062 	if ((ni = id->id_node) == NULL) {
1063 		DPRINTF(("wi_lower_rate: missing node\n"));
1064 		goto out;
1065 	}
1066 
1067 	wn = (void *)ni;
1068 
1069 	ieee80211_rssadapt_lower_rate(ic, ni, &wn->wn_rssadapt, id);
1070 out:
1071 	splx(s);
1072 	return;
1073 }
1074 
1075 STATIC void
wi_start(struct ifnet * ifp)1076 wi_start(struct ifnet *ifp)
1077 {
1078 	struct wi_softc	*sc = ifp->if_softc;
1079 	struct ieee80211com *ic = &sc->sc_ic;
1080 	struct ether_header *eh;
1081 	struct ieee80211_node *ni;
1082 	struct ieee80211_frame *wh;
1083 	struct ieee80211_rateset *rs;
1084 	struct wi_rssdesc *rd;
1085 	struct ieee80211_rssdesc *id;
1086 	struct mbuf *m0;
1087 	struct wi_frame frmhdr;
1088 	int cur, fid, off, rateidx;
1089 
1090 	if (!sc->sc_enabled || sc->sc_invalid)
1091 		return;
1092 	if (sc->sc_flags & WI_FLAGS_OUTRANGE)
1093 		return;
1094 
1095 	memset(&frmhdr, 0, sizeof(frmhdr));
1096 	cur = sc->sc_txqueue;
1097 	for (;;) {
1098 		ni = ic->ic_bss;
1099 		if (sc->sc_txalloced == 0 || SLIST_EMPTY(&sc->sc_rssdfree)) {
1100 			ifp->if_flags |= IFF_OACTIVE;
1101 			break;
1102 		}
1103 		if (!IF_IS_EMPTY(&ic->ic_mgtq)) {
1104 			IF_DEQUEUE(&ic->ic_mgtq, m0);
1105 			m_copydata(m0, 4, ETHER_ADDR_LEN * 2,
1106 			    (void *)&frmhdr.wi_ehdr);
1107 			frmhdr.wi_ehdr.ether_type = 0;
1108                         wh = mtod(m0, struct ieee80211_frame *);
1109 			ni = M_GETCTX(m0, struct ieee80211_node *);
1110 			M_CLEARCTX(m0);
1111 		} else if (ic->ic_state == IEEE80211_S_RUN) {
1112 			IFQ_POLL(&ifp->if_snd, m0);
1113 			if (m0 == NULL)
1114 				break;
1115 			IFQ_DEQUEUE(&ifp->if_snd, m0);
1116 			ifp->if_opackets++;
1117 			m_copydata(m0, 0, ETHER_HDR_LEN,
1118 			    (void *)&frmhdr.wi_ehdr);
1119 			bpf_mtap(ifp, m0);
1120 
1121 			eh = mtod(m0, struct ether_header *);
1122 			ni = ieee80211_find_txnode(ic, eh->ether_dhost);
1123 			if (ni == NULL) {
1124 				ifp->if_oerrors++;
1125 				continue;
1126 			}
1127 			if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
1128 			    (m0->m_flags & M_PWR_SAV) == 0) {
1129 				ieee80211_pwrsave(ic, ni, m0);
1130 				goto next;
1131 			}
1132 			if ((m0 = ieee80211_encap(ic, m0, ni)) == NULL) {
1133 				ieee80211_free_node(ni);
1134 				ifp->if_oerrors++;
1135 				continue;
1136 			}
1137 			wh = mtod(m0, struct ieee80211_frame *);
1138 		} else
1139 			break;
1140 		bpf_mtap3(ic->ic_rawbpf, m0);
1141 		frmhdr.wi_tx_ctl =
1142 		    htole16(WI_ENC_TX_802_11|WI_TXCNTL_TX_EX|WI_TXCNTL_TX_OK);
1143 #ifndef	IEEE80211_NO_HOSTAP
1144 		if (ic->ic_opmode == IEEE80211_M_HOSTAP)
1145 			frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_ALTRTRY);
1146 		if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
1147 		    (wh->i_fc[1] & IEEE80211_FC1_WEP)) {
1148 			if (ieee80211_crypto_encap(ic, ni, m0) == NULL) {
1149 				m_freem(m0);
1150 				ifp->if_oerrors++;
1151 				goto next;
1152 			}
1153 			frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT);
1154 		}
1155 #endif /* !IEEE80211_NO_HOSTAP */
1156 
1157 		rateidx = wi_choose_rate(ic, ni, wh, m0->m_pkthdr.len);
1158 		rs = &ni->ni_rates;
1159 
1160 		if (sc->sc_drvbpf) {
1161 			struct wi_tx_radiotap_header *tap = &sc->sc_txtap;
1162 
1163 			tap->wt_rate = rs->rs_rates[rateidx];
1164 			tap->wt_chan_freq =
1165 			    htole16(ic->ic_bss->ni_chan->ic_freq);
1166 			tap->wt_chan_flags =
1167 			    htole16(ic->ic_bss->ni_chan->ic_flags);
1168 			/* TBD tap->wt_flags */
1169 
1170 			bpf_mtap2(sc->sc_drvbpf, tap, tap->wt_ihdr.it_len, m0);
1171 		}
1172 
1173 		rd = SLIST_FIRST(&sc->sc_rssdfree);
1174 		id = &rd->rd_desc;
1175 		id->id_len = m0->m_pkthdr.len;
1176 		id->id_rateidx = ni->ni_txrate;
1177 		id->id_rssi = ni->ni_rssi;
1178 
1179 		frmhdr.wi_tx_idx = rd - sc->sc_rssd;
1180 
1181 		if (ic->ic_opmode == IEEE80211_M_HOSTAP)
1182 			frmhdr.wi_tx_rate = 5 * (rs->rs_rates[rateidx] &
1183 			    IEEE80211_RATE_VAL);
1184 		else if (sc->sc_flags & WI_FLAGS_RSSADAPTSTA)
1185 			(void)wi_write_txrate(sc, rs->rs_rates[rateidx]);
1186 
1187 		m_copydata(m0, 0, sizeof(struct ieee80211_frame),
1188 		    (void *)&frmhdr.wi_whdr);
1189 		m_adj(m0, sizeof(struct ieee80211_frame));
1190 		frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len);
1191 		if (IFF_DUMPPKTS(ifp))
1192 			wi_dump_pkt(&frmhdr, ni, -1);
1193 		fid = sc->sc_txd[cur].d_fid;
1194 		off = sizeof(frmhdr);
1195 		if (wi_write_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr)) != 0 ||
1196 		    wi_mwrite_bap(sc, fid, off, m0, m0->m_pkthdr.len) != 0) {
1197 			aprint_error_dev(sc->sc_dev, "%s write fid %x failed\n",
1198 			    __func__, fid);
1199 			ifp->if_oerrors++;
1200 			m_freem(m0);
1201 			goto next;
1202 		}
1203 		m_freem(m0);
1204 		sc->sc_txpending[ni->ni_txrate]++;
1205 		--sc->sc_txalloced;
1206 		if (sc->sc_txqueued++ == 0) {
1207 #ifdef DIAGNOSTIC
1208 			if (cur != sc->sc_txstart)
1209 				printf("%s: ring is desynchronized\n",
1210 				    device_xname(sc->sc_dev));
1211 #endif
1212 			wi_push_packet(sc);
1213 		} else {
1214 #ifdef WI_RING_DEBUG
1215 	printf("%s: queue %04x, alloc %d queue %d start %d alloced %d queued %d started %d\n",
1216 	    device_xname(sc->sc_dev), fid,
1217 	    sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart,
1218 	    sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted);
1219 #endif
1220 		}
1221 		sc->sc_txqueue = cur = (cur + 1) % WI_NTXBUF;
1222 		SLIST_REMOVE_HEAD(&sc->sc_rssdfree, rd_next);
1223 		id->id_node = ni;
1224 		continue;
1225 next:
1226 		if (ni != NULL)
1227 			ieee80211_free_node(ni);
1228 	}
1229 }
1230 
1231 
1232 STATIC int
wi_reset(struct wi_softc * sc)1233 wi_reset(struct wi_softc *sc)
1234 {
1235 	int i, error;
1236 
1237 	DPRINTF(("wi_reset\n"));
1238 
1239 	if (sc->sc_reset)
1240 		(*sc->sc_reset)(sc);
1241 
1242 	error = 0;
1243 	for (i = 0; i < 5; i++) {
1244 		if (sc->sc_invalid)
1245 			return ENXIO;
1246 		DELAY(20*1000);	/* XXX: way too long! */
1247 		if ((error = wi_cmd(sc, WI_CMD_INI, 0, 0, 0)) == 0)
1248 			break;
1249 	}
1250 	if (error) {
1251 		aprint_error_dev(sc->sc_dev, "init failed\n");
1252 		return error;
1253 	}
1254 	CSR_WRITE_2(sc, WI_INT_EN, 0);
1255 	CSR_WRITE_2(sc, WI_EVENT_ACK, ~0);
1256 
1257 	/* Calibrate timer. */
1258 	wi_write_val(sc, WI_RID_TICK_TIME, 0);
1259 	return 0;
1260 }
1261 
1262 STATIC void
wi_watchdog(struct ifnet * ifp)1263 wi_watchdog(struct ifnet *ifp)
1264 {
1265 	struct wi_softc *sc = ifp->if_softc;
1266 
1267 	ifp->if_timer = 0;
1268 	if (!sc->sc_enabled)
1269 		return;
1270 
1271 	if (sc->sc_tx_timer) {
1272 		if (--sc->sc_tx_timer == 0) {
1273 			printf("%s: device timeout\n", ifp->if_xname);
1274 			ifp->if_oerrors++;
1275 			wi_init(ifp);
1276 			return;
1277 		}
1278 		ifp->if_timer = 1;
1279 	}
1280 
1281 	if (sc->sc_scan_timer) {
1282 		if (--sc->sc_scan_timer <= WI_SCAN_WAIT - WI_SCAN_INQWAIT &&
1283 		    sc->sc_firmware_type == WI_INTERSIL) {
1284 			DPRINTF(("wi_watchdog: inquire scan\n"));
1285 			wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0);
1286 		}
1287 		if (sc->sc_scan_timer)
1288 			ifp->if_timer = 1;
1289 	}
1290 
1291 	/* TODO: rate control */
1292 	ieee80211_watchdog(&sc->sc_ic);
1293 }
1294 
1295 static int
wi_ioctl_enter(struct wi_softc * sc)1296 wi_ioctl_enter(struct wi_softc *sc)
1297 {
1298 	int rc = 0;
1299 
1300 	mutex_enter(&sc->sc_ioctl_mtx);
1301 	sc->sc_ioctl_nwait++;
1302 	while (sc->sc_ioctl_lwp != NULL && sc->sc_ioctl_lwp != curlwp) {
1303 		rc = sc->sc_ioctl_gone
1304 		    ? ENXIO
1305 		    : cv_wait_sig(&sc->sc_ioctl_cv, &sc->sc_ioctl_mtx);
1306 		if (rc != 0)
1307 			break;
1308 	}
1309 	if (rc == 0) {
1310 		sc->sc_ioctl_lwp = curlwp;
1311 		sc->sc_ioctl_depth++;
1312 	}
1313 	if (--sc->sc_ioctl_nwait == 0)
1314 		cv_signal(&sc->sc_ioctl_cv);
1315 	mutex_exit(&sc->sc_ioctl_mtx);
1316 	return rc;
1317 }
1318 
1319 static void
wi_ioctl_exit(struct wi_softc * sc)1320 wi_ioctl_exit(struct wi_softc *sc)
1321 {
1322 	KASSERT(sc->sc_ioctl_lwp == curlwp);
1323 	mutex_enter(&sc->sc_ioctl_mtx);
1324 	if (--sc->sc_ioctl_depth == 0) {
1325 		sc->sc_ioctl_lwp = NULL;
1326 		cv_signal(&sc->sc_ioctl_cv);
1327 	}
1328 	mutex_exit(&sc->sc_ioctl_mtx);
1329 }
1330 
1331 static void
wi_ioctl_init(struct wi_softc * sc)1332 wi_ioctl_init(struct wi_softc *sc)
1333 {
1334 	mutex_init(&sc->sc_ioctl_mtx, MUTEX_DEFAULT, IPL_NONE);
1335 	cv_init(&sc->sc_ioctl_cv, device_xname(sc->sc_dev));
1336 }
1337 
1338 static void
wi_ioctl_drain(struct wi_softc * sc)1339 wi_ioctl_drain(struct wi_softc *sc)
1340 {
1341 	wi_ioctl_enter(sc);
1342 
1343 	mutex_enter(&sc->sc_ioctl_mtx);
1344 	sc->sc_ioctl_gone = true;
1345 	cv_broadcast(&sc->sc_ioctl_cv);
1346 	while (sc->sc_ioctl_nwait != 0)
1347 		cv_wait(&sc->sc_ioctl_cv, &sc->sc_ioctl_mtx);
1348 	mutex_exit(&sc->sc_ioctl_mtx);
1349 
1350 	wi_ioctl_exit(sc);
1351 
1352 	mutex_destroy(&sc->sc_ioctl_mtx);
1353 	cv_destroy(&sc->sc_ioctl_cv);
1354 }
1355 
1356 STATIC int
wi_ioctl(struct ifnet * ifp,u_long cmd,void * data)1357 wi_ioctl(struct ifnet *ifp, u_long cmd, void *data)
1358 {
1359 	struct wi_softc *sc = ifp->if_softc;
1360 	struct ieee80211com *ic = &sc->sc_ic;
1361 	struct ifreq *ifr = (struct ifreq *)data;
1362 	int s, error = 0;
1363 
1364 	if (!device_is_active(sc->sc_dev))
1365 		return ENXIO;
1366 
1367 	s = splnet();
1368 
1369 	if ((error = wi_ioctl_enter(sc)) != 0)
1370 		return error;
1371 
1372 	switch (cmd) {
1373 	case SIOCSIFFLAGS:
1374 		if ((error = ifioctl_common(ifp, cmd, data)) != 0)
1375 			break;
1376 		/*
1377 		 * Can't do promisc and hostap at the same time.  If all that's
1378 		 * changing is the promisc flag, try to short-circuit a call to
1379 		 * wi_init() by just setting PROMISC in the hardware.
1380 		 */
1381 		if (ifp->if_flags & IFF_UP) {
1382 			if (sc->sc_enabled) {
1383 				if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
1384 				    (ifp->if_flags & IFF_PROMISC) != 0)
1385 					wi_write_val(sc, WI_RID_PROMISC, 1);
1386 				else
1387 					wi_write_val(sc, WI_RID_PROMISC, 0);
1388 			} else
1389 				error = wi_init(ifp);
1390 		} else if (sc->sc_enabled)
1391 			wi_stop(ifp, 1);
1392 		break;
1393 	case SIOCSIFMEDIA:
1394 	case SIOCGIFMEDIA:
1395 		error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1396 		break;
1397 	case SIOCADDMULTI:
1398 	case SIOCDELMULTI:
1399 		if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
1400 			if (ifp->if_flags & IFF_RUNNING) {
1401 				/* do not rescan */
1402 				error = wi_write_multi(sc);
1403 			} else
1404 				error = 0;
1405 		}
1406 		break;
1407 	case SIOCGIFGENERIC:
1408 		error = wi_get_cfg(ifp, cmd, data);
1409 		break;
1410 	case SIOCSIFGENERIC:
1411 		error = kauth_authorize_network(curlwp->l_cred,
1412 		    KAUTH_NETWORK_INTERFACE,
1413 		    KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, KAUTH_ARG(cmd),
1414 		    NULL);
1415 		if (error)
1416 			break;
1417 		error = wi_set_cfg(ifp, cmd, data);
1418 		if (error == ENETRESET) {
1419 			if (ifp->if_flags & IFF_RUNNING)
1420 				error = wi_init(ifp);
1421 			else
1422 				error = 0;
1423 		}
1424 		break;
1425 	case SIOCS80211BSSID:
1426 		if (sc->sc_firmware_type == WI_LUCENT) {
1427 			error = ENODEV;
1428 			break;
1429 		}
1430 		/* fall through */
1431 	default:
1432 		ic->ic_flags |= sc->sc_ic_flags;
1433 		error = ieee80211_ioctl(&sc->sc_ic, cmd, data);
1434 		sc->sc_ic_flags = ic->ic_flags & IEEE80211_F_DROPUNENC;
1435 		if (error == ENETRESET) {
1436 			if (sc->sc_enabled)
1437 				error = wi_init(ifp);
1438 			else
1439 				error = 0;
1440 		}
1441 		break;
1442 	}
1443 	wi_mend_flags(sc, ic->ic_state);
1444 	wi_ioctl_exit(sc);
1445 	splx(s);
1446 	return error;
1447 }
1448 
1449 STATIC int
wi_media_change(struct ifnet * ifp)1450 wi_media_change(struct ifnet *ifp)
1451 {
1452 	struct wi_softc *sc = ifp->if_softc;
1453 	struct ieee80211com *ic = &sc->sc_ic;
1454 	int error;
1455 
1456 	error = ieee80211_media_change(ifp);
1457 	if (error == ENETRESET) {
1458 		if (sc->sc_enabled)
1459 			error = wi_init(ifp);
1460 		else
1461 			error = 0;
1462 	}
1463 	ifp->if_baudrate = ifmedia_baudrate(ic->ic_media.ifm_cur->ifm_media);
1464 
1465 	return error;
1466 }
1467 
1468 STATIC void
wi_media_status(struct ifnet * ifp,struct ifmediareq * imr)1469 wi_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1470 {
1471 	struct wi_softc *sc = ifp->if_softc;
1472 	struct ieee80211com *ic = &sc->sc_ic;
1473 	u_int16_t val;
1474 	int rate;
1475 
1476 	if (sc->sc_enabled == 0) {
1477 		imr->ifm_active = IFM_IEEE80211 | IFM_NONE;
1478 		imr->ifm_status = 0;
1479 		return;
1480 	}
1481 
1482 	imr->ifm_status = IFM_AVALID;
1483 	imr->ifm_active = IFM_IEEE80211;
1484 	if (ic->ic_state == IEEE80211_S_RUN &&
1485 	    (sc->sc_flags & WI_FLAGS_OUTRANGE) == 0)
1486 		imr->ifm_status |= IFM_ACTIVE;
1487 	if (wi_read_xrid(sc, WI_RID_CUR_TX_RATE, &val, sizeof(val)) == 0) {
1488 		/* convert to 802.11 rate */
1489 		val = le16toh(val);
1490 		rate = val * 2;
1491 		if (sc->sc_firmware_type == WI_LUCENT) {
1492 			if (rate == 10)
1493 				rate = 11;	/* 5.5Mbps */
1494 		} else {
1495 			if (rate == 4*2)
1496 				rate = 11;	/* 5.5Mbps */
1497 			else if (rate == 8*2)
1498 				rate = 22;	/* 11Mbps */
1499 		}
1500 	} else
1501 		rate = 0;
1502 	imr->ifm_active |= ieee80211_rate2media(ic, rate, IEEE80211_MODE_11B);
1503 	switch (ic->ic_opmode) {
1504 	case IEEE80211_M_STA:
1505 		break;
1506 	case IEEE80211_M_IBSS:
1507 		imr->ifm_active |= IFM_IEEE80211_ADHOC;
1508 		break;
1509 	case IEEE80211_M_AHDEMO:
1510 		imr->ifm_active |= IFM_IEEE80211_ADHOC | IFM_FLAG0;
1511 		break;
1512 	case IEEE80211_M_HOSTAP:
1513 		imr->ifm_active |= IFM_IEEE80211_HOSTAP;
1514 		break;
1515 	case IEEE80211_M_MONITOR:
1516 		imr->ifm_active |= IFM_IEEE80211_MONITOR;
1517 		break;
1518 	}
1519 }
1520 
1521 STATIC struct ieee80211_node *
wi_node_alloc(struct ieee80211_node_table * nt)1522 wi_node_alloc(struct ieee80211_node_table *nt)
1523 {
1524 	struct wi_node *wn =
1525 	    malloc(sizeof(struct wi_node), M_DEVBUF, M_NOWAIT | M_ZERO);
1526 	return wn ? &wn->wn_node : NULL;
1527 }
1528 
1529 STATIC void
wi_node_free(struct ieee80211_node * ni)1530 wi_node_free(struct ieee80211_node *ni)
1531 {
1532 	struct wi_softc *sc = ni->ni_ic->ic_ifp->if_softc;
1533 	int i;
1534 
1535 	for (i = 0; i < WI_NTXRSS; i++) {
1536 		if (sc->sc_rssd[i].rd_desc.id_node == ni)
1537 			sc->sc_rssd[i].rd_desc.id_node = NULL;
1538 	}
1539 	free(ni, M_DEVBUF);
1540 }
1541 
1542 STATIC void
wi_sync_bssid(struct wi_softc * sc,u_int8_t new_bssid[IEEE80211_ADDR_LEN])1543 wi_sync_bssid(struct wi_softc *sc, u_int8_t new_bssid[IEEE80211_ADDR_LEN])
1544 {
1545 	struct ieee80211com *ic = &sc->sc_ic;
1546 	struct ieee80211_node *ni = ic->ic_bss;
1547 	struct ifnet *ifp = &sc->sc_if;
1548 
1549 	if (IEEE80211_ADDR_EQ(new_bssid, ni->ni_bssid))
1550 		return;
1551 
1552 	DPRINTF(("wi_sync_bssid: bssid %s -> ", ether_sprintf(ni->ni_bssid)));
1553 	DPRINTF(("%s ?\n", ether_sprintf(new_bssid)));
1554 
1555 	/* In promiscuous mode, the BSSID field is not a reliable
1556 	 * indicator of the firmware's BSSID. Damp spurious
1557 	 * change-of-BSSID indications.
1558 	 */
1559 	if ((ifp->if_flags & IFF_PROMISC) != 0 &&
1560 	    !ppsratecheck(&sc->sc_last_syn, &sc->sc_false_syns,
1561 	                 WI_MAX_FALSE_SYNS))
1562 		return;
1563 
1564 	sc->sc_false_syns = MAX(0, sc->sc_false_syns - 1);
1565 	/*
1566 	 * XXX hack; we should create a new node with the new bssid
1567 	 * and replace the existing ic_bss with it but since we don't
1568 	 * process management frames to collect state we cheat by
1569 	 * reusing the existing node as we know wi_newstate will be
1570 	 * called and it will overwrite the node state.
1571 	 */
1572         ieee80211_sta_join(ic, ieee80211_ref_node(ni));
1573 }
1574 
1575 static inline void
wi_rssadapt_input(struct ieee80211com * ic,struct ieee80211_node * ni,struct ieee80211_frame * wh,int rssi)1576 wi_rssadapt_input(struct ieee80211com *ic, struct ieee80211_node *ni,
1577     struct ieee80211_frame *wh, int rssi)
1578 {
1579 	struct wi_node *wn;
1580 
1581 	if (ni == NULL) {
1582 		printf("%s: null node", __func__);
1583 		return;
1584 	}
1585 
1586 	wn = (void*)ni;
1587 	ieee80211_rssadapt_input(ic, ni, &wn->wn_rssadapt, rssi);
1588 }
1589 
1590 STATIC void
wi_rx_intr(struct wi_softc * sc)1591 wi_rx_intr(struct wi_softc *sc)
1592 {
1593 	struct ieee80211com *ic = &sc->sc_ic;
1594 	struct ifnet *ifp = &sc->sc_if;
1595 	struct ieee80211_node *ni;
1596 	struct wi_frame frmhdr;
1597 	struct mbuf *m;
1598 	struct ieee80211_frame *wh;
1599 	int fid, len, off, rssi;
1600 	u_int8_t dir;
1601 	u_int16_t status;
1602 	u_int32_t rstamp;
1603 
1604 	fid = CSR_READ_2(sc, WI_RX_FID);
1605 
1606 	/* First read in the frame header */
1607 	if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr))) {
1608 		aprint_error_dev(sc->sc_dev, "%s read fid %x failed\n",
1609 		    __func__, fid);
1610 		ifp->if_ierrors++;
1611 		return;
1612 	}
1613 
1614 	if (IFF_DUMPPKTS(ifp))
1615 		wi_dump_pkt(&frmhdr, NULL, frmhdr.wi_rx_signal);
1616 
1617 	/*
1618 	 * Drop undecryptable or packets with receive errors here
1619 	 */
1620 	status = le16toh(frmhdr.wi_status);
1621 	if ((status & WI_STAT_ERRSTAT) != 0 &&
1622 	    ic->ic_opmode != IEEE80211_M_MONITOR) {
1623 		ifp->if_ierrors++;
1624 		DPRINTF(("wi_rx_intr: fid %x error status %x\n", fid, status));
1625 		return;
1626 	}
1627 	rssi = frmhdr.wi_rx_signal;
1628 	rstamp = (le16toh(frmhdr.wi_rx_tstamp0) << 16) |
1629 	    le16toh(frmhdr.wi_rx_tstamp1);
1630 
1631 	len = le16toh(frmhdr.wi_dat_len);
1632 	off = ALIGN(sizeof(struct ieee80211_frame));
1633 
1634 	/* Sometimes the PRISM2.x returns bogusly large frames. Except
1635 	 * in monitor mode, just throw them away.
1636 	 */
1637 	if (off + len > MCLBYTES) {
1638 		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
1639 			ifp->if_ierrors++;
1640 			DPRINTF(("wi_rx_intr: oversized packet\n"));
1641 			return;
1642 		} else
1643 			len = 0;
1644 	}
1645 
1646 	MGETHDR(m, M_DONTWAIT, MT_DATA);
1647 	if (m == NULL) {
1648 		ifp->if_ierrors++;
1649 		DPRINTF(("wi_rx_intr: MGET failed\n"));
1650 		return;
1651 	}
1652 	if (off + len > MHLEN) {
1653 		MCLGET(m, M_DONTWAIT);
1654 		if ((m->m_flags & M_EXT) == 0) {
1655 			m_freem(m);
1656 			ifp->if_ierrors++;
1657 			DPRINTF(("wi_rx_intr: MCLGET failed\n"));
1658 			return;
1659 		}
1660 	}
1661 
1662 	m->m_data += off - sizeof(struct ieee80211_frame);
1663 	memcpy(m->m_data, &frmhdr.wi_whdr, sizeof(struct ieee80211_frame));
1664 	wi_read_bap(sc, fid, sizeof(frmhdr),
1665 	    m->m_data + sizeof(struct ieee80211_frame), len);
1666 	m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame) + len;
1667 	m_set_rcvif(m, ifp);
1668 
1669 	wh = mtod(m, struct ieee80211_frame *);
1670 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1671 		/*
1672 		 * WEP is decrypted by hardware. Clear WEP bit
1673 		 * header for ieee80211_input().
1674 		 */
1675 		wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
1676 	}
1677 	if (sc->sc_drvbpf) {
1678 		struct wi_rx_radiotap_header *tap = &sc->sc_rxtap;
1679 
1680 		tap->wr_rate = frmhdr.wi_rx_rate / 5;
1681 		tap->wr_antsignal = frmhdr.wi_rx_signal;
1682 		tap->wr_antnoise = frmhdr.wi_rx_silence;
1683 		tap->wr_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
1684 		tap->wr_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
1685 		if (frmhdr.wi_status & WI_STAT_PCF)
1686 			tap->wr_flags |= IEEE80211_RADIOTAP_F_CFP;
1687 
1688 		/* XXX IEEE80211_RADIOTAP_F_WEP */
1689 		bpf_mtap2(sc->sc_drvbpf, tap, tap->wr_ihdr.it_len, m);
1690 	}
1691 
1692 	/* synchronize driver's BSSID with firmware's BSSID */
1693 	dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
1694 	if (ic->ic_opmode == IEEE80211_M_IBSS && dir == IEEE80211_FC1_DIR_NODS)
1695 		wi_sync_bssid(sc, wh->i_addr3);
1696 
1697 	ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
1698 
1699 	ieee80211_input(ic, m, ni, rssi, rstamp);
1700 
1701 	wi_rssadapt_input(ic, ni, wh, rssi);
1702 
1703 	/*
1704 	 * The frame may have caused the node to be marked for
1705 	 * reclamation (e.g. in response to a DEAUTH message)
1706 	 * so use release_node here instead of unref_node.
1707 	 */
1708 	ieee80211_free_node(ni);
1709 }
1710 
1711 STATIC void
wi_tx_ex_intr(struct wi_softc * sc)1712 wi_tx_ex_intr(struct wi_softc *sc)
1713 {
1714 	struct ieee80211com *ic = &sc->sc_ic;
1715 	struct ifnet *ifp = &sc->sc_if;
1716 	struct ieee80211_node *ni;
1717 	struct ieee80211_rssdesc *id;
1718 	struct wi_rssdesc *rssd;
1719 	struct wi_frame frmhdr;
1720 	int fid;
1721 	u_int16_t status;
1722 
1723 	fid = CSR_READ_2(sc, WI_TX_CMP_FID);
1724 	/* Read in the frame header */
1725 	if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr)) != 0) {
1726 		aprint_error_dev(sc->sc_dev, "%s read fid %x failed\n",
1727 		    __func__, fid);
1728 		wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree,
1729 		    &sc->sc_txpending);
1730 		goto out;
1731 	}
1732 
1733 	if (frmhdr.wi_tx_idx >= WI_NTXRSS) {
1734 		aprint_error_dev(sc->sc_dev, "%s bad idx %02x\n",
1735 		    __func__, frmhdr.wi_tx_idx);
1736 		wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree,
1737 		    &sc->sc_txpending);
1738 		goto out;
1739 	}
1740 
1741 	status = le16toh(frmhdr.wi_status);
1742 
1743 	/*
1744 	 * Spontaneous station disconnects appear as xmit
1745 	 * errors.  Don't announce them and/or count them
1746 	 * as an output error.
1747 	 */
1748 	if (ppsratecheck(&lasttxerror, &curtxeps, wi_txerate)) {
1749 		aprint_error_dev(sc->sc_dev, "tx failed");
1750 		if (status & WI_TXSTAT_RET_ERR)
1751 			printf(", retry limit exceeded");
1752 		if (status & WI_TXSTAT_AGED_ERR)
1753 			printf(", max transmit lifetime exceeded");
1754 		if (status & WI_TXSTAT_DISCONNECT)
1755 			printf(", port disconnected");
1756 		if (status & WI_TXSTAT_FORM_ERR)
1757 			printf(", invalid format (data len %u src %s)",
1758 				le16toh(frmhdr.wi_dat_len),
1759 				ether_sprintf(frmhdr.wi_ehdr.ether_shost));
1760 		if (status & ~0xf)
1761 			printf(", status=0x%x", status);
1762 		printf("\n");
1763 	}
1764 	ifp->if_oerrors++;
1765 	rssd = &sc->sc_rssd[frmhdr.wi_tx_idx];
1766 	id = &rssd->rd_desc;
1767 	if ((status & WI_TXSTAT_RET_ERR) != 0)
1768 		wi_lower_rate(ic, id);
1769 
1770 	ni = id->id_node;
1771 	id->id_node = NULL;
1772 
1773 	if (ni == NULL) {
1774 		aprint_error_dev(sc->sc_dev, "%s null node, rssdesc %02x\n",
1775 		    __func__, frmhdr.wi_tx_idx);
1776 		goto out;
1777 	}
1778 
1779 	if (sc->sc_txpending[id->id_rateidx]-- == 0) {
1780 		aprint_error_dev(sc->sc_dev, "%s txpending[%i] wraparound",
1781 		    __func__, id->id_rateidx);
1782 		sc->sc_txpending[id->id_rateidx] = 0;
1783 	}
1784 	if (ni != NULL)
1785 		ieee80211_free_node(ni);
1786 	SLIST_INSERT_HEAD(&sc->sc_rssdfree, rssd, rd_next);
1787 out:
1788 	ifp->if_flags &= ~IFF_OACTIVE;
1789 }
1790 
1791 STATIC void
wi_txalloc_intr(struct wi_softc * sc)1792 wi_txalloc_intr(struct wi_softc *sc)
1793 {
1794 	int fid, cur;
1795 
1796 	fid = CSR_READ_2(sc, WI_ALLOC_FID);
1797 
1798 	cur = sc->sc_txalloc;
1799 #ifdef DIAGNOSTIC
1800 	if (sc->sc_txstarted == 0) {
1801 		printf("%s: spurious alloc %x != %x, alloc %d queue %d start %d alloced %d queued %d started %d\n",
1802 		    device_xname(sc->sc_dev), fid, sc->sc_txd[cur].d_fid, cur,
1803 		    sc->sc_txqueue, sc->sc_txstart, sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted);
1804 		return;
1805 	}
1806 #endif
1807 	--sc->sc_txstarted;
1808 	++sc->sc_txalloced;
1809 	sc->sc_txd[cur].d_fid = fid;
1810 	sc->sc_txalloc = (cur + 1) % WI_NTXBUF;
1811 #ifdef WI_RING_DEBUG
1812 	printf("%s: alloc %04x, alloc %d queue %d start %d alloced %d queued %d started %d\n",
1813 	    device_xname(sc->sc_dev), fid,
1814 	    sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart,
1815 	    sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted);
1816 #endif
1817 }
1818 
1819 STATIC void
wi_cmd_intr(struct wi_softc * sc)1820 wi_cmd_intr(struct wi_softc *sc)
1821 {
1822 	struct ifnet *ifp = &sc->sc_if;
1823 
1824 	if (sc->sc_invalid)
1825 		return;
1826 #ifdef WI_DEBUG
1827 	if (wi_debug > 1)
1828 		printf("%s: %d txcmds outstanding\n", __func__, sc->sc_txcmds);
1829 #endif
1830 	KASSERT(sc->sc_txcmds > 0);
1831 
1832 	--sc->sc_txcmds;
1833 
1834 	if (--sc->sc_txqueued == 0) {
1835 		sc->sc_tx_timer = 0;
1836 		ifp->if_flags &= ~IFF_OACTIVE;
1837 #ifdef WI_RING_DEBUG
1838 	printf("%s: cmd       , alloc %d queue %d start %d alloced %d queued %d started %d\n",
1839 	    device_xname(sc->sc_dev),
1840 	    sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart,
1841 	    sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted);
1842 #endif
1843 	} else
1844 		wi_push_packet(sc);
1845 }
1846 
1847 STATIC void
wi_push_packet(struct wi_softc * sc)1848 wi_push_packet(struct wi_softc *sc)
1849 {
1850 	struct ifnet *ifp = &sc->sc_if;
1851 	int cur, fid;
1852 
1853 	cur = sc->sc_txstart;
1854 	fid = sc->sc_txd[cur].d_fid;
1855 
1856 	KASSERT(sc->sc_txcmds == 0);
1857 
1858 	if (wi_cmd_start(sc, WI_CMD_TX | WI_RECLAIM, fid, 0, 0)) {
1859 		aprint_error_dev(sc->sc_dev, "xmit failed\n");
1860 		/* XXX ring might have a hole */
1861 	}
1862 
1863 	if (sc->sc_txcmds++ > 0)
1864 		printf("%s: %d tx cmds pending!!!\n", __func__, sc->sc_txcmds);
1865 
1866 	++sc->sc_txstarted;
1867 #ifdef DIAGNOSTIC
1868 	if (sc->sc_txstarted > WI_NTXBUF)
1869 		aprint_error_dev(sc->sc_dev, "too many buffers started\n");
1870 #endif
1871 	sc->sc_txstart = (cur + 1) % WI_NTXBUF;
1872 	sc->sc_tx_timer = 5;
1873 	ifp->if_timer = 1;
1874 #ifdef WI_RING_DEBUG
1875 	printf("%s: push  %04x, alloc %d queue %d start %d alloced %d queued %d started %d\n",
1876 	    device_xname(sc->sc_dev), fid,
1877 	    sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart,
1878 	    sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted);
1879 #endif
1880 }
1881 
1882 STATIC void
wi_tx_intr(struct wi_softc * sc)1883 wi_tx_intr(struct wi_softc *sc)
1884 {
1885 	struct ieee80211com *ic = &sc->sc_ic;
1886 	struct ifnet *ifp = &sc->sc_if;
1887 	struct ieee80211_node *ni;
1888 	struct ieee80211_rssdesc *id;
1889 	struct wi_rssdesc *rssd;
1890 	struct wi_frame frmhdr;
1891 	int fid;
1892 
1893 	fid = CSR_READ_2(sc, WI_TX_CMP_FID);
1894 	/* Read in the frame header */
1895 	if (wi_read_bap(sc, fid, offsetof(struct wi_frame, wi_tx_swsup2),
1896 	                &frmhdr.wi_tx_swsup2, 2) != 0) {
1897 		aprint_error_dev(sc->sc_dev, "%s read fid %x failed\n",
1898 		    __func__, fid);
1899 		wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree,
1900 		    &sc->sc_txpending);
1901 		goto out;
1902 	}
1903 
1904 	if (frmhdr.wi_tx_idx >= WI_NTXRSS) {
1905 		aprint_error_dev(sc->sc_dev, "%s bad idx %02x\n",
1906 		    __func__, frmhdr.wi_tx_idx);
1907 		wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree,
1908 		    &sc->sc_txpending);
1909 		goto out;
1910 	}
1911 
1912 	rssd = &sc->sc_rssd[frmhdr.wi_tx_idx];
1913 	id = &rssd->rd_desc;
1914 	wi_raise_rate(ic, id);
1915 
1916 	ni = id->id_node;
1917 	id->id_node = NULL;
1918 
1919 	if (ni == NULL) {
1920 		aprint_error_dev(sc->sc_dev, "%s null node, rssdesc %02x\n",
1921 		    __func__, frmhdr.wi_tx_idx);
1922 		goto out;
1923 	}
1924 
1925 	if (sc->sc_txpending[id->id_rateidx]-- == 0) {
1926 		aprint_error_dev(sc->sc_dev, "%s txpending[%i] wraparound",
1927 		    __func__, id->id_rateidx);
1928 		sc->sc_txpending[id->id_rateidx] = 0;
1929 	}
1930 	if (ni != NULL)
1931 		ieee80211_free_node(ni);
1932 	SLIST_INSERT_HEAD(&sc->sc_rssdfree, rssd, rd_next);
1933 out:
1934 	ifp->if_flags &= ~IFF_OACTIVE;
1935 }
1936 
1937 STATIC void
wi_info_intr(struct wi_softc * sc)1938 wi_info_intr(struct wi_softc *sc)
1939 {
1940 	struct ieee80211com *ic = &sc->sc_ic;
1941 	struct ifnet *ifp = &sc->sc_if;
1942 	int i, fid, len, off;
1943 	u_int16_t ltbuf[2];
1944 	u_int16_t stat;
1945 	u_int32_t *ptr;
1946 
1947 	fid = CSR_READ_2(sc, WI_INFO_FID);
1948 	wi_read_bap(sc, fid, 0, ltbuf, sizeof(ltbuf));
1949 
1950 	switch (le16toh(ltbuf[1])) {
1951 
1952 	case WI_INFO_LINK_STAT:
1953 		wi_read_bap(sc, fid, sizeof(ltbuf), &stat, sizeof(stat));
1954 		DPRINTF(("wi_info_intr: LINK_STAT 0x%x\n", le16toh(stat)));
1955 		switch (le16toh(stat)) {
1956 		case CONNECTED:
1957 			sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
1958 			if (ic->ic_state == IEEE80211_S_RUN &&
1959 			    ic->ic_opmode != IEEE80211_M_IBSS)
1960 				break;
1961 			/* FALLTHROUGH */
1962 		case AP_CHANGE:
1963 			ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
1964 			break;
1965 		case AP_IN_RANGE:
1966 			sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
1967 			break;
1968 		case AP_OUT_OF_RANGE:
1969 			if (sc->sc_firmware_type == WI_SYMBOL &&
1970 			    sc->sc_scan_timer > 0) {
1971 				if (wi_cmd(sc, WI_CMD_INQUIRE,
1972 				    WI_INFO_HOST_SCAN_RESULTS, 0, 0) != 0)
1973 					sc->sc_scan_timer = 0;
1974 				break;
1975 			}
1976 			if (ic->ic_opmode == IEEE80211_M_STA)
1977 				sc->sc_flags |= WI_FLAGS_OUTRANGE;
1978 			break;
1979 		case DISCONNECTED:
1980 		case ASSOC_FAILED:
1981 			if (ic->ic_opmode == IEEE80211_M_STA)
1982 				ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
1983 			break;
1984 		}
1985 		break;
1986 
1987 	case WI_INFO_COUNTERS:
1988 		/* some card versions have a larger stats structure */
1989 		len = min(le16toh(ltbuf[0]) - 1, sizeof(sc->sc_stats) / 4);
1990 		ptr = (u_int32_t *)&sc->sc_stats;
1991 		off = sizeof(ltbuf);
1992 		for (i = 0; i < len; i++, off += 2, ptr++) {
1993 			wi_read_bap(sc, fid, off, &stat, sizeof(stat));
1994 			stat = le16toh(stat);
1995 #ifdef WI_HERMES_STATS_WAR
1996 			if (stat & 0xf000)
1997 				stat = ~stat;
1998 #endif
1999 			*ptr += stat;
2000 		}
2001 		ifp->if_collisions = sc->sc_stats.wi_tx_single_retries +
2002 		    sc->sc_stats.wi_tx_multi_retries +
2003 		    sc->sc_stats.wi_tx_retry_limit;
2004 		break;
2005 
2006 	case WI_INFO_SCAN_RESULTS:
2007 	case WI_INFO_HOST_SCAN_RESULTS:
2008 		wi_scan_result(sc, fid, le16toh(ltbuf[0]));
2009 		break;
2010 
2011 	default:
2012 		DPRINTF(("wi_info_intr: got fid %x type %x len %d\n", fid,
2013 		    le16toh(ltbuf[1]), le16toh(ltbuf[0])));
2014 		break;
2015 	}
2016 }
2017 
2018 STATIC int
wi_write_multi(struct wi_softc * sc)2019 wi_write_multi(struct wi_softc *sc)
2020 {
2021 	struct ifnet *ifp = &sc->sc_if;
2022 	int n;
2023 	struct wi_mcast mlist;
2024 	struct ether_multi *enm;
2025 	struct ether_multistep estep;
2026 
2027 	if ((ifp->if_flags & IFF_PROMISC) != 0) {
2028 allmulti:
2029 		ifp->if_flags |= IFF_ALLMULTI;
2030 		memset(&mlist, 0, sizeof(mlist));
2031 		return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist,
2032 		    sizeof(mlist));
2033 	}
2034 
2035 	n = 0;
2036 	ETHER_FIRST_MULTI(estep, &sc->sc_ec, enm);
2037 	while (enm != NULL) {
2038 		/* Punt on ranges or too many multicast addresses. */
2039 		if (!IEEE80211_ADDR_EQ(enm->enm_addrlo, enm->enm_addrhi) ||
2040 		    n >= sizeof(mlist) / sizeof(mlist.wi_mcast[0]))
2041 			goto allmulti;
2042 
2043 		IEEE80211_ADDR_COPY(&mlist.wi_mcast[n], enm->enm_addrlo);
2044 		n++;
2045 		ETHER_NEXT_MULTI(estep, enm);
2046 	}
2047 	ifp->if_flags &= ~IFF_ALLMULTI;
2048 	return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist,
2049 	    IEEE80211_ADDR_LEN * n);
2050 }
2051 
2052 
2053 STATIC void
wi_read_nicid(struct wi_softc * sc)2054 wi_read_nicid(struct wi_softc *sc)
2055 {
2056 	struct wi_card_ident *id;
2057 	char *p;
2058 	int len;
2059 	u_int16_t ver[4];
2060 
2061 	/* getting chip identity */
2062 	memset(ver, 0, sizeof(ver));
2063 	len = sizeof(ver);
2064 	wi_read_rid(sc, WI_RID_CARD_ID, ver, &len);
2065 	printf("%s: using ", device_xname(sc->sc_dev));
2066 DPRINTF2(("wi_read_nicid: CARD_ID: %x %x %x %x\n", le16toh(ver[0]), le16toh(ver[1]), le16toh(ver[2]), le16toh(ver[3])));
2067 
2068 	sc->sc_firmware_type = WI_NOTYPE;
2069 	for (id = wi_card_ident; id->card_name != NULL; id++) {
2070 		if (le16toh(ver[0]) == id->card_id) {
2071 			printf("%s", id->card_name);
2072 			sc->sc_firmware_type = id->firm_type;
2073 			break;
2074 		}
2075 	}
2076 	if (sc->sc_firmware_type == WI_NOTYPE) {
2077 		if (le16toh(ver[0]) & 0x8000) {
2078 			printf("Unknown PRISM2 chip");
2079 			sc->sc_firmware_type = WI_INTERSIL;
2080 		} else {
2081 			printf("Unknown Lucent chip");
2082 			sc->sc_firmware_type = WI_LUCENT;
2083 		}
2084 	}
2085 
2086 	/* get primary firmware version (Only Prism chips) */
2087 	if (sc->sc_firmware_type != WI_LUCENT) {
2088 		memset(ver, 0, sizeof(ver));
2089 		len = sizeof(ver);
2090 		wi_read_rid(sc, WI_RID_PRI_IDENTITY, ver, &len);
2091 		sc->sc_pri_firmware_ver = le16toh(ver[2]) * 10000 +
2092 		    le16toh(ver[3]) * 100 + le16toh(ver[1]);
2093 	}
2094 
2095 	/* get station firmware version */
2096 	memset(ver, 0, sizeof(ver));
2097 	len = sizeof(ver);
2098 	wi_read_rid(sc, WI_RID_STA_IDENTITY, ver, &len);
2099 	sc->sc_sta_firmware_ver = le16toh(ver[2]) * 10000 +
2100 	    le16toh(ver[3]) * 100 + le16toh(ver[1]);
2101 	if (sc->sc_firmware_type == WI_INTERSIL &&
2102 	    (sc->sc_sta_firmware_ver == 10102 ||
2103 	     sc->sc_sta_firmware_ver == 20102)) {
2104 		char ident[12];
2105 		memset(ident, 0, sizeof(ident));
2106 		len = sizeof(ident);
2107 		/* value should be the format like "V2.00-11" */
2108 		if (wi_read_rid(sc, WI_RID_SYMBOL_IDENTITY, ident, &len) == 0 &&
2109 		    *(p = (char *)ident) >= 'A' &&
2110 		    p[2] == '.' && p[5] == '-' && p[8] == '\0') {
2111 			sc->sc_firmware_type = WI_SYMBOL;
2112 			sc->sc_sta_firmware_ver = (p[1] - '0') * 10000 +
2113 			    (p[3] - '0') * 1000 + (p[4] - '0') * 100 +
2114 			    (p[6] - '0') * 10 + (p[7] - '0');
2115 		}
2116 	}
2117 
2118 	printf("\n%s: %s Firmware: ", device_xname(sc->sc_dev),
2119 	     sc->sc_firmware_type == WI_LUCENT ? "Lucent" :
2120 	    (sc->sc_firmware_type == WI_SYMBOL ? "Symbol" : "Intersil"));
2121 	if (sc->sc_firmware_type != WI_LUCENT)	/* XXX */
2122 		printf("Primary (%u.%u.%u), ",
2123 		    sc->sc_pri_firmware_ver / 10000,
2124 		    (sc->sc_pri_firmware_ver % 10000) / 100,
2125 		    sc->sc_pri_firmware_ver % 100);
2126 	printf("Station (%u.%u.%u)\n",
2127 	    sc->sc_sta_firmware_ver / 10000,
2128 	    (sc->sc_sta_firmware_ver % 10000) / 100,
2129 	    sc->sc_sta_firmware_ver % 100);
2130 }
2131 
2132 STATIC int
wi_write_ssid(struct wi_softc * sc,int rid,u_int8_t * buf,int buflen)2133 wi_write_ssid(struct wi_softc *sc, int rid, u_int8_t *buf, int buflen)
2134 {
2135 	struct wi_ssid ssid;
2136 
2137 	if (buflen > IEEE80211_NWID_LEN)
2138 		return ENOBUFS;
2139 	memset(&ssid, 0, sizeof(ssid));
2140 	ssid.wi_len = htole16(buflen);
2141 	memcpy(ssid.wi_ssid, buf, buflen);
2142 	return wi_write_rid(sc, rid, &ssid, sizeof(ssid));
2143 }
2144 
2145 STATIC int
wi_get_cfg(struct ifnet * ifp,u_long cmd,void * data)2146 wi_get_cfg(struct ifnet *ifp, u_long cmd, void *data)
2147 {
2148 	struct wi_softc *sc = ifp->if_softc;
2149 	struct ieee80211com *ic = &sc->sc_ic;
2150 	struct ifreq *ifr = (struct ifreq *)data;
2151 	struct wi_req wreq;
2152 	int len, n, error;
2153 
2154 	error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
2155 	if (error)
2156 		return error;
2157 	len = (wreq.wi_len - 1) * 2;
2158 	if (len < sizeof(u_int16_t))
2159 		return ENOSPC;
2160 	if (len > sizeof(wreq.wi_val))
2161 		len = sizeof(wreq.wi_val);
2162 
2163 	switch (wreq.wi_type) {
2164 
2165 	case WI_RID_IFACE_STATS:
2166 		memcpy(wreq.wi_val, &sc->sc_stats, sizeof(sc->sc_stats));
2167 		if (len < sizeof(sc->sc_stats))
2168 			error = ENOSPC;
2169 		else
2170 			len = sizeof(sc->sc_stats);
2171 		break;
2172 
2173 	case WI_RID_ENCRYPTION:
2174 	case WI_RID_TX_CRYPT_KEY:
2175 	case WI_RID_DEFLT_CRYPT_KEYS:
2176 	case WI_RID_TX_RATE:
2177 		return ieee80211_cfgget(ic, cmd, data);
2178 
2179 	case WI_RID_MICROWAVE_OVEN:
2180 		if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_MOR)) {
2181 			error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2182 			    &len);
2183 			break;
2184 		}
2185 		wreq.wi_val[0] = htole16(sc->sc_microwave_oven);
2186 		len = sizeof(u_int16_t);
2187 		break;
2188 
2189 	case WI_RID_DBM_ADJUST:
2190 		if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_DBMADJUST)) {
2191 			error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2192 			    &len);
2193 			break;
2194 		}
2195 		wreq.wi_val[0] = htole16(sc->sc_dbm_offset);
2196 		len = sizeof(u_int16_t);
2197 		break;
2198 
2199 	case WI_RID_ROAMING_MODE:
2200 		if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_ROAMING)) {
2201 			error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2202 			    &len);
2203 			break;
2204 		}
2205 		wreq.wi_val[0] = htole16(sc->sc_roaming_mode);
2206 		len = sizeof(u_int16_t);
2207 		break;
2208 
2209 	case WI_RID_SYSTEM_SCALE:
2210 		if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE)) {
2211 			error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2212 			    &len);
2213 			break;
2214 		}
2215 		wreq.wi_val[0] = htole16(sc->sc_system_scale);
2216 		len = sizeof(u_int16_t);
2217 		break;
2218 
2219 	case WI_RID_FRAG_THRESH:
2220 		if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR)) {
2221 			error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2222 			    &len);
2223 			break;
2224 		}
2225 		wreq.wi_val[0] = htole16(sc->sc_frag_thresh);
2226 		len = sizeof(u_int16_t);
2227 		break;
2228 
2229 	case WI_RID_READ_APS:
2230 #ifndef	IEEE80211_NO_HOSTAP
2231 		if (ic->ic_opmode == IEEE80211_M_HOSTAP)
2232 			return ieee80211_cfgget(ic, cmd, data);
2233 #endif /* !IEEE80211_NO_HOSTAP */
2234 		if (sc->sc_scan_timer > 0) {
2235 			error = EINPROGRESS;
2236 			break;
2237 		}
2238 		n = sc->sc_naps;
2239 		if (len < sizeof(n)) {
2240 			error = ENOSPC;
2241 			break;
2242 		}
2243 		if (len < sizeof(n) + sizeof(struct wi_apinfo) * n)
2244 			n = (len - sizeof(n)) / sizeof(struct wi_apinfo);
2245 		len = sizeof(n) + sizeof(struct wi_apinfo) * n;
2246 		memcpy(wreq.wi_val, &n, sizeof(n));
2247 		memcpy((char *)wreq.wi_val + sizeof(n), sc->sc_aps,
2248 		    sizeof(struct wi_apinfo) * n);
2249 		break;
2250 
2251 	default:
2252 		if (sc->sc_enabled) {
2253 			error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2254 			    &len);
2255 			break;
2256 		}
2257 		switch (wreq.wi_type) {
2258 		case WI_RID_MAX_DATALEN:
2259 			wreq.wi_val[0] = htole16(sc->sc_max_datalen);
2260 			len = sizeof(u_int16_t);
2261 			break;
2262 		case WI_RID_FRAG_THRESH:
2263 			wreq.wi_val[0] = htole16(sc->sc_frag_thresh);
2264 			len = sizeof(u_int16_t);
2265 			break;
2266 		case WI_RID_RTS_THRESH:
2267 			wreq.wi_val[0] = htole16(sc->sc_rts_thresh);
2268 			len = sizeof(u_int16_t);
2269 			break;
2270 		case WI_RID_CNFAUTHMODE:
2271 			wreq.wi_val[0] = htole16(sc->sc_cnfauthmode);
2272 			len = sizeof(u_int16_t);
2273 			break;
2274 		case WI_RID_NODENAME:
2275 			if (len < sc->sc_nodelen + sizeof(u_int16_t)) {
2276 				error = ENOSPC;
2277 				break;
2278 			}
2279 			len = sc->sc_nodelen + sizeof(u_int16_t);
2280 			wreq.wi_val[0] = htole16((sc->sc_nodelen + 1) / 2);
2281 			memcpy(&wreq.wi_val[1], sc->sc_nodename,
2282 			    sc->sc_nodelen);
2283 			break;
2284 		default:
2285 			return ieee80211_cfgget(ic, cmd, data);
2286 		}
2287 		break;
2288 	}
2289 	if (error)
2290 		return error;
2291 	wreq.wi_len = (len + 1) / 2 + 1;
2292 	return copyout(&wreq, ifr->ifr_data, (wreq.wi_len + 1) * 2);
2293 }
2294 
2295 STATIC int
wi_set_cfg(struct ifnet * ifp,u_long cmd,void * data)2296 wi_set_cfg(struct ifnet *ifp, u_long cmd, void *data)
2297 {
2298 	struct wi_softc *sc = ifp->if_softc;
2299 	struct ieee80211com *ic = &sc->sc_ic;
2300 	struct ifreq *ifr = (struct ifreq *)data;
2301 	struct ieee80211_rateset *rs = &ic->ic_sup_rates[IEEE80211_MODE_11B];
2302 	struct wi_req wreq;
2303 	struct mbuf *m;
2304 	int i, len, error;
2305 
2306 	error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
2307 	if (error)
2308 		return error;
2309 	len = (wreq.wi_len - 1) * 2;
2310 	switch (wreq.wi_type) {
2311         case WI_RID_MAC_NODE:
2312 		/* XXX convert to SIOCALIFADDR, AF_LINK, IFLR_ACTIVE */
2313 		(void)memcpy(ic->ic_myaddr, wreq.wi_val, ETHER_ADDR_LEN);
2314 		if_set_sadl(ifp, ic->ic_myaddr, ETHER_ADDR_LEN, false);
2315 		wi_write_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr,
2316 		    IEEE80211_ADDR_LEN);
2317 		break;
2318 
2319 	case WI_RID_DBM_ADJUST:
2320 		return ENODEV;
2321 
2322 	case WI_RID_NODENAME:
2323 		if (le16toh(wreq.wi_val[0]) * 2 > len ||
2324 		    le16toh(wreq.wi_val[0]) > sizeof(sc->sc_nodename)) {
2325 			error = ENOSPC;
2326 			break;
2327 		}
2328 		if (sc->sc_enabled) {
2329 			error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val,
2330 			    len);
2331 			if (error)
2332 				break;
2333 		}
2334 		sc->sc_nodelen = le16toh(wreq.wi_val[0]) * 2;
2335 		memcpy(sc->sc_nodename, &wreq.wi_val[1], sc->sc_nodelen);
2336 		break;
2337 
2338 	case WI_RID_MICROWAVE_OVEN:
2339 	case WI_RID_ROAMING_MODE:
2340 	case WI_RID_SYSTEM_SCALE:
2341 	case WI_RID_FRAG_THRESH:
2342 		if (wreq.wi_type == WI_RID_MICROWAVE_OVEN &&
2343 		    (sc->sc_flags & WI_FLAGS_HAS_MOR) == 0)
2344 			break;
2345 		if (wreq.wi_type == WI_RID_ROAMING_MODE &&
2346 		    (sc->sc_flags & WI_FLAGS_HAS_ROAMING) == 0)
2347 			break;
2348 		if (wreq.wi_type == WI_RID_SYSTEM_SCALE &&
2349 		    (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE) == 0)
2350 			break;
2351 		if (wreq.wi_type == WI_RID_FRAG_THRESH &&
2352 		    (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR) == 0)
2353 			break;
2354 		/* FALLTHROUGH */
2355 	case WI_RID_RTS_THRESH:
2356 	case WI_RID_CNFAUTHMODE:
2357 	case WI_RID_MAX_DATALEN:
2358 		if (sc->sc_enabled) {
2359 			error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val,
2360 			    sizeof(u_int16_t));
2361 			if (error)
2362 				break;
2363 		}
2364 		switch (wreq.wi_type) {
2365 		case WI_RID_FRAG_THRESH:
2366 			sc->sc_frag_thresh = le16toh(wreq.wi_val[0]);
2367 			break;
2368 		case WI_RID_RTS_THRESH:
2369 			sc->sc_rts_thresh = le16toh(wreq.wi_val[0]);
2370 			break;
2371 		case WI_RID_MICROWAVE_OVEN:
2372 			sc->sc_microwave_oven = le16toh(wreq.wi_val[0]);
2373 			break;
2374 		case WI_RID_ROAMING_MODE:
2375 			sc->sc_roaming_mode = le16toh(wreq.wi_val[0]);
2376 			break;
2377 		case WI_RID_SYSTEM_SCALE:
2378 			sc->sc_system_scale = le16toh(wreq.wi_val[0]);
2379 			break;
2380 		case WI_RID_CNFAUTHMODE:
2381 			sc->sc_cnfauthmode = le16toh(wreq.wi_val[0]);
2382 			break;
2383 		case WI_RID_MAX_DATALEN:
2384 			sc->sc_max_datalen = le16toh(wreq.wi_val[0]);
2385 			break;
2386 		}
2387 		break;
2388 
2389 	case WI_RID_TX_RATE:
2390 		switch (le16toh(wreq.wi_val[0])) {
2391 		case 3:
2392 			ic->ic_fixed_rate = -1;
2393 			break;
2394 		default:
2395 			for (i = 0; i < IEEE80211_RATE_SIZE; i++) {
2396 				if ((rs->rs_rates[i] & IEEE80211_RATE_VAL)
2397 				    / 2 == le16toh(wreq.wi_val[0]))
2398 					break;
2399 			}
2400 			if (i == IEEE80211_RATE_SIZE)
2401 				return EINVAL;
2402 			ic->ic_fixed_rate = i;
2403 		}
2404 		if (sc->sc_enabled)
2405 			error = wi_cfg_txrate(sc);
2406 		break;
2407 
2408 	case WI_RID_SCAN_APS:
2409 		if (sc->sc_enabled && ic->ic_opmode != IEEE80211_M_HOSTAP)
2410 			error = wi_scan_ap(sc, 0x3fff, 0x000f);
2411 		break;
2412 
2413 	case WI_RID_MGMT_XMIT:
2414 		if (!sc->sc_enabled) {
2415 			error = ENETDOWN;
2416 			break;
2417 		}
2418 		if (ic->ic_mgtq.ifq_len > 5) {
2419 			error = EAGAIN;
2420 			break;
2421 		}
2422 		/* XXX wi_len looks in u_int8_t, not in u_int16_t */
2423 		m = m_devget((char *)&wreq.wi_val, wreq.wi_len, 0, ifp, NULL);
2424 		if (m == NULL) {
2425 			error = ENOMEM;
2426 			break;
2427 		}
2428 		IF_ENQUEUE(&ic->ic_mgtq, m);
2429 		break;
2430 
2431 	default:
2432 		if (sc->sc_enabled) {
2433 			error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val,
2434 			    len);
2435 			if (error)
2436 				break;
2437 		}
2438 		error = ieee80211_cfgset(ic, cmd, data);
2439 		break;
2440 	}
2441 	return error;
2442 }
2443 
2444 /* Rate is 0 for hardware auto-select, otherwise rate is
2445  * 2, 4, 11, or 22 (units of 500Kbps).
2446  */
2447 STATIC int
wi_write_txrate(struct wi_softc * sc,int rate)2448 wi_write_txrate(struct wi_softc *sc, int rate)
2449 {
2450 	u_int16_t hwrate;
2451 
2452 	/* rate: 0, 2, 4, 11, 22 */
2453 	switch (sc->sc_firmware_type) {
2454 	case WI_LUCENT:
2455 		switch (rate & IEEE80211_RATE_VAL) {
2456 		case 2:
2457 			hwrate = 1;
2458 			break;
2459 		case 4:
2460 			hwrate = 2;
2461 			break;
2462 		default:
2463 			hwrate = 3;	/* auto */
2464 			break;
2465 		case 11:
2466 			hwrate = 4;
2467 			break;
2468 		case 22:
2469 			hwrate = 5;
2470 			break;
2471 		}
2472 		break;
2473 	default:
2474 		switch (rate & IEEE80211_RATE_VAL) {
2475 		case 2:
2476 			hwrate = 1;
2477 			break;
2478 		case 4:
2479 			hwrate = 2;
2480 			break;
2481 		case 11:
2482 			hwrate = 4;
2483 			break;
2484 		case 22:
2485 			hwrate = 8;
2486 			break;
2487 		default:
2488 			hwrate = 15;	/* auto */
2489 			break;
2490 		}
2491 		break;
2492 	}
2493 
2494 	if (sc->sc_tx_rate == hwrate)
2495 		return 0;
2496 
2497 	if (sc->sc_if.if_flags & IFF_DEBUG)
2498 		printf("%s: tx rate %d -> %d (%d)\n", __func__, sc->sc_tx_rate,
2499 		    hwrate, rate);
2500 
2501 	sc->sc_tx_rate = hwrate;
2502 
2503 	return wi_write_val(sc, WI_RID_TX_RATE, sc->sc_tx_rate);
2504 }
2505 
2506 STATIC int
wi_cfg_txrate(struct wi_softc * sc)2507 wi_cfg_txrate(struct wi_softc *sc)
2508 {
2509 	struct ieee80211com *ic = &sc->sc_ic;
2510 	struct ieee80211_rateset *rs;
2511 	int rate;
2512 
2513 	rs = &ic->ic_sup_rates[IEEE80211_MODE_11B];
2514 
2515 	sc->sc_tx_rate = 0; /* force write to RID */
2516 
2517 	if (ic->ic_fixed_rate < 0)
2518 		rate = 0;	/* auto */
2519 	else
2520 		rate = rs->rs_rates[ic->ic_fixed_rate];
2521 
2522 	return wi_write_txrate(sc, rate);
2523 }
2524 
2525 STATIC int
wi_key_delete(struct ieee80211com * ic,const struct ieee80211_key * k)2526 wi_key_delete(struct ieee80211com *ic, const struct ieee80211_key *k)
2527 {
2528 	struct wi_softc *sc = ic->ic_ifp->if_softc;
2529 	u_int keyix = k->wk_keyix;
2530 
2531 	DPRINTF(("%s: delete key %u\n", __func__, keyix));
2532 
2533 	if (keyix >= IEEE80211_WEP_NKID)
2534 		return 0;
2535 	if (k->wk_keylen != 0)
2536 		sc->sc_flags &= ~WI_FLAGS_WEP_VALID;
2537 
2538 	return 1;
2539 }
2540 
2541 static int
wi_key_set(struct ieee80211com * ic,const struct ieee80211_key * k,const u_int8_t mac[IEEE80211_ADDR_LEN])2542 wi_key_set(struct ieee80211com *ic, const struct ieee80211_key *k,
2543 	const u_int8_t mac[IEEE80211_ADDR_LEN])
2544 {
2545 	struct wi_softc *sc = ic->ic_ifp->if_softc;
2546 
2547 	DPRINTF(("%s: set key %u\n", __func__, k->wk_keyix));
2548 
2549 	if (k->wk_keyix >= IEEE80211_WEP_NKID)
2550 		return 0;
2551 
2552 	sc->sc_flags &= ~WI_FLAGS_WEP_VALID;
2553 
2554 	return 1;
2555 }
2556 
2557 STATIC void
wi_key_update_begin(struct ieee80211com * ic)2558 wi_key_update_begin(struct ieee80211com *ic)
2559 {
2560 	DPRINTF(("%s:\n", __func__));
2561 }
2562 
2563 STATIC void
wi_key_update_end(struct ieee80211com * ic)2564 wi_key_update_end(struct ieee80211com *ic)
2565 {
2566 	struct ifnet *ifp = ic->ic_ifp;
2567 	struct wi_softc *sc = ifp->if_softc;
2568 
2569 	DPRINTF(("%s:\n", __func__));
2570 
2571 	if ((sc->sc_flags & WI_FLAGS_WEP_VALID) != 0)
2572 		return;
2573 	if ((ic->ic_caps & IEEE80211_C_WEP) != 0 && sc->sc_enabled &&
2574 	    !sc->sc_invalid)
2575 		(void)wi_write_wep(sc);
2576 }
2577 
2578 STATIC int
wi_write_wep(struct wi_softc * sc)2579 wi_write_wep(struct wi_softc *sc)
2580 {
2581 	struct ifnet *ifp = &sc->sc_if;
2582 	struct ieee80211com *ic = &sc->sc_ic;
2583 	int error = 0;
2584 	int i, keylen;
2585 	u_int16_t val;
2586 	struct wi_key wkey[IEEE80211_WEP_NKID];
2587 
2588 	if ((ifp->if_flags & IFF_RUNNING) != 0)
2589 		wi_cmd(sc, WI_CMD_DISABLE | sc->sc_portnum, 0, 0, 0);
2590 
2591 	switch (sc->sc_firmware_type) {
2592 	case WI_LUCENT:
2593 		val = (ic->ic_flags & IEEE80211_F_PRIVACY) ? 1 : 0;
2594 		error = wi_write_val(sc, WI_RID_ENCRYPTION, val);
2595 		if (error)
2596 			break;
2597 		error = wi_write_val(sc, WI_RID_TX_CRYPT_KEY, ic->ic_def_txkey);
2598 		if (error)
2599 			break;
2600 		memset(wkey, 0, sizeof(wkey));
2601 		for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2602 			keylen = ic->ic_nw_keys[i].wk_keylen;
2603 			wkey[i].wi_keylen = htole16(keylen);
2604 			memcpy(wkey[i].wi_keydat, ic->ic_nw_keys[i].wk_key,
2605 			    keylen);
2606 		}
2607 		error = wi_write_rid(sc, WI_RID_DEFLT_CRYPT_KEYS,
2608 		    wkey, sizeof(wkey));
2609 		break;
2610 
2611 	case WI_INTERSIL:
2612 	case WI_SYMBOL:
2613 		if (ic->ic_flags & IEEE80211_F_PRIVACY) {
2614 			/*
2615 			 * ONLY HWB3163 EVAL-CARD Firmware version
2616 			 * less than 0.8 variant2
2617 			 *
2618 			 *   If promiscuous mode disable, Prism2 chip
2619 			 *  does not work with WEP .
2620 			 * It is under investigation for details.
2621 			 * (ichiro@NetBSD.org)
2622 			 */
2623 			if (sc->sc_firmware_type == WI_INTERSIL &&
2624 			    sc->sc_sta_firmware_ver < 802 ) {
2625 				/* firm ver < 0.8 variant 2 */
2626 				wi_write_val(sc, WI_RID_PROMISC, 1);
2627 			}
2628 			wi_write_val(sc, WI_RID_CNFAUTHMODE,
2629 			    sc->sc_cnfauthmode);
2630 			val = PRIVACY_INVOKED;
2631 			if ((sc->sc_ic_flags & IEEE80211_F_DROPUNENC) != 0)
2632 				val |= EXCLUDE_UNENCRYPTED;
2633 #ifndef	IEEE80211_NO_HOSTAP
2634 			/*
2635 			 * Encryption firmware has a bug for HostAP mode.
2636 			 */
2637 			if (sc->sc_firmware_type == WI_INTERSIL &&
2638 			    ic->ic_opmode == IEEE80211_M_HOSTAP)
2639 				val |= HOST_ENCRYPT;
2640 #endif /* !IEEE80211_NO_HOSTAP */
2641 		} else {
2642 			wi_write_val(sc, WI_RID_CNFAUTHMODE,
2643 			    IEEE80211_AUTH_OPEN);
2644 			val = HOST_ENCRYPT | HOST_DECRYPT;
2645 		}
2646 		error = wi_write_val(sc, WI_RID_P2_ENCRYPTION, val);
2647 		if (error)
2648 			break;
2649 		error = wi_write_val(sc, WI_RID_P2_TX_CRYPT_KEY,
2650 		    ic->ic_def_txkey);
2651 		if (error)
2652 			break;
2653 		/*
2654 		 * It seems that the firmware accept 104bit key only if
2655 		 * all the keys have 104bit length.  We get the length of
2656 		 * the transmit key and use it for all other keys.
2657 		 * Perhaps we should use software WEP for such situation.
2658 		 */
2659 		if (ic->ic_def_txkey == IEEE80211_KEYIX_NONE ||
2660 		    IEEE80211_KEY_UNDEFINED(ic->ic_nw_keys[ic->ic_def_txkey]))
2661 			keylen = 13;	/* No keys => 104bit ok */
2662 		else
2663 			keylen = ic->ic_nw_keys[ic->ic_def_txkey].wk_keylen;
2664 
2665 		if (keylen > IEEE80211_WEP_KEYLEN)
2666 			keylen = 13;	/* 104bit keys */
2667 		else
2668 			keylen = IEEE80211_WEP_KEYLEN;
2669 		for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2670 			error = wi_write_rid(sc, WI_RID_P2_CRYPT_KEY0 + i,
2671 			    ic->ic_nw_keys[i].wk_key, keylen);
2672 			if (error)
2673 				break;
2674 		}
2675 		break;
2676 	}
2677 	if ((ifp->if_flags & IFF_RUNNING) != 0)
2678 		wi_cmd(sc, WI_CMD_ENABLE | sc->sc_portnum, 0, 0, 0);
2679 	if (error == 0)
2680 		sc->sc_flags |= WI_FLAGS_WEP_VALID;
2681 	return error;
2682 }
2683 
2684 /* Must be called at proper protection level! */
2685 STATIC int
wi_cmd_start(struct wi_softc * sc,int cmd,int val0,int val1,int val2)2686 wi_cmd_start(struct wi_softc *sc, int cmd, int val0, int val1, int val2)
2687 {
2688 #ifdef WI_HISTOGRAM
2689 	static int hist1[11];
2690 	static int hist1count;
2691 #endif
2692 	int i;
2693 
2694 	/* wait for the busy bit to clear */
2695 	for (i = 500; i > 0; i--) {	/* 5s */
2696 		if ((CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY) == 0)
2697 			break;
2698 		if (sc->sc_invalid)
2699 			return ENXIO;
2700 		DELAY(1000);	/* 1 m sec */
2701 	}
2702 	if (i == 0) {
2703 		aprint_error_dev(sc->sc_dev, "wi_cmd: busy bit won't clear.\n");
2704 		return(ETIMEDOUT);
2705   	}
2706 #ifdef WI_HISTOGRAM
2707 	if (i > 490)
2708 		hist1[500 - i]++;
2709 	else
2710 		hist1[10]++;
2711 	if (++hist1count == 1000) {
2712 		hist1count = 0;
2713 		printf("%s: hist1: %d %d %d %d %d %d %d %d %d %d %d\n",
2714 		    device_xname(sc->sc_dev),
2715 		    hist1[0], hist1[1], hist1[2], hist1[3], hist1[4],
2716 		    hist1[5], hist1[6], hist1[7], hist1[8], hist1[9],
2717 		    hist1[10]);
2718 	}
2719 #endif
2720 	CSR_WRITE_2(sc, WI_PARAM0, val0);
2721 	CSR_WRITE_2(sc, WI_PARAM1, val1);
2722 	CSR_WRITE_2(sc, WI_PARAM2, val2);
2723 	CSR_WRITE_2(sc, WI_COMMAND, cmd);
2724 
2725 	return 0;
2726 }
2727 
2728 STATIC int
wi_cmd(struct wi_softc * sc,int cmd,int val0,int val1,int val2)2729 wi_cmd(struct wi_softc *sc, int cmd, int val0, int val1, int val2)
2730 {
2731 	int rc;
2732 
2733 #ifdef WI_DEBUG
2734 	if (wi_debug) {
2735 		printf("%s: [enter] %d txcmds outstanding\n", __func__,
2736 		    sc->sc_txcmds);
2737 	}
2738 #endif
2739 	if (sc->sc_txcmds > 0)
2740 		wi_txcmd_wait(sc);
2741 
2742 	if ((rc = wi_cmd_start(sc, cmd, val0, val1, val2)) != 0)
2743 		return rc;
2744 
2745 	if (cmd == WI_CMD_INI) {
2746 		/* XXX: should sleep here. */
2747 		if (sc->sc_invalid)
2748 			return ENXIO;
2749 		DELAY(100*1000);
2750 	}
2751 	rc = wi_cmd_wait(sc, cmd, val0);
2752 
2753 #ifdef WI_DEBUG
2754 	if (wi_debug) {
2755 		printf("%s: [     ] %d txcmds outstanding\n", __func__,
2756 		    sc->sc_txcmds);
2757 	}
2758 #endif
2759 	if (sc->sc_txcmds > 0)
2760 		wi_cmd_intr(sc);
2761 
2762 #ifdef WI_DEBUG
2763 	if (wi_debug) {
2764 		printf("%s: [leave] %d txcmds outstanding\n", __func__,
2765 		    sc->sc_txcmds);
2766 	}
2767 #endif
2768 	return rc;
2769 }
2770 
2771 STATIC int
wi_cmd_wait(struct wi_softc * sc,int cmd,int val0)2772 wi_cmd_wait(struct wi_softc *sc, int cmd, int val0)
2773 {
2774 #ifdef WI_HISTOGRAM
2775 	static int hist2[11];
2776 	static int hist2count;
2777 #endif
2778 	int i, status;
2779 #ifdef WI_DEBUG
2780 	if (wi_debug > 1)
2781 		printf("%s: cmd=%#x, arg=%#x\n", __func__, cmd, val0);
2782 #endif /* WI_DEBUG */
2783 
2784 	/* wait for the cmd completed bit */
2785 	for (i = 0; i < WI_TIMEOUT; i++) {
2786 		if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_CMD)
2787 			break;
2788 		if (sc->sc_invalid)
2789 			return ENXIO;
2790 		DELAY(WI_DELAY);
2791 	}
2792 
2793 #ifdef WI_HISTOGRAM
2794 	if (i < 100)
2795 		hist2[i/10]++;
2796 	else
2797 		hist2[10]++;
2798 	if (++hist2count == 1000) {
2799 		hist2count = 0;
2800 		printf("%s: hist2: %d %d %d %d %d %d %d %d %d %d %d\n",
2801 		    device_xname(sc->sc_dev),
2802 		    hist2[0], hist2[1], hist2[2], hist2[3], hist2[4],
2803 		    hist2[5], hist2[6], hist2[7], hist2[8], hist2[9],
2804 		    hist2[10]);
2805 	}
2806 #endif
2807 
2808 	status = CSR_READ_2(sc, WI_STATUS);
2809 
2810 	if (i == WI_TIMEOUT) {
2811 		aprint_error_dev(sc->sc_dev,
2812 		    "command timed out, cmd=0x%x, arg=0x%x\n",
2813 		    cmd, val0);
2814 		return ETIMEDOUT;
2815 	}
2816 
2817 	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
2818 
2819 	if (status & WI_STAT_CMD_RESULT) {
2820 		aprint_error_dev(sc->sc_dev,
2821 		    "command failed, cmd=0x%x, arg=0x%x\n",
2822 		    cmd, val0);
2823 		return EIO;
2824 	}
2825 	return 0;
2826 }
2827 
2828 STATIC int
wi_seek_bap(struct wi_softc * sc,int id,int off)2829 wi_seek_bap(struct wi_softc *sc, int id, int off)
2830 {
2831 #ifdef WI_HISTOGRAM
2832 	static int hist4[11];
2833 	static int hist4count;
2834 #endif
2835 	int i, status;
2836 
2837 	CSR_WRITE_2(sc, WI_SEL0, id);
2838 	CSR_WRITE_2(sc, WI_OFF0, off);
2839 
2840 	for (i = 0; ; i++) {
2841 		status = CSR_READ_2(sc, WI_OFF0);
2842 		if ((status & WI_OFF_BUSY) == 0)
2843 			break;
2844 		if (i == WI_TIMEOUT) {
2845 			aprint_error_dev(sc->sc_dev,
2846 			    "timeout in wi_seek to %x/%x\n",
2847 			    id, off);
2848 			sc->sc_bap_off = WI_OFF_ERR;	/* invalidate */
2849 			return ETIMEDOUT;
2850 		}
2851 		if (sc->sc_invalid)
2852 			return ENXIO;
2853 		DELAY(2);
2854 	}
2855 #ifdef WI_HISTOGRAM
2856 	if (i < 100)
2857 		hist4[i/10]++;
2858 	else
2859 		hist4[10]++;
2860 	if (++hist4count == 2500) {
2861 		hist4count = 0;
2862 		printf("%s: hist4: %d %d %d %d %d %d %d %d %d %d %d\n",
2863 		    device_xname(sc->sc_dev),
2864 		    hist4[0], hist4[1], hist4[2], hist4[3], hist4[4],
2865 		    hist4[5], hist4[6], hist4[7], hist4[8], hist4[9],
2866 		    hist4[10]);
2867 	}
2868 #endif
2869 	if (status & WI_OFF_ERR) {
2870 		printf("%s: failed in wi_seek to %x/%x\n",
2871 		    device_xname(sc->sc_dev), id, off);
2872 		sc->sc_bap_off = WI_OFF_ERR;	/* invalidate */
2873 		return EIO;
2874 	}
2875 	sc->sc_bap_id = id;
2876 	sc->sc_bap_off = off;
2877 	return 0;
2878 }
2879 
2880 STATIC int
wi_read_bap(struct wi_softc * sc,int id,int off,void * buf,int buflen)2881 wi_read_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen)
2882 {
2883 	int error, cnt;
2884 
2885 	if (buflen == 0)
2886 		return 0;
2887 	if (id != sc->sc_bap_id || off != sc->sc_bap_off) {
2888 		if ((error = wi_seek_bap(sc, id, off)) != 0)
2889 			return error;
2890 	}
2891 	cnt = (buflen + 1) / 2;
2892 	CSR_READ_MULTI_STREAM_2(sc, WI_DATA0, (u_int16_t *)buf, cnt);
2893 	sc->sc_bap_off += cnt * 2;
2894 	return 0;
2895 }
2896 
2897 STATIC int
wi_write_bap(struct wi_softc * sc,int id,int off,void * buf,int buflen)2898 wi_write_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen)
2899 {
2900 	int error, cnt;
2901 
2902 	if (buflen == 0)
2903 		return 0;
2904 
2905 #ifdef WI_HERMES_AUTOINC_WAR
2906   again:
2907 #endif
2908 	if (id != sc->sc_bap_id || off != sc->sc_bap_off) {
2909 		if ((error = wi_seek_bap(sc, id, off)) != 0)
2910 			return error;
2911 	}
2912 	cnt = (buflen + 1) / 2;
2913 	CSR_WRITE_MULTI_STREAM_2(sc, WI_DATA0, (u_int16_t *)buf, cnt);
2914 	sc->sc_bap_off += cnt * 2;
2915 
2916 #ifdef WI_HERMES_AUTOINC_WAR
2917 	/*
2918 	 * According to the comments in the HCF Light code, there is a bug
2919 	 * in the Hermes (or possibly in certain Hermes firmware revisions)
2920 	 * where the chip's internal autoincrement counter gets thrown off
2921 	 * during data writes:  the autoincrement is missed, causing one
2922 	 * data word to be overwritten and subsequent words to be written to
2923 	 * the wrong memory locations. The end result is that we could end
2924 	 * up transmitting bogus frames without realizing it. The workaround
2925 	 * for this is to write a couple of extra guard words after the end
2926 	 * of the transfer, then attempt to read then back. If we fail to
2927 	 * locate the guard words where we expect them, we preform the
2928 	 * transfer over again.
2929 	 */
2930 	if ((sc->sc_flags & WI_FLAGS_BUG_AUTOINC) && (id & 0xf000) == 0) {
2931 		CSR_WRITE_2(sc, WI_DATA0, 0x1234);
2932 		CSR_WRITE_2(sc, WI_DATA0, 0x5678);
2933 		wi_seek_bap(sc, id, sc->sc_bap_off);
2934 		sc->sc_bap_off = WI_OFF_ERR;	/* invalidate */
2935 		if (CSR_READ_2(sc, WI_DATA0) != 0x1234 ||
2936 		    CSR_READ_2(sc, WI_DATA0) != 0x5678) {
2937 			aprint_error_dev(sc->sc_dev,
2938 			    "detect auto increment bug, try again\n");
2939 			goto again;
2940 		}
2941 	}
2942 #endif
2943 	return 0;
2944 }
2945 
2946 STATIC int
wi_mwrite_bap(struct wi_softc * sc,int id,int off,struct mbuf * m0,int totlen)2947 wi_mwrite_bap(struct wi_softc *sc, int id, int off, struct mbuf *m0, int totlen)
2948 {
2949 	int error, len;
2950 	struct mbuf *m;
2951 
2952 	for (m = m0; m != NULL && totlen > 0; m = m->m_next) {
2953 		if (m->m_len == 0)
2954 			continue;
2955 
2956 		len = min(m->m_len, totlen);
2957 
2958 		if (((u_long)m->m_data) % 2 != 0 || len % 2 != 0) {
2959 			m_copydata(m, 0, totlen, (void *)&sc->sc_txbuf);
2960 			return wi_write_bap(sc, id, off, (void *)&sc->sc_txbuf,
2961 			    totlen);
2962 		}
2963 
2964 		if ((error = wi_write_bap(sc, id, off, m->m_data, len)) != 0)
2965 			return error;
2966 
2967 		off += m->m_len;
2968 		totlen -= len;
2969 	}
2970 	return 0;
2971 }
2972 
2973 STATIC int
wi_alloc_fid(struct wi_softc * sc,int len,int * idp)2974 wi_alloc_fid(struct wi_softc *sc, int len, int *idp)
2975 {
2976 	int i;
2977 
2978 	if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len, 0, 0)) {
2979 		aprint_error_dev(sc->sc_dev, "failed to allocate %d bytes on NIC\n", len);
2980 		return ENOMEM;
2981 	}
2982 
2983 	for (i = 0; i < WI_TIMEOUT; i++) {
2984 		if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC)
2985 			break;
2986 		DELAY(1);
2987 	}
2988 	if (i == WI_TIMEOUT) {
2989 		aprint_error_dev(sc->sc_dev, "timeout in alloc\n");
2990 		return ETIMEDOUT;
2991 	}
2992 	*idp = CSR_READ_2(sc, WI_ALLOC_FID);
2993 	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
2994 	return 0;
2995 }
2996 
2997 STATIC int
wi_read_rid(struct wi_softc * sc,int rid,void * buf,int * buflenp)2998 wi_read_rid(struct wi_softc *sc, int rid, void *buf, int *buflenp)
2999 {
3000 	int error, len;
3001 	u_int16_t ltbuf[2];
3002 
3003 	/* Tell the NIC to enter record read mode. */
3004 	error = wi_cmd(sc, WI_CMD_ACCESS | WI_ACCESS_READ, rid, 0, 0);
3005 	if (error)
3006 		return error;
3007 
3008 	error = wi_read_bap(sc, rid, 0, ltbuf, sizeof(ltbuf));
3009 	if (error)
3010 		return error;
3011 
3012 	if (le16toh(ltbuf[0]) == 0)
3013 		return EOPNOTSUPP;
3014 	if (le16toh(ltbuf[1]) != rid) {
3015 		aprint_error_dev(sc->sc_dev,
3016 		    "record read mismatch, rid=%x, got=%x\n",
3017 		    rid, le16toh(ltbuf[1]));
3018 		return EIO;
3019 	}
3020 	len = (le16toh(ltbuf[0]) - 1) * 2;	 /* already got rid */
3021 	if (*buflenp < len) {
3022 		aprint_error_dev(sc->sc_dev, "record buffer is too small, "
3023 		    "rid=%x, size=%d, len=%d\n",
3024 		    rid, *buflenp, len);
3025 		return ENOSPC;
3026 	}
3027 	*buflenp = len;
3028 	return wi_read_bap(sc, rid, sizeof(ltbuf), buf, len);
3029 }
3030 
3031 STATIC int
wi_write_rid(struct wi_softc * sc,int rid,void * buf,int buflen)3032 wi_write_rid(struct wi_softc *sc, int rid, void *buf, int buflen)
3033 {
3034 	int error;
3035 	u_int16_t ltbuf[2];
3036 
3037 	ltbuf[0] = htole16((buflen + 1) / 2 + 1);	 /* includes rid */
3038 	ltbuf[1] = htole16(rid);
3039 
3040 	error = wi_write_bap(sc, rid, 0, ltbuf, sizeof(ltbuf));
3041 	if (error)
3042 		return error;
3043 	error = wi_write_bap(sc, rid, sizeof(ltbuf), buf, buflen);
3044 	if (error)
3045 		return error;
3046 
3047 	return wi_cmd(sc, WI_CMD_ACCESS | WI_ACCESS_WRITE, rid, 0, 0);
3048 }
3049 
3050 STATIC void
wi_rssadapt_updatestats_cb(void * arg,struct ieee80211_node * ni)3051 wi_rssadapt_updatestats_cb(void *arg, struct ieee80211_node *ni)
3052 {
3053 	struct wi_node *wn = (void*)ni;
3054 	ieee80211_rssadapt_updatestats(&wn->wn_rssadapt);
3055 }
3056 
3057 STATIC void
wi_rssadapt_updatestats(void * arg)3058 wi_rssadapt_updatestats(void *arg)
3059 {
3060 	struct wi_softc *sc = arg;
3061 	struct ieee80211com *ic = &sc->sc_ic;
3062 	ieee80211_iterate_nodes(&ic->ic_sta, wi_rssadapt_updatestats_cb, arg);
3063 	if (ic->ic_opmode != IEEE80211_M_MONITOR &&
3064 	    ic->ic_state == IEEE80211_S_RUN)
3065 		callout_reset(&sc->sc_rssadapt_ch, hz / 10,
3066 		    wi_rssadapt_updatestats, arg);
3067 }
3068 
3069 /*
3070  * In HOSTAP mode, restore IEEE80211_F_DROPUNENC when operating
3071  * with WEP enabled so that the AP drops unencoded frames at the
3072  * 802.11 layer.
3073  *
3074  * In all other modes, clear IEEE80211_F_DROPUNENC when operating
3075  * with WEP enabled so we don't drop unencoded frames at the 802.11
3076  * layer.  This is necessary because we must strip the WEP bit from
3077  * the 802.11 header before passing frames to ieee80211_input
3078  * because the card has already stripped the WEP crypto header from
3079  * the packet.
3080  */
3081 STATIC void
wi_mend_flags(struct wi_softc * sc,enum ieee80211_state nstate)3082 wi_mend_flags(struct wi_softc *sc, enum ieee80211_state nstate)
3083 {
3084 	struct ieee80211com *ic = &sc->sc_ic;
3085 
3086 	if (nstate == IEEE80211_S_RUN &&
3087 	    (ic->ic_flags & IEEE80211_F_PRIVACY) != 0 &&
3088 	    ic->ic_opmode != IEEE80211_M_HOSTAP)
3089 		ic->ic_flags &= ~IEEE80211_F_DROPUNENC;
3090 	else
3091 		ic->ic_flags |= sc->sc_ic_flags;
3092 
3093 	DPRINTF(("%s: state %d, "
3094 	    "ic->ic_flags & IEEE80211_F_DROPUNENC = %#" PRIx32 ", "
3095 	    "sc->sc_ic_flags & IEEE80211_F_DROPUNENC = %#" PRIx32 "\n",
3096 	    __func__, nstate,
3097 	    ic->ic_flags & IEEE80211_F_DROPUNENC,
3098 	    sc->sc_ic_flags & IEEE80211_F_DROPUNENC));
3099 }
3100 
3101 STATIC int
wi_newstate(struct ieee80211com * ic,enum ieee80211_state nstate,int arg)3102 wi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
3103 {
3104 	struct ifnet *ifp = ic->ic_ifp;
3105 	struct wi_softc *sc = ifp->if_softc;
3106 	struct ieee80211_node *ni = ic->ic_bss;
3107 	u_int16_t val;
3108 	struct wi_ssid ssid;
3109 	struct wi_macaddr bssid, old_bssid;
3110 	enum ieee80211_state ostate __unused;
3111 #ifdef WI_DEBUG
3112 	static const char *stname[] =
3113 	    { "INIT", "SCAN", "AUTH", "ASSOC", "RUN" };
3114 #endif /* WI_DEBUG */
3115 
3116 	ostate = ic->ic_state;
3117 	DPRINTF(("wi_newstate: %s -> %s\n", stname[ostate], stname[nstate]));
3118 
3119 	switch (nstate) {
3120 	case IEEE80211_S_INIT:
3121 		if (ic->ic_opmode != IEEE80211_M_MONITOR)
3122 			callout_stop(&sc->sc_rssadapt_ch);
3123 		ic->ic_flags &= ~IEEE80211_F_SIBSS;
3124 		sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
3125 		break;
3126 
3127 	case IEEE80211_S_SCAN:
3128 	case IEEE80211_S_AUTH:
3129 	case IEEE80211_S_ASSOC:
3130 		ic->ic_state = nstate; /* NB: skip normal ieee80211 handling */
3131 		wi_mend_flags(sc, nstate);
3132 		return 0;
3133 
3134 	case IEEE80211_S_RUN:
3135 		sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
3136 		IEEE80211_ADDR_COPY(old_bssid.wi_mac_addr, ni->ni_bssid);
3137 		wi_read_xrid(sc, WI_RID_CURRENT_BSSID, &bssid,
3138 		    IEEE80211_ADDR_LEN);
3139 		IEEE80211_ADDR_COPY(ni->ni_bssid, &bssid);
3140 		IEEE80211_ADDR_COPY(ni->ni_macaddr, &bssid);
3141 		wi_read_xrid(sc, WI_RID_CURRENT_CHAN, &val, sizeof(val));
3142 		if (!isset(ic->ic_chan_avail, le16toh(val)))
3143 			panic("%s: invalid channel %d\n",
3144 			    device_xname(sc->sc_dev), le16toh(val));
3145 		ni->ni_chan = &ic->ic_channels[le16toh(val)];
3146 
3147 		if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
3148 #ifndef	IEEE80211_NO_HOSTAP
3149 			ni->ni_esslen = ic->ic_des_esslen;
3150 			memcpy(ni->ni_essid, ic->ic_des_essid, ni->ni_esslen);
3151 			ni->ni_rates = ic->ic_sup_rates[
3152 			    ieee80211_chan2mode(ic, ni->ni_chan)];
3153 			ni->ni_intval = ic->ic_lintval;
3154 			ni->ni_capinfo = IEEE80211_CAPINFO_ESS;
3155 			if (ic->ic_flags & IEEE80211_F_PRIVACY)
3156 				ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY;
3157 #endif /* !IEEE80211_NO_HOSTAP */
3158 		} else {
3159 			wi_read_xrid(sc, WI_RID_CURRENT_SSID, &ssid,
3160 			    sizeof(ssid));
3161 			ni->ni_esslen = le16toh(ssid.wi_len);
3162 			if (ni->ni_esslen > IEEE80211_NWID_LEN)
3163 				ni->ni_esslen = IEEE80211_NWID_LEN;	/*XXX*/
3164 			memcpy(ni->ni_essid, ssid.wi_ssid, ni->ni_esslen);
3165 			ni->ni_rates = ic->ic_sup_rates[
3166 			    ieee80211_chan2mode(ic, ni->ni_chan)]; /*XXX*/
3167 		}
3168 		if (ic->ic_opmode != IEEE80211_M_MONITOR)
3169 			callout_reset(&sc->sc_rssadapt_ch, hz / 10,
3170 			    wi_rssadapt_updatestats, sc);
3171 		/* Trigger routing socket messages. XXX Copied from
3172 		 * ieee80211_newstate.
3173 		 */
3174 		if (ic->ic_opmode == IEEE80211_M_STA)
3175 			ieee80211_notify_node_join(ic, ic->ic_bss,
3176 				arg == IEEE80211_FC0_SUBTYPE_ASSOC_RESP);
3177 		break;
3178 	}
3179 	wi_mend_flags(sc, nstate);
3180 	return (*sc->sc_newstate)(ic, nstate, arg);
3181 }
3182 
3183 STATIC void
wi_set_tim(struct ieee80211_node * ni,int set)3184 wi_set_tim(struct ieee80211_node *ni, int set)
3185 {
3186 	struct ieee80211com *ic = ni->ni_ic;
3187 	struct wi_softc *sc = ic->ic_ifp->if_softc;
3188 
3189 	(*sc->sc_set_tim)(ni, set);
3190 
3191 	if ((ic->ic_flags & IEEE80211_F_TIMUPDATE) == 0)
3192 		return;
3193 
3194 	ic->ic_flags &= ~IEEE80211_F_TIMUPDATE;
3195 
3196 	(void)wi_write_val(sc, WI_RID_SET_TIM,
3197 	    IEEE80211_AID(ni->ni_associd) | (set ? 0x8000 : 0));
3198 }
3199 
3200 STATIC int
wi_scan_ap(struct wi_softc * sc,u_int16_t chanmask,u_int16_t txrate)3201 wi_scan_ap(struct wi_softc *sc, u_int16_t chanmask, u_int16_t txrate)
3202 {
3203 	int error = 0;
3204 	u_int16_t val[2];
3205 
3206 	if (!sc->sc_enabled)
3207 		return ENXIO;
3208 	switch (sc->sc_firmware_type) {
3209 	case WI_LUCENT:
3210 		(void)wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0);
3211 		break;
3212 	case WI_INTERSIL:
3213 		val[0] = htole16(chanmask);	/* channel */
3214 		val[1] = htole16(txrate);	/* tx rate */
3215 		error = wi_write_rid(sc, WI_RID_SCAN_REQ, val, sizeof(val));
3216 		break;
3217 	case WI_SYMBOL:
3218 		/*
3219 		 * XXX only supported on 3.x ?
3220 		 */
3221 		val[0] = htole16(BSCAN_BCAST | BSCAN_ONETIME);
3222 		error = wi_write_rid(sc, WI_RID_BCAST_SCAN_REQ,
3223 		    val, sizeof(val[0]));
3224 		break;
3225 	}
3226 	if (error == 0) {
3227 		sc->sc_scan_timer = WI_SCAN_WAIT;
3228 		sc->sc_if.if_timer = 1;
3229 		DPRINTF(("wi_scan_ap: start scanning, "
3230 			"chanmask 0x%x txrate 0x%x\n", chanmask, txrate));
3231 	}
3232 	return error;
3233 }
3234 
3235 STATIC void
wi_scan_result(struct wi_softc * sc,int fid,int cnt)3236 wi_scan_result(struct wi_softc *sc, int fid, int cnt)
3237 {
3238 #define	N(a)	(sizeof (a) / sizeof (a[0]))
3239 	int i, naps, off, szbuf;
3240 	struct wi_scan_header ws_hdr;	/* Prism2 header */
3241 	struct wi_scan_data_p2 ws_dat;	/* Prism2 scantable*/
3242 	struct wi_apinfo *ap;
3243 
3244 	off = sizeof(u_int16_t) * 2;
3245 	memset(&ws_hdr, 0, sizeof(ws_hdr));
3246 	switch (sc->sc_firmware_type) {
3247 	case WI_INTERSIL:
3248 		wi_read_bap(sc, fid, off, &ws_hdr, sizeof(ws_hdr));
3249 		off += sizeof(ws_hdr);
3250 		szbuf = sizeof(struct wi_scan_data_p2);
3251 		break;
3252 	case WI_SYMBOL:
3253 		szbuf = sizeof(struct wi_scan_data_p2) + 6;
3254 		break;
3255 	case WI_LUCENT:
3256 		szbuf = sizeof(struct wi_scan_data);
3257 		break;
3258 	default:
3259 		aprint_error_dev(sc->sc_dev,
3260 		    "wi_scan_result: unknown firmware type %u\n",
3261 		    sc->sc_firmware_type);
3262 		naps = 0;
3263 		goto done;
3264 	}
3265 	naps = (cnt * 2 + 2 - off) / szbuf;
3266 	if (naps > N(sc->sc_aps))
3267 		naps = N(sc->sc_aps);
3268 	sc->sc_naps = naps;
3269 	/* Read Data */
3270 	ap = sc->sc_aps;
3271 	memset(&ws_dat, 0, sizeof(ws_dat));
3272 	for (i = 0; i < naps; i++, ap++) {
3273 		wi_read_bap(sc, fid, off, &ws_dat,
3274 		    (sizeof(ws_dat) < szbuf ? sizeof(ws_dat) : szbuf));
3275 		DPRINTF2(("wi_scan_result: #%d: off %d bssid %s\n", i, off,
3276 		    ether_sprintf(ws_dat.wi_bssid)));
3277 		off += szbuf;
3278 		ap->scanreason = le16toh(ws_hdr.wi_reason);
3279 		memcpy(ap->bssid, ws_dat.wi_bssid, sizeof(ap->bssid));
3280 		ap->channel = le16toh(ws_dat.wi_chid);
3281 		ap->signal  = le16toh(ws_dat.wi_signal);
3282 		ap->noise   = le16toh(ws_dat.wi_noise);
3283 		ap->quality = ap->signal - ap->noise;
3284 		ap->capinfo = le16toh(ws_dat.wi_capinfo);
3285 		ap->interval = le16toh(ws_dat.wi_interval);
3286 		ap->rate    = le16toh(ws_dat.wi_rate);
3287 		ap->namelen = le16toh(ws_dat.wi_namelen);
3288 		if (ap->namelen > sizeof(ap->name))
3289 			ap->namelen = sizeof(ap->name);
3290 		memcpy(ap->name, ws_dat.wi_name, ap->namelen);
3291 	}
3292 done:
3293 	/* Done scanning */
3294 	sc->sc_scan_timer = 0;
3295 	DPRINTF(("wi_scan_result: scan complete: ap %d\n", naps));
3296 #undef N
3297 }
3298 
3299 STATIC void
wi_dump_pkt(struct wi_frame * wh,struct ieee80211_node * ni,int rssi)3300 wi_dump_pkt(struct wi_frame *wh, struct ieee80211_node *ni, int rssi)
3301 {
3302 	ieee80211_dump_pkt((u_int8_t *) &wh->wi_whdr, sizeof(wh->wi_whdr),
3303 	    ni	? ni->ni_rates.rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL
3304 		: -1,
3305 	    rssi);
3306 	printf(" status 0x%x rx_tstamp1 %u rx_tstamp0 0x%u rx_silence %u\n",
3307 		le16toh(wh->wi_status), le16toh(wh->wi_rx_tstamp1),
3308 		le16toh(wh->wi_rx_tstamp0), wh->wi_rx_silence);
3309 	printf(" rx_signal %u rx_rate %u rx_flow %u\n",
3310 		wh->wi_rx_signal, wh->wi_rx_rate, wh->wi_rx_flow);
3311 	printf(" tx_rtry %u tx_rate %u tx_ctl 0x%x dat_len %u\n",
3312 		wh->wi_tx_rtry, wh->wi_tx_rate,
3313 		le16toh(wh->wi_tx_ctl), le16toh(wh->wi_dat_len));
3314 	printf(" ehdr dst %s src %s type 0x%x\n",
3315 		ether_sprintf(wh->wi_ehdr.ether_dhost),
3316 		ether_sprintf(wh->wi_ehdr.ether_shost),
3317 		wh->wi_ehdr.ether_type);
3318 }
3319