xref: /openbsd-src/sys/dev/ic/if_wi.c (revision 0b7734b3d77bb9b21afec6f4621cae6c805dbd45)
1 /*	$OpenBSD: if_wi.c,v 1.166 2016/04/13 10:49:26 mpi 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  *	From: if_wi.c,v 1.7 1999/07/04 14:40:22 wpaul Exp $
35  */
36 
37 /*
38  * Lucent WaveLAN/IEEE 802.11 driver for OpenBSD.
39  *
40  * Originally written by Bill Paul <wpaul@ctr.columbia.edu>
41  * Electrical Engineering Department
42  * Columbia University, New York City
43  */
44 
45 /*
46  * The WaveLAN/IEEE adapter is the second generation of the WaveLAN
47  * from Lucent. Unlike the older cards, the new ones are programmed
48  * entirely via a firmware-driven controller called the Hermes.
49  * Unfortunately, Lucent will not release the Hermes programming manual
50  * without an NDA (if at all). What they do release is an API library
51  * called the HCF (Hardware Control Functions) which is supposed to
52  * do the device-specific operations of a device driver for you. The
53  * publicly available version of the HCF library (the 'HCF Light') is
54  * a) extremely gross, b) lacks certain features, particularly support
55  * for 802.11 frames, and c) is contaminated by the GNU Public License.
56  *
57  * This driver does not use the HCF or HCF Light at all. Instead, it
58  * programs the Hermes controller directly, using information gleaned
59  * from the HCF Light code and corresponding documentation.
60  */
61 
62 #define WI_HERMES_AUTOINC_WAR	/* Work around data write autoinc bug. */
63 #define WI_HERMES_STATS_WAR	/* Work around stats counter bug. */
64 
65 #include "bpfilter.h"
66 
67 #include <sys/param.h>
68 #include <sys/systm.h>
69 #include <sys/sockio.h>
70 #include <sys/mbuf.h>
71 #include <sys/malloc.h>
72 #include <sys/kernel.h>
73 #include <sys/socket.h>
74 #include <sys/device.h>
75 
76 #include <net/if.h>
77 #include <net/if_dl.h>
78 #include <net/if_media.h>
79 
80 #include <netinet/in.h>
81 #include <netinet/if_ether.h>
82 
83 #include <net80211/ieee80211_var.h>
84 #include <net80211/ieee80211_ioctl.h>
85 
86 #if NBPFILTER > 0
87 #include <net/bpf.h>
88 #endif
89 
90 #include <machine/bus.h>
91 
92 #include <dev/ic/if_wireg.h>
93 #include <dev/ic/if_wi_ieee.h>
94 #include <dev/ic/if_wivar.h>
95 
96 #include <crypto/arc4.h>
97 
98 #define BPFATTACH(if_bpf,if,dlt,sz)
99 #define STATIC
100 
101 #ifdef WIDEBUG
102 
103 u_int32_t	widebug = WIDEBUG;
104 
105 #define WID_INTR	0x01
106 #define WID_START	0x02
107 #define WID_IOCTL	0x04
108 #define WID_INIT	0x08
109 #define WID_STOP	0x10
110 #define WID_RESET	0x20
111 
112 #define DPRINTF(mask,args) if (widebug & (mask)) printf args;
113 
114 #else	/* !WIDEBUG */
115 #define DPRINTF(mask,args)
116 #endif	/* WIDEBUG */
117 
118 #ifdef foo
119 static u_int8_t	wi_mcast_addr[6] = { 0x01, 0x60, 0x1D, 0x00, 0x01, 0x00 };
120 #endif
121 
122 STATIC void wi_reset(struct wi_softc *);
123 STATIC int wi_ioctl(struct ifnet *, u_long, caddr_t);
124 STATIC void wi_init_io(struct wi_softc *);
125 STATIC void wi_start(struct ifnet *);
126 STATIC void wi_watchdog(struct ifnet *);
127 STATIC void wi_rxeof(struct wi_softc *);
128 STATIC void wi_txeof(struct wi_softc *, int);
129 STATIC void wi_update_stats(struct wi_softc *);
130 STATIC void wi_setmulti(struct wi_softc *);
131 
132 STATIC int wi_cmd_io(struct wi_softc *, int, int, int, int);
133 STATIC int wi_read_record_io(struct wi_softc *, struct wi_ltv_gen *);
134 STATIC int wi_write_record_io(struct wi_softc *, struct wi_ltv_gen *);
135 STATIC int wi_read_data_io(struct wi_softc *, int,
136 					int, caddr_t, int);
137 STATIC int wi_write_data_io(struct wi_softc *, int,
138 					int, caddr_t, int);
139 STATIC int wi_seek(struct wi_softc *, int, int, int);
140 
141 STATIC void wi_inquire(void *);
142 STATIC int wi_setdef(struct wi_softc *, struct wi_req *);
143 STATIC void wi_get_id(struct wi_softc *);
144 
145 STATIC int wi_media_change(struct ifnet *);
146 STATIC void wi_media_status(struct ifnet *, struct ifmediareq *);
147 
148 STATIC int wi_set_ssid(struct ieee80211_nwid *, u_int8_t *, int);
149 STATIC int wi_set_nwkey(struct wi_softc *, struct ieee80211_nwkey *);
150 STATIC int wi_get_nwkey(struct wi_softc *, struct ieee80211_nwkey *);
151 STATIC int wi_sync_media(struct wi_softc *, int, int);
152 STATIC int wi_set_pm(struct wi_softc *, struct ieee80211_power *);
153 STATIC int wi_get_pm(struct wi_softc *, struct ieee80211_power *);
154 STATIC int wi_set_txpower(struct wi_softc *, struct ieee80211_txpower *);
155 STATIC int wi_get_txpower(struct wi_softc *, struct ieee80211_txpower *);
156 
157 STATIC int wi_get_debug(struct wi_softc *, struct wi_req *);
158 STATIC int wi_set_debug(struct wi_softc *, struct wi_req *);
159 
160 STATIC void wi_do_hostencrypt(struct wi_softc *, caddr_t, int);
161 STATIC int wi_do_hostdecrypt(struct wi_softc *, caddr_t, int);
162 
163 STATIC int wi_alloc_nicmem_io(struct wi_softc *, int, int *);
164 STATIC int wi_get_fid_io(struct wi_softc *sc, int fid);
165 STATIC void wi_intr_enable(struct wi_softc *sc, int mode);
166 STATIC void wi_intr_ack(struct wi_softc *sc, int mode);
167 void	 wi_scan_timeout(void *);
168 
169 /* Autoconfig definition of driver back-end */
170 struct cfdriver wi_cd = {
171 	NULL, "wi", DV_IFNET
172 };
173 
174 const struct wi_card_ident wi_card_ident[] = {
175 	WI_CARD_IDS
176 };
177 
178 struct wi_funcs wi_func_io = {
179         wi_cmd_io,
180         wi_read_record_io,
181         wi_write_record_io,
182         wi_alloc_nicmem_io,
183         wi_read_data_io,
184         wi_write_data_io,
185         wi_get_fid_io,
186         wi_init_io,
187 
188         wi_start,
189         wi_ioctl,
190         wi_watchdog,
191         wi_inquire,
192 };
193 
194 int
195 wi_attach(struct wi_softc *sc, struct wi_funcs *funcs)
196 {
197 	struct ieee80211com	*ic;
198 	struct ifnet		*ifp;
199 	struct wi_ltv_macaddr	mac;
200 	struct wi_ltv_rates	rates;
201 	struct wi_ltv_gen	gen;
202 	int			error;
203 
204 	ic = &sc->sc_ic;
205 	ifp = &ic->ic_if;
206 
207 	sc->sc_funcs = funcs;
208 	sc->wi_cmd_count = 500;
209 
210 	wi_reset(sc);
211 
212 	/* Read the station address. */
213 	mac.wi_type = WI_RID_MAC_NODE;
214 	mac.wi_len = 4;
215 	error = wi_read_record(sc, (struct wi_ltv_gen *)&mac);
216 	if (error) {
217 		printf(": unable to read station address\n");
218 		return (error);
219 	}
220 	bcopy(&mac.wi_mac_addr, &ic->ic_myaddr, IEEE80211_ADDR_LEN);
221 
222 	wi_get_id(sc);
223 	printf("address %s", ether_sprintf(ic->ic_myaddr));
224 
225 	bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
226 	ifp->if_softc = sc;
227 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
228 	ifp->if_ioctl = funcs->f_ioctl;
229 	ifp->if_start = funcs->f_start;
230 	ifp->if_watchdog = funcs->f_watchdog;
231 
232 	(void)wi_set_ssid(&sc->wi_node_name, WI_DEFAULT_NODENAME,
233 	    sizeof(WI_DEFAULT_NODENAME) - 1);
234 	(void)wi_set_ssid(&sc->wi_net_name, WI_DEFAULT_NETNAME,
235 	    sizeof(WI_DEFAULT_NETNAME) - 1);
236 	(void)wi_set_ssid(&sc->wi_ibss_name, WI_DEFAULT_IBSS,
237 	    sizeof(WI_DEFAULT_IBSS) - 1);
238 
239 	sc->wi_portnum = WI_DEFAULT_PORT;
240 	sc->wi_ptype = WI_PORTTYPE_BSS;
241 	sc->wi_ap_density = WI_DEFAULT_AP_DENSITY;
242 	sc->wi_rts_thresh = WI_DEFAULT_RTS_THRESH;
243 	sc->wi_tx_rate = WI_DEFAULT_TX_RATE;
244 	sc->wi_max_data_len = WI_DEFAULT_DATALEN;
245 	sc->wi_create_ibss = WI_DEFAULT_CREATE_IBSS;
246 	sc->wi_pm_enabled = WI_DEFAULT_PM_ENABLED;
247 	sc->wi_max_sleep = WI_DEFAULT_MAX_SLEEP;
248 	sc->wi_roaming = WI_DEFAULT_ROAMING;
249 	sc->wi_authtype = WI_DEFAULT_AUTHTYPE;
250 	sc->wi_diversity = WI_DEFAULT_DIVERSITY;
251 	sc->wi_crypto_algorithm = WI_CRYPTO_FIRMWARE_WEP;
252 
253 	/*
254 	 * Read the default channel from the NIC. This may vary
255 	 * depending on the country where the NIC was purchased, so
256 	 * we can't hard-code a default and expect it to work for
257 	 * everyone.
258 	 */
259 	gen.wi_type = WI_RID_OWN_CHNL;
260 	gen.wi_len = 2;
261 	if (wi_read_record(sc, &gen) == 0)
262 		sc->wi_channel = letoh16(gen.wi_val);
263 	else
264 		sc->wi_channel = 3;
265 
266 	/*
267 	 * Set flags based on firmware version.
268 	 */
269 	switch (sc->sc_firmware_type) {
270 	case WI_LUCENT:
271 		sc->wi_flags |= WI_FLAGS_HAS_ROAMING;
272 		if (sc->sc_sta_firmware_ver >= 60000)
273 			sc->wi_flags |= WI_FLAGS_HAS_MOR;
274 		if (sc->sc_sta_firmware_ver >= 60006) {
275 			sc->wi_flags |= WI_FLAGS_HAS_IBSS;
276 			sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS;
277 		}
278 		sc->wi_ibss_port = htole16(1);
279 		break;
280 	case WI_INTERSIL:
281 		sc->wi_flags |= WI_FLAGS_HAS_ROAMING;
282 		/* older prism firmware is slow so crank the count */
283 		if (sc->sc_sta_firmware_ver < 10000)
284 			sc->wi_cmd_count = 5000;
285 		else
286 			sc->wi_cmd_count = 2000;
287 		if (sc->sc_sta_firmware_ver >= 800) {
288 #ifndef SMALL_KERNEL
289 			/*
290 			 * USB hostap is more pain than it is worth
291 			 * for now, things would have to be overhauled
292 			 */
293 			if ((sc->sc_sta_firmware_ver != 10402) &&
294 			    (!(sc->wi_flags & WI_FLAGS_BUS_USB)))
295 				sc->wi_flags |= WI_FLAGS_HAS_HOSTAP;
296 #endif
297 			sc->wi_flags |= WI_FLAGS_HAS_IBSS;
298 			sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS;
299 		}
300 		if (sc->sc_sta_firmware_ver >= 10603)
301 			sc->wi_flags |= WI_FLAGS_HAS_ENH_SECURITY;
302 		sc->wi_ibss_port = htole16(0);
303 		break;
304 	case WI_SYMBOL:
305 		sc->wi_flags |= WI_FLAGS_HAS_DIVERSITY;
306 		if (sc->sc_sta_firmware_ver >= 20000)
307 			sc->wi_flags |= WI_FLAGS_HAS_IBSS;
308 		if (sc->sc_sta_firmware_ver >= 25000)
309 			sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS;
310 		sc->wi_ibss_port = htole16(4);
311 		break;
312 	}
313 
314 	/*
315 	 * Find out if we support WEP on this card.
316 	 */
317 	gen.wi_type = WI_RID_WEP_AVAIL;
318 	gen.wi_len = 2;
319 	if (wi_read_record(sc, &gen) == 0 && gen.wi_val != htole16(0))
320 		sc->wi_flags |= WI_FLAGS_HAS_WEP;
321 	timeout_set(&sc->sc_timo, funcs->f_inquire, sc);
322 
323 	bzero(&sc->wi_stats, sizeof(sc->wi_stats));
324 
325 	/* Find supported rates. */
326 	rates.wi_type = WI_RID_DATA_RATES;
327 	rates.wi_len = sizeof(rates.wi_rates);
328 	if (wi_read_record(sc, (struct wi_ltv_gen *)&rates) == 0) {
329 		int i, nrates;
330 
331 		nrates = letoh16(*(u_int16_t *)rates.wi_rates);
332 		if (nrates > sizeof(rates.wi_rates) - 2)
333 			nrates = sizeof(rates.wi_rates) - 2;
334 
335 		sc->wi_supprates = 0;
336 		for (i = 0; i < nrates; i++)
337 			sc->wi_supprates |= rates.wi_rates[2 + i];
338 	} else
339 		sc->wi_supprates = WI_SUPPRATES_1M | WI_SUPPRATES_2M |
340 		    WI_SUPPRATES_5M | WI_SUPPRATES_11M;
341 
342 	ifmedia_init(&sc->sc_media, 0, wi_media_change, wi_media_status);
343 #define	ADD(m, c)	ifmedia_add(&sc->sc_media, (m), (c), NULL)
344 	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0);
345 	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_ADHOC, 0), 0);
346 	if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
347 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_IBSS,
348 		    0), 0);
349 	if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
350 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO,
351 		    IFM_IEEE80211_IBSSMASTER, 0), 0);
352 	if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP)
353 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO,
354 		    IFM_IEEE80211_HOSTAP, 0), 0);
355 	if (sc->wi_supprates & WI_SUPPRATES_1M) {
356 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0);
357 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
358 		    IFM_IEEE80211_ADHOC, 0), 0);
359 		if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
360 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
361 			    IFM_IEEE80211_IBSS, 0), 0);
362 		if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
363 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
364 			    IFM_IEEE80211_IBSSMASTER, 0), 0);
365 		if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP)
366 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
367 			    IFM_IEEE80211_HOSTAP, 0), 0);
368 	}
369 	if (sc->wi_supprates & WI_SUPPRATES_2M) {
370 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0);
371 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
372 		    IFM_IEEE80211_ADHOC, 0), 0);
373 		if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
374 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
375 			    IFM_IEEE80211_IBSS, 0), 0);
376 		if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
377 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
378 			    IFM_IEEE80211_IBSSMASTER, 0), 0);
379 		if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP)
380 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
381 			    IFM_IEEE80211_HOSTAP, 0), 0);
382 	}
383 	if (sc->wi_supprates & WI_SUPPRATES_5M) {
384 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 0, 0), 0);
385 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
386 		    IFM_IEEE80211_ADHOC, 0), 0);
387 		if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
388 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
389 			    IFM_IEEE80211_IBSS, 0), 0);
390 		if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
391 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
392 			    IFM_IEEE80211_IBSSMASTER, 0), 0);
393 		if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP)
394 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
395 			    IFM_IEEE80211_HOSTAP, 0), 0);
396 	}
397 	if (sc->wi_supprates & WI_SUPPRATES_11M) {
398 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0);
399 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
400 		    IFM_IEEE80211_ADHOC, 0), 0);
401 		if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
402 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
403 			    IFM_IEEE80211_IBSS, 0), 0);
404 		if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
405 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
406 			    IFM_IEEE80211_IBSSMASTER, 0), 0);
407 		if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP)
408 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
409 			    IFM_IEEE80211_HOSTAP, 0), 0);
410 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_MANUAL, 0, 0), 0);
411 	}
412 #undef ADD
413 	ifmedia_set(&sc->sc_media,
414 	    IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0));
415 
416 	/*
417 	 * Call MI attach routines.
418 	 */
419 	if_attach(ifp);
420 	memcpy(((struct arpcom *)ifp)->ac_enaddr, ic->ic_myaddr,
421 	    ETHER_ADDR_LEN);
422 	ether_ifattach(ifp);
423 	printf("\n");
424 
425 	sc->wi_flags |= WI_FLAGS_ATTACHED;
426 
427 #if NBPFILTER > 0
428 	BPFATTACH(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
429 #endif
430 
431 	if_addgroup(ifp, "wlan");
432 	ifp->if_priority = IF_WIRELESS_DEFAULT_PRIORITY;
433 
434 	wi_init(sc);
435 	wi_stop(sc);
436 
437 	return (0);
438 }
439 
440 STATIC void
441 wi_intr_enable(struct wi_softc *sc, int mode)
442 {
443 	if (!(sc->wi_flags & WI_FLAGS_BUS_USB))
444 		CSR_WRITE_2(sc, WI_INT_EN, mode);
445 }
446 
447 STATIC void
448 wi_intr_ack(struct wi_softc *sc, int mode)
449 {
450 	if (!(sc->wi_flags & WI_FLAGS_BUS_USB))
451 		CSR_WRITE_2(sc, WI_EVENT_ACK, mode);
452 }
453 
454 int
455 wi_intr(void *vsc)
456 {
457 	struct wi_softc		*sc = vsc;
458 	struct ifnet		*ifp;
459 	u_int16_t		status;
460 
461 	DPRINTF(WID_INTR, ("wi_intr: sc %p\n", sc));
462 
463 	ifp = &sc->sc_ic.ic_if;
464 
465 	if (!(sc->wi_flags & WI_FLAGS_ATTACHED) || !(ifp->if_flags & IFF_UP)) {
466 		CSR_WRITE_2(sc, WI_INT_EN, 0);
467 		CSR_WRITE_2(sc, WI_EVENT_ACK, 0xffff);
468 		return (0);
469 	}
470 
471 	/* Disable interrupts. */
472 	CSR_WRITE_2(sc, WI_INT_EN, 0);
473 
474 	status = CSR_READ_2(sc, WI_EVENT_STAT);
475 	CSR_WRITE_2(sc, WI_EVENT_ACK, ~WI_INTRS);
476 
477 	if (status & WI_EV_RX) {
478 		wi_rxeof(sc);
479 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
480 	}
481 
482 	if (status & WI_EV_TX) {
483 		wi_txeof(sc, status);
484 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX);
485 	}
486 
487 	if (status & WI_EV_ALLOC) {
488 		int			id;
489 		id = CSR_READ_2(sc, WI_ALLOC_FID);
490 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
491 		if (id == sc->wi_tx_data_id)
492 			wi_txeof(sc, status);
493 	}
494 
495 	if (status & WI_EV_INFO) {
496 		wi_update_stats(sc);
497 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO);
498 	}
499 
500 	if (status & WI_EV_TX_EXC) {
501 		wi_txeof(sc, status);
502 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX_EXC);
503 	}
504 
505 	if (status & WI_EV_INFO_DROP) {
506 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO_DROP);
507 	}
508 
509 	/* Re-enable interrupts. */
510 	CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
511 
512 	if (status == 0)
513 		return (0);
514 
515 	if (!IFQ_IS_EMPTY(&ifp->if_snd))
516 		wi_start(ifp);
517 
518 	return (1);
519 }
520 
521 STATIC int
522 wi_get_fid_io(struct wi_softc *sc, int fid)
523 {
524 	return CSR_READ_2(sc, fid);
525 }
526 
527 
528 void
529 wi_rxeof(struct wi_softc *sc)
530 {
531 	struct ifnet		*ifp;
532 	struct ether_header	*eh;
533 	struct mbuf_list	ml = MBUF_LIST_INITIALIZER();
534 	struct mbuf		*m;
535 	caddr_t			olddata;
536 	u_int16_t		ftype;
537 	int			maxlen;
538 	int			id;
539 
540 	ifp = &sc->sc_ic.ic_if;
541 
542 	id = wi_get_fid(sc, WI_RX_FID);
543 
544 	if (sc->wi_procframe || sc->wi_debug.wi_monitor) {
545 		struct wi_frame	*rx_frame;
546 		int		datlen, hdrlen;
547 
548 		MGETHDR(m, M_DONTWAIT, MT_DATA);
549 		if (m == NULL) {
550 			ifp->if_ierrors++;
551 			return;
552 		}
553 		MCLGET(m, M_DONTWAIT);
554 		if (!(m->m_flags & M_EXT)) {
555 			m_freem(m);
556 			ifp->if_ierrors++;
557 			return;
558 		}
559 
560 		if (wi_read_data(sc, id, 0, mtod(m, caddr_t),
561 		    sizeof(struct wi_frame))) {
562 			m_freem(m);
563 			ifp->if_ierrors++;
564 			return;
565 		}
566 
567 		rx_frame = mtod(m, struct wi_frame *);
568 
569 		if (rx_frame->wi_status & htole16(WI_STAT_BADCRC)) {
570 			m_freem(m);
571 			ifp->if_ierrors++;
572 			return;
573 		}
574 
575 		switch ((letoh16(rx_frame->wi_status) & WI_STAT_MAC_PORT)
576 		    >> 8) {
577 		case 7:
578 			switch (letoh16(rx_frame->wi_frame_ctl) &
579 			    WI_FCTL_FTYPE) {
580 			case WI_FTYPE_DATA:
581 				hdrlen = WI_DATA_HDRLEN;
582 				datlen = letoh16(rx_frame->wi_dat_len);
583 				break;
584 			case WI_FTYPE_MGMT:
585 				hdrlen = WI_MGMT_HDRLEN;
586 				datlen = letoh16(rx_frame->wi_dat_len);
587 				break;
588 			case WI_FTYPE_CTL:
589 				hdrlen = WI_CTL_HDRLEN;
590 				datlen = 0;
591 				break;
592 			default:
593 				printf(WI_PRT_FMT ": received packet of "
594 				    "unknown type on port 7\n", WI_PRT_ARG(sc));
595 				m_freem(m);
596 				ifp->if_ierrors++;
597 				return;
598 			}
599 			break;
600 		case 0:
601 			hdrlen = WI_DATA_HDRLEN;
602 			datlen = letoh16(rx_frame->wi_dat_len);
603 			break;
604 		default:
605 			printf(WI_PRT_FMT ": received packet on invalid port "
606 			    "(wi_status=0x%x)\n", WI_PRT_ARG(sc),
607 			    letoh16(rx_frame->wi_status));
608 			m_freem(m);
609 			ifp->if_ierrors++;
610 			return;
611 		}
612 
613 		if ((hdrlen + datlen + 2) > MCLBYTES) {
614 			m_freem(m);
615 			ifp->if_ierrors++;
616 			return;
617 		}
618 
619 		if (wi_read_data(sc, id, hdrlen, mtod(m, caddr_t) + hdrlen,
620 		    datlen + 2)) {
621 			m_freem(m);
622 			ifp->if_ierrors++;
623 			return;
624 		}
625 
626 		m->m_pkthdr.len = m->m_len = hdrlen + datlen;
627 	} else {
628 		struct wi_frame rx_frame;
629 
630 		/* First read in the frame header */
631 		if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame,
632 		    sizeof(rx_frame))) {
633 			ifp->if_ierrors++;
634 			return;
635 		}
636 
637 		/* Drop undecryptable or packets with receive errors here */
638 		if (rx_frame.wi_status & htole16(WI_STAT_ERRSTAT)) {
639 			ifp->if_ierrors++;
640 			return;
641 		}
642 
643 		/* Stash frame type in host byte order for later use */
644 		ftype = letoh16(rx_frame.wi_frame_ctl) & WI_FCTL_FTYPE;
645 
646 		MGETHDR(m, M_DONTWAIT, MT_DATA);
647 		if (m == NULL) {
648 			ifp->if_ierrors++;
649 			return;
650 		}
651 		MCLGET(m, M_DONTWAIT);
652 		if (!(m->m_flags & M_EXT)) {
653 			m_freem(m);
654 			ifp->if_ierrors++;
655 			return;
656 		}
657 
658 		olddata = m->m_data;
659 		/* Align the data after the ethernet header */
660 		m->m_data = (caddr_t)ALIGN(m->m_data +
661 		    sizeof(struct ether_header)) - sizeof(struct ether_header);
662 
663 		eh = mtod(m, struct ether_header *);
664 		maxlen = MCLBYTES - (m->m_data - olddata);
665 
666 		if (ftype == WI_FTYPE_MGMT &&
667 		    sc->wi_ptype == WI_PORTTYPE_HOSTAP) {
668 
669 			u_int16_t rxlen = letoh16(rx_frame.wi_dat_len);
670 
671 			if ((WI_802_11_OFFSET_RAW + rxlen + 2) > maxlen) {
672 				printf("%s: oversized mgmt packet received in "
673 				    "hostap mode (wi_dat_len=%d, "
674 				    "wi_status=0x%x)\n", sc->sc_dev.dv_xname,
675 				    rxlen, letoh16(rx_frame.wi_status));
676 				m_freem(m);
677 				ifp->if_ierrors++;
678 				return;
679 			}
680 
681 			/* Put the whole header in there. */
682 			bcopy(&rx_frame, mtod(m, void *),
683 			    sizeof(struct wi_frame));
684 			if (wi_read_data(sc, id, WI_802_11_OFFSET_RAW,
685 			    mtod(m, caddr_t) + WI_802_11_OFFSET_RAW,
686 			    rxlen + 2)) {
687 				m_freem(m);
688 				if (sc->sc_ic.ic_if.if_flags & IFF_DEBUG)
689 					printf("wihap: failed to copy header\n");
690 				ifp->if_ierrors++;
691 				return;
692 			}
693 
694 			m->m_pkthdr.len = m->m_len =
695 			    WI_802_11_OFFSET_RAW + rxlen;
696 
697 			/* XXX: consider giving packet to bhp? */
698 
699 			wihap_mgmt_input(sc, &rx_frame, m);
700 
701 			return;
702 		}
703 
704 		switch (letoh16(rx_frame.wi_status) & WI_RXSTAT_MSG_TYPE) {
705 		case WI_STAT_1042:
706 		case WI_STAT_TUNNEL:
707 		case WI_STAT_WMP_MSG:
708 			if ((letoh16(rx_frame.wi_dat_len) + WI_SNAPHDR_LEN) >
709 			    maxlen) {
710 				printf(WI_PRT_FMT ": oversized packet received "
711 				    "(wi_dat_len=%d, wi_status=0x%x)\n",
712 				    WI_PRT_ARG(sc),
713 				    letoh16(rx_frame.wi_dat_len),
714 				    letoh16(rx_frame.wi_status));
715 				m_freem(m);
716 				ifp->if_ierrors++;
717 				return;
718 			}
719 			m->m_pkthdr.len = m->m_len =
720 			    letoh16(rx_frame.wi_dat_len) + WI_SNAPHDR_LEN;
721 
722 			bcopy(&rx_frame.wi_dst_addr,
723 			    &eh->ether_dhost, ETHER_ADDR_LEN);
724 			bcopy(&rx_frame.wi_src_addr,
725 			    &eh->ether_shost, ETHER_ADDR_LEN);
726 			bcopy(&rx_frame.wi_type,
727 			    &eh->ether_type, ETHER_TYPE_LEN);
728 
729 			if (wi_read_data(sc, id, WI_802_11_OFFSET,
730 			    mtod(m, caddr_t) + sizeof(struct ether_header),
731 			    m->m_len + 2)) {
732 				ifp->if_ierrors++;
733 				m_freem(m);
734 				return;
735 			}
736 			break;
737 		default:
738 			if ((letoh16(rx_frame.wi_dat_len) +
739 			    sizeof(struct ether_header)) > maxlen) {
740 				printf(WI_PRT_FMT ": oversized packet received "
741 				    "(wi_dat_len=%d, wi_status=0x%x)\n",
742 				    WI_PRT_ARG(sc),
743 				    letoh16(rx_frame.wi_dat_len),
744 				    letoh16(rx_frame.wi_status));
745 				m_freem(m);
746 				ifp->if_ierrors++;
747 				return;
748 			}
749 			m->m_pkthdr.len = m->m_len =
750 			    letoh16(rx_frame.wi_dat_len) +
751 			    sizeof(struct ether_header);
752 
753 			if (wi_read_data(sc, id, WI_802_3_OFFSET,
754 			    mtod(m, caddr_t), m->m_len + 2)) {
755 				m_freem(m);
756 				ifp->if_ierrors++;
757 				return;
758 			}
759 			break;
760 		}
761 
762 		if (sc->wi_use_wep &&
763 		    rx_frame.wi_frame_ctl & htole16(WI_FCTL_WEP)) {
764 			int len;
765 
766 			switch (sc->wi_crypto_algorithm) {
767 			case WI_CRYPTO_FIRMWARE_WEP:
768 				break;
769 			case WI_CRYPTO_SOFTWARE_WEP:
770 				m_copydata(m, 0, m->m_pkthdr.len,
771 				    (caddr_t)sc->wi_rxbuf);
772 				len = m->m_pkthdr.len -
773 				    sizeof(struct ether_header);
774 				if (wi_do_hostdecrypt(sc, sc->wi_rxbuf +
775 				    sizeof(struct ether_header), len)) {
776 					if (sc->sc_ic.ic_if.if_flags & IFF_DEBUG)
777 						printf(WI_PRT_FMT ": Error decrypting incoming packet.\n", WI_PRT_ARG(sc));
778 					m_freem(m);
779 					ifp->if_ierrors++;
780 					return;
781 				}
782 				len -= IEEE80211_WEP_IVLEN +
783 				    IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN;
784 				/*
785 				 * copy data back to mbufs:
786 				 * we need to ditch the IV & most LLC/SNAP stuff
787 				 * (except SNAP type, we're going use that to
788 				 * overwrite the ethertype in the ether_header)
789 				 */
790 				m_copyback(m, sizeof(struct ether_header) -
791 				    WI_ETHERTYPE_LEN, WI_ETHERTYPE_LEN +
792 				    (len - WI_SNAPHDR_LEN),
793 				    sc->wi_rxbuf + sizeof(struct ether_header) +
794 				    IEEE80211_WEP_IVLEN +
795 				    IEEE80211_WEP_KIDLEN + WI_SNAPHDR_LEN,
796 				    M_NOWAIT);
797 				m_adj(m, -(WI_ETHERTYPE_LEN +
798 				    IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
799 				    WI_SNAPHDR_LEN));
800 				break;
801 			}
802 		}
803 
804 		if (sc->wi_ptype == WI_PORTTYPE_HOSTAP) {
805 			/*
806 			 * Give host AP code first crack at data packets.
807 			 * If it decides to handle it (or drop it), it will
808 			 * return a non-zero.  Otherwise, it is destined for
809 			 * this host.
810 			 */
811 			if (wihap_data_input(sc, &rx_frame, m))
812 				return;
813 		}
814 	}
815 
816 	/* Receive packet unless in procframe or monitor mode. */
817 	if (sc->wi_procframe || sc->wi_debug.wi_monitor)
818 		m_freem(m);
819 	else {
820 		ml_enqueue(&ml, m);
821 		if_input(ifp, &ml);
822 	}
823 
824 	return;
825 }
826 
827 void
828 wi_txeof(struct wi_softc *sc, int status)
829 {
830 	struct ifnet		*ifp;
831 
832 	ifp = &sc->sc_ic.ic_if;
833 
834 	ifp->if_timer = 0;
835 	ifq_clr_oactive(&ifp->if_snd);
836 
837 	if (status & WI_EV_TX_EXC)
838 		ifp->if_oerrors++;
839 	else
840 		ifp->if_opackets++;
841 
842 	return;
843 }
844 
845 void
846 wi_inquire(void *xsc)
847 {
848 	struct wi_softc		*sc;
849 	struct ifnet		*ifp;
850 	int s, rv;
851 
852 	sc = xsc;
853 	ifp = &sc->sc_ic.ic_if;
854 
855 	timeout_add_sec(&sc->sc_timo, 60);
856 
857 	/* Don't do this while we're transmitting */
858 	if (ifq_is_oactive(&ifp->if_snd))
859 		return;
860 
861 	s = splnet();
862 	rv = wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_COUNTERS, 0, 0);
863 	splx(s);
864 	if (rv)
865 		printf(WI_PRT_FMT ": wi_cmd failed with %d\n", WI_PRT_ARG(sc),
866 		    rv);
867 
868 	return;
869 }
870 
871 void
872 wi_update_stats(struct wi_softc *sc)
873 {
874 	struct wi_ltv_gen	gen;
875 	u_int16_t		id;
876 	struct ifnet		*ifp;
877 	u_int32_t		*ptr;
878 	int			len, i;
879 	u_int16_t		t;
880 
881 	ifp = &sc->sc_ic.ic_if;
882 
883 	id = wi_get_fid(sc, WI_INFO_FID);
884 
885 	wi_read_data(sc, id, 0, (char *)&gen, 4);
886 
887 	if (gen.wi_type == htole16(WI_INFO_SCAN_RESULTS)) {
888 		sc->wi_scanbuf_len = letoh16(gen.wi_len);
889 		wi_read_data(sc, id, 4, (caddr_t)sc->wi_scanbuf,
890 		    sc->wi_scanbuf_len * 2);
891 		return;
892 	} else if (gen.wi_type != htole16(WI_INFO_COUNTERS))
893 		return;
894 
895 	/* Some card versions have a larger stats structure */
896 	len = (letoh16(gen.wi_len) - 1 < sizeof(sc->wi_stats) / 4) ?
897 	    letoh16(gen.wi_len) - 1 : sizeof(sc->wi_stats) / 4;
898 
899 	ptr = (u_int32_t *)&sc->wi_stats;
900 
901 	for (i = 0; i < len; i++) {
902 		if (sc->wi_flags & WI_FLAGS_BUS_USB) {
903 			wi_read_data(sc, id, 4 + i*2, (char *)&t, 2);
904 			t = letoh16(t);
905 		} else
906 			t = CSR_READ_2(sc, WI_DATA1);
907 #ifdef WI_HERMES_STATS_WAR
908 		if (t > 0xF000)
909 			t = ~t & 0xFFFF;
910 #endif
911 		ptr[i] += t;
912 	}
913 
914 	ifp->if_collisions = sc->wi_stats.wi_tx_single_retries +
915 	    sc->wi_stats.wi_tx_multi_retries +
916 	    sc->wi_stats.wi_tx_retry_limit;
917 
918 	return;
919 }
920 
921 STATIC int
922 wi_cmd_io(struct wi_softc *sc, int cmd, int val0, int val1, int val2)
923 {
924 	int			i, s = 0;
925 
926 	/* Wait for the busy bit to clear. */
927 	for (i = sc->wi_cmd_count; i--; DELAY(1000)) {
928 		if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY))
929 			break;
930 	}
931 	if (i < 0) {
932 		if (sc->sc_ic.ic_if.if_flags & IFF_DEBUG)
933 			printf(WI_PRT_FMT ": wi_cmd_io: busy bit won't clear\n",
934 			    WI_PRT_ARG(sc));
935 		return(ETIMEDOUT);
936 	}
937 
938 	CSR_WRITE_2(sc, WI_PARAM0, val0);
939 	CSR_WRITE_2(sc, WI_PARAM1, val1);
940 	CSR_WRITE_2(sc, WI_PARAM2, val2);
941 	CSR_WRITE_2(sc, WI_COMMAND, cmd);
942 
943 	for (i = WI_TIMEOUT; i--; DELAY(WI_DELAY)) {
944 		/*
945 		 * Wait for 'command complete' bit to be
946 		 * set in the event status register.
947 		 */
948 		s = CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_CMD;
949 		if (s) {
950 			/* Ack the event and read result code. */
951 			s = CSR_READ_2(sc, WI_STATUS);
952 			CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
953 			if (s & WI_STAT_CMD_RESULT)
954 				return(EIO);
955 			break;
956 		}
957 	}
958 
959 	if (i < 0) {
960 		if (sc->sc_ic.ic_if.if_flags & IFF_DEBUG)
961 			printf(WI_PRT_FMT
962 			    ": timeout in wi_cmd 0x%04x; event status 0x%04x\n",
963 			    WI_PRT_ARG(sc), cmd, s);
964 		return(ETIMEDOUT);
965 	}
966 
967 	return(0);
968 }
969 
970 STATIC void
971 wi_reset(struct wi_softc *sc)
972 {
973 	int error, tries = 3;
974 
975 	DPRINTF(WID_RESET, ("wi_reset: sc %p\n", sc));
976 
977 	/* Symbol firmware cannot be initialized more than once. */
978 	if (sc->sc_firmware_type == WI_SYMBOL) {
979 		if (sc->wi_flags & WI_FLAGS_INITIALIZED)
980 			return;
981 		tries = 1;
982 	}
983 
984 	for (; tries--; DELAY(WI_DELAY * 1000)) {
985 		if ((error = wi_cmd(sc, WI_CMD_INI, 0, 0, 0)) == 0)
986 			break;
987 	}
988 	if (tries < 0) {
989 		printf(WI_PRT_FMT ": init failed\n", WI_PRT_ARG(sc));
990 		return;
991 	}
992 	sc->wi_flags |= WI_FLAGS_INITIALIZED;
993 
994 	wi_intr_enable(sc, 0);
995 	wi_intr_ack(sc, 0xffff);
996 
997 	/* Calibrate timer. */
998 	WI_SETVAL(WI_RID_TICK_TIME, 8);
999 
1000 	return;
1001 }
1002 
1003 STATIC void
1004 wi_cor_reset(struct wi_softc *sc)
1005 {
1006 	u_int8_t cor_value;
1007 
1008 	DPRINTF(WID_RESET, ("wi_cor_reset: sc %p\n", sc));
1009 
1010 	/*
1011 	 * Do a soft reset of the card; this is required for Symbol cards.
1012 	 * This shouldn't hurt other cards but there have been reports
1013 	 * of the COR reset messing up old Lucent firmware revisions so
1014 	 * we avoid soft reset on Lucent cards for now.
1015 	 */
1016 	if (sc->sc_firmware_type != WI_LUCENT) {
1017 		cor_value = bus_space_read_1(sc->wi_ltag, sc->wi_lhandle,
1018 		    sc->wi_cor_offset);
1019 		bus_space_write_1(sc->wi_ltag, sc->wi_lhandle,
1020 		    sc->wi_cor_offset, (cor_value | WI_COR_SOFT_RESET));
1021 		DELAY(1000);
1022 		bus_space_write_1(sc->wi_ltag, sc->wi_lhandle,
1023 		    sc->wi_cor_offset, (cor_value & ~WI_COR_SOFT_RESET));
1024 		DELAY(1000);
1025 	}
1026 
1027 	return;
1028 }
1029 
1030 /*
1031  * Read an LTV record from the NIC.
1032  */
1033 STATIC int
1034 wi_read_record_io(struct wi_softc *sc, struct wi_ltv_gen *ltv)
1035 {
1036 	u_int8_t		*ptr;
1037 	int			len, code;
1038 	struct wi_ltv_gen	*oltv, p2ltv;
1039 
1040 	if (sc->sc_firmware_type != WI_LUCENT) {
1041 		oltv = ltv;
1042 		switch (ltv->wi_type) {
1043 		case WI_RID_ENCRYPTION:
1044 			p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
1045 			p2ltv.wi_len = 2;
1046 			ltv = &p2ltv;
1047 			break;
1048 		case WI_RID_TX_CRYPT_KEY:
1049 			if (ltv->wi_val > WI_NLTV_KEYS)
1050 				return (EINVAL);
1051 			p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
1052 			p2ltv.wi_len = 2;
1053 			ltv = &p2ltv;
1054 			break;
1055 		}
1056 	}
1057 
1058 	/* Tell the NIC to enter record read mode. */
1059 	if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type, 0, 0))
1060 		return(EIO);
1061 
1062 	/* Seek to the record. */
1063 	if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
1064 		return(EIO);
1065 
1066 	/*
1067 	 * Read the length and record type and make sure they
1068 	 * match what we expect (this verifies that we have enough
1069 	 * room to hold all of the returned data).
1070 	 */
1071 	len = CSR_READ_2(sc, WI_DATA1);
1072 	if (len > ltv->wi_len)
1073 		return(ENOSPC);
1074 	code = CSR_READ_2(sc, WI_DATA1);
1075 	if (code != ltv->wi_type)
1076 		return(EIO);
1077 
1078 	ltv->wi_len = len;
1079 	ltv->wi_type = code;
1080 
1081 	/* Now read the data. */
1082 	ptr = (u_int8_t *)&ltv->wi_val;
1083 	if (ltv->wi_len > 1)
1084 		CSR_READ_RAW_2(sc, WI_DATA1, ptr, (ltv->wi_len-1)*2);
1085 
1086 	if (ltv->wi_type == WI_RID_PORTTYPE && sc->wi_ptype == WI_PORTTYPE_IBSS
1087 	    && ltv->wi_val == sc->wi_ibss_port) {
1088 		/*
1089 		 * Convert vendor IBSS port type to WI_PORTTYPE_IBSS.
1090 		 * Since Lucent uses port type 1 for BSS *and* IBSS we
1091 		 * have to rely on wi_ptype to distinguish this for us.
1092 		 */
1093 		ltv->wi_val = htole16(WI_PORTTYPE_IBSS);
1094 	} else if (sc->sc_firmware_type != WI_LUCENT) {
1095 		int v;
1096 
1097 		switch (oltv->wi_type) {
1098 		case WI_RID_TX_RATE:
1099 		case WI_RID_CUR_TX_RATE:
1100 			switch (letoh16(ltv->wi_val)) {
1101 			case 1: v = 1; break;
1102 			case 2: v = 2; break;
1103 			case 3:	v = 6; break;
1104 			case 4: v = 5; break;
1105 			case 7: v = 7; break;
1106 			case 8: v = 11; break;
1107 			case 15: v = 3; break;
1108 			default: v = 0x100 + letoh16(ltv->wi_val); break;
1109 			}
1110 			oltv->wi_val = htole16(v);
1111 			break;
1112 		case WI_RID_ENCRYPTION:
1113 			oltv->wi_len = 2;
1114 			if (ltv->wi_val & htole16(0x01))
1115 				oltv->wi_val = htole16(1);
1116 			else
1117 				oltv->wi_val = htole16(0);
1118 			break;
1119 		case WI_RID_TX_CRYPT_KEY:
1120 		case WI_RID_CNFAUTHMODE:
1121 			oltv->wi_len = 2;
1122 			oltv->wi_val = ltv->wi_val;
1123 			break;
1124 		}
1125 	}
1126 
1127 	return(0);
1128 }
1129 
1130 /*
1131  * Same as read, except we inject data instead of reading it.
1132  */
1133 STATIC int
1134 wi_write_record_io(struct wi_softc *sc, struct wi_ltv_gen *ltv)
1135 {
1136 	u_int8_t		*ptr;
1137 	u_int16_t		val = 0;
1138 	int			i;
1139 	struct wi_ltv_gen	p2ltv;
1140 
1141 	if (ltv->wi_type == WI_RID_PORTTYPE &&
1142 	    letoh16(ltv->wi_val) == WI_PORTTYPE_IBSS) {
1143 		/* Convert WI_PORTTYPE_IBSS to vendor IBSS port type. */
1144 		p2ltv.wi_type = WI_RID_PORTTYPE;
1145 		p2ltv.wi_len = 2;
1146 		p2ltv.wi_val = sc->wi_ibss_port;
1147 		ltv = &p2ltv;
1148 	} else if (sc->sc_firmware_type != WI_LUCENT) {
1149 		int v;
1150 
1151 		switch (ltv->wi_type) {
1152 		case WI_RID_TX_RATE:
1153 			p2ltv.wi_type = WI_RID_TX_RATE;
1154 			p2ltv.wi_len = 2;
1155 			switch (letoh16(ltv->wi_val)) {
1156 			case 1: v = 1; break;
1157 			case 2: v = 2; break;
1158 			case 3:	v = 15; break;
1159 			case 5: v = 4; break;
1160 			case 6: v = 3; break;
1161 			case 7: v = 7; break;
1162 			case 11: v = 8; break;
1163 			default: return EINVAL;
1164 			}
1165 			p2ltv.wi_val = htole16(v);
1166 			ltv = &p2ltv;
1167 			break;
1168 		case WI_RID_ENCRYPTION:
1169 			p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
1170 			p2ltv.wi_len = 2;
1171 			if (ltv->wi_val & htole16(0x01)) {
1172 				val = PRIVACY_INVOKED;
1173 				/*
1174 				 * If using shared key WEP we must set the
1175 				 * EXCLUDE_UNENCRYPTED bit.  Symbol cards
1176 				 * need this bit set even when not using
1177 				 * shared key. We can't just test for
1178 				 * IEEE80211_AUTH_SHARED since Symbol cards
1179 				 * have 2 shared key modes.
1180 				 */
1181 				if (sc->wi_authtype != IEEE80211_AUTH_OPEN ||
1182 				    sc->sc_firmware_type == WI_SYMBOL)
1183 					val |= EXCLUDE_UNENCRYPTED;
1184 
1185 				switch (sc->wi_crypto_algorithm) {
1186 				case WI_CRYPTO_FIRMWARE_WEP:
1187 					/*
1188 					 * TX encryption is broken in
1189 					 * Host AP mode.
1190 					 */
1191 					if (sc->wi_ptype == WI_PORTTYPE_HOSTAP)
1192 						val |= HOST_ENCRYPT;
1193 					break;
1194 				case WI_CRYPTO_SOFTWARE_WEP:
1195 					val |= HOST_ENCRYPT|HOST_DECRYPT;
1196 					break;
1197 				}
1198 				p2ltv.wi_val = htole16(val);
1199 			} else
1200 				p2ltv.wi_val = htole16(HOST_ENCRYPT | HOST_DECRYPT);
1201 			ltv = &p2ltv;
1202 			break;
1203 		case WI_RID_TX_CRYPT_KEY:
1204 			if (ltv->wi_val > WI_NLTV_KEYS)
1205 				return (EINVAL);
1206 			p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
1207 			p2ltv.wi_len = 2;
1208 			p2ltv.wi_val = ltv->wi_val;
1209 			ltv = &p2ltv;
1210 			break;
1211 		case WI_RID_DEFLT_CRYPT_KEYS: {
1212 				int error;
1213 				int keylen;
1214 				struct wi_ltv_str ws;
1215 				struct wi_ltv_keys *wk = (struct wi_ltv_keys *)ltv;
1216 
1217 				keylen = wk->wi_keys[sc->wi_tx_key].wi_keylen;
1218 				keylen = letoh16(keylen);
1219 
1220 				for (i = 0; i < 4; i++) {
1221 					bzero(&ws, sizeof(ws));
1222 					ws.wi_len = (keylen > 5) ? 8 : 4;
1223 					ws.wi_type = WI_RID_P2_CRYPT_KEY0 + i;
1224 					bcopy(&wk->wi_keys[i].wi_keydat,
1225 					    ws.wi_str, keylen);
1226 					error = wi_write_record(sc,
1227 					    (struct wi_ltv_gen *)&ws);
1228 					if (error)
1229 						return (error);
1230 				}
1231 			}
1232 			return (0);
1233 		}
1234 	}
1235 
1236 	if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
1237 		return(EIO);
1238 
1239 	CSR_WRITE_2(sc, WI_DATA1, ltv->wi_len);
1240 	CSR_WRITE_2(sc, WI_DATA1, ltv->wi_type);
1241 
1242 	ptr = (u_int8_t *)&ltv->wi_val;
1243 	if (ltv->wi_len > 1)
1244 		CSR_WRITE_RAW_2(sc, WI_DATA1, ptr, (ltv->wi_len-1) *2);
1245 
1246 	if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_WRITE, ltv->wi_type, 0, 0))
1247 		return(EIO);
1248 
1249 	return(0);
1250 }
1251 
1252 STATIC int
1253 wi_seek(struct wi_softc *sc, int id, int off, int chan)
1254 {
1255 	int			i;
1256 	int			selreg, offreg;
1257 
1258 	switch (chan) {
1259 	case WI_BAP0:
1260 		selreg = WI_SEL0;
1261 		offreg = WI_OFF0;
1262 		break;
1263 	case WI_BAP1:
1264 		selreg = WI_SEL1;
1265 		offreg = WI_OFF1;
1266 		break;
1267 	default:
1268 		printf(WI_PRT_FMT ": invalid data path: %x\n", WI_PRT_ARG(sc),
1269 		    chan);
1270 		return(EIO);
1271 	}
1272 
1273 	CSR_WRITE_2(sc, selreg, id);
1274 	CSR_WRITE_2(sc, offreg, off);
1275 
1276 	for (i = WI_TIMEOUT; i--; DELAY(1))
1277 		if (!(CSR_READ_2(sc, offreg) & (WI_OFF_BUSY|WI_OFF_ERR)))
1278 			break;
1279 
1280 	if (i < 0)
1281 		return(ETIMEDOUT);
1282 
1283 	return(0);
1284 }
1285 
1286 STATIC int
1287 wi_read_data_io(struct wi_softc *sc, int id, int off, caddr_t buf, int len)
1288 {
1289 	u_int8_t		*ptr;
1290 
1291 	if (wi_seek(sc, id, off, WI_BAP1))
1292 		return(EIO);
1293 
1294 	ptr = (u_int8_t *)buf;
1295 	CSR_READ_RAW_2(sc, WI_DATA1, ptr, len);
1296 
1297 	return(0);
1298 }
1299 
1300 /*
1301  * According to the comments in the HCF Light code, there is a bug in
1302  * the Hermes (or possibly in certain Hermes firmware revisions) where
1303  * the chip's internal autoincrement counter gets thrown off during
1304  * data writes: the autoincrement is missed, causing one data word to
1305  * be overwritten and subsequent words to be written to the wrong memory
1306  * locations. The end result is that we could end up transmitting bogus
1307  * frames without realizing it. The workaround for this is to write a
1308  * couple of extra guard words after the end of the transfer, then
1309  * attempt to read then back. If we fail to locate the guard words where
1310  * we expect them, we preform the transfer over again.
1311  */
1312 STATIC int
1313 wi_write_data_io(struct wi_softc *sc, int id, int off, caddr_t buf, int len)
1314 {
1315 	u_int8_t		*ptr;
1316 
1317 #ifdef WI_HERMES_AUTOINC_WAR
1318 again:
1319 #endif
1320 
1321 	if (wi_seek(sc, id, off, WI_BAP0))
1322 		return(EIO);
1323 
1324 	ptr = (u_int8_t *)buf;
1325 	CSR_WRITE_RAW_2(sc, WI_DATA0, ptr, len);
1326 
1327 #ifdef WI_HERMES_AUTOINC_WAR
1328 	CSR_WRITE_2(sc, WI_DATA0, 0x1234);
1329 	CSR_WRITE_2(sc, WI_DATA0, 0x5678);
1330 
1331 	if (wi_seek(sc, id, off + len, WI_BAP0))
1332 		return(EIO);
1333 
1334 	if (CSR_READ_2(sc, WI_DATA0) != 0x1234 ||
1335 	    CSR_READ_2(sc, WI_DATA0) != 0x5678)
1336 		goto again;
1337 #endif
1338 
1339 	return(0);
1340 }
1341 
1342 /*
1343  * Allocate a region of memory inside the NIC and zero
1344  * it out.
1345  */
1346 STATIC int
1347 wi_alloc_nicmem_io(struct wi_softc *sc, int len, int *id)
1348 {
1349 	int			i;
1350 
1351 	if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len, 0, 0)) {
1352 		printf(WI_PRT_FMT ": failed to allocate %d bytes on NIC\n",
1353 		    WI_PRT_ARG(sc), len);
1354 		return(ENOMEM);
1355 	}
1356 
1357 	for (i = WI_TIMEOUT; i--; DELAY(1)) {
1358 		if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC)
1359 			break;
1360 	}
1361 
1362 	if (i < 0)
1363 		return(ETIMEDOUT);
1364 
1365 	*id = CSR_READ_2(sc, WI_ALLOC_FID);
1366 	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
1367 
1368 	if (wi_seek(sc, *id, 0, WI_BAP0))
1369 		return(EIO);
1370 
1371 	for (i = 0; i < len / 2; i++)
1372 		CSR_WRITE_2(sc, WI_DATA0, 0);
1373 
1374 	return(0);
1375 }
1376 
1377 STATIC void
1378 wi_setmulti(struct wi_softc *sc)
1379 {
1380 	struct arpcom		*ac = &sc->sc_ic.ic_ac;
1381 	struct ifnet		*ifp;
1382 	int			i = 0;
1383 	struct wi_ltv_mcast	mcast;
1384 	struct ether_multistep	step;
1385 	struct ether_multi	*enm;
1386 
1387 	ifp = &sc->sc_ic.ic_if;
1388 
1389 	bzero(&mcast, sizeof(mcast));
1390 
1391 	mcast.wi_type = WI_RID_MCAST_LIST;
1392 	mcast.wi_len = ((ETHER_ADDR_LEN / 2) * 16) + 1;
1393 
1394 	if (ac->ac_multirangecnt > 0)
1395 		ifp->if_flags |= IFF_ALLMULTI;
1396 
1397 	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
1398 		wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
1399 		return;
1400 	}
1401 
1402 	ETHER_FIRST_MULTI(step, &sc->sc_ic.ic_ac, enm);
1403 	while (enm != NULL) {
1404 		if (i >= 16) {
1405 			bzero(&mcast, sizeof(mcast));
1406 			break;
1407 		}
1408 
1409 		bcopy(enm->enm_addrlo, &mcast.wi_mcast[i], ETHER_ADDR_LEN);
1410 		i++;
1411 		ETHER_NEXT_MULTI(step, enm);
1412 	}
1413 
1414 	mcast.wi_len = (i * 3) + 1;
1415 	wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
1416 
1417 	return;
1418 }
1419 
1420 STATIC int
1421 wi_setdef(struct wi_softc *sc, struct wi_req *wreq)
1422 {
1423 	struct ifnet		*ifp;
1424 	int error = 0;
1425 
1426 	ifp = &sc->sc_ic.ic_if;
1427 
1428 	switch(wreq->wi_type) {
1429 	case WI_RID_MAC_NODE:
1430 		bcopy(&wreq->wi_val, LLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
1431 		bcopy(&wreq->wi_val, &sc->sc_ic.ic_myaddr, ETHER_ADDR_LEN);
1432 		break;
1433 	case WI_RID_PORTTYPE:
1434 		error = wi_sync_media(sc, letoh16(wreq->wi_val[0]),
1435 		    sc->wi_tx_rate);
1436 		break;
1437 	case WI_RID_TX_RATE:
1438 		error = wi_sync_media(sc, sc->wi_ptype,
1439 		    letoh16(wreq->wi_val[0]));
1440 		break;
1441 	case WI_RID_MAX_DATALEN:
1442 		sc->wi_max_data_len = letoh16(wreq->wi_val[0]);
1443 		break;
1444 	case WI_RID_RTS_THRESH:
1445 		sc->wi_rts_thresh = letoh16(wreq->wi_val[0]);
1446 		break;
1447 	case WI_RID_SYSTEM_SCALE:
1448 		sc->wi_ap_density = letoh16(wreq->wi_val[0]);
1449 		break;
1450 	case WI_RID_CREATE_IBSS:
1451 		sc->wi_create_ibss = letoh16(wreq->wi_val[0]);
1452 		error = wi_sync_media(sc, sc->wi_ptype, sc->wi_tx_rate);
1453 		break;
1454 	case WI_RID_OWN_CHNL:
1455 		sc->wi_channel = letoh16(wreq->wi_val[0]);
1456 		break;
1457 	case WI_RID_NODENAME:
1458 		error = wi_set_ssid(&sc->wi_node_name,
1459 		    (u_int8_t *)&wreq->wi_val[1], letoh16(wreq->wi_val[0]));
1460 		break;
1461 	case WI_RID_DESIRED_SSID:
1462 		error = wi_set_ssid(&sc->wi_net_name,
1463 		    (u_int8_t *)&wreq->wi_val[1], letoh16(wreq->wi_val[0]));
1464 		break;
1465 	case WI_RID_OWN_SSID:
1466 		error = wi_set_ssid(&sc->wi_ibss_name,
1467 		    (u_int8_t *)&wreq->wi_val[1], letoh16(wreq->wi_val[0]));
1468 		break;
1469 	case WI_RID_PM_ENABLED:
1470 		sc->wi_pm_enabled = letoh16(wreq->wi_val[0]);
1471 		break;
1472 	case WI_RID_MICROWAVE_OVEN:
1473 		sc->wi_mor_enabled = letoh16(wreq->wi_val[0]);
1474 		break;
1475 	case WI_RID_MAX_SLEEP:
1476 		sc->wi_max_sleep = letoh16(wreq->wi_val[0]);
1477 		break;
1478 	case WI_RID_CNFAUTHMODE:
1479 		sc->wi_authtype = letoh16(wreq->wi_val[0]);
1480 		break;
1481 	case WI_RID_ROAMING_MODE:
1482 		sc->wi_roaming = letoh16(wreq->wi_val[0]);
1483 		break;
1484 	case WI_RID_SYMBOL_DIVERSITY:
1485 		sc->wi_diversity = letoh16(wreq->wi_val[0]);
1486 		break;
1487 	case WI_RID_ENH_SECURITY:
1488 		sc->wi_enh_security = letoh16(wreq->wi_val[0]);
1489 		break;
1490 	case WI_RID_ENCRYPTION:
1491 		sc->wi_use_wep = letoh16(wreq->wi_val[0]);
1492 		break;
1493 	case WI_RID_TX_CRYPT_KEY:
1494 		sc->wi_tx_key = letoh16(wreq->wi_val[0]);
1495 		break;
1496 	case WI_RID_DEFLT_CRYPT_KEYS:
1497 		bcopy(wreq, &sc->wi_keys, sizeof(struct wi_ltv_keys));
1498 		break;
1499 	case WI_FRID_CRYPTO_ALG:
1500 		switch (letoh16(wreq->wi_val[0])) {
1501 		case WI_CRYPTO_FIRMWARE_WEP:
1502 			sc->wi_crypto_algorithm = WI_CRYPTO_FIRMWARE_WEP;
1503 			break;
1504 		case WI_CRYPTO_SOFTWARE_WEP:
1505 			sc->wi_crypto_algorithm = WI_CRYPTO_SOFTWARE_WEP;
1506 			break;
1507 		default:
1508 			printf(WI_PRT_FMT ": unsupported crypto algorithm %d\n",
1509 			    WI_PRT_ARG(sc), letoh16(wreq->wi_val[0]));
1510 			error = EINVAL;
1511 		}
1512 		break;
1513 	default:
1514 		error = EINVAL;
1515 		break;
1516 	}
1517 
1518 	return (error);
1519 }
1520 
1521 STATIC int
1522 wi_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
1523 {
1524 	int			s, error = 0, i, j, len;
1525 	struct wi_softc		*sc = ifp->if_softc;
1526 	struct ifreq		*ifr = (struct ifreq *)data;
1527 	struct proc		*p = curproc;
1528 	struct wi_scan_res	*res;
1529 	struct wi_scan_p2_hdr	*p2;
1530 	struct wi_req		*wreq = NULL;
1531 	u_int32_t		flags;
1532 	struct ieee80211_nwid		*nwidp = NULL;
1533 	struct ieee80211_nodereq_all	*na;
1534 	struct ieee80211_bssid		*bssid;
1535 
1536 	s = splnet();
1537 	if (!(sc->wi_flags & WI_FLAGS_ATTACHED)) {
1538 		error = ENODEV;
1539 		goto fail;
1540 	}
1541 
1542 	/*
1543 	 * Prevent processes from entering this function while another
1544 	 * process is tsleep'ing in it.
1545 	 */
1546 	while ((sc->wi_flags & WI_FLAGS_BUSY) && error == 0)
1547 		error = tsleep(&sc->wi_flags, PCATCH, "wiioc", 0);
1548 	if (error != 0) {
1549 		splx(s);
1550 		return error;
1551 	}
1552 	sc->wi_flags |= WI_FLAGS_BUSY;
1553 
1554 
1555 	DPRINTF (WID_IOCTL, ("wi_ioctl: command %lu data %p\n",
1556 	    command, data));
1557 
1558 	switch(command) {
1559 	case SIOCSIFADDR:
1560 		ifp->if_flags |= IFF_UP;
1561 		wi_init(sc);
1562 		break;
1563 	case SIOCSIFFLAGS:
1564 		if (ifp->if_flags & IFF_UP) {
1565 			if (ifp->if_flags & IFF_RUNNING &&
1566 			    ifp->if_flags & IFF_PROMISC &&
1567 			    !(sc->wi_if_flags & IFF_PROMISC)) {
1568 				if (sc->wi_ptype != WI_PORTTYPE_HOSTAP)
1569 					WI_SETVAL(WI_RID_PROMISC, 1);
1570 			} else if (ifp->if_flags & IFF_RUNNING &&
1571 			    !(ifp->if_flags & IFF_PROMISC) &&
1572 			    sc->wi_if_flags & IFF_PROMISC) {
1573 				if (sc->wi_ptype != WI_PORTTYPE_HOSTAP)
1574 					WI_SETVAL(WI_RID_PROMISC, 0);
1575 			} else
1576 				wi_init(sc);
1577 		} else if (ifp->if_flags & IFF_RUNNING)
1578 			wi_stop(sc);
1579 		sc->wi_if_flags = ifp->if_flags;
1580 		error = 0;
1581 		break;
1582 	case SIOCSIFMEDIA:
1583 	case SIOCGIFMEDIA:
1584 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, command);
1585 		break;
1586 	case SIOCGWAVELAN:
1587 		wreq = malloc(sizeof *wreq, M_DEVBUF, M_WAITOK | M_ZERO);
1588 		error = copyin(ifr->ifr_data, wreq, sizeof(*wreq));
1589 		if (error)
1590 			break;
1591 		if (wreq->wi_len > WI_MAX_DATALEN) {
1592 			error = EINVAL;
1593 			break;
1594 		}
1595 		switch (wreq->wi_type) {
1596 		case WI_RID_IFACE_STATS:
1597 			/* XXX native byte order */
1598 			bcopy(&sc->wi_stats, &wreq->wi_val,
1599 			    sizeof(sc->wi_stats));
1600 			wreq->wi_len = (sizeof(sc->wi_stats) / 2) + 1;
1601 			break;
1602 		case WI_RID_DEFLT_CRYPT_KEYS:
1603 			/* For non-root user, return all-zeroes keys */
1604 			if (suser(p, 0))
1605 				bzero(wreq, sizeof(struct wi_ltv_keys));
1606 			else
1607 				bcopy(&sc->wi_keys, wreq,
1608 					sizeof(struct wi_ltv_keys));
1609 			break;
1610 		case WI_RID_PROCFRAME:
1611 			wreq->wi_len = 2;
1612 			wreq->wi_val[0] = htole16(sc->wi_procframe);
1613 			break;
1614 		case WI_RID_PRISM2:
1615 			wreq->wi_len = 2;
1616 			wreq->wi_val[0] = htole16(sc->sc_firmware_type ==
1617 			    WI_LUCENT ? 0 : 1);
1618 			break;
1619 		case WI_FRID_CRYPTO_ALG:
1620 			wreq->wi_val[0] =
1621 			    htole16((u_int16_t)sc->wi_crypto_algorithm);
1622 			wreq->wi_len = 1;
1623 			break;
1624 		case WI_RID_SCAN_RES:
1625 			if (sc->sc_firmware_type == WI_LUCENT) {
1626 				memcpy((char *)wreq->wi_val,
1627 				    (char *)sc->wi_scanbuf,
1628 				    sc->wi_scanbuf_len * 2);
1629 				wreq->wi_len = sc->wi_scanbuf_len;
1630 				break;
1631 			}
1632 			/* FALLTHROUGH */
1633 		default:
1634 			if (wi_read_record(sc, (struct wi_ltv_gen *)wreq)) {
1635 				error = EINVAL;
1636 			}
1637 			break;
1638 		}
1639 		error = copyout(wreq, ifr->ifr_data, sizeof(*wreq));
1640 		break;
1641 	case SIOCSWAVELAN:
1642 		if ((error = suser(curproc, 0)) != 0)
1643 			break;
1644 		wreq = malloc(sizeof *wreq, M_DEVBUF, M_WAITOK | M_ZERO);
1645 		error = copyin(ifr->ifr_data, wreq, sizeof(*wreq));
1646 		if (error)
1647 			break;
1648 		error = EINVAL;
1649 		if (wreq->wi_len > WI_MAX_DATALEN)
1650 			break;
1651 		switch (wreq->wi_type) {
1652 		case WI_RID_IFACE_STATS:
1653 			break;
1654 		case WI_RID_MGMT_XMIT:
1655 			error = wi_mgmt_xmit(sc, (caddr_t)&wreq->wi_val,
1656 			    wreq->wi_len);
1657 			break;
1658 		case WI_RID_PROCFRAME:
1659 			sc->wi_procframe = letoh16(wreq->wi_val[0]);
1660 			error = 0;
1661 			break;
1662 		case WI_RID_SCAN_REQ:
1663 			error = 0;
1664 			if (sc->sc_firmware_type == WI_LUCENT)
1665 				wi_cmd(sc, WI_CMD_INQUIRE,
1666 				    WI_INFO_SCAN_RESULTS, 0, 0);
1667 			else
1668 				error = wi_write_record(sc,
1669 				    (struct wi_ltv_gen *)wreq);
1670 			break;
1671 		case WI_FRID_CRYPTO_ALG:
1672 			if (sc->sc_firmware_type != WI_LUCENT) {
1673 				error = wi_setdef(sc, wreq);
1674 				if (!error && (ifp->if_flags & IFF_UP))
1675 					wi_init(sc);
1676 			}
1677 			break;
1678 		case WI_RID_SYMBOL_DIVERSITY:
1679 		case WI_RID_ROAMING_MODE:
1680 		case WI_RID_CREATE_IBSS:
1681 		case WI_RID_MICROWAVE_OVEN:
1682 		case WI_RID_OWN_SSID:
1683 		case WI_RID_ENH_SECURITY:
1684 			/*
1685 			 * Check for features that may not be supported
1686 			 * (must be just before default case).
1687 			 */
1688 			if ((wreq->wi_type == WI_RID_SYMBOL_DIVERSITY &&
1689 			    !(sc->wi_flags & WI_FLAGS_HAS_DIVERSITY)) ||
1690 			    (wreq->wi_type == WI_RID_ROAMING_MODE &&
1691 			    !(sc->wi_flags & WI_FLAGS_HAS_ROAMING)) ||
1692 			    (wreq->wi_type == WI_RID_CREATE_IBSS &&
1693 			    !(sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)) ||
1694 			    (wreq->wi_type == WI_RID_MICROWAVE_OVEN &&
1695 			    !(sc->wi_flags & WI_FLAGS_HAS_MOR)) ||
1696 			    (wreq->wi_type == WI_RID_ENH_SECURITY &&
1697 			    !(sc->wi_flags & WI_FLAGS_HAS_ENH_SECURITY)) ||
1698 			    (wreq->wi_type == WI_RID_OWN_SSID &&
1699 			    wreq->wi_len != 0))
1700 				break;
1701 			/* FALLTHROUGH */
1702 		default:
1703 			error = wi_write_record(sc, (struct wi_ltv_gen *)wreq);
1704 			if (!error)
1705 				error = wi_setdef(sc, wreq);
1706 			if (!error && (ifp->if_flags & IFF_UP))
1707 				wi_init(sc);
1708 		}
1709 		break;
1710 	case SIOCGPRISM2DEBUG:
1711 		wreq = malloc(sizeof *wreq, M_DEVBUF, M_WAITOK | M_ZERO);
1712 		error = copyin(ifr->ifr_data, wreq, sizeof(*wreq));
1713 		if (error)
1714 			break;
1715 		if (!(ifp->if_flags & IFF_RUNNING) ||
1716 		    sc->sc_firmware_type == WI_LUCENT) {
1717 			error = EIO;
1718 			break;
1719 		}
1720 		error = wi_get_debug(sc, wreq);
1721 		if (error == 0)
1722 			error = copyout(wreq, ifr->ifr_data, sizeof(*wreq));
1723 		break;
1724 	case SIOCSPRISM2DEBUG:
1725 		if ((error = suser(curproc, 0)) != 0)
1726 			break;
1727 		wreq = malloc(sizeof *wreq, M_DEVBUF, M_WAITOK | M_ZERO);
1728 		error = copyin(ifr->ifr_data, wreq, sizeof(*wreq));
1729 		if (error)
1730 			break;
1731 		error = wi_set_debug(sc, wreq);
1732 		break;
1733 	case SIOCG80211NWID:
1734 		if ((ifp->if_flags & IFF_UP) && sc->wi_net_name.i_len > 0) {
1735 			/* Return the desired ID */
1736 			error = copyout(&sc->wi_net_name, ifr->ifr_data,
1737 			    sizeof(sc->wi_net_name));
1738 		} else {
1739 			wreq = malloc(sizeof *wreq, M_DEVBUF, M_WAITOK|M_ZERO);
1740 			wreq->wi_type = WI_RID_CURRENT_SSID;
1741 			wreq->wi_len = WI_MAX_DATALEN;
1742 			if (wi_read_record(sc, (struct wi_ltv_gen *)wreq) ||
1743 			    letoh16(wreq->wi_val[0]) > IEEE80211_NWID_LEN)
1744 				error = EINVAL;
1745 			else {
1746 				nwidp = malloc(sizeof *nwidp, M_DEVBUF,
1747 				    M_WAITOK | M_ZERO);
1748 				wi_set_ssid(nwidp, (u_int8_t *)&wreq->wi_val[1],
1749 				    letoh16(wreq->wi_val[0]));
1750 				error = copyout(nwidp, ifr->ifr_data,
1751 				    sizeof(*nwidp));
1752 			}
1753 		}
1754 		break;
1755 	case SIOCS80211NWID:
1756 		if ((error = suser(curproc, 0)) != 0)
1757 			break;
1758 		nwidp = malloc(sizeof *nwidp, M_DEVBUF, M_WAITOK);
1759 		error = copyin(ifr->ifr_data, nwidp, sizeof(*nwidp));
1760 		if (error)
1761 			break;
1762 		if (nwidp->i_len > IEEE80211_NWID_LEN) {
1763 			error = EINVAL;
1764 			break;
1765 		}
1766 		if (sc->wi_net_name.i_len == nwidp->i_len &&
1767 		    memcmp(sc->wi_net_name.i_nwid, nwidp->i_nwid, nwidp->i_len) == 0)
1768 			break;
1769 		wi_set_ssid(&sc->wi_net_name, nwidp->i_nwid, nwidp->i_len);
1770 		WI_SETSTR(WI_RID_DESIRED_SSID, sc->wi_net_name);
1771 		if (ifp->if_flags & IFF_UP)
1772 			/* Reinitialize WaveLAN. */
1773 			wi_init(sc);
1774 		break;
1775 	case SIOCS80211NWKEY:
1776 		if ((error = suser(curproc, 0)) != 0)
1777 			break;
1778 		error = wi_set_nwkey(sc, (struct ieee80211_nwkey *)data);
1779 		break;
1780 	case SIOCG80211NWKEY:
1781 		error = wi_get_nwkey(sc, (struct ieee80211_nwkey *)data);
1782 		break;
1783 	case SIOCS80211POWER:
1784 		if ((error = suser(curproc, 0)) != 0)
1785 			break;
1786 		error = wi_set_pm(sc, (struct ieee80211_power *)data);
1787 		break;
1788 	case SIOCG80211POWER:
1789 		error = wi_get_pm(sc, (struct ieee80211_power *)data);
1790 		break;
1791 	case SIOCS80211TXPOWER:
1792 		if ((error = suser(curproc, 0)) != 0)
1793 			break;
1794 		error = wi_set_txpower(sc, (struct ieee80211_txpower *)data);
1795 		break;
1796 	case SIOCG80211TXPOWER:
1797 		error = wi_get_txpower(sc, (struct ieee80211_txpower *)data);
1798 		break;
1799 	case SIOCS80211CHANNEL:
1800 		if ((error = suser(curproc, 0)) != 0)
1801 			break;
1802 		if (((struct ieee80211chanreq *)data)->i_channel > 14) {
1803 			error = EINVAL;
1804 			break;
1805 		}
1806 		wreq = malloc(sizeof *wreq, M_DEVBUF, M_WAITOK | M_ZERO);
1807 		wreq->wi_type = WI_RID_OWN_CHNL;
1808 		wreq->wi_val[0] =
1809 		    htole16(((struct ieee80211chanreq *)data)->i_channel);
1810 		error = wi_setdef(sc, wreq);
1811 		if (!error && (ifp->if_flags & IFF_UP))
1812 			wi_init(sc);
1813 		break;
1814 	case SIOCG80211CHANNEL:
1815 		wreq = malloc(sizeof *wreq, M_DEVBUF, M_WAITOK | M_ZERO);
1816 		wreq->wi_type = WI_RID_CURRENT_CHAN;
1817 		wreq->wi_len = WI_MAX_DATALEN;
1818 		if (wi_read_record(sc, (struct wi_ltv_gen *)wreq)) {
1819 			error = EINVAL;
1820 			break;
1821 		}
1822 		((struct ieee80211chanreq *)data)->i_channel =
1823 		    letoh16(wreq->wi_val[0]);
1824 		break;
1825 	case SIOCG80211BSSID:
1826 		bssid = (struct ieee80211_bssid *)data;
1827 		wreq = malloc(sizeof *wreq, M_DEVBUF, M_WAITOK | M_ZERO);
1828 		wreq->wi_type = WI_RID_CURRENT_BSSID;
1829 		wreq->wi_len = WI_MAX_DATALEN;
1830 		if (wi_read_record(sc, (struct wi_ltv_gen *)wreq)) {
1831 			error = EINVAL;
1832 			break;
1833 		}
1834 		IEEE80211_ADDR_COPY(bssid->i_bssid, wreq->wi_val);
1835 		break;
1836 	case SIOCS80211SCAN:
1837 		if ((error = suser(curproc, 0)) != 0)
1838 			break;
1839 		if (sc->wi_ptype == WI_PORTTYPE_HOSTAP)
1840 			break;
1841 		if ((ifp->if_flags & IFF_UP) == 0) {
1842 			error = ENETDOWN;
1843 			break;
1844 		}
1845 		if (sc->sc_firmware_type == WI_LUCENT) {
1846 			wi_cmd(sc, WI_CMD_INQUIRE,
1847 			    WI_INFO_SCAN_RESULTS, 0, 0);
1848 		} else {
1849 			wreq = malloc(sizeof *wreq, M_DEVBUF, M_WAITOK|M_ZERO);
1850 			wreq->wi_len = 3;
1851 			wreq->wi_type = WI_RID_SCAN_REQ;
1852 			wreq->wi_val[0] = 0x3FFF;
1853 			wreq->wi_val[1] = 0x000F;
1854 
1855 			error = wi_write_record(sc,
1856 			    (struct wi_ltv_gen *)wreq);
1857 			if (error)
1858 				break;
1859 		}
1860 		sc->wi_scan_lock = 0;
1861 		timeout_set(&sc->wi_scan_timeout, wi_scan_timeout, sc);
1862 		len = WI_WAVELAN_RES_TIMEOUT;
1863 		if (sc->wi_flags & WI_FLAGS_BUS_USB) {
1864 			/* Use a longer timeout for wi@usb */
1865 			len = WI_WAVELAN_RES_TIMEOUT * 4;
1866 		}
1867 		timeout_add(&sc->wi_scan_timeout, len);
1868 
1869 		/* Let the userspace process wait for completion */
1870 		error = tsleep(&sc->wi_scan_lock, PCATCH, "wiscan",
1871 		    hz * IEEE80211_SCAN_TIMEOUT);
1872 		break;
1873 	case SIOCG80211ALLNODES:
1874 	    {
1875 		struct ieee80211_nodereq	*nr = NULL;
1876 
1877 		if ((error = suser(curproc, 0)) != 0)
1878 			break;
1879 		na = (struct ieee80211_nodereq_all *)data;
1880 		if (sc->wi_ptype == WI_PORTTYPE_HOSTAP) {
1881 			/* List all associated stations */
1882 			error = wihap_ioctl(sc, command, data);
1883 			break;
1884 		}
1885 		wreq = malloc(sizeof *wreq, M_DEVBUF, M_WAITOK | M_ZERO);
1886 		wreq->wi_len = WI_MAX_DATALEN;
1887 		wreq->wi_type = WI_RID_SCAN_RES;
1888 		if (sc->sc_firmware_type == WI_LUCENT) {
1889 			bcopy(sc->wi_scanbuf, wreq->wi_val,
1890 			    sc->wi_scanbuf_len * 2);
1891 			wreq->wi_len = sc->wi_scanbuf_len;
1892 			i = 0;
1893 			len = WI_WAVELAN_RES_SIZE;
1894 		} else {
1895 			if (wi_read_record(sc, (struct wi_ltv_gen *)wreq)) {
1896 				error = EINVAL;
1897 				break;
1898 			}
1899 			p2 = (struct wi_scan_p2_hdr *)wreq->wi_val;
1900 			if (p2->wi_reason == 0)
1901 				break;
1902 			i = sizeof(*p2);
1903 			len = WI_PRISM2_RES_SIZE;
1904 		}
1905 
1906 		for (na->na_nodes = j = 0; (i < (wreq->wi_len * 2) - len) &&
1907 		    (na->na_size >= j + sizeof(struct ieee80211_nodereq));
1908 		    i += len) {
1909 
1910 			if (nr == NULL)
1911 				nr = malloc(sizeof *nr, M_DEVBUF, M_WAITOK);
1912 			res = (struct wi_scan_res *)((char *)wreq->wi_val + i);
1913 			if (res == NULL)
1914 				break;
1915 
1916 			bzero(nr, sizeof(*nr));
1917 			IEEE80211_ADDR_COPY(nr->nr_macaddr, res->wi_bssid);
1918 			IEEE80211_ADDR_COPY(nr->nr_bssid, res->wi_bssid);
1919 			nr->nr_channel = letoh16(res->wi_chan);
1920 			nr->nr_chan_flags = IEEE80211_CHAN_B;
1921 			nr->nr_rssi = letoh16(res->wi_signal);
1922 			nr->nr_max_rssi = 0; /* XXX */
1923 			nr->nr_nwid_len = letoh16(res->wi_ssid_len);
1924 			bcopy(res->wi_ssid, nr->nr_nwid, nr->nr_nwid_len);
1925 			nr->nr_intval = letoh16(res->wi_interval);
1926 			nr->nr_capinfo = letoh16(res->wi_capinfo);
1927 			nr->nr_txrate = res->wi_rate == WI_WAVELAN_RES_1M ? 2 :
1928 			    (res->wi_rate == WI_WAVELAN_RES_2M ? 4 :
1929 			    (res->wi_rate == WI_WAVELAN_RES_5M ? 11 :
1930 			    (res->wi_rate == WI_WAVELAN_RES_11M ? 22 : 0)));
1931 			nr->nr_nrates = 0;
1932 			while (res->wi_srates[nr->nr_nrates] != 0) {
1933 				nr->nr_rates[nr->nr_nrates] =
1934 				    res->wi_srates[nr->nr_nrates] &
1935 				    WI_VAR_SRATES_MASK;
1936 				nr->nr_nrates++;
1937 			}
1938 			nr->nr_flags = 0;
1939 			if (bcmp(nr->nr_macaddr, nr->nr_bssid,
1940 			    IEEE80211_ADDR_LEN) == 0)
1941 				nr->nr_flags |= IEEE80211_NODEREQ_AP;
1942 
1943 			error = copyout(nr, (caddr_t)na->na_node + j,
1944 			    sizeof(struct ieee80211_nodereq));
1945 			if (error)
1946 				break;
1947 			j += sizeof(struct ieee80211_nodereq);
1948 			na->na_nodes++;
1949 		}
1950 		if (nr)
1951 			free(nr, M_DEVBUF, 0);
1952 		break;
1953 	    }
1954 	case SIOCG80211FLAGS:
1955 		if (sc->wi_ptype != WI_PORTTYPE_HOSTAP)
1956 			break;
1957 		ifr->ifr_flags = 0;
1958 		if (sc->wi_flags & WI_FLAGS_HAS_ENH_SECURITY) {
1959 			wreq = malloc(sizeof *wreq, M_DEVBUF, M_WAITOK|M_ZERO);
1960 			wreq->wi_len = WI_MAX_DATALEN;
1961 			wreq->wi_type = WI_RID_ENH_SECURITY;
1962 			if (wi_read_record(sc, (struct wi_ltv_gen *)wreq)) {
1963 				error = EINVAL;
1964 				break;
1965 			}
1966 			sc->wi_enh_security = letoh16(wreq->wi_val[0]);
1967 			if (sc->wi_enh_security == WI_HIDESSID_IGNPROBES)
1968 				ifr->ifr_flags |= IEEE80211_F_HIDENWID >>
1969 				    IEEE80211_F_USERSHIFT;
1970 		}
1971 		break;
1972 	case SIOCS80211FLAGS:
1973 		if ((error = suser(curproc, 0)) != 0)
1974 			break;
1975 		if (sc->wi_ptype != WI_PORTTYPE_HOSTAP) {
1976 			error = EINVAL;
1977 			break;
1978 		}
1979 		flags = (u_int32_t)ifr->ifr_flags << IEEE80211_F_USERSHIFT;
1980 		if (sc->wi_flags & WI_FLAGS_HAS_ENH_SECURITY) {
1981 			sc->wi_enh_security = (flags & IEEE80211_F_HIDENWID) ?
1982 			    WI_HIDESSID_IGNPROBES : 0;
1983 			WI_SETVAL(WI_RID_ENH_SECURITY, sc->wi_enh_security);
1984 		}
1985 		break;
1986 	case SIOCHOSTAP_ADD:
1987 	case SIOCHOSTAP_DEL:
1988 	case SIOCHOSTAP_GET:
1989 	case SIOCHOSTAP_GETALL:
1990 	case SIOCHOSTAP_GFLAGS:
1991 	case SIOCHOSTAP_SFLAGS:
1992 		/* Send all Host AP specific ioctl's to Host AP code. */
1993 		error = wihap_ioctl(sc, command, data);
1994 		break;
1995 	default:
1996 		error = ether_ioctl(ifp, &sc->sc_ic.ic_ac, command, data);
1997 	}
1998 
1999 	if (error == ENETRESET) {
2000 		if (ifp->if_flags & IFF_RUNNING)
2001 			wi_setmulti(sc);
2002 		error = 0;
2003 	}
2004 
2005 	if (wreq)
2006 		free(wreq, M_DEVBUF, 0);
2007 	if (nwidp)
2008 		free(nwidp, M_DEVBUF, 0);
2009 
2010 fail:
2011 	sc->wi_flags &= ~WI_FLAGS_BUSY;
2012 	wakeup(&sc->wi_flags);
2013 	splx(s);
2014 	return(error);
2015 }
2016 
2017 void
2018 wi_scan_timeout(void *arg)
2019 {
2020 	struct wi_softc		*sc = (struct wi_softc *)arg;
2021 	struct wi_req		wreq;
2022 
2023 	if (sc->wi_scan_lock++ < WI_WAVELAN_RES_TRIES &&
2024 	    sc->sc_firmware_type != WI_LUCENT &&
2025 	    (sc->wi_flags & WI_FLAGS_BUS_USB) == 0) {
2026 		/*
2027 		 * The Prism2/2.5/3 chipsets will set an extra field in the
2028 		 * scan result if the scan request has been completed by the
2029 		 * firmware. This allows to poll for completion and to
2030 		 * wait for some more time if the scan is still in progress.
2031 		 *
2032 		 * XXX This doesn't work with wi@usb because it isn't safe
2033 		 * to call wi_read_record_usb() while beeing in the timeout
2034 		 * handler.
2035 		 */
2036 		wreq.wi_len = WI_MAX_DATALEN;
2037 		wreq.wi_type = WI_RID_SCAN_RES;
2038 
2039 		if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) == 0 &&
2040 		    ((struct wi_scan_p2_hdr *)wreq.wi_val)->wi_reason == 0) {
2041 			/* Wait some more time for scan completion */
2042 			timeout_add(&sc->wi_scan_timeout, WI_WAVELAN_RES_TIMEOUT);
2043 			return;
2044 		}
2045 	}
2046 
2047 	if (sc->sc_ic.ic_if.if_flags & IFF_DEBUG)
2048 		printf(WI_PRT_FMT ": wi_scan_timeout: %d tries\n",
2049 		    WI_PRT_ARG(sc), sc->wi_scan_lock);
2050 
2051 	/* Wakeup the userland */
2052 	wakeup(&sc->wi_scan_lock);
2053 	sc->wi_scan_lock = 0;
2054 }
2055 
2056 STATIC void
2057 wi_init_io(struct wi_softc *sc)
2058 {
2059 	struct ifnet		*ifp = &sc->sc_ic.ic_ac.ac_if;
2060 	int			s;
2061 	struct wi_ltv_macaddr	mac;
2062 	int			id = 0;
2063 
2064 	if (!(sc->wi_flags & WI_FLAGS_ATTACHED))
2065 		return;
2066 
2067 	DPRINTF(WID_INIT, ("wi_init: sc %p\n", sc));
2068 
2069 	s = splnet();
2070 
2071 	if (ifp->if_flags & IFF_RUNNING)
2072 		wi_stop(sc);
2073 
2074 	wi_reset(sc);
2075 
2076 	/* Program max data length. */
2077 	WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len);
2078 
2079 	/* Set the port type. */
2080 	WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype);
2081 
2082 	/* Enable/disable IBSS creation. */
2083 	WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss);
2084 
2085 	/* Program the RTS/CTS threshold. */
2086 	WI_SETVAL(WI_RID_RTS_THRESH, sc->wi_rts_thresh);
2087 
2088 	/* Program the TX rate */
2089 	WI_SETVAL(WI_RID_TX_RATE, sc->wi_tx_rate);
2090 
2091 	/* Access point density */
2092 	WI_SETVAL(WI_RID_SYSTEM_SCALE, sc->wi_ap_density);
2093 
2094 	/* Power Management Enabled */
2095 	WI_SETVAL(WI_RID_PM_ENABLED, sc->wi_pm_enabled);
2096 
2097 	/* Power Management Max Sleep */
2098 	WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep);
2099 
2100 	/* Set Enhanced Security if supported. */
2101 	if (sc->wi_flags & WI_FLAGS_HAS_ENH_SECURITY)
2102 		WI_SETVAL(WI_RID_ENH_SECURITY, sc->wi_enh_security);
2103 
2104 	/* Set Roaming Mode unless this is a Symbol card. */
2105 	if (sc->wi_flags & WI_FLAGS_HAS_ROAMING)
2106 		WI_SETVAL(WI_RID_ROAMING_MODE, sc->wi_roaming);
2107 
2108 	/* Set Antenna Diversity if this is a Symbol card. */
2109 	if (sc->wi_flags & WI_FLAGS_HAS_DIVERSITY)
2110 		WI_SETVAL(WI_RID_SYMBOL_DIVERSITY, sc->wi_diversity);
2111 
2112 	/* Specify the network name */
2113 	WI_SETSTR(WI_RID_DESIRED_SSID, sc->wi_net_name);
2114 
2115 	/* Specify the IBSS name */
2116 	if (sc->wi_net_name.i_len != 0 && (sc->wi_ptype == WI_PORTTYPE_HOSTAP ||
2117 	    (sc->wi_create_ibss && sc->wi_ptype == WI_PORTTYPE_IBSS)))
2118 		WI_SETSTR(WI_RID_OWN_SSID, sc->wi_net_name);
2119 	else
2120 		WI_SETSTR(WI_RID_OWN_SSID, sc->wi_ibss_name);
2121 
2122 	/* Specify the frequency to use */
2123 	WI_SETVAL(WI_RID_OWN_CHNL, sc->wi_channel);
2124 
2125 	/* Program the nodename. */
2126 	WI_SETSTR(WI_RID_NODENAME, sc->wi_node_name);
2127 
2128 	/* Set our MAC address. */
2129 	mac.wi_len = 4;
2130 	mac.wi_type = WI_RID_MAC_NODE;
2131 	bcopy(LLADDR(ifp->if_sadl), &sc->sc_ic.ic_myaddr, ETHER_ADDR_LEN);
2132 	bcopy(&sc->sc_ic.ic_myaddr, &mac.wi_mac_addr, ETHER_ADDR_LEN);
2133 	wi_write_record(sc, (struct wi_ltv_gen *)&mac);
2134 
2135 	/*
2136 	 * Initialize promisc mode.
2137 	 *	Being in the Host-AP mode causes
2138 	 *	great deal of pain if promisc mode is set.
2139 	 *	Therefore we avoid confusing the firmware
2140 	 *	and always reset promisc mode in Host-AP regime,
2141 	 *	it shows us all the packets anyway.
2142 	 */
2143 	if (sc->wi_ptype != WI_PORTTYPE_HOSTAP && ifp->if_flags & IFF_PROMISC)
2144 		WI_SETVAL(WI_RID_PROMISC, 1);
2145 	else
2146 		WI_SETVAL(WI_RID_PROMISC, 0);
2147 
2148 	/* Configure WEP. */
2149 	if (sc->wi_flags & WI_FLAGS_HAS_WEP) {
2150 		WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep);
2151 		WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key);
2152 		sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1;
2153 		sc->wi_keys.wi_type = WI_RID_DEFLT_CRYPT_KEYS;
2154 		wi_write_record(sc, (struct wi_ltv_gen *)&sc->wi_keys);
2155 		if (sc->sc_firmware_type != WI_LUCENT && sc->wi_use_wep) {
2156 			/*
2157 			 * HWB3163 EVAL-CARD Firmware version less than 0.8.2.
2158 			 *
2159 			 * If promiscuous mode is disabled, the Prism2 chip
2160 			 * does not work with WEP .
2161 			 * I'm currently investigating the details of this.
2162 			 * (ichiro@netbsd.org)
2163 			 */
2164 			 if (sc->sc_firmware_type == WI_INTERSIL &&
2165 			    sc->sc_sta_firmware_ver < 802 ) {
2166 				/* firm ver < 0.8.2 */
2167 				WI_SETVAL(WI_RID_PROMISC, 1);
2168 			 }
2169 			 WI_SETVAL(WI_RID_CNFAUTHMODE, sc->wi_authtype);
2170 		}
2171 	}
2172 
2173 	/* Set multicast filter. */
2174 	wi_setmulti(sc);
2175 
2176 	/* Enable desired port */
2177 	wi_cmd(sc, WI_CMD_ENABLE | sc->wi_portnum, 0, 0, 0);
2178 
2179 	if (wi_alloc_nicmem(sc, ETHER_MAX_LEN + sizeof(struct wi_frame) + 8, &id))
2180 		printf(WI_PRT_FMT ": tx buffer allocation failed\n",
2181 		    WI_PRT_ARG(sc));
2182 	sc->wi_tx_data_id = id;
2183 
2184 	if (wi_alloc_nicmem(sc, ETHER_MAX_LEN + sizeof(struct wi_frame) + 8, &id))
2185 		printf(WI_PRT_FMT ": mgmt. buffer allocation failed\n",
2186 		    WI_PRT_ARG(sc));
2187 	sc->wi_tx_mgmt_id = id;
2188 
2189 	/* Set txpower */
2190 	if (sc->wi_flags & WI_FLAGS_TXPOWER)
2191 		wi_set_txpower(sc, NULL);
2192 
2193 	/* enable interrupts */
2194 	wi_intr_enable(sc, WI_INTRS);
2195 
2196         wihap_init(sc);
2197 
2198 	splx(s);
2199 
2200 	ifp->if_flags |= IFF_RUNNING;
2201 	ifq_clr_oactive(&ifp->if_snd);
2202 
2203 	timeout_add_sec(&sc->sc_timo, 60);
2204 
2205 	return;
2206 }
2207 
2208 STATIC void
2209 wi_do_hostencrypt(struct wi_softc *sc, caddr_t buf, int len)
2210 {
2211 	u_int32_t crc, klen;
2212 	u_int8_t key[RC4KEYLEN];
2213 	u_int8_t *dat;
2214 	struct rc4_ctx ctx;
2215 
2216 	if (!sc->wi_icv_flag) {
2217 		sc->wi_icv = arc4random();
2218 		sc->wi_icv_flag++;
2219         } else
2220 		sc->wi_icv++;
2221 	/*
2222 	 * Skip 'bad' IVs from Fluhrer/Mantin/Shamir:
2223 	 * (B, 255, N) with 3 <= B < 8
2224 	 */
2225 	if (sc->wi_icv >= 0x03ff00 &&
2226             (sc->wi_icv & 0xf8ff00) == 0x00ff00)
2227                 sc->wi_icv += 0x000100;
2228 
2229 	/* prepend 24bit IV to tx key, byte order does not matter */
2230 	bzero(key, sizeof(key));
2231 	key[0] = sc->wi_icv >> 16;
2232 	key[1] = sc->wi_icv >> 8;
2233 	key[2] = sc->wi_icv;
2234 
2235 	klen = letoh16(sc->wi_keys.wi_keys[sc->wi_tx_key].wi_keylen);
2236 	bcopy(&sc->wi_keys.wi_keys[sc->wi_tx_key].wi_keydat,
2237 	    key + IEEE80211_WEP_IVLEN, klen);
2238 	klen = (klen > IEEE80211_WEP_KEYLEN) ? RC4KEYLEN : RC4KEYLEN / 2;
2239 
2240 	/* rc4 keysetup */
2241 	rc4_keysetup(&ctx, key, klen);
2242 
2243 	/* output: IV, tx keyid, rc4(data), rc4(crc32(data)) */
2244 	dat = buf;
2245 	dat[0] = key[0];
2246 	dat[1] = key[1];
2247 	dat[2] = key[2];
2248 	dat[3] = sc->wi_tx_key << 6;		/* pad and keyid */
2249 	dat += 4;
2250 
2251 	/* compute crc32 over data and encrypt */
2252 	crc = ~ether_crc32_le(dat, len);
2253 	rc4_crypt(&ctx, dat, dat, len);
2254 	dat += len;
2255 
2256 	/* append little-endian crc32 and encrypt */
2257 	dat[0] = crc;
2258 	dat[1] = crc >> 8;
2259 	dat[2] = crc >> 16;
2260 	dat[3] = crc >> 24;
2261 	rc4_crypt(&ctx, dat, dat, IEEE80211_WEP_CRCLEN);
2262 }
2263 
2264 STATIC int
2265 wi_do_hostdecrypt(struct wi_softc *sc, caddr_t buf, int len)
2266 {
2267 	u_int32_t crc, klen, kid;
2268 	u_int8_t key[RC4KEYLEN];
2269 	u_int8_t *dat;
2270 	struct rc4_ctx ctx;
2271 
2272 	if (len < IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
2273 	    IEEE80211_WEP_CRCLEN)
2274 		return -1;
2275 	len -= (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
2276 	    IEEE80211_WEP_CRCLEN);
2277 
2278 	dat = buf;
2279 
2280 	bzero(key, sizeof(key));
2281 	key[0] = dat[0];
2282 	key[1] = dat[1];
2283 	key[2] = dat[2];
2284 	kid = (dat[3] >> 6) % 4;
2285 	dat += 4;
2286 
2287 	klen = letoh16(sc->wi_keys.wi_keys[kid].wi_keylen);
2288 	bcopy(&sc->wi_keys.wi_keys[kid].wi_keydat,
2289 	    key + IEEE80211_WEP_IVLEN, klen);
2290 	klen = (klen > IEEE80211_WEP_KEYLEN) ? RC4KEYLEN : RC4KEYLEN / 2;
2291 
2292 	/* rc4 keysetup */
2293 	rc4_keysetup(&ctx, key, klen);
2294 
2295 	/* decrypt and compute crc32 over data */
2296 	rc4_crypt(&ctx, dat, dat, len);
2297 	crc = ~ether_crc32_le(dat, len);
2298 	dat += len;
2299 
2300 	/* decrypt little-endian crc32 and verify */
2301 	rc4_crypt(&ctx, dat, dat, IEEE80211_WEP_CRCLEN);
2302 
2303 	if ((dat[0] != crc) && (dat[1] != crc >> 8) &&
2304 	    (dat[2] != crc >> 16) && (dat[3] != crc >> 24)) {
2305 		if (sc->sc_ic.ic_if.if_flags & IFF_DEBUG)
2306 			printf(WI_PRT_FMT ": wi_do_hostdecrypt: iv mismatch: "
2307 			    "0x%02x%02x%02x%02x vs. 0x%x\n", WI_PRT_ARG(sc),
2308 			    dat[3], dat[2], dat[1], dat[0], crc);
2309 		return -1;
2310 	}
2311 
2312 	return 0;
2313 }
2314 
2315 void
2316 wi_start(struct ifnet *ifp)
2317 {
2318 	struct wi_softc		*sc;
2319 	struct mbuf		*m0;
2320 	struct wi_frame		tx_frame;
2321 	struct ether_header	*eh;
2322 	int			id, hostencrypt = 0;
2323 
2324 	sc = ifp->if_softc;
2325 
2326 	DPRINTF(WID_START, ("wi_start: ifp %p sc %p\n", ifp, sc));
2327 
2328 	if (!(sc->wi_flags & WI_FLAGS_ATTACHED))
2329 		return;
2330 
2331 	if (ifq_is_oactive(&ifp->if_snd))
2332 		return;
2333 
2334 nextpkt:
2335 	IFQ_DEQUEUE(&ifp->if_snd, m0);
2336 	if (m0 == NULL)
2337 		return;
2338 
2339 	bzero(&tx_frame, sizeof(tx_frame));
2340 	tx_frame.wi_frame_ctl = htole16(WI_FTYPE_DATA | WI_STYPE_DATA);
2341 	id = sc->wi_tx_data_id;
2342 	eh = mtod(m0, struct ether_header *);
2343 
2344 	if (sc->wi_ptype == WI_PORTTYPE_HOSTAP) {
2345 		if (!wihap_check_tx(&sc->wi_hostap_info, eh->ether_dhost,
2346 		    &tx_frame.wi_tx_rate) && !(ifp->if_flags & IFF_PROMISC)) {
2347 			if (ifp->if_flags & IFF_DEBUG)
2348 				printf(WI_PRT_FMT
2349 				    ": wi_start: dropping unassoc dst %s\n",
2350 				    WI_PRT_ARG(sc),
2351 				    ether_sprintf(eh->ether_dhost));
2352 			m_freem(m0);
2353 			goto nextpkt;
2354 		}
2355 	}
2356 
2357 	/*
2358 	 * Use RFC1042 encoding for IP and ARP datagrams,
2359 	 * 802.3 for anything else.
2360 	 */
2361 	if (eh->ether_type == htons(ETHERTYPE_IP) ||
2362 	    eh->ether_type == htons(ETHERTYPE_ARP) ||
2363 	    eh->ether_type == htons(ETHERTYPE_REVARP) ||
2364 	    eh->ether_type == htons(ETHERTYPE_IPV6)) {
2365 		bcopy(&eh->ether_dhost,
2366 		    &tx_frame.wi_addr1, ETHER_ADDR_LEN);
2367 		if (sc->wi_ptype == WI_PORTTYPE_HOSTAP) {
2368 			tx_frame.wi_tx_ctl = htole16(WI_ENC_TX_MGMT); /* XXX */
2369 			tx_frame.wi_frame_ctl |= htole16(WI_FCTL_FROMDS);
2370 			bcopy(&sc->sc_ic.ic_myaddr,
2371 			    &tx_frame.wi_addr2, ETHER_ADDR_LEN);
2372 			bcopy(&eh->ether_shost,
2373 			    &tx_frame.wi_addr3, ETHER_ADDR_LEN);
2374 			if (sc->wi_use_wep)
2375 				hostencrypt = 1;
2376 		} else if (sc->wi_ptype == WI_PORTTYPE_BSS && sc->wi_use_wep &&
2377 		    sc->wi_crypto_algorithm != WI_CRYPTO_FIRMWARE_WEP) {
2378 			tx_frame.wi_tx_ctl = htole16(WI_ENC_TX_MGMT); /* XXX */
2379 			tx_frame.wi_frame_ctl |= htole16(WI_FCTL_TODS);
2380 			bcopy(&sc->sc_ic.ic_myaddr,
2381 			    &tx_frame.wi_addr2, ETHER_ADDR_LEN);
2382 			bcopy(&eh->ether_dhost,
2383 			    &tx_frame.wi_addr3, ETHER_ADDR_LEN);
2384 			hostencrypt = 1;
2385 		} else
2386 			bcopy(&eh->ether_shost,
2387 			    &tx_frame.wi_addr2, ETHER_ADDR_LEN);
2388 		bcopy(&eh->ether_dhost, &tx_frame.wi_dst_addr, ETHER_ADDR_LEN);
2389 		bcopy(&eh->ether_shost, &tx_frame.wi_src_addr, ETHER_ADDR_LEN);
2390 
2391 		tx_frame.wi_dat_len = m0->m_pkthdr.len - WI_SNAPHDR_LEN;
2392 		tx_frame.wi_dat[0] = htons(WI_SNAP_WORD0);
2393 		tx_frame.wi_dat[1] = htons(WI_SNAP_WORD1);
2394 		tx_frame.wi_len = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN);
2395 		tx_frame.wi_type = eh->ether_type;
2396 
2397 		if (hostencrypt) {
2398 
2399 			/* Do host encryption. */
2400 			tx_frame.wi_frame_ctl |= htole16(WI_FCTL_WEP);
2401 			bcopy(&tx_frame.wi_dat[0], &sc->wi_txbuf[4], 6);
2402 			bcopy(&tx_frame.wi_type, &sc->wi_txbuf[10], 2);
2403 
2404 			m_copydata(m0, sizeof(struct ether_header),
2405 			    m0->m_pkthdr.len - sizeof(struct ether_header),
2406 			    (caddr_t)&sc->wi_txbuf[12]);
2407 
2408 			wi_do_hostencrypt(sc, (caddr_t)&sc->wi_txbuf,
2409 			    tx_frame.wi_dat_len);
2410 
2411 			tx_frame.wi_dat_len += IEEE80211_WEP_IVLEN +
2412 			    IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN;
2413 
2414 			tx_frame.wi_dat_len = htole16(tx_frame.wi_dat_len);
2415 			wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
2416 			    sizeof(struct wi_frame));
2417 			wi_write_data(sc, id, WI_802_11_OFFSET_RAW,
2418 			    (caddr_t)&sc->wi_txbuf,
2419 			    (m0->m_pkthdr.len -
2420 			     sizeof(struct ether_header)) + 18);
2421 		} else {
2422 			m_copydata(m0, sizeof(struct ether_header),
2423 			    m0->m_pkthdr.len - sizeof(struct ether_header),
2424 			    (caddr_t)&sc->wi_txbuf);
2425 
2426 			tx_frame.wi_dat_len = htole16(tx_frame.wi_dat_len);
2427 			wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
2428 			    sizeof(struct wi_frame));
2429 			wi_write_data(sc, id, WI_802_11_OFFSET,
2430 			    (caddr_t)&sc->wi_txbuf,
2431 			    (m0->m_pkthdr.len -
2432 			     sizeof(struct ether_header)) + 2);
2433 		}
2434 	} else {
2435 		tx_frame.wi_dat_len = htole16(m0->m_pkthdr.len);
2436 
2437 		if (sc->wi_ptype == WI_PORTTYPE_HOSTAP && sc->wi_use_wep) {
2438 
2439 			/* Do host encryption. (XXX - not implemented) */
2440 			printf(WI_PRT_FMT
2441 			    ": host encrypt not implemented for 802.3\n",
2442 			    WI_PRT_ARG(sc));
2443 		} else {
2444 			m_copydata(m0, 0, m0->m_pkthdr.len,
2445 			    (caddr_t)&sc->wi_txbuf);
2446 
2447 			wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
2448 			    sizeof(struct wi_frame));
2449 			wi_write_data(sc, id, WI_802_3_OFFSET,
2450 			    (caddr_t)&sc->wi_txbuf, m0->m_pkthdr.len + 2);
2451 		}
2452 	}
2453 
2454 #if NBPFILTER > 0
2455 	/*
2456 	 * If there's a BPF listener, bounce a copy of
2457 	 * this frame to him.
2458 	 */
2459 	if (ifp->if_bpf)
2460 		bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
2461 #endif
2462 
2463 	m_freem(m0);
2464 
2465 	ifq_set_oactive(&ifp->if_snd);
2466 
2467 	/*
2468 	 * Set a timeout in case the chip goes out to lunch.
2469 	 */
2470 	ifp->if_timer = 5;
2471 
2472 	if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id, 0, 0))
2473 		printf(WI_PRT_FMT ": wi_start: xmit failed\n", WI_PRT_ARG(sc));
2474 
2475 	return;
2476 }
2477 
2478 STATIC int
2479 wi_mgmt_xmit(struct wi_softc *sc, caddr_t data, int len)
2480 {
2481 	struct wi_frame		tx_frame;
2482 	int			id;
2483 	struct wi_80211_hdr	*hdr;
2484 	caddr_t			dptr;
2485 
2486 	if (!(sc->wi_flags & WI_FLAGS_ATTACHED))
2487 		return(ENODEV);
2488 
2489 	hdr = (struct wi_80211_hdr *)data;
2490 	dptr = data + sizeof(struct wi_80211_hdr);
2491 
2492 	bzero(&tx_frame, sizeof(tx_frame));
2493 	id = sc->wi_tx_mgmt_id;
2494 
2495 	bcopy(hdr, &tx_frame.wi_frame_ctl, sizeof(struct wi_80211_hdr));
2496 
2497 	tx_frame.wi_tx_ctl = htole16(WI_ENC_TX_MGMT);
2498 	tx_frame.wi_dat_len = len - sizeof(struct wi_80211_hdr);
2499 	tx_frame.wi_len = htole16(tx_frame.wi_dat_len);
2500 
2501 	tx_frame.wi_dat_len = htole16(tx_frame.wi_dat_len);
2502 	wi_write_data(sc, id, 0, (caddr_t)&tx_frame, sizeof(struct wi_frame));
2503 	wi_write_data(sc, id, WI_802_11_OFFSET_RAW, dptr,
2504 	    (len - sizeof(struct wi_80211_hdr)) + 2);
2505 
2506 	if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id, 0, 0)) {
2507 		printf(WI_PRT_FMT ": wi_mgmt_xmit: xmit failed\n",
2508 		    WI_PRT_ARG(sc));
2509 		/*
2510 		 * Hostile stations or corrupt frames may crash the card
2511 		 * and cause the kernel to get stuck printing complaints.
2512 		 * Reset the card and hope the problem goes away.
2513 		 */
2514 		wi_reset(sc);
2515 		return(EIO);
2516 	}
2517 
2518 	return(0);
2519 }
2520 
2521 void
2522 wi_stop(struct wi_softc *sc)
2523 {
2524 	struct ifnet		*ifp;
2525 
2526 	wihap_shutdown(sc);
2527 
2528 	if (!(sc->wi_flags & WI_FLAGS_ATTACHED))
2529 		return;
2530 
2531 	DPRINTF(WID_STOP, ("wi_stop: sc %p\n", sc));
2532 
2533 	timeout_del(&sc->sc_timo);
2534 
2535 	ifp = &sc->sc_ic.ic_if;
2536 
2537 	wi_intr_enable(sc, 0);
2538 	wi_cmd(sc, WI_CMD_DISABLE|sc->wi_portnum, 0, 0, 0);
2539 
2540 	ifp->if_flags &= ~IFF_RUNNING;
2541 	ifq_clr_oactive(&ifp->if_snd);
2542 	ifp->if_timer = 0;
2543 
2544 	return;
2545 }
2546 
2547 
2548 void
2549 wi_watchdog(struct ifnet *ifp)
2550 {
2551 	struct wi_softc		*sc;
2552 
2553 	sc = ifp->if_softc;
2554 
2555 	printf(WI_PRT_FMT ": device timeout\n", WI_PRT_ARG(sc));
2556 
2557 	wi_cor_reset(sc);
2558 	wi_init(sc);
2559 
2560 	ifp->if_oerrors++;
2561 
2562 	return;
2563 }
2564 
2565 void
2566 wi_detach(struct wi_softc *sc)
2567 {
2568 	struct ifnet *ifp;
2569 	ifp = &sc->sc_ic.ic_if;
2570 
2571 	if (ifp->if_flags & IFF_RUNNING)
2572 		wi_stop(sc);
2573 
2574 	if (sc->wi_flags & WI_FLAGS_ATTACHED) {
2575 		sc->wi_flags &= ~WI_FLAGS_ATTACHED;
2576 	}
2577 }
2578 
2579 STATIC void
2580 wi_get_id(struct wi_softc *sc)
2581 {
2582 	struct wi_ltv_ver		ver;
2583 	const struct wi_card_ident	*id;
2584 	u_int16_t			pri_fw_ver[3];
2585 	const char			*card_name;
2586 	u_int16_t			card_id;
2587 
2588 	/* get chip identity */
2589 	bzero(&ver, sizeof(ver));
2590 	ver.wi_type = WI_RID_CARD_ID;
2591 	ver.wi_len = 5;
2592 	wi_read_record(sc, (struct wi_ltv_gen *)&ver);
2593 	card_id = letoh16(ver.wi_ver[0]);
2594 	for (id = wi_card_ident; id->firm_type != WI_NOTYPE; id++) {
2595 		if (card_id == id->card_id)
2596 			break;
2597 	}
2598 	if (id->firm_type != WI_NOTYPE) {
2599 		sc->sc_firmware_type = id->firm_type;
2600 		card_name = id->card_name;
2601 	} else if (ver.wi_ver[0] & htole16(0x8000)) {
2602 		sc->sc_firmware_type = WI_INTERSIL;
2603 		card_name = "Unknown PRISM2 chip";
2604 	} else {
2605 		sc->sc_firmware_type = WI_LUCENT;
2606 	}
2607 
2608 	/* get primary firmware version (XXX - how to do Lucent?) */
2609 	if (sc->sc_firmware_type != WI_LUCENT) {
2610 		bzero(&ver, sizeof(ver));
2611 		ver.wi_type = WI_RID_PRI_IDENTITY;
2612 		ver.wi_len = 5;
2613 		wi_read_record(sc, (struct wi_ltv_gen *)&ver);
2614 		pri_fw_ver[0] = letoh16(ver.wi_ver[2]);
2615 		pri_fw_ver[1] = letoh16(ver.wi_ver[3]);
2616 		pri_fw_ver[2] = letoh16(ver.wi_ver[1]);
2617 	}
2618 
2619 	/* get station firmware version */
2620 	bzero(&ver, sizeof(ver));
2621 	ver.wi_type = WI_RID_STA_IDENTITY;
2622 	ver.wi_len = 5;
2623 	wi_read_record(sc, (struct wi_ltv_gen *)&ver);
2624 	ver.wi_ver[1] = letoh16(ver.wi_ver[1]);
2625 	ver.wi_ver[2] = letoh16(ver.wi_ver[2]);
2626 	ver.wi_ver[3] = letoh16(ver.wi_ver[3]);
2627 	sc->sc_sta_firmware_ver = ver.wi_ver[2] * 10000 +
2628 	    ver.wi_ver[3] * 100 + ver.wi_ver[1];
2629 
2630 	if (sc->sc_firmware_type == WI_INTERSIL &&
2631 	    (sc->sc_sta_firmware_ver == 10102 || sc->sc_sta_firmware_ver == 20102)) {
2632 		struct wi_ltv_str sver;
2633 		char *p;
2634 
2635 		bzero(&sver, sizeof(sver));
2636 		sver.wi_type = WI_RID_SYMBOL_IDENTITY;
2637 		sver.wi_len = 7;
2638 		/* value should be something like "V2.00-11" */
2639 		if (wi_read_record(sc, (struct wi_ltv_gen *)&sver) == 0 &&
2640 		    *(p = (char *)sver.wi_str) >= 'A' &&
2641 		    p[2] == '.' && p[5] == '-' && p[8] == '\0') {
2642 			sc->sc_firmware_type = WI_SYMBOL;
2643 			sc->sc_sta_firmware_ver = (p[1] - '0') * 10000 +
2644 			    (p[3] - '0') * 1000 + (p[4] - '0') * 100 +
2645 			    (p[6] - '0') * 10 + (p[7] - '0');
2646 		}
2647 	}
2648 
2649 	if (sc->sc_firmware_type == WI_LUCENT) {
2650 		printf("%s: Firmware %d.%02d variant %d, ", WI_PRT_ARG(sc),
2651 		    ver.wi_ver[2], ver.wi_ver[3], ver.wi_ver[1]);
2652 	} else {
2653 		printf("%s: %s%s (0x%04x), Firmware %d.%d.%d (primary), %d.%d.%d (station), ",
2654 		    WI_PRT_ARG(sc),
2655 		    sc->sc_firmware_type == WI_SYMBOL ? "Symbol " : "",
2656 		    card_name, card_id, pri_fw_ver[0], pri_fw_ver[1],
2657 		    pri_fw_ver[2], sc->sc_sta_firmware_ver / 10000,
2658 		    (sc->sc_sta_firmware_ver % 10000) / 100,
2659 		    sc->sc_sta_firmware_ver % 100);
2660 	}
2661 }
2662 
2663 STATIC int
2664 wi_sync_media(struct wi_softc *sc, int ptype, int txrate)
2665 {
2666 	uint64_t media = sc->sc_media.ifm_cur->ifm_media;
2667 	uint64_t options = IFM_OPTIONS(media);
2668 	uint64_t subtype;
2669 
2670 	switch (txrate) {
2671 	case 1:
2672 		subtype = IFM_IEEE80211_DS1;
2673 		break;
2674 	case 2:
2675 		subtype = IFM_IEEE80211_DS2;
2676 		break;
2677 	case 3:
2678 		subtype = IFM_AUTO;
2679 		break;
2680 	case 5:
2681 		subtype = IFM_IEEE80211_DS5;
2682 		break;
2683 	case 11:
2684 		subtype = IFM_IEEE80211_DS11;
2685 		break;
2686 	default:
2687 		subtype = IFM_MANUAL;		/* Unable to represent */
2688 		break;
2689 	}
2690 
2691 	options &= ~IFM_OMASK;
2692 	switch (ptype) {
2693 	case WI_PORTTYPE_BSS:
2694 		/* default port type */
2695 		break;
2696 	case WI_PORTTYPE_ADHOC:
2697 		options |= IFM_IEEE80211_ADHOC;
2698 		break;
2699 	case WI_PORTTYPE_HOSTAP:
2700 		options |= IFM_IEEE80211_HOSTAP;
2701 		break;
2702 	case WI_PORTTYPE_IBSS:
2703 		if (sc->wi_create_ibss)
2704 			options |= IFM_IEEE80211_IBSSMASTER;
2705 		else
2706 			options |= IFM_IEEE80211_IBSS;
2707 		break;
2708 	default:
2709 		subtype = IFM_MANUAL;		/* Unable to represent */
2710 		break;
2711 	}
2712 	media = IFM_MAKEWORD(IFM_TYPE(media), subtype, options,
2713 	IFM_INST(media));
2714 	if (ifmedia_match(&sc->sc_media, media, sc->sc_media.ifm_mask) == NULL)
2715 		return (EINVAL);
2716 	ifmedia_set(&sc->sc_media, media);
2717 	sc->wi_ptype = ptype;
2718 	sc->wi_tx_rate = txrate;
2719 	return (0);
2720 }
2721 
2722 STATIC int
2723 wi_media_change(struct ifnet *ifp)
2724 {
2725 	struct wi_softc *sc = ifp->if_softc;
2726 	int otype = sc->wi_ptype;
2727 	int orate = sc->wi_tx_rate;
2728 	int ocreate_ibss = sc->wi_create_ibss;
2729 
2730 	if ((sc->sc_media.ifm_cur->ifm_media & IFM_IEEE80211_HOSTAP) &&
2731 	    sc->sc_firmware_type != WI_INTERSIL)
2732 		return (EINVAL);
2733 
2734 	sc->wi_create_ibss = 0;
2735 
2736 	switch (sc->sc_media.ifm_cur->ifm_media & IFM_OMASK) {
2737 	case 0:
2738 		sc->wi_ptype = WI_PORTTYPE_BSS;
2739 		break;
2740 	case IFM_IEEE80211_ADHOC:
2741 		sc->wi_ptype = WI_PORTTYPE_ADHOC;
2742 		break;
2743 	case IFM_IEEE80211_HOSTAP:
2744 		sc->wi_ptype = WI_PORTTYPE_HOSTAP;
2745 		break;
2746 	case IFM_IEEE80211_IBSSMASTER:
2747 	case IFM_IEEE80211_IBSSMASTER|IFM_IEEE80211_IBSS:
2748 		if (!(sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS))
2749 			return (EINVAL);
2750 		sc->wi_create_ibss = 1;
2751 		/* FALLTHROUGH */
2752 	case IFM_IEEE80211_IBSS:
2753 		sc->wi_ptype = WI_PORTTYPE_IBSS;
2754 		break;
2755 	default:
2756 		/* Invalid combination. */
2757 		return (EINVAL);
2758 	}
2759 
2760 	switch (IFM_SUBTYPE(sc->sc_media.ifm_cur->ifm_media)) {
2761 	case IFM_IEEE80211_DS1:
2762 		sc->wi_tx_rate = 1;
2763 		break;
2764 	case IFM_IEEE80211_DS2:
2765 		sc->wi_tx_rate = 2;
2766 		break;
2767 	case IFM_AUTO:
2768 		sc->wi_tx_rate = 3;
2769 		break;
2770 	case IFM_IEEE80211_DS5:
2771 		sc->wi_tx_rate = 5;
2772 		break;
2773 	case IFM_IEEE80211_DS11:
2774 		sc->wi_tx_rate = 11;
2775 		break;
2776 	}
2777 
2778 	if (sc->sc_ic.ic_if.if_flags & IFF_UP) {
2779 		if (otype != sc->wi_ptype || orate != sc->wi_tx_rate ||
2780 		    ocreate_ibss != sc->wi_create_ibss)
2781 			wi_init(sc);
2782 	}
2783 
2784 	ifp->if_baudrate = ifmedia_baudrate(sc->sc_media.ifm_cur->ifm_media);
2785 
2786 	return (0);
2787 }
2788 
2789 STATIC void
2790 wi_media_status(struct ifnet *ifp, struct ifmediareq *imr)
2791 {
2792 	struct wi_softc *sc = ifp->if_softc;
2793 	struct wi_req wreq;
2794 
2795 	if (!(sc->sc_ic.ic_if.if_flags & IFF_UP)) {
2796 		imr->ifm_active = IFM_IEEE80211|IFM_NONE;
2797 		imr->ifm_status = 0;
2798 		return;
2799 	}
2800 
2801 	if (sc->wi_tx_rate == 3) {
2802 		imr->ifm_active = IFM_IEEE80211|IFM_AUTO;
2803 
2804 		wreq.wi_type = WI_RID_CUR_TX_RATE;
2805 		wreq.wi_len = WI_MAX_DATALEN;
2806 		if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) == 0) {
2807 			switch (letoh16(wreq.wi_val[0])) {
2808 			case 1:
2809 				imr->ifm_active |= IFM_IEEE80211_DS1;
2810 				break;
2811 			case 2:
2812 				imr->ifm_active |= IFM_IEEE80211_DS2;
2813 				break;
2814 			case 6:
2815 				imr->ifm_active |= IFM_IEEE80211_DS5;
2816 				break;
2817 			case 11:
2818 				imr->ifm_active |= IFM_IEEE80211_DS11;
2819 				break;
2820 			}
2821 		}
2822 	} else {
2823 		imr->ifm_active = sc->sc_media.ifm_cur->ifm_media;
2824 	}
2825 
2826 	imr->ifm_status = IFM_AVALID;
2827 	switch (sc->wi_ptype) {
2828 	case WI_PORTTYPE_ADHOC:
2829 	case WI_PORTTYPE_IBSS:
2830 		/*
2831 		 * XXX: It would be nice if we could give some actually
2832 		 * useful status like whether we joined another IBSS or
2833 		 * created one ourselves.
2834 		 */
2835 		/* FALLTHROUGH */
2836 	case WI_PORTTYPE_HOSTAP:
2837 		imr->ifm_status |= IFM_ACTIVE;
2838 		break;
2839 	default:
2840 		wreq.wi_type = WI_RID_COMMQUAL;
2841 		wreq.wi_len = WI_MAX_DATALEN;
2842 		if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) == 0 &&
2843 		    letoh16(wreq.wi_val[0]) != 0)
2844 			imr->ifm_status |= IFM_ACTIVE;
2845 	}
2846 }
2847 
2848 STATIC int
2849 wi_set_nwkey(struct wi_softc *sc, struct ieee80211_nwkey *nwkey)
2850 {
2851 	int i, len, error;
2852 	struct wi_req wreq;
2853 	struct wi_ltv_keys *wk = (struct wi_ltv_keys *)&wreq;
2854 
2855 	if (!(sc->wi_flags & WI_FLAGS_HAS_WEP))
2856 		return ENODEV;
2857 	if (nwkey->i_defkid <= 0 || nwkey->i_defkid > IEEE80211_WEP_NKID)
2858 		return EINVAL;
2859 	memcpy(wk, &sc->wi_keys, sizeof(*wk));
2860 	for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2861 		if (nwkey->i_key[i].i_keydat == NULL)
2862 			continue;
2863 		len = nwkey->i_key[i].i_keylen;
2864 		if (len > sizeof(wk->wi_keys[i].wi_keydat))
2865 			return EINVAL;
2866 		error = copyin(nwkey->i_key[i].i_keydat,
2867 		    wk->wi_keys[i].wi_keydat, len);
2868 		if (error)
2869 			return error;
2870 		wk->wi_keys[i].wi_keylen = htole16(len);
2871 	}
2872 
2873 	wk->wi_len = (sizeof(*wk) / 2) + 1;
2874 	wk->wi_type = WI_RID_DEFLT_CRYPT_KEYS;
2875 	if (sc->sc_ic.ic_if.if_flags & IFF_UP) {
2876 		error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
2877 		if (error)
2878 			return error;
2879 	}
2880 	if ((error = wi_setdef(sc, &wreq)))
2881 		return (error);
2882 
2883 	wreq.wi_len = 2;
2884 	wreq.wi_type = WI_RID_TX_CRYPT_KEY;
2885 	wreq.wi_val[0] = htole16(nwkey->i_defkid - 1);
2886 	if (sc->sc_ic.ic_if.if_flags & IFF_UP) {
2887 		error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
2888 		if (error)
2889 			return error;
2890 	}
2891 	if ((error = wi_setdef(sc, &wreq)))
2892 		return (error);
2893 
2894 	wreq.wi_type = WI_RID_ENCRYPTION;
2895 	wreq.wi_val[0] = htole16(nwkey->i_wepon);
2896 	if (sc->sc_ic.ic_if.if_flags & IFF_UP) {
2897 		error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
2898 		if (error)
2899 			return error;
2900 	}
2901 	if ((error = wi_setdef(sc, &wreq)))
2902 		return (error);
2903 
2904 	if (sc->sc_ic.ic_if.if_flags & IFF_UP)
2905 		wi_init(sc);
2906 	return 0;
2907 }
2908 
2909 STATIC int
2910 wi_get_nwkey(struct wi_softc *sc, struct ieee80211_nwkey *nwkey)
2911 {
2912 	int i, len, error;
2913 	struct wi_ltv_keys *wk = &sc->wi_keys;
2914 
2915 	if (!(sc->wi_flags & WI_FLAGS_HAS_WEP))
2916 		return ENODEV;
2917 	nwkey->i_wepon = sc->wi_use_wep;
2918 	nwkey->i_defkid = sc->wi_tx_key + 1;
2919 
2920 	/* do not show any keys to non-root user */
2921 	error = suser(curproc, 0);
2922 	for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2923 		if (nwkey->i_key[i].i_keydat == NULL)
2924 			continue;
2925 		/* error holds results of suser() for the first time */
2926 		if (error)
2927 			return error;
2928 		len = letoh16(wk->wi_keys[i].wi_keylen);
2929 		if (nwkey->i_key[i].i_keylen < len)
2930 			return ENOSPC;
2931 		nwkey->i_key[i].i_keylen = len;
2932 		error = copyout(wk->wi_keys[i].wi_keydat,
2933 		    nwkey->i_key[i].i_keydat, len);
2934 		if (error)
2935 			return error;
2936 	}
2937 	return 0;
2938 }
2939 
2940 STATIC int
2941 wi_set_pm(struct wi_softc *sc, struct ieee80211_power *power)
2942 {
2943 
2944 	sc->wi_pm_enabled = power->i_enabled;
2945 	sc->wi_max_sleep = power->i_maxsleep;
2946 
2947 	if (sc->sc_ic.ic_if.if_flags & IFF_UP)
2948 		wi_init(sc);
2949 
2950 	return (0);
2951 }
2952 
2953 STATIC int
2954 wi_get_pm(struct wi_softc *sc, struct ieee80211_power *power)
2955 {
2956 
2957 	power->i_enabled = sc->wi_pm_enabled;
2958 	power->i_maxsleep = sc->wi_max_sleep;
2959 
2960 	return (0);
2961 }
2962 
2963 STATIC int
2964 wi_set_txpower(struct wi_softc *sc, struct ieee80211_txpower *txpower)
2965 {
2966 	u_int16_t	cmd;
2967 	u_int16_t	power;
2968 	int8_t		tmp;
2969 	int		error;
2970 	int		alc;
2971 
2972 	if (txpower == NULL) {
2973 		if (!(sc->wi_flags & WI_FLAGS_TXPOWER))
2974 			return (EINVAL);
2975 		alc = 0;		/* disable ALC */
2976 	} else {
2977 		if (txpower->i_mode == IEEE80211_TXPOWER_MODE_AUTO) {
2978 			alc = 1;	/* enable ALC */
2979 			sc->wi_flags &= ~WI_FLAGS_TXPOWER;
2980 		} else {
2981 			alc = 0;	/* disable ALC */
2982 			sc->wi_flags |= WI_FLAGS_TXPOWER;
2983 			sc->wi_txpower = txpower->i_val;
2984 		}
2985 	}
2986 
2987 	/* Set ALC */
2988 	cmd = WI_CMD_DEBUG | (WI_DEBUG_CONFBITS << 8);
2989 	if ((error = wi_cmd(sc, cmd, alc, 0x8, 0)) != 0)
2990 		return (error);
2991 
2992 	/* No need to set the TX power value if ALC is enabled */
2993 	if (alc)
2994 		return (0);
2995 
2996 	/* Convert dBM to internal TX power value */
2997 	if (sc->wi_txpower > 20)
2998 		power = 128;
2999 	else if (sc->wi_txpower < -43)
3000 		power = 127;
3001 	else {
3002 		tmp = sc->wi_txpower;
3003 		tmp = -12 - tmp;
3004 		tmp <<= 2;
3005 
3006 		power = (u_int16_t)tmp;
3007 	}
3008 
3009 	/* Set manual TX power */
3010 	cmd = WI_CMD_WRITE_MIF;
3011 	if ((error = wi_cmd(sc, cmd,
3012 		 WI_HFA384X_CR_MANUAL_TX_POWER, power, 0)) != 0)
3013 		return (error);
3014 
3015 	if (sc->sc_ic.ic_if.if_flags & IFF_DEBUG)
3016 		printf("%s: %u (%d dBm)\n", sc->sc_dev.dv_xname, power,
3017 		    sc->wi_txpower);
3018 
3019 	return (0);
3020 }
3021 
3022 STATIC int
3023 wi_get_txpower(struct wi_softc *sc, struct ieee80211_txpower *txpower)
3024 {
3025 	u_int16_t	cmd;
3026 	u_int16_t	power;
3027 	int8_t		tmp;
3028 	int		error;
3029 
3030 	if (sc->wi_flags & WI_FLAGS_BUS_USB)
3031 		return (EOPNOTSUPP);
3032 
3033 	/* Get manual TX power */
3034 	cmd = WI_CMD_READ_MIF;
3035 	if ((error = wi_cmd(sc, cmd,
3036 		 WI_HFA384X_CR_MANUAL_TX_POWER, 0, 0)) != 0)
3037 		return (error);
3038 
3039 	power = CSR_READ_2(sc, WI_RESP0);
3040 
3041 	/* Convert internal TX power value to dBM */
3042 	if (power > 255)
3043 		txpower->i_val = 255;
3044 	else {
3045 		tmp = power;
3046 		tmp >>= 2;
3047 		txpower->i_val = (u_int16_t)(-12 - tmp);
3048 	}
3049 
3050 	if (sc->wi_flags & WI_FLAGS_TXPOWER)
3051 		txpower->i_mode = IEEE80211_TXPOWER_MODE_FIXED;
3052 	else
3053 		txpower->i_mode = IEEE80211_TXPOWER_MODE_AUTO;
3054 
3055 	return (0);
3056 }
3057 
3058 STATIC int
3059 wi_set_ssid(struct ieee80211_nwid *ws, u_int8_t *id, int len)
3060 {
3061 
3062 	if (len > IEEE80211_NWID_LEN)
3063 		return (EINVAL);
3064 	ws->i_len = len;
3065 	memcpy(ws->i_nwid, id, len);
3066 	return (0);
3067 }
3068 
3069 STATIC int
3070 wi_get_debug(struct wi_softc *sc, struct wi_req *wreq)
3071 {
3072 	int			error = 0;
3073 
3074 	wreq->wi_len = 1;
3075 
3076 	switch (wreq->wi_type) {
3077 	case WI_DEBUG_SLEEP:
3078 		wreq->wi_len++;
3079 		wreq->wi_val[0] = htole16(sc->wi_debug.wi_sleep);
3080 		break;
3081 	case WI_DEBUG_DELAYSUPP:
3082 		wreq->wi_len++;
3083 		wreq->wi_val[0] = htole16(sc->wi_debug.wi_delaysupp);
3084 		break;
3085 	case WI_DEBUG_TXSUPP:
3086 		wreq->wi_len++;
3087 		wreq->wi_val[0] = htole16(sc->wi_debug.wi_txsupp);
3088 		break;
3089 	case WI_DEBUG_MONITOR:
3090 		wreq->wi_len++;
3091 		wreq->wi_val[0] = htole16(sc->wi_debug.wi_monitor);
3092 		break;
3093 	case WI_DEBUG_LEDTEST:
3094 		wreq->wi_len += 3;
3095 		wreq->wi_val[0] = htole16(sc->wi_debug.wi_ledtest);
3096 		wreq->wi_val[1] = htole16(sc->wi_debug.wi_ledtest_param0);
3097 		wreq->wi_val[2] = htole16(sc->wi_debug.wi_ledtest_param1);
3098 		break;
3099 	case WI_DEBUG_CONTTX:
3100 		wreq->wi_len += 2;
3101 		wreq->wi_val[0] = htole16(sc->wi_debug.wi_conttx);
3102 		wreq->wi_val[1] = htole16(sc->wi_debug.wi_conttx_param0);
3103 		break;
3104 	case WI_DEBUG_CONTRX:
3105 		wreq->wi_len++;
3106 		wreq->wi_val[0] = htole16(sc->wi_debug.wi_contrx);
3107 		break;
3108 	case WI_DEBUG_SIGSTATE:
3109 		wreq->wi_len += 2;
3110 		wreq->wi_val[0] = htole16(sc->wi_debug.wi_sigstate);
3111 		wreq->wi_val[1] = htole16(sc->wi_debug.wi_sigstate_param0);
3112 		break;
3113 	case WI_DEBUG_CONFBITS:
3114 		wreq->wi_len += 2;
3115 		wreq->wi_val[0] = htole16(sc->wi_debug.wi_confbits);
3116 		wreq->wi_val[1] = htole16(sc->wi_debug.wi_confbits_param0);
3117 		break;
3118 	default:
3119 		error = EIO;
3120 		break;
3121 	}
3122 
3123 	return (error);
3124 }
3125 
3126 STATIC int
3127 wi_set_debug(struct wi_softc *sc, struct wi_req *wreq)
3128 {
3129 	int				error = 0;
3130 	u_int16_t			cmd, param0 = 0, param1 = 0;
3131 
3132 	switch (wreq->wi_type) {
3133 	case WI_DEBUG_RESET:
3134 	case WI_DEBUG_INIT:
3135 	case WI_DEBUG_CALENABLE:
3136 		break;
3137 	case WI_DEBUG_SLEEP:
3138 		sc->wi_debug.wi_sleep = 1;
3139 		break;
3140 	case WI_DEBUG_WAKE:
3141 		sc->wi_debug.wi_sleep = 0;
3142 		break;
3143 	case WI_DEBUG_CHAN:
3144 		param0 = letoh16(wreq->wi_val[0]);
3145 		break;
3146 	case WI_DEBUG_DELAYSUPP:
3147 		sc->wi_debug.wi_delaysupp = 1;
3148 		break;
3149 	case WI_DEBUG_TXSUPP:
3150 		sc->wi_debug.wi_txsupp = 1;
3151 		break;
3152 	case WI_DEBUG_MONITOR:
3153 		sc->wi_debug.wi_monitor = 1;
3154 		break;
3155 	case WI_DEBUG_LEDTEST:
3156 		param0 = letoh16(wreq->wi_val[0]);
3157 		param1 = letoh16(wreq->wi_val[1]);
3158 		sc->wi_debug.wi_ledtest = 1;
3159 		sc->wi_debug.wi_ledtest_param0 = param0;
3160 		sc->wi_debug.wi_ledtest_param1 = param1;
3161 		break;
3162 	case WI_DEBUG_CONTTX:
3163 		param0 = letoh16(wreq->wi_val[0]);
3164 		sc->wi_debug.wi_conttx = 1;
3165 		sc->wi_debug.wi_conttx_param0 = param0;
3166 		break;
3167 	case WI_DEBUG_STOPTEST:
3168 		sc->wi_debug.wi_delaysupp = 0;
3169 		sc->wi_debug.wi_txsupp = 0;
3170 		sc->wi_debug.wi_monitor = 0;
3171 		sc->wi_debug.wi_ledtest = 0;
3172 		sc->wi_debug.wi_ledtest_param0 = 0;
3173 		sc->wi_debug.wi_ledtest_param1 = 0;
3174 		sc->wi_debug.wi_conttx = 0;
3175 		sc->wi_debug.wi_conttx_param0 = 0;
3176 		sc->wi_debug.wi_contrx = 0;
3177 		sc->wi_debug.wi_sigstate = 0;
3178 		sc->wi_debug.wi_sigstate_param0 = 0;
3179 		break;
3180 	case WI_DEBUG_CONTRX:
3181 		sc->wi_debug.wi_contrx = 1;
3182 		break;
3183 	case WI_DEBUG_SIGSTATE:
3184 		param0 = letoh16(wreq->wi_val[0]);
3185 		sc->wi_debug.wi_sigstate = 1;
3186 		sc->wi_debug.wi_sigstate_param0 = param0;
3187 		break;
3188 	case WI_DEBUG_CONFBITS:
3189 		param0 = letoh16(wreq->wi_val[0]);
3190 		param1 = letoh16(wreq->wi_val[1]);
3191 		sc->wi_debug.wi_confbits = param0;
3192 		sc->wi_debug.wi_confbits_param0 = param1;
3193 		break;
3194 	default:
3195 		error = EIO;
3196 		break;
3197 	}
3198 
3199 	if (error)
3200 		return (error);
3201 
3202 	cmd = WI_CMD_DEBUG | (wreq->wi_type << 8);
3203 	error = wi_cmd(sc, cmd, param0, param1, 0);
3204 
3205 	return (error);
3206 }
3207