xref: /dragonfly/sys/dev/netif/wi/if_wi.c (revision 9bb2a92d)
1 /*
2  * Copyright (c) 1997, 1998, 1999
3  *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by Bill Paul.
16  * 4. Neither the name of the author nor the names of any co-contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30  * THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * $FreeBSD: src/sys/dev/wi/if_wi.c,v 1.103.2.2 2002/08/02 07:11:34 imp Exp $
33  * $DragonFly: src/sys/dev/netif/wi/if_wi.c,v 1.8 2004/02/13 02:44:48 joerg Exp $
34  */
35 
36 /*
37  * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for FreeBSD.
38  *
39  * Written by Bill Paul <wpaul@ctr.columbia.edu>
40  * Electrical Engineering Department
41  * Columbia University, New York City
42  */
43 
44 /*
45  * The WaveLAN/IEEE adapter is the second generation of the WaveLAN
46  * from Lucent. Unlike the older cards, the new ones are programmed
47  * entirely via a firmware-driven controller called the Hermes.
48  * Unfortunately, Lucent will not release the Hermes programming manual
49  * without an NDA (if at all). What they do release is an API library
50  * called the HCF (Hardware Control Functions) which is supposed to
51  * do the device-specific operations of a device driver for you. The
52  * publically available version of the HCF library (the 'HCF Light') is
53  * a) extremely gross, b) lacks certain features, particularly support
54  * for 802.11 frames, and c) is contaminated by the GNU Public License.
55  *
56  * This driver does not use the HCF or HCF Light at all. Instead, it
57  * programs the Hermes controller directly, using information gleaned
58  * from the HCF Light code and corresponding documentation.
59  *
60  * This driver supports the ISA, PCMCIA and PCI versions of the Lucent
61  * WaveLan cards (based on the Hermes chipset), as well as the newer
62  * Prism 2 chipsets with firmware from Intersil and Symbol.
63  */
64 
65 #include <sys/param.h>
66 #include <sys/systm.h>
67 #if defined(__FreeBSD__) && __FreeBSD_version >= 500033
68 #include <sys/endian.h>
69 #endif
70 #include <sys/sockio.h>
71 #include <sys/mbuf.h>
72 #include <sys/proc.h>
73 #include <sys/kernel.h>
74 #include <sys/socket.h>
75 #include <sys/module.h>
76 #include <sys/bus.h>
77 #include <sys/random.h>
78 #include <sys/syslog.h>
79 #include <sys/sysctl.h>
80 
81 #include <machine/bus.h>
82 #include <machine/resource.h>
83 #include <machine/clock.h>
84 #include <sys/rman.h>
85 
86 #include <net/if.h>
87 #include <net/if_arp.h>
88 #include <net/ethernet.h>
89 #include <net/if_dl.h>
90 #include <net/if_media.h>
91 #include <net/if_types.h>
92 #include <net/if_ieee80211.h>
93 
94 #include <netinet/in.h>
95 #include <netinet/in_systm.h>
96 #include <netinet/in_var.h>
97 #include <netinet/ip.h>
98 #include <netinet/if_ether.h>
99 
100 #include <net/bpf.h>
101 
102 #include "if_wavelan_ieee.h"
103 #include "wi_hostap.h"
104 #include "if_wivar.h"
105 #include "if_wireg.h"
106 
107 static void wi_intr(void *);
108 static void wi_reset(struct wi_softc *);
109 static int wi_ioctl(struct ifnet *, u_long, caddr_t);
110 static void wi_init(void *);
111 static void wi_start(struct ifnet *);
112 static void wi_stop(struct wi_softc *);
113 static void wi_watchdog(struct ifnet *);
114 static void wi_rxeof(struct wi_softc *);
115 static void wi_txeof(struct wi_softc *, int);
116 static void wi_update_stats(struct wi_softc *);
117 static void wi_setmulti(struct wi_softc *);
118 
119 static int wi_cmd(struct wi_softc *, int, int, int, int);
120 static int wi_read_record(struct wi_softc *, struct wi_ltv_gen *);
121 static int wi_write_record(struct wi_softc *, struct wi_ltv_gen *);
122 static int wi_read_data(struct wi_softc *, int, int, caddr_t, int);
123 static int wi_write_data(struct wi_softc *, int, int, caddr_t, int);
124 static int wi_seek(struct wi_softc *, int, int, int);
125 static int wi_alloc_nicmem(struct wi_softc *, int, int *);
126 static void wi_inquire(void *);
127 static void wi_setdef(struct wi_softc *, struct wi_req *);
128 
129 #ifdef WICACHE
130 static
131 void wi_cache_store(struct wi_softc *, struct ether_header *,
132 	struct mbuf *, unsigned short);
133 #endif
134 
135 static int wi_get_cur_ssid(struct wi_softc *, char *, int *);
136 static void wi_get_id(struct wi_softc *);
137 static int wi_media_change(struct ifnet *);
138 static void wi_media_status(struct ifnet *, struct ifmediareq *);
139 
140 static int wi_get_debug(struct wi_softc *, struct wi_req *);
141 static int wi_set_debug(struct wi_softc *, struct wi_req *);
142 
143 DECLARE_DUMMY_MODULE(if_wi);
144 
145 devclass_t wi_devclass;
146 
147 struct wi_card_ident wi_card_ident[] = {
148 	/* CARD_ID			CARD_NAME		FIRM_TYPE */
149 	{ WI_NIC_LUCENT_ID,		WI_NIC_LUCENT_STR,	WI_LUCENT },
150 	{ WI_NIC_SONY_ID,		WI_NIC_SONY_STR,	WI_LUCENT },
151 	{ WI_NIC_LUCENT_EMB_ID,		WI_NIC_LUCENT_EMB_STR,	WI_LUCENT },
152 	{ WI_NIC_EVB2_ID,		WI_NIC_EVB2_STR,	WI_INTERSIL },
153 	{ WI_NIC_HWB3763_ID,		WI_NIC_HWB3763_STR,	WI_INTERSIL },
154 	{ WI_NIC_HWB3163_ID,		WI_NIC_HWB3163_STR,	WI_INTERSIL },
155 	{ WI_NIC_HWB3163B_ID,		WI_NIC_HWB3163B_STR,	WI_INTERSIL },
156 	{ WI_NIC_EVB3_ID,		WI_NIC_EVB3_STR,	WI_INTERSIL },
157 	{ WI_NIC_HWB1153_ID,		WI_NIC_HWB1153_STR,	WI_INTERSIL },
158 	{ WI_NIC_P2_SST_ID,		WI_NIC_P2_SST_STR,	WI_INTERSIL },
159 	{ WI_NIC_EVB2_SST_ID,		WI_NIC_EVB2_SST_STR,	WI_INTERSIL },
160 	{ WI_NIC_3842_EVA_ID,		WI_NIC_3842_EVA_STR,	WI_INTERSIL },
161 	{ WI_NIC_3842_PCMCIA_AMD_ID,	WI_NIC_3842_PCMCIA_STR,	WI_INTERSIL },
162 	{ WI_NIC_3842_PCMCIA_SST_ID,	WI_NIC_3842_PCMCIA_STR,	WI_INTERSIL },
163 	{ WI_NIC_3842_PCMCIA_ATM_ID,	WI_NIC_3842_PCMCIA_STR,	WI_INTERSIL },
164 	{ WI_NIC_3842_MINI_AMD_ID,	WI_NIC_3842_MINI_STR,	WI_INTERSIL },
165 	{ WI_NIC_3842_MINI_SST_ID,	WI_NIC_3842_MINI_STR,	WI_INTERSIL },
166 	{ WI_NIC_3842_MINI_ATM_ID,	WI_NIC_3842_MINI_STR,	WI_INTERSIL },
167 	{ WI_NIC_3842_PCI_AMD_ID,	WI_NIC_3842_PCI_STR,	WI_INTERSIL },
168 	{ WI_NIC_3842_PCI_SST_ID,	WI_NIC_3842_PCI_STR,	WI_INTERSIL },
169 	{ WI_NIC_3842_PCI_ATM_ID,	WI_NIC_3842_PCI_STR,	WI_INTERSIL },
170 	{ WI_NIC_P3_PCMCIA_AMD_ID,	WI_NIC_P3_PCMCIA_STR,	WI_INTERSIL },
171 	{ WI_NIC_P3_PCMCIA_SST_ID,	WI_NIC_P3_PCMCIA_STR,	WI_INTERSIL },
172 	{ WI_NIC_P3_MINI_AMD_ID,	WI_NIC_P3_MINI_STR,	WI_INTERSIL },
173 	{ WI_NIC_P3_MINI_SST_ID,	WI_NIC_P3_MINI_STR,	WI_INTERSIL },
174 	{ 0,	NULL,	0 },
175 };
176 
177 int
178 wi_generic_detach(dev)
179 	device_t		dev;
180 {
181 	struct wi_softc		*sc;
182 	struct ifnet		*ifp;
183 	int			s;
184 
185 	sc = device_get_softc(dev);
186 	WI_LOCK(sc, s);
187 	ifp = &sc->arpcom.ac_if;
188 
189 	if (sc->wi_gone) {
190 		device_printf(dev, "already unloaded\n");
191 		WI_UNLOCK(sc, s);
192 		return(ENODEV);
193 	}
194 
195 	wi_stop(sc);
196 
197 	/* Delete all remaining media. */
198 	ifmedia_removeall(&sc->ifmedia);
199 
200 	ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
201 	bus_teardown_intr(dev, sc->irq, sc->wi_intrhand);
202 	wi_free(dev);
203 	sc->wi_gone = 1;
204 
205 	WI_UNLOCK(sc, s);
206 #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
207 	mtx_destroy(&sc->wi_mtx);
208 #endif
209 
210 	return(0);
211 }
212 
213 int
214 wi_generic_attach(device_t dev)
215 {
216 	struct wi_softc		*sc;
217 	struct wi_ltv_macaddr	mac;
218 	struct wi_ltv_gen	gen;
219 	struct ifnet		*ifp;
220 	int			error;
221 	int			s;
222 
223 	/* XXX maybe we need the splimp stuff here XXX */
224 	sc = device_get_softc(dev);
225 	ifp = &sc->arpcom.ac_if;
226 
227 	error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET,
228 	    wi_intr, sc, &sc->wi_intrhand);
229 
230 	if (error) {
231 		device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
232 		wi_free(dev);
233 		return (error);
234 	}
235 
236 #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
237 	mtx_init(&sc->wi_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
238 	    MTX_DEF | MTX_RECURSE);
239 #endif
240 	WI_LOCK(sc, s);
241 
242 	/* Reset the NIC. */
243 	wi_reset(sc);
244 
245 	/*
246 	 * Read the station address.
247 	 * And do it twice. I've seen PRISM-based cards that return
248 	 * an error when trying to read it the first time, which causes
249 	 * the probe to fail.
250 	 */
251 	mac.wi_type = WI_RID_MAC_NODE;
252 	mac.wi_len = 4;
253 	wi_read_record(sc, (struct wi_ltv_gen *)&mac);
254 	if ((error = wi_read_record(sc, (struct wi_ltv_gen *)&mac)) != 0) {
255 		device_printf(dev, "mac read failed %d\n", error);
256 		wi_free(dev);
257 		return (error);
258 	}
259 	bcopy((char *)&mac.wi_mac_addr,
260 	   (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
261 
262 	device_printf(dev, "802.11 address: %6D\n", sc->arpcom.ac_enaddr, ":");
263 
264 	wi_get_id(sc);
265 
266 	ifp->if_softc = sc;
267 	if_initname(ifp, "wi", sc->wi_unit);
268 	ifp->if_mtu = ETHERMTU;
269 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
270 	ifp->if_ioctl = wi_ioctl;
271 	ifp->if_output = ether_output;
272 	ifp->if_start = wi_start;
273 	ifp->if_watchdog = wi_watchdog;
274 	ifp->if_init = wi_init;
275 	ifp->if_baudrate = 10000000;
276 	ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
277 
278 	bzero(sc->wi_node_name, sizeof(sc->wi_node_name));
279 	bcopy(WI_DEFAULT_NODENAME, sc->wi_node_name,
280 	    sizeof(WI_DEFAULT_NODENAME) - 1);
281 
282 	bzero(sc->wi_net_name, sizeof(sc->wi_net_name));
283 	bcopy(WI_DEFAULT_NETNAME, sc->wi_net_name,
284 	    sizeof(WI_DEFAULT_NETNAME) - 1);
285 
286 	bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name));
287 	bcopy(WI_DEFAULT_IBSS, sc->wi_ibss_name,
288 	    sizeof(WI_DEFAULT_IBSS) - 1);
289 
290 	sc->wi_portnum = WI_DEFAULT_PORT;
291 	sc->wi_ptype = WI_PORTTYPE_BSS;
292 	sc->wi_ap_density = WI_DEFAULT_AP_DENSITY;
293 	sc->wi_rts_thresh = WI_DEFAULT_RTS_THRESH;
294 	sc->wi_tx_rate = WI_DEFAULT_TX_RATE;
295 	sc->wi_max_data_len = WI_DEFAULT_DATALEN;
296 	sc->wi_create_ibss = WI_DEFAULT_CREATE_IBSS;
297 	sc->wi_pm_enabled = WI_DEFAULT_PM_ENABLED;
298 	sc->wi_max_sleep = WI_DEFAULT_MAX_SLEEP;
299 	sc->wi_roaming = WI_DEFAULT_ROAMING;
300 	sc->wi_authtype = WI_DEFAULT_AUTHTYPE;
301 	sc->wi_authmode = IEEE80211_AUTH_OPEN;
302 
303 	/*
304 	 * Read the default channel from the NIC. This may vary
305 	 * depending on the country where the NIC was purchased, so
306 	 * we can't hard-code a default and expect it to work for
307 	 * everyone.
308 	 */
309 	gen.wi_type = WI_RID_OWN_CHNL;
310 	gen.wi_len = 2;
311 	wi_read_record(sc, &gen);
312 	sc->wi_channel = gen.wi_val;
313 
314 	/*
315 	 * Set flags based on firmware version.
316 	 */
317 	switch (sc->sc_firmware_type) {
318 	case WI_LUCENT:
319 		sc->wi_flags |= WI_FLAGS_HAS_ROAMING;
320 		if (sc->sc_sta_firmware_ver >= 60000)
321 			sc->wi_flags |= WI_FLAGS_HAS_MOR;
322 		if (sc->sc_sta_firmware_ver >= 60006) {
323 			sc->wi_flags |= WI_FLAGS_HAS_IBSS;
324 			sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS;
325 		}
326 		sc->wi_ibss_port = htole16(1);
327 		break;
328 	case WI_INTERSIL:
329 		sc->wi_flags |= WI_FLAGS_HAS_ROAMING;
330 		if (sc->sc_sta_firmware_ver >= 800) {
331 			sc->wi_flags |= WI_FLAGS_HAS_IBSS;
332 			sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS;
333 		}
334 		/*
335 		 * version 0.8.3 and newer are the only ones that are known
336 		 * to currently work.  Earlier versions can be made to work,
337 		 * at least according to the Linux driver.
338 		 */
339 		if (sc->sc_sta_firmware_ver >= 803)
340 			sc->wi_flags |= WI_FLAGS_HAS_HOSTAP;
341 		sc->wi_ibss_port = htole16(0);
342 		break;
343 	case WI_SYMBOL:
344 		sc->wi_flags |= WI_FLAGS_HAS_DIVERSITY;
345 		if (sc->sc_sta_firmware_ver >= 20000)
346 			sc->wi_flags |= WI_FLAGS_HAS_IBSS;
347 		/* Older Symbol firmware does not support IBSS creation. */
348 		if (sc->sc_sta_firmware_ver >= 25000)
349 			sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS;
350 		sc->wi_ibss_port = htole16(4);
351 		break;
352 	}
353 
354 	/*
355 	 * Find out if we support WEP on this card.
356 	 */
357 	gen.wi_type = WI_RID_WEP_AVAIL;
358 	gen.wi_len = 2;
359 	wi_read_record(sc, &gen);
360 	sc->wi_has_wep = gen.wi_val;
361 
362 	if (bootverbose)
363 		device_printf(sc->dev, "wi_has_wep = %d\n", sc->wi_has_wep);
364 
365 	/*
366 	 * Find supported rates.
367 	 */
368 	gen.wi_type = WI_RID_DATA_RATES;
369 	gen.wi_len = 2;
370 	if (wi_read_record(sc, &gen))
371 		sc->wi_supprates = WI_SUPPRATES_1M | WI_SUPPRATES_2M |
372 		    WI_SUPPRATES_5M | WI_SUPPRATES_11M;
373 	else
374 		sc->wi_supprates = gen.wi_val;
375 
376 	bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats));
377 
378 	wi_init(sc);
379 	wi_stop(sc);
380 
381 	ifmedia_init(&sc->ifmedia, 0, wi_media_change, wi_media_status);
382 #define ADD(m, c)       ifmedia_add(&sc->ifmedia, (m), (c), NULL)
383 	if (sc->wi_supprates & WI_SUPPRATES_1M) {
384 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0);
385 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
386 		    IFM_IEEE80211_ADHOC, 0), 0);
387 		if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
388 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
389 			    IFM_IEEE80211_IBSS, 0), 0);
390 		if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
391 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
392 			    IFM_IEEE80211_IBSSMASTER, 0), 0);
393 		if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP)
394 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
395 			    IFM_IEEE80211_HOSTAP, 0), 0);
396 	}
397 	if (sc->wi_supprates & WI_SUPPRATES_2M) {
398 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0);
399 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
400 		    IFM_IEEE80211_ADHOC, 0), 0);
401 		if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
402 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
403 			    IFM_IEEE80211_IBSS, 0), 0);
404 		if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
405 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
406 			    IFM_IEEE80211_IBSSMASTER, 0), 0);
407 		if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP)
408 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
409 			    IFM_IEEE80211_HOSTAP, 0), 0);
410 	}
411 	if (sc->wi_supprates & WI_SUPPRATES_5M) {
412 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 0, 0), 0);
413 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
414 		    IFM_IEEE80211_ADHOC, 0), 0);
415 		if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
416 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
417 			    IFM_IEEE80211_IBSS, 0), 0);
418 		if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
419 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
420 			    IFM_IEEE80211_IBSSMASTER, 0), 0);
421 		if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP)
422 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
423 			    IFM_IEEE80211_HOSTAP, 0), 0);
424 	}
425 	if (sc->wi_supprates & WI_SUPPRATES_11M) {
426 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0);
427 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
428 		    IFM_IEEE80211_ADHOC, 0), 0);
429 		if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
430 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
431 			    IFM_IEEE80211_IBSS, 0), 0);
432 		if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
433 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
434 			    IFM_IEEE80211_IBSSMASTER, 0), 0);
435 		if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP)
436 			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
437 			    IFM_IEEE80211_HOSTAP, 0), 0);
438 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_MANUAL, 0, 0), 0);
439 	}
440 	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_ADHOC, 0), 0);
441 	if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
442 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_IBSS,
443 		    0), 0);
444 	if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
445 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO,
446 		    IFM_IEEE80211_IBSSMASTER, 0), 0);
447 	if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP)
448 		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO,
449 		    IFM_IEEE80211_HOSTAP, 0), 0);
450 	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0);
451 #undef ADD
452 	ifmedia_set(&sc->ifmedia, IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0));
453 
454 	/*
455 	 * Call MI attach routine.
456 	 */
457 	ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
458 	callout_handle_init(&sc->wi_stat_ch);
459 	WI_UNLOCK(sc, s);
460 
461 	return(0);
462 }
463 
464 static void
465 wi_get_id(sc)
466 	struct wi_softc *sc;
467 {
468 	struct wi_ltv_ver       ver;
469 	struct wi_card_ident	*id;
470 
471 	/* getting chip identity */
472 	memset(&ver, 0, sizeof(ver));
473 	ver.wi_type = WI_RID_CARD_ID;
474 	ver.wi_len = 5;
475 	wi_read_record(sc, (struct wi_ltv_gen *)&ver);
476 	device_printf(sc->dev, "using ");
477 	sc->sc_firmware_type = WI_NOTYPE;
478 	for (id = wi_card_ident; id->card_name != NULL; id++) {
479 		if (le16toh(ver.wi_ver[0]) == id->card_id) {
480 			printf("%s", id->card_name);
481 			sc->sc_firmware_type = id->firm_type;
482 			break;
483 		}
484 	}
485 	if (sc->sc_firmware_type == WI_NOTYPE) {
486 		if (le16toh(ver.wi_ver[0]) & 0x8000) {
487 			printf("Unknown PRISM2 chip");
488 			sc->sc_firmware_type = WI_INTERSIL;
489 		} else {
490 			printf("Unknown Lucent chip");
491 			sc->sc_firmware_type = WI_LUCENT;
492 		}
493 	}
494 
495 	if (sc->sc_firmware_type != WI_LUCENT) {
496 		/* get primary firmware version */
497 		memset(&ver, 0, sizeof(ver));
498 		ver.wi_type = WI_RID_PRI_IDENTITY;
499 		ver.wi_len = 5;
500 		wi_read_record(sc, (struct wi_ltv_gen *)&ver);
501 		ver.wi_ver[1] = le16toh(ver.wi_ver[1]);
502 		ver.wi_ver[2] = le16toh(ver.wi_ver[2]);
503 		ver.wi_ver[3] = le16toh(ver.wi_ver[3]);
504 		sc->sc_pri_firmware_ver = ver.wi_ver[2] * 10000 +
505 		    ver.wi_ver[3] * 100 + ver.wi_ver[1];
506 	}
507 
508 	/* get station firmware version */
509 	memset(&ver, 0, sizeof(ver));
510 	ver.wi_type = WI_RID_STA_IDENTITY;
511 	ver.wi_len = 5;
512 	wi_read_record(sc, (struct wi_ltv_gen *)&ver);
513 	ver.wi_ver[1] = le16toh(ver.wi_ver[1]);
514 	ver.wi_ver[2] = le16toh(ver.wi_ver[2]);
515 	ver.wi_ver[3] = le16toh(ver.wi_ver[3]);
516 	sc->sc_sta_firmware_ver = ver.wi_ver[2] * 10000 +
517 	    ver.wi_ver[3] * 100 + ver.wi_ver[1];
518 	if (sc->sc_firmware_type == WI_INTERSIL &&
519 	    (sc->sc_sta_firmware_ver == 10102 ||
520 	     sc->sc_sta_firmware_ver == 20102)) {
521 		struct wi_ltv_str sver;
522 		char *p;
523 
524 		memset(&sver, 0, sizeof(sver));
525 		sver.wi_type = WI_RID_SYMBOL_IDENTITY;
526 		sver.wi_len = 7;
527 		/* value should be the format like "V2.00-11" */
528 		if (wi_read_record(sc, (struct wi_ltv_gen *)&sver) == 0 &&
529 		    *(p = (char *)sver.wi_str) >= 'A' &&
530 		    p[2] == '.' && p[5] == '-' && p[8] == '\0') {
531 			sc->sc_firmware_type = WI_SYMBOL;
532 			sc->sc_sta_firmware_ver = (p[1] - '0') * 10000 +
533 			    (p[3] - '0') * 1000 + (p[4] - '0') * 100 +
534 			    (p[6] - '0') * 10 + (p[7] - '0');
535 		}
536 	}
537 	printf("\n");
538 	device_printf(sc->dev, "%s Firmware: ",
539 	     sc->sc_firmware_type == WI_LUCENT ? "Lucent" :
540 	    (sc->sc_firmware_type == WI_SYMBOL ? "Symbol" : "Intersil"));
541 
542 	/*
543 	 * The primary firmware is only valid on Prism based chipsets
544 	 * (INTERSIL or SYMBOL).
545 	 */
546 	if (sc->sc_firmware_type != WI_LUCENT)
547 	    printf("Primary %u.%02u.%02u, ", sc->sc_pri_firmware_ver / 10000,
548 		    (sc->sc_pri_firmware_ver % 10000) / 100,
549 		    sc->sc_pri_firmware_ver % 100);
550 	printf("Station %u.%02u.%02u\n",
551 	    sc->sc_sta_firmware_ver / 10000, (sc->sc_sta_firmware_ver % 10000) / 100,
552 	    sc->sc_sta_firmware_ver % 100);
553 	return;
554 }
555 
556 static void
557 wi_rxeof(sc)
558 	struct wi_softc		*sc;
559 {
560 	struct ifnet		*ifp;
561 	struct ether_header	*eh;
562 	struct mbuf		*m;
563 	int			id;
564 
565 	ifp = &sc->arpcom.ac_if;
566 
567 	id = CSR_READ_2(sc, WI_RX_FID);
568 
569 	/*
570 	 * if we have the procframe flag set, disregard all this and just
571 	 * read the data from the device.
572 	 */
573 	if (sc->wi_procframe || sc->wi_debug.wi_monitor) {
574 		struct wi_frame		*rx_frame;
575 		int			datlen, hdrlen;
576 
577 		/* first allocate mbuf for packet storage */
578 		MGETHDR(m, M_DONTWAIT, MT_DATA);
579 		if (m == NULL) {
580 			ifp->if_ierrors++;
581 			return;
582 		}
583 		MCLGET(m, M_DONTWAIT);
584 		if (!(m->m_flags & M_EXT)) {
585 			m_freem(m);
586 			ifp->if_ierrors++;
587 			return;
588 		}
589 
590 		m->m_pkthdr.rcvif = ifp;
591 
592 		/* now read wi_frame first so we know how much data to read */
593 		if (wi_read_data(sc, id, 0, mtod(m, caddr_t),
594 		    sizeof(struct wi_frame))) {
595 			m_freem(m);
596 			ifp->if_ierrors++;
597 			return;
598 		}
599 
600 		rx_frame = mtod(m, struct wi_frame *);
601 
602 		switch ((rx_frame->wi_status & WI_STAT_MAC_PORT) >> 8) {
603 		case 7:
604 			switch (rx_frame->wi_frame_ctl & WI_FCTL_FTYPE) {
605 			case WI_FTYPE_DATA:
606 				hdrlen = WI_DATA_HDRLEN;
607 				datlen = rx_frame->wi_dat_len + WI_FCS_LEN;
608 				break;
609 			case WI_FTYPE_MGMT:
610 				hdrlen = WI_MGMT_HDRLEN;
611 				datlen = rx_frame->wi_dat_len + WI_FCS_LEN;
612 				break;
613 			case WI_FTYPE_CTL:
614 				/*
615 				 * prism2 cards don't pass control packets
616 				 * down properly or consistently, so we'll only
617 				 * pass down the header.
618 				 */
619 				hdrlen = WI_CTL_HDRLEN;
620 				datlen = 0;
621 				break;
622 			default:
623 				device_printf(sc->dev, "received packet of "
624 				    "unknown type on port 7\n");
625 				m_freem(m);
626 				ifp->if_ierrors++;
627 				return;
628 			}
629 			break;
630 		case 0:
631 			hdrlen = WI_DATA_HDRLEN;
632 			datlen = rx_frame->wi_dat_len + WI_FCS_LEN;
633 			break;
634 		default:
635 			device_printf(sc->dev, "received packet on invalid "
636 			    "port (wi_status=0x%x)\n", rx_frame->wi_status);
637 			m_freem(m);
638 			ifp->if_ierrors++;
639 			return;
640 		}
641 
642 		if ((hdrlen + datlen + 2) > MCLBYTES) {
643 			device_printf(sc->dev, "oversized packet received "
644 			    "(wi_dat_len=%d, wi_status=0x%x)\n",
645 			    datlen, rx_frame->wi_status);
646 			m_freem(m);
647 			ifp->if_ierrors++;
648 			return;
649 		}
650 
651 		if (wi_read_data(sc, id, hdrlen, mtod(m, caddr_t) + hdrlen,
652 		    datlen + 2)) {
653 			m_freem(m);
654 			ifp->if_ierrors++;
655 			return;
656 		}
657 
658 		m->m_pkthdr.len = m->m_len = hdrlen + datlen;
659 
660 		ifp->if_ipackets++;
661 
662 		/* Handle BPF listeners. */
663 		if (ifp->if_bpf)
664 			bpf_mtap(ifp, m);
665 
666 		m_freem(m);
667 	} else {
668 		struct wi_frame		rx_frame;
669 
670 		/* First read in the frame header */
671 		if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame,
672 		    sizeof(rx_frame))) {
673 			ifp->if_ierrors++;
674 			return;
675 		}
676 
677 		if (rx_frame.wi_status & WI_STAT_ERRSTAT) {
678 			ifp->if_ierrors++;
679 			return;
680 		}
681 
682 		MGETHDR(m, M_DONTWAIT, MT_DATA);
683 		if (m == NULL) {
684 			ifp->if_ierrors++;
685 			return;
686 		}
687 		MCLGET(m, M_DONTWAIT);
688 		if (!(m->m_flags & M_EXT)) {
689 			m_freem(m);
690 			ifp->if_ierrors++;
691 			return;
692 		}
693 
694 		eh = mtod(m, struct ether_header *);
695 		m->m_pkthdr.rcvif = ifp;
696 
697 		if (rx_frame.wi_status == WI_STAT_MGMT &&
698 		    sc->wi_ptype == WI_PORTTYPE_AP) {
699 			if ((WI_802_11_OFFSET_RAW + rx_frame.wi_dat_len + 2) >
700 			    MCLBYTES) {
701 				device_printf(sc->dev, "oversized mgmt packet "
702 				    "received in hostap mode "
703 				    "(wi_dat_len=%d, wi_status=0x%x)\n",
704 				    rx_frame.wi_dat_len, rx_frame.wi_status);
705 				m_freem(m);
706 				ifp->if_ierrors++;
707 				return;
708 			}
709 
710 			/* Put the whole header in there. */
711 			bcopy(&rx_frame, mtod(m, void *),
712 			    sizeof(struct wi_frame));
713 			if (wi_read_data(sc, id, WI_802_11_OFFSET_RAW,
714 			    mtod(m, caddr_t) + WI_802_11_OFFSET_RAW,
715 			    rx_frame.wi_dat_len + 2)) {
716 				m_freem(m);
717 				ifp->if_ierrors++;
718 				return;
719 			}
720 			m->m_pkthdr.len = m->m_len =
721 			    WI_802_11_OFFSET_RAW + rx_frame.wi_dat_len;
722 			/* XXX: consider giving packet to bhp? */
723 			wihap_mgmt_input(sc, &rx_frame, m);
724 			return;
725 		}
726 
727 		if (rx_frame.wi_status == WI_STAT_1042 ||
728 		    rx_frame.wi_status == WI_STAT_TUNNEL ||
729 		    rx_frame.wi_status == WI_STAT_WMP_MSG) {
730 			if((rx_frame.wi_dat_len + WI_SNAPHDR_LEN) > MCLBYTES) {
731 				device_printf(sc->dev,
732 				    "oversized packet received "
733 				    "(wi_dat_len=%d, wi_status=0x%x)\n",
734 				    rx_frame.wi_dat_len, rx_frame.wi_status);
735 				m_freem(m);
736 				ifp->if_ierrors++;
737 				return;
738 			}
739 			m->m_pkthdr.len = m->m_len =
740 			    rx_frame.wi_dat_len + WI_SNAPHDR_LEN;
741 
742 #if 0
743 			bcopy((char *)&rx_frame.wi_addr1,
744 			    (char *)&eh->ether_dhost, ETHER_ADDR_LEN);
745 			if (sc->wi_ptype == WI_PORTTYPE_ADHOC) {
746 				bcopy((char *)&rx_frame.wi_addr2,
747 				    (char *)&eh->ether_shost, ETHER_ADDR_LEN);
748 			} else {
749 				bcopy((char *)&rx_frame.wi_addr3,
750 				    (char *)&eh->ether_shost, ETHER_ADDR_LEN);
751 			}
752 #else
753 			bcopy((char *)&rx_frame.wi_dst_addr,
754 				(char *)&eh->ether_dhost, ETHER_ADDR_LEN);
755 			bcopy((char *)&rx_frame.wi_src_addr,
756 				(char *)&eh->ether_shost, ETHER_ADDR_LEN);
757 #endif
758 
759 			bcopy((char *)&rx_frame.wi_type,
760 			    (char *)&eh->ether_type, ETHER_TYPE_LEN);
761 
762 			if (wi_read_data(sc, id, WI_802_11_OFFSET,
763 			    mtod(m, caddr_t) + sizeof(struct ether_header),
764 			    m->m_len + 2)) {
765 				m_freem(m);
766 				ifp->if_ierrors++;
767 				return;
768 			}
769 		} else {
770 			if((rx_frame.wi_dat_len +
771 			    sizeof(struct ether_header)) > MCLBYTES) {
772 				device_printf(sc->dev,
773 				    "oversized packet received "
774 				    "(wi_dat_len=%d, wi_status=0x%x)\n",
775 				    rx_frame.wi_dat_len, rx_frame.wi_status);
776 				m_freem(m);
777 				ifp->if_ierrors++;
778 				return;
779 			}
780 			m->m_pkthdr.len = m->m_len =
781 			    rx_frame.wi_dat_len + sizeof(struct ether_header);
782 
783 			if (wi_read_data(sc, id, WI_802_3_OFFSET,
784 			    mtod(m, caddr_t), m->m_len + 2)) {
785 				m_freem(m);
786 				ifp->if_ierrors++;
787 				return;
788 			}
789 		}
790 
791 		ifp->if_ipackets++;
792 
793 		if (sc->wi_ptype == WI_PORTTYPE_AP) {
794 			/*
795 			 * Give host AP code first crack at data
796 			 * packets.  If it decides to handle it (or
797 			 * drop it), it will return a non-zero.
798 			 * Otherwise, it is destined for this host.
799 			 */
800 			if (wihap_data_input(sc, &rx_frame, m))
801 				return;
802 		}
803 		/* Receive packet. */
804 		m_adj(m, sizeof(struct ether_header));
805 #ifdef WICACHE
806 		wi_cache_store(sc, eh, m, rx_frame.wi_q_info);
807 #endif
808 		ether_input(ifp, eh, m);
809 	}
810 }
811 
812 static void
813 wi_txeof(sc, status)
814 	struct wi_softc		*sc;
815 	int			status;
816 {
817 	struct ifnet		*ifp;
818 
819 	ifp = &sc->arpcom.ac_if;
820 
821 	ifp->if_timer = 0;
822 	ifp->if_flags &= ~IFF_OACTIVE;
823 
824 	if (status & WI_EV_TX_EXC)
825 		ifp->if_oerrors++;
826 	else
827 		ifp->if_opackets++;
828 
829 	return;
830 }
831 
832 void
833 wi_inquire(xsc)
834 	void			*xsc;
835 {
836 	struct wi_softc		*sc;
837 	struct ifnet		*ifp;
838 	int			s;
839 
840 	sc = xsc;
841 	ifp = &sc->arpcom.ac_if;
842 
843 	sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60);
844 
845 	/* Don't do this while we're transmitting */
846 	if (ifp->if_flags & IFF_OACTIVE)
847 		return;
848 
849 	WI_LOCK(sc, s);
850 	wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_COUNTERS, 0, 0);
851 	WI_UNLOCK(sc, s);
852 
853 	return;
854 }
855 
856 void
857 wi_update_stats(sc)
858 	struct wi_softc		*sc;
859 {
860 	struct wi_ltv_gen	gen;
861 	u_int16_t		id;
862 	struct ifnet		*ifp;
863 	u_int32_t		*ptr;
864 	int			len, i;
865 	u_int16_t		t;
866 
867 	ifp = &sc->arpcom.ac_if;
868 
869 	id = CSR_READ_2(sc, WI_INFO_FID);
870 
871 	wi_read_data(sc, id, 0, (char *)&gen, 4);
872 
873 	/*
874 	 * if we just got our scan results, copy it over into the scan buffer
875 	 * so we can return it to anyone that asks for it. (add a little
876 	 * compatibility with the prism2 scanning mechanism)
877 	 */
878 	if (gen.wi_type == WI_INFO_SCAN_RESULTS)
879 	{
880 		sc->wi_scanbuf_len = gen.wi_len;
881 		wi_read_data(sc, id, 4, (char *)sc->wi_scanbuf,
882 		    sc->wi_scanbuf_len * 2);
883 
884 		return;
885 	}
886 	else if (gen.wi_type != WI_INFO_COUNTERS)
887 		return;
888 
889 	len = (gen.wi_len - 1 < sizeof(sc->wi_stats) / 4) ?
890 		gen.wi_len - 1 : sizeof(sc->wi_stats) / 4;
891 	ptr = (u_int32_t *)&sc->wi_stats;
892 
893 	for (i = 0; i < len - 1; i++) {
894 		t = CSR_READ_2(sc, WI_DATA1);
895 #ifdef WI_HERMES_STATS_WAR
896 		if (t > 0xF000)
897 			t = ~t & 0xFFFF;
898 #endif
899 		ptr[i] += t;
900 	}
901 
902 	ifp->if_collisions = sc->wi_stats.wi_tx_single_retries +
903 	    sc->wi_stats.wi_tx_multi_retries +
904 	    sc->wi_stats.wi_tx_retry_limit;
905 
906 	return;
907 }
908 
909 static void
910 wi_intr(xsc)
911 	void		*xsc;
912 {
913 	struct wi_softc		*sc = xsc;
914 	struct ifnet		*ifp;
915 	u_int16_t		status;
916 	int			s;
917 
918 	WI_LOCK(sc, s);
919 
920 	ifp = &sc->arpcom.ac_if;
921 
922 	if (sc->wi_gone || !(ifp->if_flags & IFF_UP)) {
923 		CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
924 		CSR_WRITE_2(sc, WI_INT_EN, 0);
925 		WI_UNLOCK(sc, s);
926 		return;
927 	}
928 
929 	/* Disable interrupts. */
930 	CSR_WRITE_2(sc, WI_INT_EN, 0);
931 
932 	status = CSR_READ_2(sc, WI_EVENT_STAT);
933 	CSR_WRITE_2(sc, WI_EVENT_ACK, ~WI_INTRS);
934 
935 	if (status & WI_EV_RX) {
936 		wi_rxeof(sc);
937 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
938 	}
939 
940 	if (status & WI_EV_TX) {
941 		wi_txeof(sc, status);
942 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX);
943 	}
944 
945 	if (status & WI_EV_ALLOC) {
946 		int			id;
947 
948 		id = CSR_READ_2(sc, WI_ALLOC_FID);
949 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
950 		if (id == sc->wi_tx_data_id)
951 			wi_txeof(sc, status);
952 	}
953 
954 	if (status & WI_EV_INFO) {
955 		wi_update_stats(sc);
956 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO);
957 	}
958 
959 	if (status & WI_EV_TX_EXC) {
960 		wi_txeof(sc, status);
961 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX_EXC);
962 	}
963 
964 	if (status & WI_EV_INFO_DROP) {
965 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO_DROP);
966 	}
967 
968 	/* Re-enable interrupts. */
969 	CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
970 
971 	if (ifp->if_snd.ifq_head != NULL) {
972 		wi_start(ifp);
973 	}
974 
975 	WI_UNLOCK(sc, s);
976 
977 	return;
978 }
979 
980 static int
981 wi_cmd(sc, cmd, val0, val1, val2)
982 	struct wi_softc		*sc;
983 	int			cmd;
984 	int			val0;
985 	int			val1;
986 	int			val2;
987 {
988 	int			i, s = 0;
989 	static volatile int count  = 0;
990 
991 	if (count > 1)
992 		panic("Hey partner, hold on there!");
993 	count++;
994 
995 	/* wait for the busy bit to clear */
996 	for (i = 500; i > 0; i--) {	/* 5s */
997 		if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY)) {
998 			break;
999 		}
1000 		DELAY(10*1000);	/* 10 m sec */
1001 	}
1002 	if (i == 0) {
1003 		device_printf(sc->dev, "wi_cmd: busy bit won't clear.\n" );
1004 		count--;
1005 		return(ETIMEDOUT);
1006 	}
1007 
1008 	CSR_WRITE_2(sc, WI_PARAM0, val0);
1009 	CSR_WRITE_2(sc, WI_PARAM1, val1);
1010 	CSR_WRITE_2(sc, WI_PARAM2, val2);
1011 	CSR_WRITE_2(sc, WI_COMMAND, cmd);
1012 
1013 	for (i = 0; i < WI_TIMEOUT; i++) {
1014 		/*
1015 		 * Wait for 'command complete' bit to be
1016 		 * set in the event status register.
1017 		 */
1018 		s = CSR_READ_2(sc, WI_EVENT_STAT);
1019 		if (s & WI_EV_CMD) {
1020 			/* Ack the event and read result code. */
1021 			s = CSR_READ_2(sc, WI_STATUS);
1022 			CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
1023 #ifdef foo
1024 			if ((s & WI_CMD_CODE_MASK) != (cmd & WI_CMD_CODE_MASK))
1025 				return(EIO);
1026 #endif
1027 			if (s & WI_STAT_CMD_RESULT) {
1028 				count--;
1029 				return(EIO);
1030 			}
1031 			break;
1032 		}
1033 		DELAY(WI_DELAY);
1034 	}
1035 
1036 	count--;
1037 	if (i == WI_TIMEOUT) {
1038 		device_printf(sc->dev,
1039 		    "timeout in wi_cmd 0x%04x; event status 0x%04x\n", cmd, s);
1040 		return(ETIMEDOUT);
1041 	}
1042 	return(0);
1043 }
1044 
1045 static void
1046 wi_reset(sc)
1047 	struct wi_softc		*sc;
1048 {
1049 #define WI_INIT_TRIES 3
1050 	int i;
1051 	int tries;
1052 
1053 	/* Symbol firmware cannot be initialized more than once */
1054 	if (sc->sc_firmware_type == WI_SYMBOL && sc->sc_enabled)
1055 		return;
1056 	if (sc->sc_firmware_type == WI_SYMBOL)
1057 		tries = 1;
1058 	else
1059 		tries = WI_INIT_TRIES;
1060 
1061 	for (i = 0; i < tries; i++) {
1062 		if (wi_cmd(sc, WI_CMD_INI, 0, 0, 0) == 0)
1063 			break;
1064 		DELAY(WI_DELAY * 1000);
1065 	}
1066 	sc->sc_enabled = 1;
1067 
1068 	if (i == tries) {
1069 		device_printf(sc->dev, "init failed\n");
1070 		return;
1071 	}
1072 
1073 	CSR_WRITE_2(sc, WI_INT_EN, 0);
1074 	CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
1075 
1076 	/* Calibrate timer. */
1077 	WI_SETVAL(WI_RID_TICK_TIME, 8);
1078 
1079 	return;
1080 }
1081 
1082 /*
1083  * Read an LTV record from the NIC.
1084  */
1085 static int
1086 wi_read_record(sc, ltv)
1087 	struct wi_softc		*sc;
1088 	struct wi_ltv_gen	*ltv;
1089 {
1090 	u_int16_t		*ptr;
1091 	int			i, len, code;
1092 	struct wi_ltv_gen	*oltv, p2ltv;
1093 
1094 	oltv = ltv;
1095 	if (sc->sc_firmware_type != WI_LUCENT) {
1096 		switch (ltv->wi_type) {
1097 		case WI_RID_ENCRYPTION:
1098 			p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
1099 			p2ltv.wi_len = 2;
1100 			ltv = &p2ltv;
1101 			break;
1102 		case WI_RID_TX_CRYPT_KEY:
1103 			p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
1104 			p2ltv.wi_len = 2;
1105 			ltv = &p2ltv;
1106 			break;
1107 		case WI_RID_ROAMING_MODE:
1108 			if (sc->sc_firmware_type == WI_INTERSIL)
1109 				break;
1110 			/* not supported */
1111 			ltv->wi_len = 1;
1112 			return 0;
1113 		case WI_RID_MICROWAVE_OVEN:
1114 			/* not supported */
1115 			ltv->wi_len = 1;
1116 			return 0;
1117 		}
1118 	}
1119 
1120 	/* Tell the NIC to enter record read mode. */
1121 	if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type, 0, 0))
1122 		return(EIO);
1123 
1124 	/* Seek to the record. */
1125 	if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
1126 		return(EIO);
1127 
1128 	/*
1129 	 * Read the length and record type and make sure they
1130 	 * match what we expect (this verifies that we have enough
1131 	 * room to hold all of the returned data).
1132 	 */
1133 	len = CSR_READ_2(sc, WI_DATA1);
1134 	if (len > ltv->wi_len)
1135 		return(ENOSPC);
1136 	code = CSR_READ_2(sc, WI_DATA1);
1137 	if (code != ltv->wi_type)
1138 		return(EIO);
1139 
1140 	ltv->wi_len = len;
1141 	ltv->wi_type = code;
1142 
1143 	/* Now read the data. */
1144 	ptr = &ltv->wi_val;
1145 	for (i = 0; i < ltv->wi_len - 1; i++)
1146 		ptr[i] = CSR_READ_2(sc, WI_DATA1);
1147 
1148 	if (ltv->wi_type == WI_RID_PORTTYPE && sc->wi_ptype == WI_PORTTYPE_IBSS
1149 	    && ltv->wi_val == sc->wi_ibss_port) {
1150 		/*
1151 		 * Convert vendor IBSS port type to WI_PORTTYPE_IBSS.
1152 		 * Since Lucent uses port type 1 for BSS *and* IBSS we
1153 		 * have to rely on wi_ptype to distinguish this for us.
1154 		 */
1155 		ltv->wi_val = htole16(WI_PORTTYPE_IBSS);
1156 	} else if (sc->sc_firmware_type != WI_LUCENT) {
1157 		switch (oltv->wi_type) {
1158 		case WI_RID_TX_RATE:
1159 		case WI_RID_CUR_TX_RATE:
1160 			switch (ltv->wi_val) {
1161 			case 1: oltv->wi_val = 1; break;
1162 			case 2: oltv->wi_val = 2; break;
1163 			case 3:	oltv->wi_val = 6; break;
1164 			case 4: oltv->wi_val = 5; break;
1165 			case 7: oltv->wi_val = 7; break;
1166 			case 8: oltv->wi_val = 11; break;
1167 			case 15: oltv->wi_val = 3; break;
1168 			default: oltv->wi_val = 0x100 + ltv->wi_val; break;
1169 			}
1170 			break;
1171 		case WI_RID_ENCRYPTION:
1172 			oltv->wi_len = 2;
1173 			if (ltv->wi_val & 0x01)
1174 				oltv->wi_val = 1;
1175 			else
1176 				oltv->wi_val = 0;
1177 			break;
1178 		case WI_RID_TX_CRYPT_KEY:
1179 			oltv->wi_len = 2;
1180 			oltv->wi_val = ltv->wi_val;
1181 			break;
1182 		case WI_RID_CNFAUTHMODE:
1183                         oltv->wi_len = 2;
1184 			if (le16toh(ltv->wi_val) & 0x01)
1185 				oltv->wi_val = htole16(1);
1186 			else if (le16toh(ltv->wi_val) & 0x02)
1187 				oltv->wi_val = htole16(2);
1188 			break;
1189 		}
1190 	}
1191 
1192 	return(0);
1193 }
1194 
1195 /*
1196  * Same as read, except we inject data instead of reading it.
1197  */
1198 static int
1199 wi_write_record(sc, ltv)
1200 	struct wi_softc		*sc;
1201 	struct wi_ltv_gen	*ltv;
1202 {
1203 	u_int16_t		*ptr;
1204 	int			i;
1205 	struct wi_ltv_gen	p2ltv;
1206 
1207 	if (ltv->wi_type == WI_RID_PORTTYPE &&
1208 	    le16toh(ltv->wi_val) == WI_PORTTYPE_IBSS) {
1209 		/* Convert WI_PORTTYPE_IBSS to vendor IBSS port type. */
1210 		p2ltv.wi_type = WI_RID_PORTTYPE;
1211 		p2ltv.wi_len = 2;
1212 		p2ltv.wi_val = sc->wi_ibss_port;
1213 		ltv = &p2ltv;
1214 	} else if (sc->sc_firmware_type != WI_LUCENT) {
1215 		switch (ltv->wi_type) {
1216 		case WI_RID_TX_RATE:
1217 			p2ltv.wi_type = WI_RID_TX_RATE;
1218 			p2ltv.wi_len = 2;
1219 			switch (ltv->wi_val) {
1220 			case 1: p2ltv.wi_val = 1; break;
1221 			case 2: p2ltv.wi_val = 2; break;
1222 			case 3:	p2ltv.wi_val = 15; break;
1223 			case 5: p2ltv.wi_val = 4; break;
1224 			case 6: p2ltv.wi_val = 3; break;
1225 			case 7: p2ltv.wi_val = 7; break;
1226 			case 11: p2ltv.wi_val = 8; break;
1227 			default: return EINVAL;
1228 			}
1229 			ltv = &p2ltv;
1230 			break;
1231 		case WI_RID_ENCRYPTION:
1232 			p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
1233 			p2ltv.wi_len = 2;
1234 			if (le16toh(ltv->wi_val)) {
1235 				p2ltv.wi_val =htole16(PRIVACY_INVOKED |
1236 				    EXCLUDE_UNENCRYPTED);
1237 				if (sc->wi_ptype == WI_PORTTYPE_AP)
1238 					/*
1239 					 * Disable tx encryption...
1240 					 * it's broken.
1241 					 */
1242 					p2ltv.wi_val |= htole16(HOST_ENCRYPT);
1243 			} else
1244 				p2ltv.wi_val =
1245 				    htole16(HOST_ENCRYPT | HOST_DECRYPT);
1246 			ltv = &p2ltv;
1247 			break;
1248 		case WI_RID_TX_CRYPT_KEY:
1249 			p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
1250 			p2ltv.wi_len = 2;
1251 			p2ltv.wi_val = ltv->wi_val;
1252 			ltv = &p2ltv;
1253 			break;
1254 		case WI_RID_DEFLT_CRYPT_KEYS:
1255 		    {
1256 			int error;
1257 			int keylen;
1258 			struct wi_ltv_str	ws;
1259 			struct wi_ltv_keys	*wk =
1260 			    (struct wi_ltv_keys *)ltv;
1261 
1262 			keylen = wk->wi_keys[sc->wi_tx_key].wi_keylen;
1263 
1264 			for (i = 0; i < 4; i++) {
1265 				bzero(&ws, sizeof(ws));
1266 				ws.wi_len = (keylen > 5) ? 8 : 4;
1267 				ws.wi_type = WI_RID_P2_CRYPT_KEY0 + i;
1268 				memcpy(ws.wi_str,
1269 				    &wk->wi_keys[i].wi_keydat, keylen);
1270 				error = wi_write_record(sc,
1271 				    (struct wi_ltv_gen *)&ws);
1272 				if (error)
1273 					return error;
1274 			}
1275 			return 0;
1276 		    }
1277 		case WI_RID_CNFAUTHMODE:
1278 			p2ltv.wi_type = WI_RID_CNFAUTHMODE;
1279 			p2ltv.wi_len = 2;
1280 			if (le16toh(ltv->wi_val) == 1)
1281 				p2ltv.wi_val = htole16(0x01);
1282 			else if (le16toh(ltv->wi_val) == 2)
1283 				p2ltv.wi_val = htole16(0x02);
1284 			ltv = &p2ltv;
1285 			break;
1286 		case WI_RID_ROAMING_MODE:
1287 			if (sc->sc_firmware_type == WI_INTERSIL)
1288 				break;
1289 			/* not supported */
1290 			return 0;
1291 		case WI_RID_MICROWAVE_OVEN:
1292 			/* not supported */
1293 			return 0;
1294 		}
1295 	} else {
1296 		/* LUCENT */
1297 		switch (ltv->wi_type) {
1298 		case WI_RID_TX_RATE:
1299 			switch (ltv->wi_val) {
1300 			case 1: ltv->wi_val = 1; break;  /* 1Mb/s fixed */
1301 			case 2: ltv->wi_val = 2; break;  /* 2Mb/s fixed */
1302 			case 3: ltv->wi_val = 3; break;  /* 11Mb/s auto */
1303 			case 5: ltv->wi_val = 4; break;  /* 5.5Mb/s fixed */
1304 			case 6: ltv->wi_val = 6; break;  /* 2Mb/s auto */
1305 			case 7: ltv->wi_val = 7; break;  /* 5.5Mb/s auto */
1306 			case 11: ltv->wi_val = 5; break; /* 11Mb/s fixed */
1307 			default: return EINVAL;
1308 			}
1309 		}
1310 	}
1311 
1312 	if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
1313 		return(EIO);
1314 
1315 	CSR_WRITE_2(sc, WI_DATA1, ltv->wi_len);
1316 	CSR_WRITE_2(sc, WI_DATA1, ltv->wi_type);
1317 
1318 	ptr = &ltv->wi_val;
1319 	for (i = 0; i < ltv->wi_len - 1; i++)
1320 		CSR_WRITE_2(sc, WI_DATA1, ptr[i]);
1321 
1322 	if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_WRITE, ltv->wi_type, 0, 0))
1323 		return(EIO);
1324 
1325 	return(0);
1326 }
1327 
1328 static int
1329 wi_seek(sc, id, off, chan)
1330 	struct wi_softc		*sc;
1331 	int			id, off, chan;
1332 {
1333 	int			i;
1334 	int			selreg, offreg;
1335 	int			status;
1336 
1337 	switch (chan) {
1338 	case WI_BAP0:
1339 		selreg = WI_SEL0;
1340 		offreg = WI_OFF0;
1341 		break;
1342 	case WI_BAP1:
1343 		selreg = WI_SEL1;
1344 		offreg = WI_OFF1;
1345 		break;
1346 	default:
1347 		device_printf(sc->dev, "invalid data path: %x\n", chan);
1348 		return(EIO);
1349 	}
1350 
1351 	CSR_WRITE_2(sc, selreg, id);
1352 	CSR_WRITE_2(sc, offreg, off);
1353 
1354 	for (i = 0; i < WI_TIMEOUT; i++) {
1355 		status = CSR_READ_2(sc, offreg);
1356 		if (!(status & (WI_OFF_BUSY|WI_OFF_ERR)))
1357 			break;
1358 		DELAY(WI_DELAY);
1359 	}
1360 
1361 	if (i == WI_TIMEOUT) {
1362 		device_printf(sc->dev, "timeout in wi_seek to %x/%x; last status %x\n",
1363 			id, off, status);
1364 		return(ETIMEDOUT);
1365 	}
1366 
1367 	return(0);
1368 }
1369 
1370 static int
1371 wi_read_data(sc, id, off, buf, len)
1372 	struct wi_softc		*sc;
1373 	int			id, off;
1374 	caddr_t			buf;
1375 	int			len;
1376 {
1377 	int			i;
1378 	u_int16_t		*ptr;
1379 
1380 	if (wi_seek(sc, id, off, WI_BAP1))
1381 		return(EIO);
1382 
1383 	ptr = (u_int16_t *)buf;
1384 	for (i = 0; i < len / 2; i++)
1385 		ptr[i] = CSR_READ_2(sc, WI_DATA1);
1386 
1387 	return(0);
1388 }
1389 
1390 /*
1391  * According to the comments in the HCF Light code, there is a bug in
1392  * the Hermes (or possibly in certain Hermes firmware revisions) where
1393  * the chip's internal autoincrement counter gets thrown off during
1394  * data writes: the autoincrement is missed, causing one data word to
1395  * be overwritten and subsequent words to be written to the wrong memory
1396  * locations. The end result is that we could end up transmitting bogus
1397  * frames without realizing it. The workaround for this is to write a
1398  * couple of extra guard words after the end of the transfer, then
1399  * attempt to read then back. If we fail to locate the guard words where
1400  * we expect them, we preform the transfer over again.
1401  */
1402 static int
1403 wi_write_data(sc, id, off, buf, len)
1404 	struct wi_softc		*sc;
1405 	int			id, off;
1406 	caddr_t			buf;
1407 	int			len;
1408 {
1409 	int			i;
1410 	u_int16_t		*ptr;
1411 #ifdef WI_HERMES_AUTOINC_WAR
1412 	int			retries;
1413 
1414 	retries = 512;
1415 again:
1416 #endif
1417 
1418 	if (wi_seek(sc, id, off, WI_BAP0))
1419 		return(EIO);
1420 
1421 	ptr = (u_int16_t *)buf;
1422 	for (i = 0; i < (len / 2); i++)
1423 		CSR_WRITE_2(sc, WI_DATA0, ptr[i]);
1424 
1425 #ifdef WI_HERMES_AUTOINC_WAR
1426 	CSR_WRITE_2(sc, WI_DATA0, 0x1234);
1427 	CSR_WRITE_2(sc, WI_DATA0, 0x5678);
1428 
1429 	if (wi_seek(sc, id, off + len, WI_BAP0))
1430 		return(EIO);
1431 
1432 	if (CSR_READ_2(sc, WI_DATA0) != 0x1234 ||
1433 	    CSR_READ_2(sc, WI_DATA0) != 0x5678) {
1434 		if (--retries >= 0)
1435 			goto again;
1436 		device_printf(sc->dev, "wi_write_data device timeout\n");
1437 		return (EIO);
1438 	}
1439 #endif
1440 
1441 	return(0);
1442 }
1443 
1444 /*
1445  * Allocate a region of memory inside the NIC and zero
1446  * it out.
1447  */
1448 static int
1449 wi_alloc_nicmem(sc, len, id)
1450 	struct wi_softc		*sc;
1451 	int			len;
1452 	int			*id;
1453 {
1454 	int			i;
1455 
1456 	if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len, 0, 0)) {
1457 		device_printf(sc->dev,
1458 		    "failed to allocate %d bytes on NIC\n", len);
1459 		return(ENOMEM);
1460 	}
1461 
1462 	for (i = 0; i < WI_TIMEOUT; i++) {
1463 		if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC)
1464 			break;
1465 		DELAY(WI_DELAY);
1466 	}
1467 
1468 	if (i == WI_TIMEOUT) {
1469 		device_printf(sc->dev, "time out allocating memory on card\n");
1470 		return(ETIMEDOUT);
1471 	}
1472 
1473 	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
1474 	*id = CSR_READ_2(sc, WI_ALLOC_FID);
1475 
1476 	if (wi_seek(sc, *id, 0, WI_BAP0)) {
1477 		device_printf(sc->dev, "seek failed while allocating memory on card\n");
1478 		return(EIO);
1479 	}
1480 
1481 	for (i = 0; i < len / 2; i++)
1482 		CSR_WRITE_2(sc, WI_DATA0, 0);
1483 
1484 	return(0);
1485 }
1486 
1487 static void
1488 wi_setmulti(sc)
1489 	struct wi_softc		*sc;
1490 {
1491 	struct ifnet		*ifp;
1492 	int			i = 0;
1493 	struct ifmultiaddr	*ifma;
1494 	struct wi_ltv_mcast	mcast;
1495 
1496 	ifp = &sc->arpcom.ac_if;
1497 
1498 	bzero((char *)&mcast, sizeof(mcast));
1499 
1500 	mcast.wi_type = WI_RID_MCAST_LIST;
1501 	mcast.wi_len = (3 * 16) + 1;
1502 
1503 	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
1504 		wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
1505 		return;
1506 	}
1507 
1508 #if defined(__DragonFly__) || __FreeBSD_version < 500000
1509 	LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1510 #else
1511 	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1512 #endif
1513 		if (ifma->ifma_addr->sa_family != AF_LINK)
1514 			continue;
1515 		if (i < 16) {
1516 			bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
1517 			    (char *)&mcast.wi_mcast[i], ETHER_ADDR_LEN);
1518 			i++;
1519 		} else {
1520 			bzero((char *)&mcast, sizeof(mcast));
1521 			break;
1522 		}
1523 	}
1524 
1525 	mcast.wi_len = (i * 3) + 1;
1526 	wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
1527 
1528 	return;
1529 }
1530 
1531 static void
1532 wi_setdef(sc, wreq)
1533 	struct wi_softc		*sc;
1534 	struct wi_req		*wreq;
1535 {
1536 	struct sockaddr_dl	*sdl;
1537 	struct ifaddr		*ifa;
1538 	struct ifnet		*ifp;
1539 
1540 	ifp = &sc->arpcom.ac_if;
1541 
1542 	switch(wreq->wi_type) {
1543 	case WI_RID_MAC_NODE:
1544 		ifa = ifaddr_byindex(ifp->if_index);
1545 		sdl = (struct sockaddr_dl *)ifa->ifa_addr;
1546 		bcopy((char *)&wreq->wi_val, (char *)&sc->arpcom.ac_enaddr,
1547 		   ETHER_ADDR_LEN);
1548 		bcopy((char *)&wreq->wi_val, LLADDR(sdl), ETHER_ADDR_LEN);
1549 		break;
1550 	case WI_RID_PORTTYPE:
1551 		sc->wi_ptype = le16toh(wreq->wi_val[0]);
1552 		break;
1553 	case WI_RID_TX_RATE:
1554 		sc->wi_tx_rate = le16toh(wreq->wi_val[0]);
1555 		break;
1556 	case WI_RID_MAX_DATALEN:
1557 		sc->wi_max_data_len = le16toh(wreq->wi_val[0]);
1558 		break;
1559 	case WI_RID_RTS_THRESH:
1560 		sc->wi_rts_thresh = le16toh(wreq->wi_val[0]);
1561 		break;
1562 	case WI_RID_SYSTEM_SCALE:
1563 		sc->wi_ap_density = le16toh(wreq->wi_val[0]);
1564 		break;
1565 	case WI_RID_CREATE_IBSS:
1566 		sc->wi_create_ibss = le16toh(wreq->wi_val[0]);
1567 		break;
1568 	case WI_RID_OWN_CHNL:
1569 		sc->wi_channel = le16toh(wreq->wi_val[0]);
1570 		break;
1571 	case WI_RID_NODENAME:
1572 		bzero(sc->wi_node_name, sizeof(sc->wi_node_name));
1573 		bcopy((char *)&wreq->wi_val[1], sc->wi_node_name, 30);
1574 		break;
1575 	case WI_RID_DESIRED_SSID:
1576 		bzero(sc->wi_net_name, sizeof(sc->wi_net_name));
1577 		bcopy((char *)&wreq->wi_val[1], sc->wi_net_name, 30);
1578 		break;
1579 	case WI_RID_OWN_SSID:
1580 		bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name));
1581 		bcopy((char *)&wreq->wi_val[1], sc->wi_ibss_name, 30);
1582 		break;
1583 	case WI_RID_PM_ENABLED:
1584 		sc->wi_pm_enabled = le16toh(wreq->wi_val[0]);
1585 		break;
1586 	case WI_RID_MICROWAVE_OVEN:
1587 		sc->wi_mor_enabled = le16toh(wreq->wi_val[0]);
1588 		break;
1589 	case WI_RID_MAX_SLEEP:
1590 		sc->wi_max_sleep = le16toh(wreq->wi_val[0]);
1591 		break;
1592 	case WI_RID_CNFAUTHMODE:
1593 		sc->wi_authtype = le16toh(wreq->wi_val[0]);
1594 		break;
1595 	case WI_RID_ROAMING_MODE:
1596 		sc->wi_roaming = le16toh(wreq->wi_val[0]);
1597 		break;
1598 	case WI_RID_ENCRYPTION:
1599 		sc->wi_use_wep = le16toh(wreq->wi_val[0]);
1600 		break;
1601 	case WI_RID_TX_CRYPT_KEY:
1602 		sc->wi_tx_key = le16toh(wreq->wi_val[0]);
1603 		break;
1604 	case WI_RID_DEFLT_CRYPT_KEYS:
1605 		bcopy((char *)wreq, (char *)&sc->wi_keys,
1606 		    sizeof(struct wi_ltv_keys));
1607 		break;
1608 	default:
1609 		break;
1610 	}
1611 
1612 	/* Reinitialize WaveLAN. */
1613 	wi_init(sc);
1614 
1615 	return;
1616 }
1617 
1618 static int
1619 wi_ioctl(ifp, command, data)
1620 	struct ifnet		*ifp;
1621 	u_long			command;
1622 	caddr_t			data;
1623 {
1624 	int			error = 0;
1625 	int			len;
1626 	u_int8_t		tmpkey[14];
1627 	char			tmpssid[IEEE80211_NWID_LEN];
1628 	struct wi_softc		*sc;
1629 	struct wi_req		wreq;
1630 	struct ifreq		*ifr;
1631 	struct ieee80211req	*ireq;
1632 	struct thread		*td = curthread;
1633 	int			s;
1634 
1635 	sc = ifp->if_softc;
1636 	WI_LOCK(sc, s);
1637 	ifr = (struct ifreq *)data;
1638 	ireq = (struct ieee80211req *)data;
1639 
1640 	if (sc->wi_gone) {
1641 		error = ENODEV;
1642 		goto out;
1643 	}
1644 
1645 	switch(command) {
1646 	case SIOCSIFADDR:
1647 	case SIOCGIFADDR:
1648 	case SIOCSIFMTU:
1649 		error = ether_ioctl(ifp, command, data);
1650 		break;
1651 	case SIOCSIFFLAGS:
1652 		/*
1653 		 * Can't do promisc and hostap at the same time.  If all that's
1654 		 * changing is the promisc flag, try to short-circuit a call to
1655 		 * wi_init() by just setting PROMISC in the hardware.
1656 		 */
1657 		if (ifp->if_flags & IFF_UP) {
1658 			if (sc->wi_ptype != WI_PORTTYPE_AP &&
1659 			    ifp->if_flags & IFF_RUNNING) {
1660 				if (ifp->if_flags & IFF_PROMISC &&
1661 				    !(sc->wi_if_flags & IFF_PROMISC)) {
1662 					WI_SETVAL(WI_RID_PROMISC, 1);
1663 				} else if (!(ifp->if_flags & IFF_PROMISC) &&
1664 				    sc->wi_if_flags & IFF_PROMISC) {
1665 					WI_SETVAL(WI_RID_PROMISC, 0);
1666 				} else {
1667 					wi_init(sc);
1668 				}
1669 			} else {
1670 				wi_init(sc);
1671 			}
1672 		} else {
1673 			if (ifp->if_flags & IFF_RUNNING) {
1674 				wi_stop(sc);
1675 			}
1676 		}
1677 		sc->wi_if_flags = ifp->if_flags;
1678 		error = 0;
1679 		break;
1680 	case SIOCSIFMEDIA:
1681 	case SIOCGIFMEDIA:
1682 		error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
1683 		break;
1684 	case SIOCADDMULTI:
1685 	case SIOCDELMULTI:
1686 		wi_setmulti(sc);
1687 		error = 0;
1688 		break;
1689 	case SIOCGWAVELAN:
1690 		error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1691 		if (error)
1692 			break;
1693 		if (wreq.wi_len > WI_MAX_DATALEN) {
1694 			error = EINVAL;
1695 			break;
1696 		}
1697 		/* Don't show WEP keys to non-root users. */
1698 		if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS && suser(td))
1699 			break;
1700 		if (wreq.wi_type == WI_RID_IFACE_STATS) {
1701 			bcopy((char *)&sc->wi_stats, (char *)&wreq.wi_val,
1702 			    sizeof(sc->wi_stats));
1703 			wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1;
1704 		} else if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS) {
1705 			bcopy((char *)&sc->wi_keys, (char *)&wreq,
1706 			    sizeof(struct wi_ltv_keys));
1707 		}
1708 #ifdef WICACHE
1709 		else if (wreq.wi_type == WI_RID_ZERO_CACHE) {
1710 			sc->wi_sigitems = sc->wi_nextitem = 0;
1711 		} else if (wreq.wi_type == WI_RID_READ_CACHE) {
1712 			char *pt = (char *)&wreq.wi_val;
1713 			bcopy((char *)&sc->wi_sigitems,
1714 			    (char *)pt, sizeof(int));
1715 			pt += (sizeof (int));
1716 			wreq.wi_len = sizeof(int) / 2;
1717 			bcopy((char *)&sc->wi_sigcache, (char *)pt,
1718 			    sizeof(struct wi_sigcache) * sc->wi_sigitems);
1719 			wreq.wi_len += ((sizeof(struct wi_sigcache) *
1720 			    sc->wi_sigitems) / 2) + 1;
1721 		}
1722 #endif
1723 		else if (wreq.wi_type == WI_RID_PROCFRAME) {
1724 			wreq.wi_len = 2;
1725 			wreq.wi_val[0] = sc->wi_procframe;
1726 		} else if (wreq.wi_type == WI_RID_PRISM2) {
1727 			wreq.wi_len = 2;
1728 			wreq.wi_val[0] = sc->sc_firmware_type != WI_LUCENT;
1729 		} else if (wreq.wi_type == WI_RID_SCAN_RES &&
1730 		    sc->sc_firmware_type == WI_LUCENT) {
1731 			memcpy((char *)wreq.wi_val, (char *)sc->wi_scanbuf,
1732 			    sc->wi_scanbuf_len * 2);
1733 			wreq.wi_len = sc->wi_scanbuf_len;
1734 		} else {
1735 			if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) {
1736 				error = EINVAL;
1737 				break;
1738 			}
1739 		}
1740 		error = copyout(&wreq, ifr->ifr_data, sizeof(wreq));
1741 		break;
1742 	case SIOCSWAVELAN:
1743 		if ((error = suser(td)))
1744 			goto out;
1745 		error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1746 		if (error)
1747 			break;
1748 		if (wreq.wi_len > WI_MAX_DATALEN) {
1749 			error = EINVAL;
1750 			break;
1751 		}
1752 		if (wreq.wi_type == WI_RID_IFACE_STATS) {
1753 			error = EINVAL;
1754 			break;
1755 		} else if (wreq.wi_type == WI_RID_MGMT_XMIT) {
1756 			error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val,
1757 			    wreq.wi_len);
1758 		} else if (wreq.wi_type == WI_RID_PROCFRAME) {
1759 			sc->wi_procframe = wreq.wi_val[0];
1760 		/*
1761 		 * if we're getting a scan request from a wavelan card
1762 		 * (non-prism2), send out a cmd_inquire to the card to scan
1763 		 * results for the scan will be received through the info
1764 		 * interrupt handler. otherwise the scan request can be
1765 		 * directly handled by a prism2 card's rid interface.
1766 		 */
1767 		} else if (wreq.wi_type == WI_RID_SCAN_REQ &&
1768 		    sc->sc_firmware_type == WI_LUCENT) {
1769 			wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0);
1770 		} else {
1771 			error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
1772 			if (!error)
1773 				wi_setdef(sc, &wreq);
1774 		}
1775 		break;
1776 	case SIOCGPRISM2DEBUG:
1777 		error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1778 		if (error)
1779 			break;
1780 		if (!(ifp->if_flags & IFF_RUNNING) ||
1781 		    sc->sc_firmware_type == WI_LUCENT) {
1782 			error = EIO;
1783 			break;
1784 		}
1785 		error = wi_get_debug(sc, &wreq);
1786 		if (error == 0)
1787 			error = copyout(&wreq, ifr->ifr_data, sizeof(wreq));
1788 		break;
1789 	case SIOCSPRISM2DEBUG:
1790 		if ((error = suser(td)))
1791 			goto out;
1792 		error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1793 		if (error)
1794 			break;
1795 		error = wi_set_debug(sc, &wreq);
1796 		break;
1797 	case SIOCG80211:
1798 		switch(ireq->i_type) {
1799 		case IEEE80211_IOC_SSID:
1800 			if(ireq->i_val == -1) {
1801 				bzero(tmpssid, IEEE80211_NWID_LEN);
1802 				error = wi_get_cur_ssid(sc, tmpssid, &len);
1803 				if (error != 0)
1804 					break;
1805 				error = copyout(tmpssid, ireq->i_data,
1806 					IEEE80211_NWID_LEN);
1807 				ireq->i_len = len;
1808 			} else if (ireq->i_val == 0) {
1809 				error = copyout(sc->wi_net_name,
1810 				    ireq->i_data,
1811 				    IEEE80211_NWID_LEN);
1812 				ireq->i_len = IEEE80211_NWID_LEN;
1813 			} else
1814 				error = EINVAL;
1815 			break;
1816 		case IEEE80211_IOC_NUMSSIDS:
1817 			ireq->i_val = 1;
1818 			break;
1819 		case IEEE80211_IOC_WEP:
1820 			if(!sc->wi_has_wep) {
1821 				ireq->i_val = IEEE80211_WEP_NOSUP;
1822 			} else {
1823 				if(sc->wi_use_wep) {
1824 					ireq->i_val =
1825 					    IEEE80211_WEP_MIXED;
1826 				} else {
1827 					ireq->i_val =
1828 					    IEEE80211_WEP_OFF;
1829 				}
1830 			}
1831 			break;
1832 		case IEEE80211_IOC_WEPKEY:
1833 			if(!sc->wi_has_wep ||
1834 			    ireq->i_val < 0 || ireq->i_val > 3) {
1835 				error = EINVAL;
1836 				break;
1837 			}
1838 			len = sc->wi_keys.wi_keys[ireq->i_val].wi_keylen;
1839 			if (suser(td))
1840 				bcopy(sc->wi_keys.wi_keys[ireq->i_val].wi_keydat,
1841 				    tmpkey, len);
1842 			else
1843 				bzero(tmpkey, len);
1844 
1845 			ireq->i_len = len;
1846 			error = copyout(tmpkey, ireq->i_data, len);
1847 
1848 			break;
1849 		case IEEE80211_IOC_NUMWEPKEYS:
1850 			if(!sc->wi_has_wep)
1851 				error = EINVAL;
1852 			else
1853 				ireq->i_val = 4;
1854 			break;
1855 		case IEEE80211_IOC_WEPTXKEY:
1856 			if(!sc->wi_has_wep)
1857 				error = EINVAL;
1858 			else
1859 				ireq->i_val = sc->wi_tx_key;
1860 			break;
1861 		case IEEE80211_IOC_AUTHMODE:
1862 			ireq->i_val = sc->wi_authmode;
1863 			break;
1864 		case IEEE80211_IOC_STATIONNAME:
1865 			error = copyout(sc->wi_node_name,
1866 			    ireq->i_data, IEEE80211_NWID_LEN);
1867 			ireq->i_len = IEEE80211_NWID_LEN;
1868 			break;
1869 		case IEEE80211_IOC_CHANNEL:
1870 			wreq.wi_type = WI_RID_CURRENT_CHAN;
1871 			wreq.wi_len = WI_MAX_DATALEN;
1872 			if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq))
1873 				error = EINVAL;
1874 			else {
1875 				ireq->i_val = wreq.wi_val[0];
1876 			}
1877 			break;
1878 		case IEEE80211_IOC_POWERSAVE:
1879 			if(sc->wi_pm_enabled)
1880 				ireq->i_val = IEEE80211_POWERSAVE_ON;
1881 			else
1882 				ireq->i_val = IEEE80211_POWERSAVE_OFF;
1883 			break;
1884 		case IEEE80211_IOC_POWERSAVESLEEP:
1885 			ireq->i_val = sc->wi_max_sleep;
1886 			break;
1887 		default:
1888 			error = EINVAL;
1889 		}
1890 		break;
1891 	case SIOCS80211:
1892 		if ((error = suser(td)))
1893 			goto out;
1894 		switch(ireq->i_type) {
1895 		case IEEE80211_IOC_SSID:
1896 			if (ireq->i_val != 0 ||
1897 			    ireq->i_len > IEEE80211_NWID_LEN) {
1898 				error = EINVAL;
1899 				break;
1900 			}
1901 			/* We set both of them */
1902 			bzero(sc->wi_net_name, IEEE80211_NWID_LEN);
1903 			error = copyin(ireq->i_data,
1904 			    sc->wi_net_name, ireq->i_len);
1905 			bcopy(sc->wi_net_name, sc->wi_ibss_name, IEEE80211_NWID_LEN);
1906 			break;
1907 		case IEEE80211_IOC_WEP:
1908 			/*
1909 			 * These cards only support one mode so
1910 			 * we just turn wep on what ever is
1911 			 * passed in if it's not OFF.
1912 			 */
1913 			if (ireq->i_val == IEEE80211_WEP_OFF) {
1914 				sc->wi_use_wep = 0;
1915 			} else {
1916 				sc->wi_use_wep = 1;
1917 			}
1918 			break;
1919 		case IEEE80211_IOC_WEPKEY:
1920 			if (ireq->i_val < 0 || ireq->i_val > 3 ||
1921 				ireq->i_len > 13) {
1922 				error = EINVAL;
1923 				break;
1924 			}
1925 			bzero(sc->wi_keys.wi_keys[ireq->i_val].wi_keydat, 13);
1926 			error = copyin(ireq->i_data,
1927 			    sc->wi_keys.wi_keys[ireq->i_val].wi_keydat,
1928 			    ireq->i_len);
1929 			if(error)
1930 				break;
1931 			sc->wi_keys.wi_keys[ireq->i_val].wi_keylen =
1932 				    ireq->i_len;
1933 			break;
1934 		case IEEE80211_IOC_WEPTXKEY:
1935 			if (ireq->i_val < 0 || ireq->i_val > 3) {
1936 				error = EINVAL;
1937 				break;
1938 			}
1939 			sc->wi_tx_key = ireq->i_val;
1940 			break;
1941 		case IEEE80211_IOC_AUTHMODE:
1942 			sc->wi_authmode = ireq->i_val;
1943 			break;
1944 		case IEEE80211_IOC_STATIONNAME:
1945 			if (ireq->i_len > 32) {
1946 				error = EINVAL;
1947 				break;
1948 			}
1949 			bzero(sc->wi_node_name, 32);
1950 			error = copyin(ireq->i_data,
1951 			    sc->wi_node_name, ireq->i_len);
1952 			break;
1953 		case IEEE80211_IOC_CHANNEL:
1954 			/*
1955 			 * The actual range is 1-14, but if you
1956 			 * set it to 0 you get the default. So
1957 			 * we let that work too.
1958 			 */
1959 			if (ireq->i_val < 0 || ireq->i_val > 14) {
1960 				error = EINVAL;
1961 				break;
1962 			}
1963 			sc->wi_channel = ireq->i_val;
1964 			break;
1965 		case IEEE80211_IOC_POWERSAVE:
1966 			switch (ireq->i_val) {
1967 			case IEEE80211_POWERSAVE_OFF:
1968 				sc->wi_pm_enabled = 0;
1969 				break;
1970 			case IEEE80211_POWERSAVE_ON:
1971 				sc->wi_pm_enabled = 1;
1972 				break;
1973 			default:
1974 				error = EINVAL;
1975 				break;
1976 			}
1977 			break;
1978 		case IEEE80211_IOC_POWERSAVESLEEP:
1979 			if (ireq->i_val < 0) {
1980 				error = EINVAL;
1981 				break;
1982 			}
1983 			sc->wi_max_sleep = ireq->i_val;
1984 			break;
1985 		default:
1986 			error = EINVAL;
1987 			break;
1988 		}
1989 
1990 		/* Reinitialize WaveLAN. */
1991 		wi_init(sc);
1992 
1993 	break;
1994 	case SIOCHOSTAP_ADD:
1995 	case SIOCHOSTAP_DEL:
1996 	case SIOCHOSTAP_GET:
1997 	case SIOCHOSTAP_GETALL:
1998 	case SIOCHOSTAP_GFLAGS:
1999 	case SIOCHOSTAP_SFLAGS:
2000 		/* Send all Host AP specific ioctl's to Host AP code. */
2001 		error = wihap_ioctl(sc, command, data);
2002 		break;
2003 	default:
2004 		error = EINVAL;
2005 		break;
2006 	}
2007 out:
2008 	WI_UNLOCK(sc, s);
2009 
2010 	return(error);
2011 }
2012 
2013 static void
2014 wi_init(xsc)
2015 	void			*xsc;
2016 {
2017 	struct wi_softc		*sc = xsc;
2018 	struct ifnet		*ifp = &sc->arpcom.ac_if;
2019 	struct wi_ltv_macaddr	mac;
2020 	int			id = 0;
2021 	int			s;
2022 
2023 	WI_LOCK(sc, s);
2024 
2025 	if (sc->wi_gone) {
2026 		WI_UNLOCK(sc, s);
2027 		return;
2028 	}
2029 
2030 	if (ifp->if_flags & IFF_RUNNING)
2031 		wi_stop(sc);
2032 
2033 	wi_reset(sc);
2034 
2035 	/* Program max data length. */
2036 	WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len);
2037 
2038 	/* Set the port type. */
2039 	WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype);
2040 
2041 	/* Enable/disable IBSS creation. */
2042 	WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss);
2043 
2044 	/* Program the RTS/CTS threshold. */
2045 	WI_SETVAL(WI_RID_RTS_THRESH, sc->wi_rts_thresh);
2046 
2047 	/* Program the TX rate */
2048 	WI_SETVAL(WI_RID_TX_RATE, sc->wi_tx_rate);
2049 
2050 	/* Access point density */
2051 	WI_SETVAL(WI_RID_SYSTEM_SCALE, sc->wi_ap_density);
2052 
2053 	/* Power Management Enabled */
2054 	WI_SETVAL(WI_RID_PM_ENABLED, sc->wi_pm_enabled);
2055 
2056 	/* Power Managment Max Sleep */
2057 	WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep);
2058 
2059 	/* Roaming type */
2060 	WI_SETVAL(WI_RID_ROAMING_MODE, sc->wi_roaming);
2061 
2062 	/* Specify the IBSS name */
2063 	WI_SETSTR(WI_RID_OWN_SSID, sc->wi_ibss_name);
2064 
2065 	/* Specify the network name */
2066 	WI_SETSTR(WI_RID_DESIRED_SSID, sc->wi_net_name);
2067 
2068 	/* Specify the frequency to use */
2069 	WI_SETVAL(WI_RID_OWN_CHNL, sc->wi_channel);
2070 
2071 	/* Program the nodename. */
2072 	WI_SETSTR(WI_RID_NODENAME, sc->wi_node_name);
2073 
2074 	/* Specify the authentication mode. */
2075 	WI_SETVAL(WI_RID_CNFAUTHMODE, sc->wi_authmode);
2076 
2077 	/* Set our MAC address. */
2078 	mac.wi_len = 4;
2079 	mac.wi_type = WI_RID_MAC_NODE;
2080 	bcopy((char *)&sc->arpcom.ac_enaddr,
2081 	   (char *)&mac.wi_mac_addr, ETHER_ADDR_LEN);
2082 	wi_write_record(sc, (struct wi_ltv_gen *)&mac);
2083 
2084 	/*
2085 	 * Initialize promisc mode.
2086 	 *      Being in the Host-AP mode causes
2087 	 *      great deal of pain if promisc mode is set.
2088 	 *      Therefore we avoid confusing the firmware
2089 	 *      and always reset promisc mode in Host-AP regime,
2090 	 *      it shows us all the packets anyway.
2091 	 */
2092 	if (sc->wi_ptype != WI_PORTTYPE_AP && ifp->if_flags & IFF_PROMISC)
2093 		WI_SETVAL(WI_RID_PROMISC, 1);
2094 	else
2095 		WI_SETVAL(WI_RID_PROMISC, 0);
2096 
2097 	/* Configure WEP. */
2098 	if (sc->wi_has_wep) {
2099 		WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep);
2100 		WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key);
2101 		sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1;
2102 		sc->wi_keys.wi_type = WI_RID_DEFLT_CRYPT_KEYS;
2103 		wi_write_record(sc, (struct wi_ltv_gen *)&sc->wi_keys);
2104 		if (sc->sc_firmware_type != WI_LUCENT && sc->wi_use_wep) {
2105 			/*
2106 			 * ONLY HWB3163 EVAL-CARD Firmware version
2107 			 * less than 0.8 variant2
2108 			 *
2109 			 * If promiscuous mode disable, Prism2 chip
2110 			 * does not work with WEP.
2111 			 * It is under investigation for details.
2112 			 * (ichiro@netbsd.org)
2113 			 *
2114 			 * And make sure that we don't need to do it
2115 			 * in hostap mode, since it interferes with
2116 			 * the above hostap workaround.
2117 			 */
2118 			if (sc->wi_ptype != WI_PORTTYPE_AP &&
2119 			    sc->sc_firmware_type == WI_INTERSIL &&
2120 			    sc->sc_sta_firmware_ver < 802 ) {
2121 				/* firm ver < 0.8 variant 2 */
2122 				WI_SETVAL(WI_RID_PROMISC, 1);
2123 			}
2124 			WI_SETVAL(WI_RID_CNFAUTHMODE, sc->wi_authtype);
2125 		}
2126 	}
2127 
2128 	/* Set multicast filter. */
2129 	wi_setmulti(sc);
2130 
2131 	/* Enable desired port */
2132 	wi_cmd(sc, WI_CMD_ENABLE | sc->wi_portnum, 0, 0, 0);
2133 
2134 	if (wi_alloc_nicmem(sc, ETHER_MAX_LEN + sizeof(struct wi_frame) + 8, &id))
2135 		device_printf(sc->dev, "tx buffer allocation failed\n");
2136 	sc->wi_tx_data_id = id;
2137 
2138 	if (wi_alloc_nicmem(sc, ETHER_MAX_LEN + sizeof(struct wi_frame) + 8, &id))
2139 		device_printf(sc->dev, "mgmt. buffer allocation failed\n");
2140 	sc->wi_tx_mgmt_id = id;
2141 
2142 	/* enable interrupts */
2143 	CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
2144 
2145 	wihap_init(sc);
2146 
2147 	ifp->if_flags |= IFF_RUNNING;
2148 	ifp->if_flags &= ~IFF_OACTIVE;
2149 
2150 	sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60);
2151 	WI_UNLOCK(sc, s);
2152 
2153 	return;
2154 }
2155 
2156 #define RC4STATE 256
2157 #define RC4KEYLEN 16
2158 #define RC4SWAP(x,y) \
2159     do { u_int8_t t = state[x]; state[x] = state[y]; state[y] = t; } while(0)
2160 
2161 static void
2162 wi_do_hostencrypt(struct wi_softc *sc, caddr_t buf, int len)
2163 {
2164 	u_int32_t i, crc, klen;
2165 	u_int8_t state[RC4STATE], key[RC4KEYLEN];
2166 	u_int8_t x, y, *dat;
2167 
2168 	if (!sc->wi_icv_flag) {
2169 		sc->wi_icv = arc4random();
2170 		sc->wi_icv_flag++;
2171         } else
2172 		sc->wi_icv++;
2173 	/*
2174 	 * Skip 'bad' IVs from Fluhrer/Mantin/Shamir:
2175 	 * (B, 255, N) with 3 <= B < 8
2176 	 */
2177 	if (sc->wi_icv >= 0x03ff00 &&
2178             (sc->wi_icv & 0xf8ff00) == 0x00ff00)
2179                 sc->wi_icv += 0x000100;
2180 
2181 	/* prepend 24bit IV to tx key, byte order does not matter */
2182 	key[0] = sc->wi_icv >> 16;
2183 	key[1] = sc->wi_icv >> 8;
2184 	key[2] = sc->wi_icv;
2185 
2186 	klen = sc->wi_keys.wi_keys[sc->wi_tx_key].wi_keylen +
2187 	    IEEE80211_WEP_IVLEN;
2188 	klen = (klen >= RC4KEYLEN) ? RC4KEYLEN : RC4KEYLEN/2;
2189 	bcopy((char *)&sc->wi_keys.wi_keys[sc->wi_tx_key].wi_keydat,
2190 	    (char *)key + IEEE80211_WEP_IVLEN, klen - IEEE80211_WEP_IVLEN);
2191 
2192 	/* rc4 keysetup */
2193 	x = y = 0;
2194 	for (i = 0; i < RC4STATE; i++)
2195 		state[i] = i;
2196 	for (i = 0; i < RC4STATE; i++) {
2197 		y = (key[x] + state[i] + y) % RC4STATE;
2198 		RC4SWAP(i, y);
2199 		x = (x + 1) % klen;
2200 	}
2201 
2202 	/* output: IV, tx keyid, rc4(data), rc4(crc32(data)) */
2203 	dat = buf;
2204 	dat[0] = key[0];
2205 	dat[1] = key[1];
2206 	dat[2] = key[2];
2207 	dat[3] = sc->wi_tx_key << 6;		/* pad and keyid */
2208 	dat += 4;
2209 
2210 	/* compute rc4 over data, crc32 over data */
2211 	crc = ~0;
2212 	x = y = 0;
2213 	for (i = 0; i < len; i++) {
2214 		x = (x + 1) % RC4STATE;
2215 		y = (state[x] + y) % RC4STATE;
2216 		RC4SWAP(x, y);
2217 		crc = crc32_tab[(crc ^ dat[i]) & 0xff] ^ (crc >> 8);
2218 		dat[i] ^= state[(state[x] + state[y]) % RC4STATE];
2219 	}
2220 	crc = ~crc;
2221 	dat += len;
2222 
2223 	/* append little-endian crc32 and encrypt */
2224 	dat[0] = crc;
2225 	dat[1] = crc >> 8;
2226 	dat[2] = crc >> 16;
2227 	dat[3] = crc >> 24;
2228 	for (i = 0; i < IEEE80211_WEP_CRCLEN; i++) {
2229 		x = (x + 1) % RC4STATE;
2230 		y = (state[x] + y) % RC4STATE;
2231 		RC4SWAP(x, y);
2232 		dat[i] ^= state[(state[x] + state[y]) % RC4STATE];
2233 	}
2234 }
2235 
2236 static void
2237 wi_start(ifp)
2238 	struct ifnet		*ifp;
2239 {
2240 	struct wi_softc		*sc;
2241 	struct mbuf		*m0;
2242 	struct wi_frame		tx_frame;
2243 	struct ether_header	*eh;
2244 	int			id;
2245 	int			s;
2246 
2247 	sc = ifp->if_softc;
2248 	WI_LOCK(sc, s);
2249 
2250 	if (sc->wi_gone) {
2251 		WI_UNLOCK(sc, s);
2252 		return;
2253 	}
2254 
2255 	if (ifp->if_flags & IFF_OACTIVE) {
2256 		WI_UNLOCK(sc, s);
2257 		return;
2258 	}
2259 
2260 nextpkt:
2261 	IF_DEQUEUE(&ifp->if_snd, m0);
2262 	if (m0 == NULL) {
2263 		WI_UNLOCK(sc, s);
2264 		return;
2265 	}
2266 
2267 	bzero((char *)&tx_frame, sizeof(tx_frame));
2268 	tx_frame.wi_frame_ctl = htole16(WI_FTYPE_DATA);
2269 	id = sc->wi_tx_data_id;
2270 	eh = mtod(m0, struct ether_header *);
2271 
2272 	if (sc->wi_ptype == WI_PORTTYPE_AP) {
2273 		if (!wihap_check_tx(&sc->wi_hostap_info,
2274 		    eh->ether_dhost, &tx_frame.wi_tx_rate)) {
2275 			if (ifp->if_flags & IFF_DEBUG)
2276 				printf("wi_start: dropping unassoc "
2277 				       "dst %6D\n", eh->ether_dhost, ":");
2278 			m_freem(m0);
2279 			goto nextpkt;
2280 		}
2281 	}
2282 	/*
2283 	 * Use RFC1042 encoding for IP and ARP datagrams,
2284 	 * 802.3 for anything else.
2285 	 */
2286 	if (ntohs(eh->ether_type) > ETHER_MAX_LEN) {
2287 		bcopy((char *)&eh->ether_dhost,
2288 		    (char *)&tx_frame.wi_addr1, ETHER_ADDR_LEN);
2289 		if (sc->wi_ptype == WI_PORTTYPE_AP) {
2290 			tx_frame.wi_tx_ctl = WI_ENC_TX_MGMT; /* XXX */
2291 			tx_frame.wi_frame_ctl |= WI_FCTL_FROMDS;
2292 			if (sc->wi_use_wep)
2293 				tx_frame.wi_frame_ctl |= WI_FCTL_WEP;
2294 			bcopy((char *)&sc->arpcom.ac_enaddr,
2295 			      (char *)&tx_frame.wi_addr2, ETHER_ADDR_LEN);
2296 			bcopy((char *)&eh->ether_shost,
2297 			      (char *)&tx_frame.wi_addr3, ETHER_ADDR_LEN);
2298 		}
2299 		else
2300 			bcopy((char *)&eh->ether_shost,
2301 			    (char *)&tx_frame.wi_addr2, ETHER_ADDR_LEN);
2302 		bcopy((char *)&eh->ether_dhost,
2303 		    (char *)&tx_frame.wi_dst_addr, ETHER_ADDR_LEN);
2304 		bcopy((char *)&eh->ether_shost,
2305 		    (char *)&tx_frame.wi_src_addr, ETHER_ADDR_LEN);
2306 
2307 		tx_frame.wi_dat_len = m0->m_pkthdr.len - WI_SNAPHDR_LEN;
2308 		tx_frame.wi_dat[0] = htons(WI_SNAP_WORD0);
2309 		tx_frame.wi_dat[1] = htons(WI_SNAP_WORD1);
2310 		tx_frame.wi_len = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN);
2311 		tx_frame.wi_type = eh->ether_type;
2312 
2313 		if (sc->wi_ptype == WI_PORTTYPE_AP && sc->wi_use_wep) {
2314 			/* Do host encryption. */
2315 			bcopy(&tx_frame.wi_dat[0], &sc->wi_txbuf[4], 8);
2316 			m_copydata(m0, sizeof(struct ether_header),
2317 			    m0->m_pkthdr.len - sizeof(struct ether_header),
2318 			    (caddr_t)&sc->wi_txbuf[12]);
2319 			wi_do_hostencrypt(sc, &sc->wi_txbuf[0],
2320 			    tx_frame.wi_dat_len);
2321 			tx_frame.wi_dat_len += IEEE80211_WEP_IVLEN +
2322 			    IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN;
2323 			wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
2324 			    sizeof(struct wi_frame));
2325 			wi_write_data(sc, id, WI_802_11_OFFSET_RAW,
2326 			    (caddr_t)&sc->wi_txbuf, (m0->m_pkthdr.len -
2327 			    sizeof(struct ether_header)) + 18);
2328 		} else {
2329 			m_copydata(m0, sizeof(struct ether_header),
2330 			    m0->m_pkthdr.len - sizeof(struct ether_header),
2331 			    (caddr_t)&sc->wi_txbuf);
2332 			wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
2333 			    sizeof(struct wi_frame));
2334 			wi_write_data(sc, id, WI_802_11_OFFSET,
2335 			    (caddr_t)&sc->wi_txbuf, (m0->m_pkthdr.len -
2336 			    sizeof(struct ether_header)) + 2);
2337 		}
2338 	} else {
2339 		tx_frame.wi_dat_len = m0->m_pkthdr.len;
2340 
2341 		if (sc->wi_ptype == WI_PORTTYPE_AP && sc->wi_use_wep) {
2342 			/* Do host encryption. */
2343 			printf( "XXX: host encrypt not implemented for 802.3\n" );
2344 		} else {
2345 			eh->ether_type = htons(m0->m_pkthdr.len -
2346 			    WI_SNAPHDR_LEN);
2347 			m_copydata(m0, 0, m0->m_pkthdr.len,
2348 			    (caddr_t)&sc->wi_txbuf);
2349 
2350 			wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
2351 			    sizeof(struct wi_frame));
2352 			wi_write_data(sc, id, WI_802_3_OFFSET,
2353 			    (caddr_t)&sc->wi_txbuf, m0->m_pkthdr.len + 2);
2354 		}
2355 	}
2356 
2357 	/*
2358 	 * If there's a BPF listner, bounce a copy of
2359  	 * this frame to him. Also, don't send this to the bpf sniffer
2360  	 * if we're in procframe or monitor sniffing mode.
2361 	 */
2362  	if (!(sc->wi_procframe || sc->wi_debug.wi_monitor) && ifp->if_bpf)
2363 		bpf_mtap(ifp, m0);
2364 
2365 	m_freem(m0);
2366 
2367 	if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id, 0, 0))
2368 		device_printf(sc->dev, "xmit failed\n");
2369 
2370 	ifp->if_flags |= IFF_OACTIVE;
2371 
2372 	/*
2373 	 * Set a timeout in case the chip goes out to lunch.
2374 	 */
2375 	ifp->if_timer = 5;
2376 
2377 	WI_UNLOCK(sc, s);
2378 	return;
2379 }
2380 
2381 int
2382 wi_mgmt_xmit(sc, data, len)
2383 	struct wi_softc		*sc;
2384 	caddr_t			data;
2385 	int			len;
2386 {
2387 	struct wi_frame		tx_frame;
2388 	int			id;
2389 	struct wi_80211_hdr	*hdr;
2390 	caddr_t			dptr;
2391 
2392 	if (sc->wi_gone)
2393 		return(ENODEV);
2394 
2395 	hdr = (struct wi_80211_hdr *)data;
2396 	dptr = data + sizeof(struct wi_80211_hdr);
2397 
2398 	bzero((char *)&tx_frame, sizeof(tx_frame));
2399 	id = sc->wi_tx_mgmt_id;
2400 
2401 	bcopy((char *)hdr, (char *)&tx_frame.wi_frame_ctl,
2402 	   sizeof(struct wi_80211_hdr));
2403 
2404 	tx_frame.wi_tx_ctl = WI_ENC_TX_MGMT;
2405 	tx_frame.wi_dat_len = len - sizeof(struct wi_80211_hdr);
2406 	tx_frame.wi_len = htons(tx_frame.wi_dat_len);
2407 
2408 	wi_write_data(sc, id, 0, (caddr_t)&tx_frame, sizeof(struct wi_frame));
2409 	wi_write_data(sc, id, WI_802_11_OFFSET_RAW, dptr,
2410 	    len - sizeof(struct wi_80211_hdr) + 2);
2411 
2412 	if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id, 0, 0)) {
2413 		device_printf(sc->dev, "xmit failed\n");
2414 		return(EIO);
2415 	}
2416 
2417 	return(0);
2418 }
2419 
2420 static void
2421 wi_stop(sc)
2422 	struct wi_softc		*sc;
2423 {
2424 	struct ifnet		*ifp;
2425 	int			s;
2426 
2427 	WI_LOCK(sc, s);
2428 
2429 	if (sc->wi_gone) {
2430 		WI_UNLOCK(sc, s);
2431 		return;
2432 	}
2433 
2434 	wihap_shutdown(sc);
2435 
2436 	ifp = &sc->arpcom.ac_if;
2437 
2438 	/*
2439 	 * If the card is gone and the memory port isn't mapped, we will
2440 	 * (hopefully) get 0xffff back from the status read, which is not
2441 	 * a valid status value.
2442 	 */
2443 	if (CSR_READ_2(sc, WI_STATUS) != 0xffff) {
2444 		CSR_WRITE_2(sc, WI_INT_EN, 0);
2445 		wi_cmd(sc, WI_CMD_DISABLE|sc->wi_portnum, 0, 0, 0);
2446 	}
2447 
2448 	untimeout(wi_inquire, sc, sc->wi_stat_ch);
2449 
2450 	ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
2451 
2452 	WI_UNLOCK(sc, s);
2453 	return;
2454 }
2455 
2456 static void
2457 wi_watchdog(ifp)
2458 	struct ifnet		*ifp;
2459 {
2460 	struct wi_softc		*sc;
2461 
2462 	sc = ifp->if_softc;
2463 
2464 	device_printf(sc->dev, "watchdog timeout\n");
2465 
2466 	wi_init(sc);
2467 
2468 	ifp->if_oerrors++;
2469 
2470 	return;
2471 }
2472 
2473 int
2474 wi_alloc(dev, rid)
2475 	device_t		dev;
2476 	int			rid;
2477 {
2478 	struct wi_softc		*sc = device_get_softc(dev);
2479 
2480 	if (sc->wi_bus_type != WI_BUS_PCI_NATIVE) {
2481 		sc->iobase_rid = rid;
2482 		sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT,
2483 		    &sc->iobase_rid, 0, ~0, (1 << 6),
2484 		    rman_make_alignment_flags(1 << 6) | RF_ACTIVE);
2485 		if (!sc->iobase) {
2486 			device_printf(dev, "No I/O space?!\n");
2487 			return (ENXIO);
2488 		}
2489 
2490 		sc->wi_io_addr = rman_get_start(sc->iobase);
2491 		sc->wi_btag = rman_get_bustag(sc->iobase);
2492 		sc->wi_bhandle = rman_get_bushandle(sc->iobase);
2493 	} else {
2494 		sc->mem_rid = rid;
2495 		sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY,
2496 		    &sc->mem_rid, 0, ~0, 1, RF_ACTIVE);
2497 
2498 		if (!sc->mem) {
2499 			device_printf(dev, "No Mem space on prism2.5?\n");
2500 			return (ENXIO);
2501 		}
2502 
2503 		sc->wi_btag = rman_get_bustag(sc->mem);
2504 		sc->wi_bhandle = rman_get_bushandle(sc->mem);
2505 	}
2506 
2507 
2508 	sc->irq_rid = 0;
2509 	sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid,
2510 	    0, ~0, 1, RF_ACTIVE |
2511 	    ((sc->wi_bus_type == WI_BUS_PCCARD) ? 0 : RF_SHAREABLE));
2512 
2513 	if (!sc->irq) {
2514 		wi_free(dev);
2515 		device_printf(dev, "No irq?!\n");
2516 		return (ENXIO);
2517 	}
2518 
2519 	sc->dev = dev;
2520 	sc->wi_unit = device_get_unit(dev);
2521 
2522 	return (0);
2523 }
2524 
2525 void
2526 wi_free(dev)
2527 	device_t		dev;
2528 {
2529 	struct wi_softc		*sc = device_get_softc(dev);
2530 
2531 	if (sc->iobase != NULL) {
2532 		bus_release_resource(dev, SYS_RES_IOPORT, sc->iobase_rid, sc->iobase);
2533 		sc->iobase = NULL;
2534 	}
2535 	if (sc->irq != NULL) {
2536 		bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
2537 		sc->irq = NULL;
2538 	}
2539 	if (sc->mem != NULL) {
2540 		bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
2541 		sc->mem = NULL;
2542 	}
2543 
2544 	return;
2545 }
2546 
2547 void
2548 wi_shutdown(dev)
2549 	device_t		dev;
2550 {
2551 	struct wi_softc		*sc;
2552 
2553 	sc = device_get_softc(dev);
2554 	wi_stop(sc);
2555 
2556 	return;
2557 }
2558 
2559 #ifdef WICACHE
2560 /* wavelan signal strength cache code.
2561  * store signal/noise/quality on per MAC src basis in
2562  * a small fixed cache.  The cache wraps if > MAX slots
2563  * used.  The cache may be zeroed out to start over.
2564  * Two simple filters exist to reduce computation:
2565  * 1. ip only (literally 0x800) which may be used
2566  * to ignore some packets.  It defaults to ip only.
2567  * it could be used to focus on broadcast, non-IP 802.11 beacons.
2568  * 2. multicast/broadcast only.  This may be used to
2569  * ignore unicast packets and only cache signal strength
2570  * for multicast/broadcast packets (beacons); e.g., Mobile-IP
2571  * beacons and not unicast traffic.
2572  *
2573  * The cache stores (MAC src(index), IP src (major clue), signal,
2574  *	quality, noise)
2575  *
2576  * No apologies for storing IP src here.  It's easy and saves much
2577  * trouble elsewhere.  The cache is assumed to be INET dependent,
2578  * although it need not be.
2579  */
2580 
2581 #ifdef documentation
2582 
2583 int wi_sigitems;                                /* number of cached entries */
2584 struct wi_sigcache wi_sigcache[MAXWICACHE];  /*  array of cache entries */
2585 int wi_nextitem;                                /*  index/# of entries */
2586 
2587 
2588 #endif
2589 
2590 /* control variables for cache filtering.  Basic idea is
2591  * to reduce cost (e.g., to only Mobile-IP agent beacons
2592  * which are broadcast or multicast).  Still you might
2593  * want to measure signal strength with unicast ping packets
2594  * on a pt. to pt. ant. setup.
2595  */
2596 /* set true if you want to limit cache items to broadcast/mcast
2597  * only packets (not unicast).  Useful for mobile-ip beacons which
2598  * are broadcast/multicast at network layer.  Default is all packets
2599  * so ping/unicast will work say with pt. to pt. antennae setup.
2600  */
2601 static int wi_cache_mcastonly = 0;
2602 SYSCTL_INT(_machdep, OID_AUTO, wi_cache_mcastonly, CTLFLAG_RW,
2603 	&wi_cache_mcastonly, 0, "");
2604 
2605 /* set true if you want to limit cache items to IP packets only
2606 */
2607 static int wi_cache_iponly = 1;
2608 SYSCTL_INT(_machdep, OID_AUTO, wi_cache_iponly, CTLFLAG_RW,
2609 	&wi_cache_iponly, 0, "");
2610 
2611 /*
2612  * Original comments:
2613  * -----------------
2614  * wi_cache_store, per rx packet store signal
2615  * strength in MAC (src) indexed cache.
2616  *
2617  * follows linux driver in how signal strength is computed.
2618  * In ad hoc mode, we use the rx_quality field.
2619  * signal and noise are trimmed to fit in the range from 47..138.
2620  * rx_quality field MSB is signal strength.
2621  * rx_quality field LSB is noise.
2622  * "quality" is (signal - noise) as is log value.
2623  * note: quality CAN be negative.
2624  *
2625  * In BSS mode, we use the RID for communication quality.
2626  * TBD:  BSS mode is currently untested.
2627  *
2628  * Bill's comments:
2629  * ---------------
2630  * Actually, we use the rx_quality field all the time for both "ad-hoc"
2631  * and BSS modes. Why? Because reading an RID is really, really expensive:
2632  * there's a bunch of PIO operations that have to be done to read a record
2633  * from the NIC, and reading the comms quality RID each time a packet is
2634  * received can really hurt performance. We don't have to do this anyway:
2635  * the comms quality field only reflects the values in the rx_quality field
2636  * anyway. The comms quality RID is only meaningful in infrastructure mode,
2637  * but the values it contains are updated based on the rx_quality from
2638  * frames received from the access point.
2639  *
2640  * Also, according to Lucent, the signal strength and noise level values
2641  * can be converted to dBms by subtracting 149, so I've modified the code
2642  * to do that instead of the scaling it did originally.
2643  */
2644 static void
2645 wi_cache_store(struct wi_softc *sc, struct ether_header *eh,
2646                      struct mbuf *m, unsigned short rx_quality)
2647 {
2648 	struct ip *ip = 0;
2649 	int i;
2650 	static int cache_slot = 0; 	/* use this cache entry */
2651 	static int wrapindex = 0;       /* next "free" cache entry */
2652 	int sig, noise;
2653 	int sawip=0;
2654 
2655 	/*
2656 	 * filters:
2657 	 * 1. ip only
2658 	 * 2. configurable filter to throw out unicast packets,
2659 	 * keep multicast only.
2660 	 */
2661 
2662 	if ((ntohs(eh->ether_type) == ETHERTYPE_IP)) {
2663 		sawip = 1;
2664 	}
2665 
2666 	/*
2667 	 * filter for ip packets only
2668 	*/
2669 	if (wi_cache_iponly && !sawip) {
2670 		return;
2671 	}
2672 
2673 	/*
2674 	 *  filter for broadcast/multicast only
2675 	 */
2676 	if (wi_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) {
2677 		return;
2678 	}
2679 
2680 #ifdef SIGDEBUG
2681 	printf("wi%d: q value %x (MSB=0x%x, LSB=0x%x) \n", sc->wi_unit,
2682 	    rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff);
2683 #endif
2684 
2685 	/*
2686 	 *  find the ip header.  we want to store the ip_src
2687 	 * address.
2688 	 */
2689 	if (sawip)
2690 		ip = mtod(m, struct ip *);
2691 
2692 	/*
2693 	 * do a linear search for a matching MAC address
2694 	 * in the cache table
2695 	 * . MAC address is 6 bytes,
2696 	 * . var w_nextitem holds total number of entries already cached
2697 	 */
2698 	for(i = 0; i < sc->wi_nextitem; i++) {
2699 		if (! bcmp(eh->ether_shost , sc->wi_sigcache[i].macsrc,  6 )) {
2700 			/*
2701 			 * Match!,
2702 			 * so we already have this entry,
2703 			 * update the data
2704 			 */
2705 			break;
2706 		}
2707 	}
2708 
2709 	/*
2710 	 *  did we find a matching mac address?
2711 	 * if yes, then overwrite a previously existing cache entry
2712 	 */
2713 	if (i < sc->wi_nextitem )   {
2714 		cache_slot = i;
2715 	}
2716 	/*
2717 	 * else, have a new address entry,so
2718 	 * add this new entry,
2719 	 * if table full, then we need to replace LRU entry
2720 	 */
2721 	else    {
2722 
2723 		/*
2724 		 * check for space in cache table
2725 		 * note: wi_nextitem also holds number of entries
2726 		 * added in the cache table
2727 		 */
2728 		if ( sc->wi_nextitem < MAXWICACHE ) {
2729 			cache_slot = sc->wi_nextitem;
2730 			sc->wi_nextitem++;
2731 			sc->wi_sigitems = sc->wi_nextitem;
2732 		}
2733         	/* no space found, so simply wrap with wrap index
2734 		 * and "zap" the next entry
2735 		 */
2736 		else {
2737 			if (wrapindex == MAXWICACHE) {
2738 				wrapindex = 0;
2739 			}
2740 			cache_slot = wrapindex++;
2741 		}
2742 	}
2743 
2744 	/*
2745 	 * invariant: cache_slot now points at some slot
2746 	 * in cache.
2747 	 */
2748 	if (cache_slot < 0 || cache_slot >= MAXWICACHE) {
2749 		log(LOG_ERR, "wi_cache_store, bad index: %d of "
2750 		    "[0..%d], gross cache error\n",
2751 		    cache_slot, MAXWICACHE);
2752 		return;
2753 	}
2754 
2755 	/*
2756 	 *  store items in cache
2757 	 *  .ip source address
2758 	 *  .mac src
2759 	 *  .signal, etc.
2760 	 */
2761 	if (sawip)
2762 		sc->wi_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr;
2763 	bcopy( eh->ether_shost, sc->wi_sigcache[cache_slot].macsrc,  6);
2764 
2765 	sig = (rx_quality >> 8) & 0xFF;
2766 	noise = rx_quality & 0xFF;
2767 	sc->wi_sigcache[cache_slot].signal = sig - 149;
2768 	sc->wi_sigcache[cache_slot].noise = noise - 149;
2769 	sc->wi_sigcache[cache_slot].quality = sig - noise;
2770 
2771 	return;
2772 }
2773 #endif
2774 
2775 static int
2776 wi_get_cur_ssid(sc, ssid, len)
2777 	struct wi_softc		*sc;
2778 	char			*ssid;
2779 	int			*len;
2780 {
2781 	int			error = 0;
2782 	struct wi_req		wreq;
2783 
2784 	wreq.wi_len = WI_MAX_DATALEN;
2785 	switch (sc->wi_ptype) {
2786 	case WI_PORTTYPE_AP:
2787 		*len = IEEE80211_NWID_LEN;
2788 		bcopy(sc->wi_net_name, ssid, IEEE80211_NWID_LEN);
2789 		break;
2790 	case WI_PORTTYPE_ADHOC:
2791 		wreq.wi_type = WI_RID_CURRENT_SSID;
2792 		error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq);
2793 		if (error != 0)
2794 			break;
2795 		if (wreq.wi_val[0] > IEEE80211_NWID_LEN) {
2796 			error = EINVAL;
2797 			break;
2798 		}
2799 		*len = wreq.wi_val[0];
2800 		bcopy(&wreq.wi_val[1], ssid, IEEE80211_NWID_LEN);
2801 		break;
2802 	case WI_PORTTYPE_BSS:
2803 		wreq.wi_type = WI_RID_COMMQUAL;
2804 		error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq);
2805 		if (error != 0)
2806 			break;
2807 		if (wreq.wi_val[0] != 0) /* associated */ {
2808 			wreq.wi_type = WI_RID_CURRENT_SSID;
2809 			wreq.wi_len = WI_MAX_DATALEN;
2810 			error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq);
2811 			if (error != 0)
2812 				break;
2813 			if (wreq.wi_val[0] > IEEE80211_NWID_LEN) {
2814 				error = EINVAL;
2815 				break;
2816 			}
2817 			*len = wreq.wi_val[0];
2818 			bcopy(&wreq.wi_val[1], ssid, IEEE80211_NWID_LEN);
2819 		} else {
2820 			*len = IEEE80211_NWID_LEN;
2821 			bcopy(sc->wi_net_name, ssid, IEEE80211_NWID_LEN);
2822 		}
2823 		break;
2824 	default:
2825 		error = EINVAL;
2826 		break;
2827 	}
2828 
2829 	return error;
2830 }
2831 
2832 static int
2833 wi_media_change(ifp)
2834 	struct ifnet		*ifp;
2835 {
2836 	struct wi_softc		*sc = ifp->if_softc;
2837 	int			otype = sc->wi_ptype;
2838 	int			orate = sc->wi_tx_rate;
2839 	int			ocreate_ibss = sc->wi_create_ibss;
2840 
2841 	if ((sc->ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_HOSTAP) &&
2842 	    sc->sc_firmware_type != WI_INTERSIL)
2843 		return (EINVAL);
2844 
2845 	sc->wi_create_ibss = 0;
2846 
2847 	switch (sc->ifmedia.ifm_cur->ifm_media & IFM_OMASK) {
2848 	case 0:
2849 		sc->wi_ptype = WI_PORTTYPE_BSS;
2850 		break;
2851 	case IFM_IEEE80211_ADHOC:
2852 		sc->wi_ptype = WI_PORTTYPE_ADHOC;
2853 		break;
2854 	case IFM_IEEE80211_HOSTAP:
2855 		sc->wi_ptype = WI_PORTTYPE_AP;
2856 		break;
2857 	case IFM_IEEE80211_IBSSMASTER:
2858 	case IFM_IEEE80211_IBSSMASTER|IFM_IEEE80211_IBSS:
2859 		if (!(sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS))
2860 			return (EINVAL);
2861 		sc->wi_create_ibss = 1;
2862 		/* FALLTHROUGH */
2863 	case IFM_IEEE80211_IBSS:
2864 		sc->wi_ptype = WI_PORTTYPE_IBSS;
2865 		break;
2866 	default:
2867 		/* Invalid combination. */
2868 		return (EINVAL);
2869 	}
2870 
2871 	switch (IFM_SUBTYPE(sc->ifmedia.ifm_cur->ifm_media)) {
2872 	case IFM_IEEE80211_DS1:
2873 		sc->wi_tx_rate = 1;
2874 		break;
2875 	case IFM_IEEE80211_DS2:
2876 		sc->wi_tx_rate = 2;
2877 		break;
2878 	case IFM_IEEE80211_DS5:
2879 		sc->wi_tx_rate = 5;
2880 		break;
2881 	case IFM_IEEE80211_DS11:
2882 		sc->wi_tx_rate = 11;
2883 		break;
2884 	case IFM_AUTO:
2885 		sc->wi_tx_rate = 3;
2886 		break;
2887 	}
2888 
2889 	if (ocreate_ibss != sc->wi_create_ibss || otype != sc->wi_ptype ||
2890 	    orate != sc->wi_tx_rate)
2891 		wi_init(sc);
2892 
2893 	return(0);
2894 }
2895 
2896 static void
2897 wi_media_status(ifp, imr)
2898 	struct ifnet		*ifp;
2899 	struct ifmediareq	*imr;
2900 {
2901 	struct wi_req		wreq;
2902 	struct wi_softc		*sc = ifp->if_softc;
2903 
2904 	if (sc->wi_tx_rate == 3) {
2905 		imr->ifm_active = IFM_IEEE80211|IFM_AUTO;
2906 		if (sc->wi_ptype == WI_PORTTYPE_ADHOC)
2907 			imr->ifm_active |= IFM_IEEE80211_ADHOC;
2908 		else if (sc->wi_ptype == WI_PORTTYPE_AP)
2909 			imr->ifm_active |= IFM_IEEE80211_HOSTAP;
2910 		else if (sc->wi_ptype == WI_PORTTYPE_IBSS) {
2911 			if (sc->wi_create_ibss)
2912 				imr->ifm_active |= IFM_IEEE80211_IBSSMASTER;
2913 			else
2914 				imr->ifm_active |= IFM_IEEE80211_IBSS;
2915 		}
2916 		wreq.wi_type = WI_RID_CUR_TX_RATE;
2917 		wreq.wi_len = WI_MAX_DATALEN;
2918 		if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) == 0) {
2919 			switch(wreq.wi_val[0]) {
2920 			case 1:
2921 				imr->ifm_active |= IFM_IEEE80211_DS1;
2922 				break;
2923 			case 2:
2924 				imr->ifm_active |= IFM_IEEE80211_DS2;
2925 				break;
2926 			case 6:
2927 				imr->ifm_active |= IFM_IEEE80211_DS5;
2928 				break;
2929 			case 11:
2930 				imr->ifm_active |= IFM_IEEE80211_DS11;
2931 				break;
2932 				}
2933 		}
2934 	} else {
2935 		imr->ifm_active = sc->ifmedia.ifm_cur->ifm_media;
2936 	}
2937 
2938 	imr->ifm_status = IFM_AVALID;
2939 	if (sc->wi_ptype == WI_PORTTYPE_ADHOC ||
2940 	    sc->wi_ptype == WI_PORTTYPE_IBSS)
2941 		/*
2942 		 * XXX: It would be nice if we could give some actually
2943 		 * useful status like whether we joined another IBSS or
2944 		 * created one ourselves.
2945 		 */
2946 		imr->ifm_status |= IFM_ACTIVE;
2947 	else if (sc->wi_ptype == WI_PORTTYPE_AP)
2948 		imr->ifm_status |= IFM_ACTIVE;
2949 	else {
2950 		wreq.wi_type = WI_RID_COMMQUAL;
2951 		wreq.wi_len = WI_MAX_DATALEN;
2952 		if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) == 0 &&
2953 		    wreq.wi_val[0] != 0)
2954 			imr->ifm_status |= IFM_ACTIVE;
2955 	}
2956 }
2957 
2958 static int
2959 wi_get_debug(sc, wreq)
2960 	struct wi_softc		*sc;
2961 	struct wi_req		*wreq;
2962 {
2963 	int			error = 0;
2964 
2965 	wreq->wi_len = 1;
2966 
2967 	switch (wreq->wi_type) {
2968 	case WI_DEBUG_SLEEP:
2969 		wreq->wi_len++;
2970 		wreq->wi_val[0] = sc->wi_debug.wi_sleep;
2971 		break;
2972 	case WI_DEBUG_DELAYSUPP:
2973 		wreq->wi_len++;
2974 		wreq->wi_val[0] = sc->wi_debug.wi_delaysupp;
2975 		break;
2976 	case WI_DEBUG_TXSUPP:
2977 		wreq->wi_len++;
2978 		wreq->wi_val[0] = sc->wi_debug.wi_txsupp;
2979 		break;
2980 	case WI_DEBUG_MONITOR:
2981 		wreq->wi_len++;
2982 		wreq->wi_val[0] = sc->wi_debug.wi_monitor;
2983 		break;
2984 	case WI_DEBUG_LEDTEST:
2985 		wreq->wi_len += 3;
2986 		wreq->wi_val[0] = sc->wi_debug.wi_ledtest;
2987 		wreq->wi_val[1] = sc->wi_debug.wi_ledtest_param0;
2988 		wreq->wi_val[2] = sc->wi_debug.wi_ledtest_param1;
2989 		break;
2990 	case WI_DEBUG_CONTTX:
2991 		wreq->wi_len += 2;
2992 		wreq->wi_val[0] = sc->wi_debug.wi_conttx;
2993 		wreq->wi_val[1] = sc->wi_debug.wi_conttx_param0;
2994 		break;
2995 	case WI_DEBUG_CONTRX:
2996 		wreq->wi_len++;
2997 		wreq->wi_val[0] = sc->wi_debug.wi_contrx;
2998 		break;
2999 	case WI_DEBUG_SIGSTATE:
3000 		wreq->wi_len += 2;
3001 		wreq->wi_val[0] = sc->wi_debug.wi_sigstate;
3002 		wreq->wi_val[1] = sc->wi_debug.wi_sigstate_param0;
3003 		break;
3004 	case WI_DEBUG_CONFBITS:
3005 		wreq->wi_len += 2;
3006 		wreq->wi_val[0] = sc->wi_debug.wi_confbits;
3007 		wreq->wi_val[1] = sc->wi_debug.wi_confbits_param0;
3008 		break;
3009 	default:
3010 		error = EIO;
3011 		break;
3012 	}
3013 
3014 	return (error);
3015 }
3016 
3017 static int
3018 wi_set_debug(sc, wreq)
3019 	struct wi_softc		*sc;
3020 	struct wi_req		*wreq;
3021 {
3022 	int			error = 0;
3023 	u_int16_t		cmd, param0 = 0, param1 = 0;
3024 
3025 	switch (wreq->wi_type) {
3026 	case WI_DEBUG_RESET:
3027 	case WI_DEBUG_INIT:
3028 	case WI_DEBUG_CALENABLE:
3029 		break;
3030 	case WI_DEBUG_SLEEP:
3031 		sc->wi_debug.wi_sleep = 1;
3032 		break;
3033 	case WI_DEBUG_WAKE:
3034 		sc->wi_debug.wi_sleep = 0;
3035 		break;
3036 	case WI_DEBUG_CHAN:
3037 		param0 = wreq->wi_val[0];
3038 		break;
3039 	case WI_DEBUG_DELAYSUPP:
3040 		sc->wi_debug.wi_delaysupp = 1;
3041 		break;
3042 	case WI_DEBUG_TXSUPP:
3043 		sc->wi_debug.wi_txsupp = 1;
3044 		break;
3045 	case WI_DEBUG_MONITOR:
3046 		sc->wi_debug.wi_monitor = 1;
3047 		break;
3048 	case WI_DEBUG_LEDTEST:
3049 		param0 = wreq->wi_val[0];
3050 		param1 = wreq->wi_val[1];
3051 		sc->wi_debug.wi_ledtest = 1;
3052 		sc->wi_debug.wi_ledtest_param0 = param0;
3053 		sc->wi_debug.wi_ledtest_param1 = param1;
3054 		break;
3055 	case WI_DEBUG_CONTTX:
3056 		param0 = wreq->wi_val[0];
3057 		sc->wi_debug.wi_conttx = 1;
3058 		sc->wi_debug.wi_conttx_param0 = param0;
3059 		break;
3060 	case WI_DEBUG_STOPTEST:
3061 		sc->wi_debug.wi_delaysupp = 0;
3062 		sc->wi_debug.wi_txsupp = 0;
3063 		sc->wi_debug.wi_monitor = 0;
3064 		sc->wi_debug.wi_ledtest = 0;
3065 		sc->wi_debug.wi_ledtest_param0 = 0;
3066 		sc->wi_debug.wi_ledtest_param1 = 0;
3067 		sc->wi_debug.wi_conttx = 0;
3068 		sc->wi_debug.wi_conttx_param0 = 0;
3069 		sc->wi_debug.wi_contrx = 0;
3070 		sc->wi_debug.wi_sigstate = 0;
3071 		sc->wi_debug.wi_sigstate_param0 = 0;
3072 		break;
3073 	case WI_DEBUG_CONTRX:
3074 		sc->wi_debug.wi_contrx = 1;
3075 		break;
3076 	case WI_DEBUG_SIGSTATE:
3077 		param0 = wreq->wi_val[0];
3078 		sc->wi_debug.wi_sigstate = 1;
3079 		sc->wi_debug.wi_sigstate_param0 = param0;
3080 		break;
3081 	case WI_DEBUG_CONFBITS:
3082 		param0 = wreq->wi_val[0];
3083 		param1 = wreq->wi_val[1];
3084 		sc->wi_debug.wi_confbits = param0;
3085 		sc->wi_debug.wi_confbits_param0 = param1;
3086 		break;
3087 	default:
3088 		error = EIO;
3089 		break;
3090 	}
3091 
3092 	if (error)
3093 		return (error);
3094 
3095 	cmd = WI_CMD_DEBUG | (wreq->wi_type << 8);
3096 	error = wi_cmd(sc, cmd, param0, param1, 0);
3097 
3098 	return (error);
3099 }
3100