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