xref: /netbsd-src/sys/dev/ic/wi.c (revision 1ca5c1b28139779176bd5c13ad7c5f25c0bcd5f8)
1 /*	$NetBSD: wi.c,v 1.36 2002/01/21 11:29:22 ichiro Exp $	*/
2 
3 /*
4  * Copyright (c) 1997, 1998, 1999
5  *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by Bill Paul.
18  * 4. Neither the name of the author nor the names of any co-contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
26  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32  * THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 /*
36  * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for NetBSD.
37  *
38  * Original FreeBSD driver written by Bill Paul <wpaul@ctr.columbia.edu>
39  * Electrical Engineering Department
40  * Columbia University, New York City
41  */
42 
43 /*
44  * The WaveLAN/IEEE adapter is the second generation of the WaveLAN
45  * from Lucent. Unlike the older cards, the new ones are programmed
46  * entirely via a firmware-driven controller called the Hermes.
47  * Unfortunately, Lucent will not release the Hermes programming manual
48  * without an NDA (if at all). What they do release is an API library
49  * called the HCF (Hardware Control Functions) which is supposed to
50  * do the device-specific operations of a device driver for you. The
51  * publically available version of the HCF library (the 'HCF Light') is
52  * a) extremely gross, b) lacks certain features, particularly support
53  * for 802.11 frames, and c) is contaminated by the GNU Public License.
54  *
55  * This driver does not use the HCF or HCF Light at all. Instead, it
56  * programs the Hermes controller directly, using information gleaned
57  * from the HCF Light code and corresponding documentation.
58  *
59  * This driver supports both the PCMCIA and ISA versions of the
60  * WaveLAN/IEEE cards. Note however that the ISA card isn't really
61  * anything of the sort: it's actually a PCMCIA bridge adapter
62  * that fits into an ISA slot, into which a PCMCIA WaveLAN card is
63  * inserted. Consequently, you need to use the pccard support for
64  * both the ISA and PCMCIA adapters.
65  */
66 
67 /*
68  * FreeBSD driver ported to NetBSD by Bill Sommerfeld in the back of the
69  * Oslo IETF plenary meeting.
70  */
71 
72 #include <sys/cdefs.h>
73 __KERNEL_RCSID(0, "$NetBSD: wi.c,v 1.36 2002/01/21 11:29:22 ichiro Exp $");
74 
75 #define WI_HERMES_AUTOINC_WAR	/* Work around data write autoinc bug. */
76 #define WI_HERMES_STATS_WAR	/* Work around stats counter bug. */
77 
78 #include "bpfilter.h"
79 
80 #include <sys/param.h>
81 #include <sys/systm.h>
82 #include <sys/callout.h>
83 #include <sys/device.h>
84 #include <sys/socket.h>
85 #include <sys/mbuf.h>
86 #include <sys/ioctl.h>
87 #include <sys/kernel.h>		/* for hz */
88 #include <sys/proc.h>
89 
90 #include <net/if.h>
91 #include <net/if_dl.h>
92 #include <net/if_media.h>
93 #include <net/if_ether.h>
94 #include <net/if_ieee80211.h>
95 
96 #if NBPFILTER > 0
97 #include <net/bpf.h>
98 #include <net/bpfdesc.h>
99 #endif
100 
101 #include <machine/bus.h>
102 
103 #include <dev/ic/wi_ieee.h>
104 #include <dev/ic/wireg.h>
105 #include <dev/ic/wivar.h>
106 
107 static void wi_reset		__P((struct wi_softc *));
108 static int wi_ioctl		__P((struct ifnet *, u_long, caddr_t));
109 static void wi_start		__P((struct ifnet *));
110 static void wi_watchdog		__P((struct ifnet *));
111 static int wi_init		__P((struct ifnet *));
112 static void wi_stop		__P((struct ifnet *, int));
113 static void wi_rxeof		__P((struct wi_softc *));
114 static void wi_txeof		__P((struct wi_softc *, int));
115 static void wi_update_stats	__P((struct wi_softc *));
116 static void wi_setmulti		__P((struct wi_softc *));
117 
118 static int wi_cmd		__P((struct wi_softc *, int, int));
119 static int wi_read_record	__P((struct wi_softc *, struct wi_ltv_gen *));
120 static int wi_write_record	__P((struct wi_softc *, struct wi_ltv_gen *));
121 static int wi_read_data		__P((struct wi_softc *, int,
122 					int, caddr_t, int));
123 static int wi_write_data	__P((struct wi_softc *, int,
124 					int, caddr_t, int));
125 static int wi_seek		__P((struct wi_softc *, int, int, int));
126 static int wi_alloc_nicmem	__P((struct wi_softc *, int, int *));
127 static void wi_inquire		__P((void *));
128 static void wi_wait_scan	__P((void *));
129 static int wi_setdef		__P((struct wi_softc *, struct wi_req *));
130 static int wi_getdef		__P((struct wi_softc *, struct wi_req *));
131 static int wi_mgmt_xmit		__P((struct wi_softc *, caddr_t, int));
132 
133 static int wi_media_change __P((struct ifnet *));
134 static void wi_media_status __P((struct ifnet *, struct ifmediareq *));
135 
136 static void wi_get_id		__P((struct wi_softc *));
137 
138 static int wi_set_ssid __P((struct ieee80211_nwid *, u_int8_t *, int));
139 static void wi_request_fill_ssid __P((struct wi_req *,
140     struct ieee80211_nwid *));
141 static int wi_write_ssid __P((struct wi_softc *, int, struct wi_req *,
142     struct ieee80211_nwid *));
143 static int wi_set_nwkey __P((struct wi_softc *, struct ieee80211_nwkey *));
144 static int wi_get_nwkey __P((struct wi_softc *, struct ieee80211_nwkey *));
145 static int wi_sync_media __P((struct wi_softc *, int, int));
146 static int wi_set_pm(struct wi_softc *, struct ieee80211_power *);
147 static int wi_get_pm(struct wi_softc *, struct ieee80211_power *);
148 
149 int
150 wi_attach(sc)
151 	struct wi_softc *sc;
152 {
153 	struct ifnet *ifp = sc->sc_ifp;
154 	struct wi_ltv_macaddr   mac;
155 	struct wi_ltv_gen       gen;
156 	static const u_int8_t empty_macaddr[ETHER_ADDR_LEN] = {
157 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00
158 	};
159 	int s;
160 
161 	s = splnet();
162 
163 	callout_init(&sc->wi_inquire_ch);
164 	callout_init(&sc->wi_scan_sh);
165 
166 	/* Make sure interrupts are disabled. */
167 	CSR_WRITE_2(sc, WI_INT_EN, 0);
168 	CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
169 
170 	/* Reset the NIC. */
171 	wi_reset(sc);
172 
173 	memset(&mac, 0, sizeof(mac));
174 	/* Read the station address. */
175 	mac.wi_type = WI_RID_MAC_NODE;
176 	mac.wi_len = 4;
177 	wi_read_record(sc, (struct wi_ltv_gen *)&mac);
178 	memcpy(sc->sc_macaddr, mac.wi_mac_addr, ETHER_ADDR_LEN);
179 
180 	/*
181 	 * Check if we got anything meaningful.
182 	 *
183 	 * Is it really enough just checking against null ethernet address?
184 	 * Or, check against possible vendor?  XXX.
185 	 */
186 	if (memcmp(sc->sc_macaddr, empty_macaddr, ETHER_ADDR_LEN) == 0) {
187 		printf("%s: could not get mac address, attach failed\n",
188 		    sc->sc_dev.dv_xname);
189 			return 1;
190 	}
191 
192 	printf(" 802.11 address %s\n", ether_sprintf(sc->sc_macaddr));
193 
194 	/* Read NIC identification */
195 	wi_get_id(sc);
196 
197 	memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
198 	ifp->if_softc = sc;
199 	ifp->if_start = wi_start;
200 	ifp->if_ioctl = wi_ioctl;
201 	ifp->if_watchdog = wi_watchdog;
202 	ifp->if_init = wi_init;
203 	ifp->if_stop = wi_stop;
204 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
205 #ifdef IFF_NOTRAILERS
206 	ifp->if_flags |= IFF_NOTRAILERS;
207 #endif
208 	IFQ_SET_READY(&ifp->if_snd);
209 
210 	(void)wi_set_ssid(&sc->wi_nodeid, WI_DEFAULT_NODENAME,
211 	    sizeof(WI_DEFAULT_NODENAME) - 1);
212 	(void)wi_set_ssid(&sc->wi_netid, WI_DEFAULT_NETNAME,
213 	    sizeof(WI_DEFAULT_NETNAME) - 1);
214 	(void)wi_set_ssid(&sc->wi_ibssid, WI_DEFAULT_IBSS,
215 	    sizeof(WI_DEFAULT_IBSS) - 1);
216 
217 	sc->wi_portnum = WI_DEFAULT_PORT;
218 	sc->wi_ptype = WI_PORTTYPE_BSS;
219 	sc->wi_ap_density = WI_DEFAULT_AP_DENSITY;
220 	sc->wi_rts_thresh = WI_DEFAULT_RTS_THRESH;
221 	sc->wi_tx_rate = WI_DEFAULT_TX_RATE;
222 	sc->wi_max_data_len = WI_DEFAULT_DATALEN;
223 	sc->wi_create_ibss = WI_DEFAULT_CREATE_IBSS;
224 	sc->wi_pm_enabled = WI_DEFAULT_PM_ENABLED;
225 	sc->wi_max_sleep = WI_DEFAULT_MAX_SLEEP;
226 	sc->wi_roaming = WI_DEFAULT_ROAMING;
227 	sc->wi_authtype = WI_DEFAULT_AUTHTYPE;
228 
229 	/*
230 	 * Read the default channel from the NIC. This may vary
231 	 * depending on the country where the NIC was purchased, so
232 	 * we can't hard-code a default and expect it to work for
233 	 * everyone.
234 	 */
235 	gen.wi_type = WI_RID_OWN_CHNL;
236 	gen.wi_len = 2;
237 	wi_read_record(sc, &gen);
238 	sc->wi_channel = le16toh(gen.wi_val);
239 
240 	memset((char *)&sc->wi_stats, 0, sizeof(sc->wi_stats));
241 
242 	/* AP info was filled with 0 */
243 	memset((char *)&sc->wi_aps, 0, sizeof(sc->wi_aps));
244 	sc->wi_scanning=0;
245 	sc->wi_naps=0;
246 
247 	/*
248 	 * Find out if we support WEP on this card.
249 	 */
250 	gen.wi_type = WI_RID_WEP_AVAIL;
251 	gen.wi_len = 2;
252 	wi_read_record(sc, &gen);
253 	sc->wi_has_wep = le16toh(gen.wi_val);
254 
255 	ifmedia_init(&sc->sc_media, 0, wi_media_change, wi_media_status);
256 #define	IFM_AUTOADHOC \
257 	IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_ADHOC, 0)
258 #define	ADD(m, c)	ifmedia_add(&sc->sc_media, (m), (c), NULL)
259 	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0);
260 	ADD(IFM_AUTOADHOC, 0);
261 	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0);
262 	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
263 	    IFM_IEEE80211_ADHOC, 0), 0);
264 	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0);
265 	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
266 	    IFM_IEEE80211_ADHOC, 0), 0);
267 	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 0, 0), 0);
268 	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
269 	    IFM_IEEE80211_ADHOC, 0), 0);
270 	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0);
271 	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
272 	    IFM_IEEE80211_ADHOC, 0), 0);
273 	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_MANUAL, 0, 0), 0);
274 #undef ADD
275 	ifmedia_set(&sc->sc_media, IFM_AUTOADHOC);
276 
277 	/*
278 	 * Call MI attach routines.
279 	 */
280 	if_attach(ifp);
281 	ether_ifattach(ifp, mac.wi_mac_addr);
282 
283 	ifp->if_baudrate = IF_Mbps(2);
284 
285 	/* Attach is successful. */
286 	sc->sc_attached = 1;
287 
288 	splx(s);
289 	return 0;
290 }
291 
292 static void wi_rxeof(sc)
293 	struct wi_softc		*sc;
294 {
295 	struct ifnet		*ifp;
296 	struct ether_header	*eh;
297 	struct wi_frame		rx_frame;
298 	struct mbuf		*m;
299 	int			id;
300 
301 	ifp = sc->sc_ifp;
302 
303 	id = CSR_READ_2(sc, WI_RX_FID);
304 
305 	/* First read in the frame header */
306 	if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame, sizeof(rx_frame))) {
307 		ifp->if_ierrors++;
308 		return;
309 	}
310 
311 	/*
312 	 * Drop undecryptable or packets with receive errors here
313 	 */
314 	if (le16toh(rx_frame.wi_status) & WI_STAT_ERRSTAT) {
315 		ifp->if_ierrors++;
316 		return;
317 	}
318 
319 	MGETHDR(m, M_DONTWAIT, MT_DATA);
320 	if (m == NULL) {
321 		ifp->if_ierrors++;
322 		return;
323 	}
324 	MCLGET(m, M_DONTWAIT);
325 	if (!(m->m_flags & M_EXT)) {
326 		m_freem(m);
327 		ifp->if_ierrors++;
328 		return;
329 	}
330 
331 	/* Align the data after the ethernet header */
332 	m->m_data = (caddr_t) ALIGN(m->m_data + sizeof(struct ether_header))
333 	    - sizeof(struct ether_header);
334 
335 	eh = mtod(m, struct ether_header *);
336 	m->m_pkthdr.rcvif = ifp;
337 
338 	if (le16toh(rx_frame.wi_status) == WI_STAT_1042 ||
339 	    le16toh(rx_frame.wi_status) == WI_STAT_TUNNEL ||
340 	    le16toh(rx_frame.wi_status) == WI_STAT_WMP_MSG) {
341 		if ((le16toh(rx_frame.wi_dat_len) + WI_SNAPHDR_LEN) > MCLBYTES) {
342 			printf("%s: oversized packet received "
343 			    "(wi_dat_len=%d, wi_status=0x%x)\n",
344 			    sc->sc_dev.dv_xname,
345 			    le16toh(rx_frame.wi_dat_len), le16toh(rx_frame.wi_status));
346 			m_freem(m);
347 			ifp->if_ierrors++;
348 			return;
349 		}
350 		m->m_pkthdr.len = m->m_len =
351 		    le16toh(rx_frame.wi_dat_len) + WI_SNAPHDR_LEN;
352 
353 		memcpy((char *)&eh->ether_dhost, (char *)&rx_frame.wi_dst_addr,
354 		    ETHER_ADDR_LEN);
355 		memcpy((char *)&eh->ether_shost, (char *)&rx_frame.wi_src_addr,
356 		    ETHER_ADDR_LEN);
357 		memcpy((char *)&eh->ether_type, (char *)&rx_frame.wi_type,
358 		    sizeof(u_int16_t));
359 
360 		if (wi_read_data(sc, id, WI_802_11_OFFSET,
361 		    mtod(m, caddr_t) + sizeof(struct ether_header),
362 		    m->m_len + 2)) {
363 			m_freem(m);
364 			ifp->if_ierrors++;
365 			return;
366 		}
367 	} else {
368 		if ((le16toh(rx_frame.wi_dat_len) +
369 		    sizeof(struct ether_header)) > MCLBYTES) {
370 			printf("%s: oversized packet received "
371 			    "(wi_dat_len=%d, wi_status=0x%x)\n",
372 			    sc->sc_dev.dv_xname,
373 			    le16toh(rx_frame.wi_dat_len), le16toh(rx_frame.wi_status));
374 			m_freem(m);
375 			ifp->if_ierrors++;
376 			return;
377 		}
378 		m->m_pkthdr.len = m->m_len =
379 		    le16toh(rx_frame.wi_dat_len) + sizeof(struct ether_header);
380 
381 		if (wi_read_data(sc, id, WI_802_3_OFFSET,
382 		    mtod(m, caddr_t), m->m_len + 2)) {
383 			m_freem(m);
384 			ifp->if_ierrors++;
385 			return;
386 		}
387 	}
388 
389 	ifp->if_ipackets++;
390 
391 #if NBPFILTER > 0
392 	/* Handle BPF listeners. */
393 	if (ifp->if_bpf)
394 		bpf_mtap(ifp->if_bpf, m);
395 #endif
396 
397 	/* Receive packet. */
398 	(*ifp->if_input)(ifp, m);
399 }
400 
401 static void wi_txeof(sc, status)
402 	struct wi_softc	*sc;
403 	int		status;
404 {
405 	struct ifnet	*ifp = sc->sc_ifp;
406 
407 	ifp->if_timer = 0;
408 	ifp->if_flags &= ~IFF_OACTIVE;
409 
410 	if (status & WI_EV_TX_EXC)
411 		ifp->if_oerrors++;
412 	else
413 		ifp->if_opackets++;
414 
415 	return;
416 }
417 
418 void wi_inquire(xsc)
419 	void			*xsc;
420 {
421 	struct wi_softc		*sc;
422 	struct ifnet		*ifp;
423 
424 	sc = xsc;
425 	ifp = &sc->sc_ethercom.ec_if;
426 
427 	if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
428 		return;
429 
430 	callout_reset(&sc->wi_inquire_ch, hz * 60, wi_inquire, sc);
431 
432 	/* Don't do this while we're transmitting */
433 	if (ifp->if_flags & IFF_OACTIVE)
434 		return;
435 
436 	wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_COUNTERS);
437 }
438 
439 void wi_wait_scan(xsc)
440 	void			*xsc;
441 {
442 	struct wi_softc         *sc;
443 	struct ifnet            *ifp;
444 
445 	sc = xsc;
446 	ifp = &sc->sc_ethercom.ec_if;
447 
448 	/* If not scanning, ignore */
449 	if (!sc->wi_scanning)
450 		return;
451 
452 	/* Wait for to make INQUIRE */
453 	if (ifp->if_flags & IFF_OACTIVE) {
454 		callout_reset(&sc->wi_scan_sh, hz * 1, wi_wait_scan, sc);
455 		return;
456 	}
457 
458 	/* try INQUIRE */
459 	if (wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS) == ETIMEDOUT) {
460 		callout_reset(&sc->wi_scan_sh, hz * 1, wi_wait_scan, sc);
461 		return;
462 	}
463 }
464 
465 void wi_update_stats(sc)
466 	struct wi_softc		*sc;
467 {
468 	struct wi_ltv_gen	gen;
469 	struct wi_scan_header	ap2_header;	/* Prism2 header */
470 	struct wi_scan_data_p2	ap2;		/* Prism2 scantable*/
471 	struct wi_scan_data	ap;		/* Lucent scantable */
472 	struct wi_assoc		assoc;		/* Association Status */
473 	u_int16_t		id;
474 	struct ifnet		*ifp;
475 	u_int32_t		*ptr;
476 	int			len, naps, i, j;
477 	u_int16_t		t;
478 
479 	ifp = &sc->sc_ethercom.ec_if;
480 
481 	id = CSR_READ_2(sc, WI_INFO_FID);
482 
483 	wi_read_data(sc, id, 0, (char *)&gen, 4);
484 
485 	switch (gen.wi_type) {
486 	case WI_INFO_SCAN_RESULTS:
487 		if (gen.wi_len < 3)
488 			break;
489 		if (sc->sc_prism2) {	/* Prism2 chip */
490 			naps = 2 * (gen.wi_len - 3) / sizeof(ap2);
491 			naps = naps > MAXAPINFO ? MAXAPINFO : naps;
492 			sc->wi_naps = naps;
493 			/* Read Header */
494 			for(j=0; j < sizeof(ap2_header) / 2; j++)
495 				((u_int16_t *)&ap2_header)[j] =
496 						CSR_READ_2(sc, WI_DATA1);
497 			/* Read Data */
498 			for (i=0; i < naps; i++) {
499 				for(j=0; j < sizeof(ap2) / 2; j++)
500 					((u_int16_t *)&ap2)[j] =
501 						CSR_READ_2(sc, WI_DATA1);
502 				sc->wi_aps[i].scanreason = ap2_header.wi_reason;
503 				memcpy(sc->wi_aps[i].bssid, ap2.wi_bssid, 6);
504 				sc->wi_aps[i].channel = ap2.wi_chid;
505 				sc->wi_aps[i].signal  = ap2.wi_signal;
506 				sc->wi_aps[i].noise   = ap2.wi_noise;
507 				sc->wi_aps[i].quality = ap2.wi_signal - ap2.wi_noise;
508 				sc->wi_aps[i].capinfo = ap2.wi_capinfo;
509 				sc->wi_aps[i].interval = ap2.wi_interval;
510 				sc->wi_aps[i].rate    = ap2.wi_rate;
511 				if (ap2.wi_namelen > 32)
512 					ap2.wi_namelen = 32;
513 				sc->wi_aps[i].namelen = ap2.wi_namelen;
514 				memcpy(sc->wi_aps[i].name, ap2.wi_name,
515 				       ap2.wi_namelen);
516 			}
517 		} else {	/* Lucent chip */
518 			naps = 2 * gen.wi_len / sizeof(ap);
519 			naps = naps > MAXAPINFO ? MAXAPINFO : naps;
520 			sc->wi_naps = naps;
521 			/* Read Data*/
522 			for (i=0; i < naps; i++) {
523 				for(j=0; j < sizeof(ap) / 2; j++)
524 					((u_int16_t *)&ap)[j] =
525 						CSR_READ_2(sc, WI_DATA1);
526 				memcpy(sc->wi_aps[i].bssid, ap.wi_bssid, 6);
527 				sc->wi_aps[i].channel = ap.wi_chid;
528 				sc->wi_aps[i].signal  = ap.wi_signal;
529 				sc->wi_aps[i].noise   = ap.wi_noise;
530 				sc->wi_aps[i].quality = ap.wi_signal - ap.wi_noise;
531 				sc->wi_aps[i].capinfo = ap.wi_capinfo;
532 				sc->wi_aps[i].interval = ap.wi_interval;
533 				if (ap.wi_namelen > 32)
534 					ap.wi_namelen = 32;
535 				sc->wi_aps[i].namelen = ap.wi_namelen;
536 				memcpy(sc->wi_aps[i].name, ap.wi_name,
537 				       ap.wi_namelen);
538 			}
539 		}
540 		/* Done scanning */
541 		sc->wi_scanning = 0;
542 		break;
543 
544 	case WI_INFO_COUNTERS:
545 		/* some card versions have a larger stats structure */
546 		len = (gen.wi_len - 1 < sizeof(sc->wi_stats) / 4) ?
547 			gen.wi_len - 1 : sizeof(sc->wi_stats) / 4;
548 		ptr = (u_int32_t *)&sc->wi_stats;
549 
550 		for (i = 0; i < len; i++) {
551 			t = CSR_READ_2(sc, WI_DATA1);
552 #ifdef WI_HERMES_STATS_WAR
553 			if (t > 0xF000)
554 				t = ~t & 0xFFFF;
555 #endif
556 			ptr[i] += t;
557 		}
558 
559 		ifp->if_collisions = sc->wi_stats.wi_tx_single_retries +
560 			sc->wi_stats.wi_tx_multi_retries +
561 			sc->wi_stats.wi_tx_retry_limit;
562 		break;
563 
564 	case WI_INFO_LINK_STAT: {
565 		static char *msg[] = {
566 			"connected",
567 			"disconnected",
568 			"AP change",
569 			"AP out of range",
570 			"AP in range",
571 			"Association Faild"
572 		};
573 
574 		if (gen.wi_len != 2) {
575 #ifdef WI_DEBUG
576 			printf("WI_INFO_LINK_STAT: len=%d\n", gen.wi_len);
577 #endif
578 			break;
579 		}
580 		t = CSR_READ_2(sc, WI_DATA1);
581 		if ((t < 1) || (t > 6)) {
582 #ifdef WI_DEBUG
583 			printf("WI_INFO_LINK_STAT: status %d\n", t);
584 #endif
585 			break;
586 		}
587 		printf("%s: %s\n", sc->sc_dev.dv_xname, msg[t - 1]);
588 		break;
589 		}
590 
591 	case WI_INFO_ASSOC_STAT: {
592 		static char *msg[] = {
593 			"STA Associated",
594 			"STA Reassociated",
595 			"STA Disassociated",
596 			"Association Failure",
597 			"Authentication Faild"
598 		};
599 		if (gen.wi_len != 10)
600                         break;
601 		for (i=0; i < gen.wi_len - 1; i++)
602 			((u_int16_t *)&assoc)[i] = CSR_READ_2(sc, WI_DATA1);
603 		switch (assoc.wi_assoc_stat) {
604 		case ASSOC:
605 		case DISASSOC:
606 		case ASSOCFAIL:
607 		case AUTHFAIL:
608 			printf("%s: %s, AP = %x:%x:%x:%x:%x:%x\n",
609 				sc->sc_dev.dv_xname,
610 				msg[assoc.wi_assoc_stat - 1],
611 				assoc.wi_assoc_sta[0]&0xff, assoc.wi_assoc_sta[1]&0xff,
612 				assoc.wi_assoc_sta[2]&0xff, assoc.wi_assoc_sta[3]&0xff,
613 				assoc.wi_assoc_sta[4]&0xff, assoc.wi_assoc_sta[5]&0xff);
614 			break;
615 		case REASSOC:
616 			printf("%s: %s, AP = %x:%x:%x:%x:%x:%x, OldAP = %x:%x:%x:%x:%x:%x\n",
617 				sc->sc_dev.dv_xname, msg[assoc.wi_assoc_stat - 1],
618 				assoc.wi_assoc_sta[0]&0xff, assoc.wi_assoc_sta[1]&0xff,
619 				assoc.wi_assoc_sta[2]&0xff, assoc.wi_assoc_sta[3]&0xff,
620 				assoc.wi_assoc_sta[4]&0xff, assoc.wi_assoc_sta[5]&0xff,
621 				assoc.wi_assoc_osta[0]&0xff, assoc.wi_assoc_osta[1]&0xff,
622 				assoc.wi_assoc_osta[2]&0xff, assoc.wi_assoc_osta[3]&0xff,
623 				assoc.wi_assoc_osta[4]&0xff, assoc.wi_assoc_osta[5]&0xff);
624 			break;
625 		}
626 		}
627 	default:
628 #if 0
629 		printf("Got info type: %04x\n", gen.wi_type);
630 #endif
631 		for (i = 0; i < gen.wi_len; i++) {
632 			t = CSR_READ_2(sc, WI_DATA1);
633 #if 0
634 			printf("[0x%02x] = 0x%04x\n", i, t);
635 #endif
636 		}
637 		break;
638 	}
639 }
640 
641 int wi_intr(arg)
642 	void *arg;
643 {
644 	struct wi_softc		*sc = arg;
645 	struct ifnet		*ifp;
646 	u_int16_t		status;
647 
648 	if (sc->sc_enabled == 0 ||
649 	    (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0 ||
650 	    (sc->sc_ethercom.ec_if.if_flags & IFF_RUNNING) == 0)
651 		return (0);
652 
653 	ifp = &sc->sc_ethercom.ec_if;
654 
655 	if (!(ifp->if_flags & IFF_UP)) {
656 		CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
657 		CSR_WRITE_2(sc, WI_INT_EN, 0);
658 		return 1;
659 	}
660 
661 	/* Disable interrupts. */
662 	CSR_WRITE_2(sc, WI_INT_EN, 0);
663 
664 	status = CSR_READ_2(sc, WI_EVENT_STAT);
665 	CSR_WRITE_2(sc, WI_EVENT_ACK, ~WI_INTRS);
666 
667 	if (status & WI_EV_RX) {
668 		wi_rxeof(sc);
669 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
670 	}
671 
672 	if (status & WI_EV_TX) {
673 		wi_txeof(sc, status);
674 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX);
675 	}
676 
677 	if (status & WI_EV_ALLOC) {
678 		int			id;
679 		id = CSR_READ_2(sc, WI_ALLOC_FID);
680 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
681 		if (id == sc->wi_tx_data_id)
682 			wi_txeof(sc, status);
683 	}
684 
685 	if (status & WI_EV_INFO) {
686 		wi_update_stats(sc);
687 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO);
688 	}
689 
690 	if (status & WI_EV_TX_EXC) {
691 		wi_txeof(sc, status);
692 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX_EXC);
693 	}
694 
695 	if (status & WI_EV_INFO_DROP) {
696 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO_DROP);
697 	}
698 
699 	/* Re-enable interrupts. */
700 	CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
701 
702 	if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
703 		wi_start(ifp);
704 
705 	return 1;
706 }
707 
708 static int
709 wi_cmd(sc, cmd, val)
710 	struct wi_softc		*sc;
711 	int			cmd;
712 	int			val;
713 {
714 	int			i, s = 0;
715 
716 	/* wait for the busy bit to clear */
717 	for (i = 0; i < WI_TIMEOUT; i++) {
718 		if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY))
719 			break;
720 	}
721 
722 	CSR_WRITE_2(sc, WI_PARAM0, val);
723 	CSR_WRITE_2(sc, WI_PARAM1, 0);
724 	CSR_WRITE_2(sc, WI_PARAM2, 0);
725 	CSR_WRITE_2(sc, WI_COMMAND, cmd);
726 
727 	/* wait for the cmd completed bit */
728 	for (i = 0; i < WI_TIMEOUT; i++) {
729 		if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_CMD)
730 			break;
731 		DELAY(1);
732 	}
733 
734 	/* Ack the command */
735 	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
736 
737 	s = CSR_READ_2(sc, WI_STATUS);
738 	if (s & WI_STAT_CMD_RESULT)
739 		return(EIO);
740 
741 	if (i == WI_TIMEOUT)
742 		return(ETIMEDOUT);
743 
744 	return(0);
745 }
746 
747 static void
748 wi_reset(sc)
749 	struct wi_softc		*sc;
750 {
751 	DELAY(100*1000); /* 100 m sec */
752 	if (wi_cmd(sc, WI_CMD_INI, 0))
753 		printf("%s: init failed\n", sc->sc_dev.dv_xname);
754 	CSR_WRITE_2(sc, WI_INT_EN, 0);
755 	CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
756 
757 	/* Calibrate timer. */
758 	WI_SETVAL(WI_RID_TICK_TIME, 8);
759 
760 	return;
761 }
762 
763 void
764 wi_pci_reset(sc)
765 	struct wi_softc		*sc;
766 {
767 	bus_space_write_2(sc->sc_iot, sc->sc_ioh,
768 			  WI_PCI_COR, WI_PCI_SOFT_RESET);
769 	DELAY(100*1000); /* 100 m sec */
770 
771 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, WI_PCI_COR, 0x0);
772 	DELAY(100*1000); /* 100 m sec */
773 
774 	return;
775 }
776 
777 /*
778  * Read an LTV record from the NIC.
779  */
780 static int wi_read_record(sc, ltv)
781 	struct wi_softc		*sc;
782 	struct wi_ltv_gen	*ltv;
783 {
784 	u_int16_t		*ptr;
785 	int			len, code;
786 	struct wi_ltv_gen	*oltv, p2ltv;
787 
788 	if (sc->sc_prism2) {
789 		oltv = ltv;
790 		switch (ltv->wi_type) {
791 		case WI_RID_ENCRYPTION:
792 			p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
793 			p2ltv.wi_len = 2;
794 			ltv = &p2ltv;
795 			break;
796 		case WI_RID_TX_CRYPT_KEY:
797 			p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
798 			p2ltv.wi_len = 2;
799 			ltv = &p2ltv;
800 			break;
801 		}
802 	}
803 
804 	/* Tell the NIC to enter record read mode. */
805 	if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type))
806 		return(EIO);
807 
808 	/* Seek to the record. */
809 	if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
810 		return(EIO);
811 
812 	/*
813 	 * Read the length and record type and make sure they
814 	 * match what we expect (this verifies that we have enough
815 	 * room to hold all of the returned data).
816 	 */
817 	len = CSR_READ_2(sc, WI_DATA1);
818 	if (len > ltv->wi_len)
819 		return(ENOSPC);
820 	code = CSR_READ_2(sc, WI_DATA1);
821 	if (code != ltv->wi_type)
822 		return(EIO);
823 
824 	ltv->wi_len = len;
825 	ltv->wi_type = code;
826 
827 	/* Now read the data. */
828 	ptr = &ltv->wi_val;
829 	if (ltv->wi_len > 1)
830 		CSR_READ_MULTI_STREAM_2(sc, WI_DATA1, ptr, ltv->wi_len - 1);
831 
832 	if (sc->sc_prism2) {
833 		int v;
834 
835 		switch (oltv->wi_type) {
836 		case WI_RID_TX_RATE:
837 		case WI_RID_CUR_TX_RATE:
838 			switch (le16toh(ltv->wi_val)) {
839 			case 1: v = 1; break;
840 			case 2: v = 2; break;
841 			case 3:	v = 6; break;
842 			case 4: v = 5; break;
843 			case 7: v = 7; break;
844 			case 8: v = 11; break;
845 			case 15: v = 3; break;
846 			default: v = 0x100 + le16toh(ltv->wi_val); break;
847 			}
848 			oltv->wi_val = htole16(v);
849 			break;
850 		case WI_RID_ENCRYPTION:
851 			oltv->wi_len = 2;
852 			if (le16toh(ltv->wi_val) & 0x01)
853 				oltv->wi_val = htole16(1);
854 			else
855 				oltv->wi_val = htole16(0);
856 			break;
857 		case WI_RID_TX_CRYPT_KEY:
858 			oltv->wi_len = 2;
859 			oltv->wi_val = ltv->wi_val;
860 			break;
861 		case WI_RID_AUTH_CNTL:
862 			oltv->wi_len = 2;
863 			if (le16toh(ltv->wi_val) & 0x01)
864 				oltv->wi_val = htole16(1);
865 			else if (le16toh(ltv->wi_val) & 0x02)
866 				oltv->wi_val = htole16(2);
867 			break;
868 		}
869 	}
870 
871 	return(0);
872 }
873 
874 /*
875  * Same as read, except we inject data instead of reading it.
876  */
877 static int wi_write_record(sc, ltv)
878 	struct wi_softc		*sc;
879 	struct wi_ltv_gen	*ltv;
880 {
881 	u_int16_t		*ptr;
882 	int			i;
883 	struct wi_ltv_gen	p2ltv;
884 
885 	if (sc->sc_prism2) {
886 		int v;
887 
888 		switch (ltv->wi_type) {
889 		case WI_RID_TX_RATE:
890 			p2ltv.wi_type = WI_RID_TX_RATE;
891 			p2ltv.wi_len = 2;
892 			switch (le16toh(ltv->wi_val)) {
893 			case 1: v = 1; break;
894 			case 2: v = 2; break;
895 			case 3:	v = 15; break;
896 			case 5: v = 4; break;
897 			case 6: v = 3; break;
898 			case 7: v = 7; break;
899 			case 11: v = 8; break;
900 			default: return EINVAL;
901 			}
902 			p2ltv.wi_val = htole16(v);
903 			ltv = &p2ltv;
904 			break;
905 		case WI_RID_ENCRYPTION:
906 			p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
907 			p2ltv.wi_len = 2;
908 			if (le16toh(ltv->wi_val))
909 				p2ltv.wi_val = htole16(0x03);
910 			else
911 				p2ltv.wi_val = htole16(0x90);
912 			ltv = &p2ltv;
913 			break;
914 		case WI_RID_TX_CRYPT_KEY:
915 			p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
916 			p2ltv.wi_len = 2;
917 			p2ltv.wi_val = ltv->wi_val;
918 			ltv = &p2ltv;
919 			break;
920 		case WI_RID_DEFLT_CRYPT_KEYS:
921 		    {
922 			int error;
923 			struct wi_ltv_str	ws;
924 			struct wi_ltv_keys	*wk = (struct wi_ltv_keys *)ltv;
925 			for (i = 0; i < 4; i++) {
926 				memset(&ws, 0, sizeof(ws));
927 				if(wk->wi_keys[i].wi_keylen <= 5) {
928 					/* 5 Octets WEP Keys */
929 					ws.wi_len = 4;
930 					memcpy(ws.wi_str, &wk->wi_keys[i].wi_keydat, 5);
931 					ws.wi_str[5] = '\0';
932 				} else {
933 					/* 13 Octets WEP Keys */
934 					ws.wi_len = 8;
935 					memcpy(ws.wi_str, &wk->wi_keys[i].wi_keydat, 13);
936 					ws.wi_str[13] = '\0';
937 				}
938 				ws.wi_type = WI_RID_P2_CRYPT_KEY0 + i;
939 
940 				if(wi_write_record(sc, (struct wi_ltv_gen *)&ws))
941 					return error;
942 			}
943 			return 0;
944 		    }
945 		case WI_RID_AUTH_CNTL:
946 			p2ltv.wi_type = WI_RID_AUTH_CNTL;
947 			p2ltv.wi_len = 2;
948 			if (le16toh(ltv->wi_val) == 1)
949 				p2ltv.wi_val = htole16(0x01);
950 			else if (le16toh(ltv->wi_val) == 2)
951 				p2ltv.wi_val = htole16(0x02);
952 			ltv = &p2ltv;
953 			break;
954 		}
955 	}
956 
957 	if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
958 		return(EIO);
959 
960 	CSR_WRITE_2(sc, WI_DATA1, ltv->wi_len);
961 	CSR_WRITE_2(sc, WI_DATA1, ltv->wi_type);
962 
963 	/* Write data */
964 	ptr = &ltv->wi_val;
965 	if (ltv->wi_len > 1)
966 		CSR_WRITE_MULTI_STREAM_2(sc, WI_DATA1, ptr, ltv->wi_len - 1);
967 
968 	if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_WRITE, ltv->wi_type))
969 		return(EIO);
970 
971 	return(0);
972 }
973 
974 static int wi_seek(sc, id, off, chan)
975 	struct wi_softc		*sc;
976 	int			id, off, chan;
977 {
978 	int			i;
979 	int			selreg, offreg;
980 	int 			status;
981 
982 	switch (chan) {
983 	case WI_BAP0:
984 		selreg = WI_SEL0;
985 		offreg = WI_OFF0;
986 		break;
987 	case WI_BAP1:
988 		selreg = WI_SEL1;
989 		offreg = WI_OFF1;
990 		break;
991 	default:
992 		printf("%s: invalid data path: %x\n",
993 		    sc->sc_dev.dv_xname, chan);
994 		return(EIO);
995 	}
996 
997 	CSR_WRITE_2(sc, selreg, id);
998 	CSR_WRITE_2(sc, offreg, off);
999 
1000 	for (i = 0; i < WI_TIMEOUT; i++) {
1001 	  	status = CSR_READ_2(sc, offreg);
1002 		if (!(status & (WI_OFF_BUSY|WI_OFF_ERR)))
1003 			break;
1004 	}
1005 
1006 	if (i == WI_TIMEOUT) {
1007 		printf("%s: timeout in wi_seek to %x/%x; last status %x\n",
1008 		       sc->sc_dev.dv_xname, id, off, status);
1009 		return(ETIMEDOUT);
1010 	}
1011 	return(0);
1012 }
1013 
1014 static int wi_read_data(sc, id, off, buf, len)
1015 	struct wi_softc		*sc;
1016 	int			id, off;
1017 	caddr_t			buf;
1018 	int			len;
1019 {
1020 	u_int16_t		*ptr;
1021 
1022 	if (wi_seek(sc, id, off, WI_BAP1))
1023 		return(EIO);
1024 
1025 	ptr = (u_int16_t *)buf;
1026 	CSR_READ_MULTI_STREAM_2(sc, WI_DATA1, ptr, len / 2);
1027 
1028 	return(0);
1029 }
1030 
1031 /*
1032  * According to the comments in the HCF Light code, there is a bug in
1033  * the Hermes (or possibly in certain Hermes firmware revisions) where
1034  * the chip's internal autoincrement counter gets thrown off during
1035  * data writes: the autoincrement is missed, causing one data word to
1036  * be overwritten and subsequent words to be written to the wrong memory
1037  * locations. The end result is that we could end up transmitting bogus
1038  * frames without realizing it. The workaround for this is to write a
1039  * couple of extra guard words after the end of the transfer, then
1040  * attempt to read then back. If we fail to locate the guard words where
1041  * we expect them, we preform the transfer over again.
1042  */
1043 static int wi_write_data(sc, id, off, buf, len)
1044 	struct wi_softc		*sc;
1045 	int			id, off;
1046 	caddr_t			buf;
1047 	int			len;
1048 {
1049 	u_int16_t		*ptr;
1050 
1051 #ifdef WI_HERMES_AUTOINC_WAR
1052 again:
1053 #endif
1054 
1055 	if (wi_seek(sc, id, off, WI_BAP0))
1056 		return(EIO);
1057 
1058 	ptr = (u_int16_t *)buf;
1059 	CSR_WRITE_MULTI_STREAM_2(sc, WI_DATA0, ptr, len / 2);
1060 
1061 #ifdef WI_HERMES_AUTOINC_WAR
1062 	CSR_WRITE_2(sc, WI_DATA0, 0x1234);
1063 	CSR_WRITE_2(sc, WI_DATA0, 0x5678);
1064 
1065 	if (wi_seek(sc, id, off + len, WI_BAP0))
1066 		return(EIO);
1067 
1068 	if (CSR_READ_2(sc, WI_DATA0) != 0x1234 ||
1069 	    CSR_READ_2(sc, WI_DATA0) != 0x5678)
1070 		goto again;
1071 #endif
1072 
1073 	return(0);
1074 }
1075 
1076 /*
1077  * Allocate a region of memory inside the NIC and zero
1078  * it out.
1079  */
1080 static int wi_alloc_nicmem(sc, len, id)
1081 	struct wi_softc		*sc;
1082 	int			len;
1083 	int			*id;
1084 {
1085 	int			i;
1086 
1087 	if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len)) {
1088 		printf("%s: failed to allocate %d bytes on NIC\n",
1089 		    sc->sc_dev.dv_xname, len);
1090 		return(ENOMEM);
1091 	}
1092 
1093 	for (i = 0; i < WI_TIMEOUT; i++) {
1094 		if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC)
1095 			break;
1096 	}
1097 
1098 	if (i == WI_TIMEOUT) {
1099 		printf("%s: TIMED OUT in alloc\n", sc->sc_dev.dv_xname);
1100 		return(ETIMEDOUT);
1101 	}
1102 
1103 	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
1104 	*id = CSR_READ_2(sc, WI_ALLOC_FID);
1105 
1106 	if (wi_seek(sc, *id, 0, WI_BAP0)) {
1107 		printf("%s: seek failed in alloc\n", sc->sc_dev.dv_xname);
1108 		return(EIO);
1109 	}
1110 
1111 	for (i = 0; i < len / 2; i++)
1112 		CSR_WRITE_2(sc, WI_DATA0, 0);
1113 
1114 	return(0);
1115 }
1116 
1117 static void wi_setmulti(sc)
1118 	struct wi_softc		*sc;
1119 {
1120 	struct ifnet		*ifp;
1121 	int			i = 0;
1122 	struct wi_ltv_mcast	mcast;
1123 	struct ether_multi *enm;
1124 	struct ether_multistep estep;
1125 	struct ethercom *ec = &sc->sc_ethercom;
1126 
1127 	ifp = &sc->sc_ethercom.ec_if;
1128 
1129 	if ((ifp->if_flags & IFF_PROMISC) != 0) {
1130 allmulti:
1131 		ifp->if_flags |= IFF_ALLMULTI;
1132 		memset((char *)&mcast, 0, sizeof(mcast));
1133 		mcast.wi_type = WI_RID_MCAST_LIST;
1134 		mcast.wi_len = ((ETHER_ADDR_LEN / 2) * 16) + 1;
1135 
1136 		wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
1137 		return;
1138 	}
1139 
1140 	i = 0;
1141 	ETHER_FIRST_MULTI(estep, ec, enm);
1142 	while (enm != NULL) {
1143 		/* Punt on ranges or too many multicast addresses. */
1144 		if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
1145 		    ETHER_ADDR_LEN) != 0 ||
1146 		    i >= 16)
1147 			goto allmulti;
1148 
1149 		memcpy((char *)&mcast.wi_mcast[i], enm->enm_addrlo,
1150 		    ETHER_ADDR_LEN);
1151 		i++;
1152 		ETHER_NEXT_MULTI(estep, enm);
1153 	}
1154 
1155 	ifp->if_flags &= ~IFF_ALLMULTI;
1156 	mcast.wi_type = WI_RID_MCAST_LIST;
1157 	mcast.wi_len = ((ETHER_ADDR_LEN / 2) * i) + 1;
1158 	wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
1159 }
1160 
1161 static int
1162 wi_setdef(sc, wreq)
1163 	struct wi_softc		*sc;
1164 	struct wi_req		*wreq;
1165 {
1166 	struct sockaddr_dl	*sdl;
1167 	struct ifnet		*ifp;
1168 	int error = 0;
1169 
1170 	ifp = &sc->sc_ethercom.ec_if;
1171 
1172 	switch(wreq->wi_type) {
1173 	case WI_RID_MAC_NODE:
1174 		sdl = (struct sockaddr_dl *)ifp->if_sadl;
1175 		memcpy((char *)&sc->sc_macaddr, (char *)&wreq->wi_val,
1176 		    ETHER_ADDR_LEN);
1177 		memcpy(LLADDR(sdl), (char *)&wreq->wi_val, ETHER_ADDR_LEN);
1178 		break;
1179 	case WI_RID_PORTTYPE:
1180 		error = wi_sync_media(sc, le16toh(wreq->wi_val[0]), sc->wi_tx_rate);
1181 		break;
1182 	case WI_RID_TX_RATE:
1183 		error = wi_sync_media(sc, sc->wi_ptype, le16toh(wreq->wi_val[0]));
1184 		break;
1185 	case WI_RID_MAX_DATALEN:
1186 		sc->wi_max_data_len = le16toh(wreq->wi_val[0]);
1187 		break;
1188 	case WI_RID_RTS_THRESH:
1189 		sc->wi_rts_thresh = le16toh(wreq->wi_val[0]);
1190 		break;
1191 	case WI_RID_SYSTEM_SCALE:
1192 		sc->wi_ap_density = le16toh(wreq->wi_val[0]);
1193 		break;
1194 	case WI_RID_CREATE_IBSS:
1195 		sc->wi_create_ibss = le16toh(wreq->wi_val[0]);
1196 		break;
1197 	case WI_RID_OWN_CHNL:
1198 		sc->wi_channel = le16toh(wreq->wi_val[0]);
1199 		break;
1200 	case WI_RID_NODENAME:
1201 		error = wi_set_ssid(&sc->wi_nodeid,
1202 		    (u_int8_t *)&wreq->wi_val[1], le16toh(wreq->wi_val[0]));
1203 		break;
1204 	case WI_RID_DESIRED_SSID:
1205 		error = wi_set_ssid(&sc->wi_netid,
1206 		    (u_int8_t *)&wreq->wi_val[1], le16toh(wreq->wi_val[0]));
1207 		break;
1208 	case WI_RID_OWN_SSID:
1209 		error = wi_set_ssid(&sc->wi_ibssid,
1210 		    (u_int8_t *)&wreq->wi_val[1], le16toh(wreq->wi_val[0]));
1211 		break;
1212 	case WI_RID_PM_ENABLED:
1213 		sc->wi_pm_enabled = le16toh(wreq->wi_val[0]);
1214 		break;
1215 	case WI_RID_MICROWAVE_OVEN:
1216 		sc->wi_mor_enabled = le16toh(wreq->wi_val[0]);
1217 		break;
1218 	case WI_RID_MAX_SLEEP:
1219 		sc->wi_max_sleep = le16toh(wreq->wi_val[0]);
1220 		break;
1221 	case WI_RID_AUTH_CNTL:
1222 		sc->wi_authtype = le16toh(wreq->wi_val[0]);
1223 		break;
1224 	case WI_RID_ROAMING_MODE:
1225 		sc->wi_roaming = le16toh(wreq->wi_val[0]);
1226 		break;
1227 	case WI_RID_ENCRYPTION:
1228 		sc->wi_use_wep = le16toh(wreq->wi_val[0]);
1229 		break;
1230 	case WI_RID_TX_CRYPT_KEY:
1231 		sc->wi_tx_key = le16toh(wreq->wi_val[0]);
1232 		break;
1233 	case WI_RID_DEFLT_CRYPT_KEYS:
1234 		memcpy((char *)&sc->wi_keys, (char *)wreq,
1235 		    sizeof(struct wi_ltv_keys));
1236 		break;
1237 	default:
1238 		error = EINVAL;
1239 		break;
1240 	}
1241 
1242 	return (error);
1243 }
1244 
1245 static int
1246 wi_getdef(sc, wreq)
1247 	struct wi_softc		*sc;
1248 	struct wi_req		*wreq;
1249 {
1250 	struct sockaddr_dl	*sdl;
1251 	struct ifnet		*ifp;
1252 	int error = 0;
1253 
1254 	ifp = &sc->sc_ethercom.ec_if;
1255 
1256 	wreq->wi_len = 2;			/* XXX */
1257 	switch (wreq->wi_type) {
1258 	case WI_RID_MAC_NODE:
1259 		wreq->wi_len += ETHER_ADDR_LEN / 2 - 1;
1260 		sdl = (struct sockaddr_dl *)ifp->if_sadl;
1261 		memcpy(&wreq->wi_val, &sc->sc_macaddr, ETHER_ADDR_LEN);
1262 		memcpy(&wreq->wi_val, LLADDR(sdl), ETHER_ADDR_LEN);
1263 		break;
1264 	case WI_RID_PORTTYPE:
1265 		wreq->wi_val[0] = htole16(sc->wi_ptype);
1266 		break;
1267 	case WI_RID_TX_RATE:
1268 		wreq->wi_val[0] = htole16(sc->wi_tx_rate);
1269 		break;
1270 	case WI_RID_MAX_DATALEN:
1271 		wreq->wi_val[0] = htole16(sc->wi_max_data_len);
1272 		break;
1273 	case WI_RID_RTS_THRESH:
1274 		wreq->wi_val[0] = htole16(sc->wi_rts_thresh);
1275 		break;
1276 	case WI_RID_SYSTEM_SCALE:
1277 		wreq->wi_val[0] = htole16(sc->wi_ap_density);
1278 		break;
1279 	case WI_RID_CREATE_IBSS:
1280 		wreq->wi_val[0] = htole16(sc->wi_create_ibss);
1281 		break;
1282 	case WI_RID_OWN_CHNL:
1283 		wreq->wi_val[0] = htole16(sc->wi_channel);
1284 		break;
1285 	case WI_RID_NODENAME:
1286 		wi_request_fill_ssid(wreq, &sc->wi_nodeid);
1287 		break;
1288 	case WI_RID_DESIRED_SSID:
1289 		wi_request_fill_ssid(wreq, &sc->wi_netid);
1290 		break;
1291 	case WI_RID_OWN_SSID:
1292 		wi_request_fill_ssid(wreq, &sc->wi_ibssid);
1293 		break;
1294 	case WI_RID_PM_ENABLED:
1295 		wreq->wi_val[0] = htole16(sc->wi_pm_enabled);
1296 		break;
1297 	case WI_RID_MICROWAVE_OVEN:
1298 		wreq->wi_val[0] = htole16(sc->wi_mor_enabled);
1299 		break;
1300 	case WI_RID_MAX_SLEEP:
1301 		wreq->wi_val[0] = htole16(sc->wi_max_sleep);
1302 		break;
1303 	case WI_RID_AUTH_CNTL:
1304 		wreq->wi_val[0] = htole16(sc->wi_authtype);
1305 		break;
1306 	case WI_RID_ROAMING_MODE:
1307 		wreq->wi_val[0] = htole16(sc->wi_roaming);
1308 		break;
1309 	case WI_RID_WEP_AVAIL:
1310 		wreq->wi_val[0] = htole16(sc->wi_has_wep);
1311 		break;
1312 	case WI_RID_ENCRYPTION:
1313 		wreq->wi_val[0] = htole16(sc->wi_use_wep);
1314 		break;
1315 	case WI_RID_TX_CRYPT_KEY:
1316 		wreq->wi_val[0] = htole16(sc->wi_tx_key);
1317 		break;
1318 	case WI_RID_DEFLT_CRYPT_KEYS:
1319 		wreq->wi_len += sizeof(struct wi_ltv_keys) / 2 - 1;
1320 		memcpy(wreq, &sc->wi_keys, sizeof(struct wi_ltv_keys));
1321 		break;
1322 	default:
1323 #if 0
1324 		error = EIO;
1325 #else
1326 #ifdef WI_DEBUG
1327 		printf("%s: wi_getdef: unknown request %d\n",
1328 		    sc->sc_dev.dv_xname, wreq->wi_type);
1329 #endif
1330 #endif
1331 		break;
1332 	}
1333 
1334 	return (error);
1335 }
1336 
1337 static int
1338 wi_ioctl(ifp, command, data)
1339 	struct ifnet		*ifp;
1340 	u_long			command;
1341 	caddr_t			data;
1342 {
1343 	int			s, error = 0;
1344 	int			len;
1345 	struct wi_softc		*sc = ifp->if_softc;
1346 	struct wi_req		wreq;
1347 	struct ifreq		*ifr;
1348 	struct proc *p = curproc;
1349 	struct ieee80211_nwid nwid;
1350 
1351 	if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
1352 		return (ENXIO);
1353 
1354 	s = splnet();
1355 
1356 	ifr = (struct ifreq *)data;
1357 	switch (command) {
1358 	case SIOCSIFADDR:
1359 	case SIOCGIFADDR:
1360 	case SIOCSIFMTU:
1361 		error = ether_ioctl(ifp, command, data);
1362 		break;
1363 	case SIOCSIFFLAGS:
1364 		if (ifp->if_flags & IFF_UP) {
1365 			if (ifp->if_flags & IFF_RUNNING &&
1366 			    ifp->if_flags & IFF_PROMISC &&
1367 			    !(sc->wi_if_flags & IFF_PROMISC)) {
1368 				WI_SETVAL(WI_RID_PROMISC, 1);
1369 			} else if (ifp->if_flags & IFF_RUNNING &&
1370 			    !(ifp->if_flags & IFF_PROMISC) &&
1371 			    sc->wi_if_flags & IFF_PROMISC) {
1372 				WI_SETVAL(WI_RID_PROMISC, 0);
1373 			}
1374 			wi_init(ifp);
1375 		} else {
1376 			if (ifp->if_flags & IFF_RUNNING) {
1377 				wi_stop(ifp, 0);
1378 			}
1379 		}
1380 		sc->wi_if_flags = ifp->if_flags;
1381 
1382 		if (!(ifp->if_flags & IFF_UP)) {
1383 			if (sc->sc_enabled) {
1384 				if (sc->sc_disable)
1385 					(*sc->sc_disable)(sc);
1386 				sc->sc_enabled = 0;
1387 				ifp->if_flags &= ~IFF_RUNNING;
1388 			}
1389 		}
1390 		error = 0;
1391 		break;
1392 	case SIOCADDMULTI:
1393 	case SIOCDELMULTI:
1394 		error = (command == SIOCADDMULTI) ?
1395 			ether_addmulti(ifr, &sc->sc_ethercom) :
1396 			ether_delmulti(ifr, &sc->sc_ethercom);
1397 		if (error == ENETRESET) {
1398 			if (sc->sc_enabled != 0) {
1399 				/*
1400 				 * Multicast list has changed.  Set the
1401 				 * hardware filter accordingly.
1402 				 */
1403 				wi_setmulti(sc);
1404 			}
1405 			error = 0;
1406 		}
1407 		break;
1408 	case SIOCSIFMEDIA:
1409 	case SIOCGIFMEDIA:
1410 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, command);
1411 		break;
1412 	case SIOCGWAVELAN:
1413 		error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1414 		if (error)
1415 			break;
1416 		if (wreq.wi_type == WI_RID_IFACE_STATS) {
1417 			wi_update_stats(sc);
1418 			/* XXX native byte order */
1419 			memcpy((char *)&wreq.wi_val, (char *)&sc->wi_stats,
1420 			    sizeof(sc->wi_stats));
1421 			wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1;
1422 		} else if (wreq.wi_type == WI_RID_READ_APS) {
1423 			if (sc->wi_scanning) {
1424 				error = EINVAL;
1425 				break;
1426 			} else {
1427 				len = sc->wi_naps * sizeof(struct wi_apinfo);
1428 				len = len > WI_MAX_DATALEN ? WI_MAX_DATALEN : len;
1429 				len = len / sizeof(struct wi_apinfo);
1430 				memcpy((char *)&wreq.wi_val, (char *)&len, sizeof(len));
1431 				memcpy((char *)&wreq.wi_val + sizeof(len),
1432 					(char *)&sc->wi_aps,
1433 					len * sizeof(struct wi_apinfo));
1434 			}
1435 		} else if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS) {
1436 			/* For non-root user, return all-zeroes keys */
1437 			if (suser(p->p_ucred, &p->p_acflag))
1438 				memset((char *)&wreq, 0,
1439 				    sizeof(struct wi_ltv_keys));
1440 			else
1441 				memcpy((char *)&wreq, (char *)&sc->wi_keys,
1442 				    sizeof(struct wi_ltv_keys));
1443 		} else {
1444 			if (sc->sc_enabled == 0)
1445 				error = wi_getdef(sc, &wreq);
1446 			else if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq))
1447 				error = EINVAL;
1448 		}
1449 		if (error == 0)
1450 			error = copyout(&wreq, ifr->ifr_data, sizeof(wreq));
1451 		break;
1452 	case SIOCSWAVELAN:
1453 		error = suser(p->p_ucred, &p->p_acflag);
1454 		if (error)
1455 			break;
1456 		error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1457 		if (error)
1458 			break;
1459 		if (wreq.wi_type == WI_RID_IFACE_STATS) {
1460 			error = EINVAL;
1461 			break;
1462 		} else if (wreq.wi_type == WI_RID_MGMT_XMIT) {
1463 			error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val,
1464 			    wreq.wi_len);
1465 		} else if (wreq.wi_type == WI_RID_SCAN_APS) {
1466 			if (wreq.wi_len != 4) {
1467 				error = EINVAL;
1468 				break;
1469 			}
1470 			if (!sc->wi_scanning) {
1471 				if (sc->sc_prism2) {
1472 					wreq.wi_type = WI_RID_SCAN_REQ;
1473 					error = wi_write_record(sc,
1474 					    (struct wi_ltv_gen *)&wreq);
1475 				}
1476 				if (!error) {
1477 					sc->wi_scanning = 1;
1478 					callout_reset(&sc->wi_scan_sh, hz * 1,
1479 						wi_wait_scan, sc);
1480 				}
1481 			}
1482 		} else {
1483 			if (sc->sc_enabled != 0)
1484 				error = wi_write_record(sc,
1485 				    (struct wi_ltv_gen *)&wreq);
1486 			if (error == 0)
1487 				error = wi_setdef(sc, &wreq);
1488 			if (error == 0 && sc->sc_enabled != 0)
1489 				/* Reinitialize WaveLAN. */
1490 				wi_init(ifp);
1491 		}
1492 		break;
1493 	case SIOCG80211NWID:
1494 		if (sc->sc_enabled == 0) {
1495 			/* Return the desired ID */
1496 			error = copyout(&sc->wi_netid, ifr->ifr_data,
1497 			    sizeof(sc->wi_netid));
1498 		} else {
1499 			wreq.wi_type = WI_RID_CURRENT_SSID;
1500 			wreq.wi_len = WI_MAX_DATALEN;
1501 			if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) ||
1502 			    le16toh(wreq.wi_val[0]) > IEEE80211_NWID_LEN)
1503 				error = EINVAL;
1504 			else {
1505 				wi_set_ssid(&nwid, (u_int8_t *)&wreq.wi_val[1],
1506 				    le16toh(wreq.wi_val[0]));
1507 				error = copyout(&nwid, ifr->ifr_data,
1508 				    sizeof(nwid));
1509 			}
1510 		}
1511 		break;
1512 	case SIOCS80211NWID:
1513 		error = copyin(ifr->ifr_data, &nwid, sizeof(nwid));
1514 		if (error != 0)
1515 			break;
1516 		if (nwid.i_len > IEEE80211_NWID_LEN) {
1517 			error = EINVAL;
1518 			break;
1519 		}
1520 		if (sc->wi_netid.i_len == nwid.i_len &&
1521 		    memcmp(sc->wi_netid.i_nwid, nwid.i_nwid, nwid.i_len) == 0)
1522 			break;
1523 		wi_set_ssid(&sc->wi_netid, nwid.i_nwid, nwid.i_len);
1524 		if (sc->sc_enabled != 0)
1525 			/* Reinitialize WaveLAN. */
1526 			wi_init(ifp);
1527 		break;
1528 	case SIOCS80211NWKEY:
1529 		error = wi_set_nwkey(sc, (struct ieee80211_nwkey *)data);
1530 		break;
1531 	case SIOCG80211NWKEY:
1532 		error = wi_get_nwkey(sc, (struct ieee80211_nwkey *)data);
1533 		break;
1534 	case SIOCS80211POWER:
1535 		error = wi_set_pm(sc, (struct ieee80211_power *)data);
1536 		break;
1537 	case SIOCG80211POWER:
1538 		error = wi_get_pm(sc, (struct ieee80211_power *)data);
1539 		break;
1540 
1541 	default:
1542 		error = EINVAL;
1543 		break;
1544 	}
1545 
1546 	splx(s);
1547 	return (error);
1548 }
1549 
1550 static int
1551 wi_init(ifp)
1552 	struct ifnet *ifp;
1553 {
1554 	struct wi_softc *sc = ifp->if_softc;
1555 	struct wi_req wreq;
1556 	struct wi_ltv_macaddr mac;
1557 	int error, id = 0;
1558 
1559 	if (!sc->sc_enabled) {
1560 		if ((error = (*sc->sc_enable)(sc)) != 0)
1561 			goto out;
1562 		sc->sc_enabled = 1;
1563 	}
1564 
1565 	wi_stop(ifp, 0);
1566 	wi_reset(sc);
1567 
1568 	/* Program max data length. */
1569 	WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len);
1570 
1571 	/* Enable/disable IBSS creation. */
1572 	WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss);
1573 
1574 	/* Set the port type. */
1575 	WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype);
1576 
1577 	/* Program the RTS/CTS threshold. */
1578 	WI_SETVAL(WI_RID_RTS_THRESH, sc->wi_rts_thresh);
1579 
1580 	/* Program the TX rate */
1581 	WI_SETVAL(WI_RID_TX_RATE, sc->wi_tx_rate);
1582 
1583 	/* Access point density */
1584 	WI_SETVAL(WI_RID_SYSTEM_SCALE, sc->wi_ap_density);
1585 
1586 	/* Power Management Enabled */
1587 	WI_SETVAL(WI_RID_PM_ENABLED, sc->wi_pm_enabled);
1588 
1589 	/* Power Managment Max Sleep */
1590 	WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep);
1591 
1592 	/* Roaming type */
1593 	WI_SETVAL(WI_RID_ROAMING_MODE, sc->wi_roaming);
1594 
1595 	/* Specify the IBSS name */
1596 	wi_write_ssid(sc, WI_RID_OWN_SSID, &wreq, &sc->wi_ibssid);
1597 
1598 	/* Specify the network name */
1599 	wi_write_ssid(sc, WI_RID_DESIRED_SSID, &wreq, &sc->wi_netid);
1600 
1601 	/* Specify the frequency to use */
1602 	WI_SETVAL(WI_RID_OWN_CHNL, sc->wi_channel);
1603 
1604 	/* Program the nodename. */
1605 	wi_write_ssid(sc, WI_RID_NODENAME, &wreq, &sc->wi_nodeid);
1606 
1607 	/* Set our MAC address. */
1608 	mac.wi_len = 4;
1609 	mac.wi_type = WI_RID_MAC_NODE;
1610 	memcpy(&mac.wi_mac_addr, sc->sc_macaddr, ETHER_ADDR_LEN);
1611 	wi_write_record(sc, (struct wi_ltv_gen *)&mac);
1612 
1613 	/* Initialize promisc mode. */
1614 	if (ifp->if_flags & IFF_PROMISC) {
1615 		WI_SETVAL(WI_RID_PROMISC, 1);
1616 	} else {
1617 		WI_SETVAL(WI_RID_PROMISC, 0);
1618 	}
1619 
1620 	/* Configure WEP. */
1621 	if (sc->wi_has_wep) {
1622 		WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep);
1623 		WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key);
1624 		sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1;
1625 		sc->wi_keys.wi_type = WI_RID_DEFLT_CRYPT_KEYS;
1626 		wi_write_record(sc, (struct wi_ltv_gen *)&sc->wi_keys);
1627 		if (sc->sc_prism2 && sc->wi_use_wep) {
1628 			/*
1629 			 * ONLY HWB3163 EVAL-CARD Firmware version
1630 			 * less than 0.8 variant3
1631 			 *
1632 			 *   If promiscuous mode disable, Prism2 chip
1633 			 *  does not work with WEP .
1634 			 * It is under investigation for details.
1635 			 * (ichiro@netbsd.org)
1636 			 */
1637 			if (sc->sc_prism2_ver < 83 ) {
1638 				/* firm ver < 0.8 variant 3 */
1639 				WI_SETVAL(WI_RID_PROMISC, 1);
1640 			}
1641 			WI_SETVAL(WI_RID_AUTH_CNTL, sc->wi_authtype);
1642 		}
1643 	}
1644 
1645 	/* Set multicast filter. */
1646 	wi_setmulti(sc);
1647 
1648 	/* Enable desired port */
1649 	wi_cmd(sc, WI_CMD_ENABLE | sc->wi_portnum, 0);
1650 
1651 	/*  scanning variable is modal, therefore reinit to OFF, in case it was on. */
1652 	sc->wi_scanning=0;
1653 	sc->wi_naps=0;
1654 
1655 	if ((error = wi_alloc_nicmem(sc,
1656 	    1518 + sizeof(struct wi_frame) + 8, &id)) != 0) {
1657 		printf("%s: tx buffer allocation failed\n",
1658 		    sc->sc_dev.dv_xname);
1659 		goto out;
1660 	}
1661 	sc->wi_tx_data_id = id;
1662 
1663 	if ((error = wi_alloc_nicmem(sc,
1664 	    1518 + sizeof(struct wi_frame) + 8, &id)) != 0) {
1665 		printf("%s: mgmt. buffer allocation failed\n",
1666 		    sc->sc_dev.dv_xname);
1667 		goto out;
1668 	}
1669 	sc->wi_tx_mgmt_id = id;
1670 
1671 	/* Enable interrupts */
1672 	CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
1673 
1674 	ifp->if_flags |= IFF_RUNNING;
1675 	ifp->if_flags &= ~IFF_OACTIVE;
1676 
1677 	callout_reset(&sc->wi_inquire_ch, hz * 60, wi_inquire, sc);
1678 
1679  out:
1680 	if (error) {
1681 		ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1682 		ifp->if_timer = 0;
1683 		printf("%s: interface not running\n", sc->sc_dev.dv_xname);
1684 	}
1685 	return (error);
1686 }
1687 
1688 static void
1689 wi_start(ifp)
1690 	struct ifnet		*ifp;
1691 {
1692 	struct wi_softc		*sc;
1693 	struct mbuf		*m0;
1694 	struct wi_frame		tx_frame;
1695 	struct ether_header	*eh;
1696 	int			id;
1697 
1698 	sc = ifp->if_softc;
1699 
1700 	if (ifp->if_flags & IFF_OACTIVE)
1701 		return;
1702 
1703 	IFQ_DEQUEUE(&ifp->if_snd, m0);
1704 	if (m0 == NULL)
1705 		return;
1706 
1707 	memset((char *)&tx_frame, 0, sizeof(tx_frame));
1708 	id = sc->wi_tx_data_id;
1709 	eh = mtod(m0, struct ether_header *);
1710 
1711 	/*
1712 	 * Use RFC1042 encoding for IP and ARP datagrams,
1713 	 * 802.3 for anything else.
1714 	 */
1715 	if (ntohs(eh->ether_type) == ETHERTYPE_IP ||
1716 	    ntohs(eh->ether_type) == ETHERTYPE_ARP ||
1717 	    ntohs(eh->ether_type) == ETHERTYPE_REVARP ||
1718 	    ntohs(eh->ether_type) == ETHERTYPE_IPV6) {
1719 		memcpy((char *)&tx_frame.wi_addr1, (char *)&eh->ether_dhost,
1720 		    ETHER_ADDR_LEN);
1721 		memcpy((char *)&tx_frame.wi_addr2, (char *)&eh->ether_shost,
1722 		    ETHER_ADDR_LEN);
1723 		memcpy((char *)&tx_frame.wi_dst_addr, (char *)&eh->ether_dhost,
1724 		    ETHER_ADDR_LEN);
1725 		memcpy((char *)&tx_frame.wi_src_addr, (char *)&eh->ether_shost,
1726 		    ETHER_ADDR_LEN);
1727 
1728 		tx_frame.wi_dat_len = htole16(m0->m_pkthdr.len - WI_SNAPHDR_LEN);
1729 		tx_frame.wi_frame_ctl = htole16(WI_FTYPE_DATA);
1730 		tx_frame.wi_dat[0] = htons(WI_SNAP_WORD0);
1731 		tx_frame.wi_dat[1] = htons(WI_SNAP_WORD1);
1732 		tx_frame.wi_len = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN);
1733 		tx_frame.wi_type = eh->ether_type;
1734 
1735 		m_copydata(m0, sizeof(struct ether_header),
1736 		    m0->m_pkthdr.len - sizeof(struct ether_header),
1737 		    (caddr_t)&sc->wi_txbuf);
1738 
1739 		wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
1740 		    sizeof(struct wi_frame));
1741 		wi_write_data(sc, id, WI_802_11_OFFSET, (caddr_t)&sc->wi_txbuf,
1742 		    (m0->m_pkthdr.len - sizeof(struct ether_header)) + 2);
1743 	} else {
1744 		tx_frame.wi_dat_len = htole16(m0->m_pkthdr.len);
1745 
1746 		m_copydata(m0, 0, m0->m_pkthdr.len, (caddr_t)&sc->wi_txbuf);
1747 
1748 		wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
1749 		    sizeof(struct wi_frame));
1750 		wi_write_data(sc, id, WI_802_3_OFFSET, (caddr_t)&sc->wi_txbuf,
1751 		    m0->m_pkthdr.len + 2);
1752 	}
1753 
1754 #if NBPFILTER > 0
1755 	/*
1756 	 * If there's a BPF listener, bounce a copy of
1757 	 * this frame to him.
1758 	 */
1759 	if (ifp->if_bpf)
1760 		bpf_mtap(ifp->if_bpf, m0);
1761 #endif
1762 
1763 	m_freem(m0);
1764 
1765 	if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id))
1766 		printf("%s: xmit failed\n", sc->sc_dev.dv_xname);
1767 
1768 	ifp->if_flags |= IFF_OACTIVE;
1769 
1770 	/*
1771 	 * Set a timeout in case the chip goes out to lunch.
1772 	 */
1773 	ifp->if_timer = 5;
1774 
1775 	return;
1776 }
1777 
1778 static int
1779 wi_mgmt_xmit(sc, data, len)
1780 	struct wi_softc		*sc;
1781 	caddr_t			data;
1782 	int			len;
1783 {
1784 	struct wi_frame		tx_frame;
1785 	int			id;
1786 	struct wi_80211_hdr	*hdr;
1787 	caddr_t			dptr;
1788 
1789 	hdr = (struct wi_80211_hdr *)data;
1790 	dptr = data + sizeof(struct wi_80211_hdr);
1791 
1792 	memset((char *)&tx_frame, 0, sizeof(tx_frame));
1793 	id = sc->wi_tx_mgmt_id;
1794 
1795 	memcpy((char *)&tx_frame.wi_frame_ctl, (char *)hdr,
1796 	   sizeof(struct wi_80211_hdr));
1797 
1798 	tx_frame.wi_dat_len = htole16(len - WI_SNAPHDR_LEN);
1799 	tx_frame.wi_len = htons(len - WI_SNAPHDR_LEN);
1800 
1801 	wi_write_data(sc, id, 0, (caddr_t)&tx_frame, sizeof(struct wi_frame));
1802 	wi_write_data(sc, id, WI_802_11_OFFSET_RAW, dptr,
1803 	    (len - sizeof(struct wi_80211_hdr)) + 2);
1804 
1805 	if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id)) {
1806 		printf("%s: xmit failed\n", sc->sc_dev.dv_xname);
1807 		return(EIO);
1808 	}
1809 
1810 	return(0);
1811 }
1812 
1813 static void
1814 wi_stop(ifp, disable)
1815 	struct ifnet *ifp;
1816 {
1817 	struct wi_softc	*sc = ifp->if_softc;
1818 
1819 	CSR_WRITE_2(sc, WI_INT_EN, 0);
1820 	wi_cmd(sc, WI_CMD_DISABLE|sc->wi_portnum, 0);
1821 
1822 	callout_stop(&sc->wi_inquire_ch);
1823 	callout_stop(&sc->wi_scan_sh);
1824 
1825 	if (disable) {
1826 		if (sc->sc_enabled) {
1827 			if (sc->sc_disable)
1828 				(*sc->sc_disable)(sc);
1829 			sc->sc_enabled = 0;
1830 		}
1831 	}
1832 
1833 	ifp->if_flags &= ~(IFF_OACTIVE | IFF_RUNNING);
1834 	ifp->if_timer = 0;
1835 }
1836 
1837 static void
1838 wi_watchdog(ifp)
1839 	struct ifnet		*ifp;
1840 {
1841 	struct wi_softc		*sc;
1842 
1843 	sc = ifp->if_softc;
1844 
1845 	printf("%s: device timeout\n", sc->sc_dev.dv_xname);
1846 
1847 	wi_init(ifp);
1848 
1849 	ifp->if_oerrors++;
1850 
1851 	return;
1852 }
1853 
1854 void
1855 wi_shutdown(sc)
1856 	struct wi_softc *sc;
1857 {
1858 	int s;
1859 
1860 	s = splnet();
1861 	if (sc->sc_enabled) {
1862 		if (sc->sc_disable)
1863 			(*sc->sc_disable)(sc);
1864 		sc->sc_enabled = 0;
1865 	}
1866 	splx(s);
1867 }
1868 
1869 int
1870 wi_activate(self, act)
1871 	struct device *self;
1872 	enum devact act;
1873 {
1874 	struct wi_softc *sc = (struct wi_softc *)self;
1875 	int rv = 0, s;
1876 
1877 	s = splnet();
1878 	switch (act) {
1879 	case DVACT_ACTIVATE:
1880 		rv = EOPNOTSUPP;
1881 		break;
1882 
1883 	case DVACT_DEACTIVATE:
1884 		if_deactivate(&sc->sc_ethercom.ec_if);
1885 		break;
1886 	}
1887 	splx(s);
1888 	return (rv);
1889 }
1890 
1891 static void
1892 wi_get_id(sc)
1893 	struct wi_softc *sc;
1894 {
1895 	struct wi_ltv_ver       ver;
1896 
1897 	/* getting chip identity */
1898 	memset(&ver, 0, sizeof(ver));
1899 	ver.wi_type = WI_RID_CARD_ID;
1900 	ver.wi_len = 5;
1901 	wi_read_record(sc, (struct wi_ltv_gen *)&ver);
1902 	printf("%s: using ", sc->sc_dev.dv_xname);
1903 	switch (le16toh(ver.wi_ver[0])) {
1904 	case WI_NIC_EVB2:
1905 		printf("RF:PRISM2 MAC:HFA3841");
1906 		sc->sc_prism2 = 1;
1907 		break;
1908 	case WI_NIC_HWB3763:
1909 		printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3763 rev.B");
1910 		sc->sc_prism2 = 1;
1911 		break;
1912 	case WI_NIC_HWB3163:
1913 		printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163 rev.A");
1914 		sc->sc_prism2 = 1;
1915 		break;
1916 	case WI_NIC_HWB3163B:
1917 		printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163 rev.B");
1918 		sc->sc_prism2 = 1;
1919 		break;
1920 	case WI_NIC_EVB3:
1921 		printf("RF:PRISM2 MAC:HFA3842");
1922 		sc->sc_prism2 = 1;
1923 		break;
1924 	case WI_NIC_HWB1153:
1925 		printf("RF:PRISM1 MAC:HFA3841 CARD:HWB1153");
1926 		sc->sc_prism2 = 1;
1927 		break;
1928 	case WI_NIC_P2_SST:
1929 		printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163-SST-flash");
1930 		sc->sc_prism2 = 1;
1931 		break;
1932 	case WI_NIC_PRISM2_5:
1933 		printf("RF:PRISM2.5 MAC:ISL3873");
1934 		sc->sc_prism2 = 1;
1935 		break;
1936 	case WI_NIC_3874A:
1937 		printf("RF:PRISM2.5 MAC:ISL3874A(PCI)");
1938 		sc->sc_prism2 = 1;
1939 		break;
1940 	default:
1941 		printf("Lucent chip or unknown chip\n");
1942 		sc->sc_prism2 = 0;
1943 		break;
1944 	}
1945 
1946 	if (sc->sc_prism2) {
1947 		/* try to get prism2 firm version */
1948 		memset(&ver, 0, sizeof(ver));
1949 		ver.wi_type = WI_RID_STA_IDENTITY;
1950 		ver.wi_len = 5;
1951 		wi_read_record(sc, (struct wi_ltv_gen *)&ver);
1952 		LE16TOH(ver.wi_ver[1]);
1953 		LE16TOH(ver.wi_ver[2]);
1954 		LE16TOH(ver.wi_ver[3]);
1955 		printf(", Firmware: %i.%i variant %i\n", ver.wi_ver[2],
1956 		       ver.wi_ver[3], ver.wi_ver[1]);
1957 		sc->sc_prism2_ver = ver.wi_ver[2] * 100 +
1958 				    ver.wi_ver[3] *  10 + ver.wi_ver[1];
1959 	}
1960 
1961 	return;
1962 }
1963 
1964 int
1965 wi_detach(sc)
1966 	struct wi_softc *sc;
1967 {
1968 	struct ifnet *ifp = sc->sc_ifp;
1969 	int s;
1970 
1971 	if (!sc->sc_attached)
1972 		return (0);
1973 
1974 	s = splnet();
1975 	callout_stop(&sc->wi_inquire_ch);
1976 
1977 	/* Delete all remaining media. */
1978 	ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
1979 
1980 	ether_ifdetach(ifp);
1981 	if_detach(ifp);
1982 	if (sc->sc_enabled) {
1983 		if (sc->sc_disable)
1984 			(*sc->sc_disable)(sc);
1985 		sc->sc_enabled = 0;
1986 	}
1987 	splx(s);
1988 	return (0);
1989 }
1990 
1991 void
1992 wi_power(sc, why)
1993 	struct wi_softc *sc;
1994 	int why;
1995 {
1996 	int s;
1997 
1998 	if (!sc->sc_enabled)
1999 		return;
2000 
2001 	s = splnet();
2002 	switch (why) {
2003 	case PWR_SUSPEND:
2004 	case PWR_STANDBY:
2005 		wi_stop(sc->sc_ifp, 0);
2006 		if (sc->sc_enabled) {
2007 			if (sc->sc_disable)
2008 				(*sc->sc_disable)(sc);
2009 		}
2010 		break;
2011 	case PWR_RESUME:
2012 		sc->sc_enabled = 0;
2013 		wi_init(sc->sc_ifp);
2014 		(void)wi_intr(sc);
2015 		break;
2016 	case PWR_SOFTSUSPEND:
2017 	case PWR_SOFTSTANDBY:
2018 	case PWR_SOFTRESUME:
2019 		break;
2020 	}
2021 	splx(s);
2022 }
2023 
2024 static int
2025 wi_set_ssid(ws, id, len)
2026 	struct ieee80211_nwid *ws;
2027 	u_int8_t *id;
2028 	int len;
2029 {
2030 
2031 	if (len > IEEE80211_NWID_LEN)
2032 		return (EINVAL);
2033 	ws->i_len = len;
2034 	memcpy(ws->i_nwid, id, len);
2035 	return (0);
2036 }
2037 
2038 static void
2039 wi_request_fill_ssid(wreq, ws)
2040 	struct wi_req *wreq;
2041 	struct ieee80211_nwid *ws;
2042 {
2043 	int len = ws->i_len;
2044 
2045 	memset(&wreq->wi_val[0], 0, sizeof(wreq->wi_val));
2046 	wreq->wi_val[0] = htole16(len);
2047 	wreq->wi_len = roundup(len, 2) / 2 + 2;
2048 	memcpy(&wreq->wi_val[1], ws->i_nwid, len);
2049 }
2050 
2051 static int
2052 wi_write_ssid(sc, type, wreq, ws)
2053 	struct wi_softc *sc;
2054 	int type;
2055 	struct wi_req *wreq;
2056 	struct ieee80211_nwid *ws;
2057 {
2058 
2059 	wreq->wi_type = type;
2060 	wi_request_fill_ssid(wreq, ws);
2061 	return (wi_write_record(sc, (struct wi_ltv_gen *)wreq));
2062 }
2063 
2064 static int
2065 wi_sync_media(sc, ptype, txrate)
2066 	struct wi_softc *sc;
2067 	int ptype;
2068 	int txrate;
2069 {
2070 	int media = sc->sc_media.ifm_cur->ifm_media;
2071 	int options = IFM_OPTIONS(media);
2072 	int subtype;
2073 
2074 	switch (txrate) {
2075 	case 1:
2076 		subtype = IFM_IEEE80211_DS1;
2077 		break;
2078 	case 2:
2079 		subtype = IFM_IEEE80211_DS2;
2080 		break;
2081 	case 3:
2082 		subtype = IFM_AUTO;
2083 		break;
2084 	case 5:
2085 		subtype = IFM_IEEE80211_DS5;
2086 		break;
2087 	case 11:
2088 		subtype = IFM_IEEE80211_DS11;
2089 		break;
2090 	default:
2091 		subtype = IFM_MANUAL;		/* Unable to represent */
2092 		break;
2093 	}
2094 	switch (ptype) {
2095 	case WI_PORTTYPE_ADHOC:
2096 		options |= IFM_IEEE80211_ADHOC;
2097 		break;
2098 	case WI_PORTTYPE_BSS:
2099 		options &= ~IFM_IEEE80211_ADHOC;
2100 		break;
2101 	default:
2102 		subtype = IFM_MANUAL;		/* Unable to represent */
2103 		break;
2104 	}
2105 	media = IFM_MAKEWORD(IFM_TYPE(media), subtype, options,
2106 	    IFM_INST(media));
2107 	if (ifmedia_match(&sc->sc_media, media, sc->sc_media.ifm_mask) == NULL)
2108 		return (EINVAL);
2109 	ifmedia_set(&sc->sc_media, media);
2110 	sc->wi_ptype = ptype;
2111 	sc->wi_tx_rate = txrate;
2112 	return (0);
2113 }
2114 
2115 static int
2116 wi_media_change(ifp)
2117 	struct ifnet *ifp;
2118 {
2119 	struct wi_softc *sc = ifp->if_softc;
2120 	int otype = sc->wi_ptype;
2121 	int orate = sc->wi_tx_rate;
2122 
2123 	if ((sc->sc_media.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0)
2124 		sc->wi_ptype = WI_PORTTYPE_ADHOC;
2125 	else
2126 		sc->wi_ptype = WI_PORTTYPE_BSS;
2127 
2128 	switch (IFM_SUBTYPE(sc->sc_media.ifm_cur->ifm_media)) {
2129 	case IFM_IEEE80211_DS1:
2130 		sc->wi_tx_rate = 1;
2131 		break;
2132 	case IFM_IEEE80211_DS2:
2133 		sc->wi_tx_rate = 2;
2134 		break;
2135 	case IFM_AUTO:
2136 		sc->wi_tx_rate = 3;
2137 		break;
2138 	case IFM_IEEE80211_DS5:
2139 		sc->wi_tx_rate = 5;
2140 		break;
2141 	case IFM_IEEE80211_DS11:
2142 		sc->wi_tx_rate = 11;
2143 		break;
2144 	}
2145 
2146 	if (sc->sc_enabled != 0) {
2147 		if (otype != sc->wi_ptype ||
2148 		    orate != sc->wi_tx_rate)
2149 			wi_init(ifp);
2150 	}
2151 
2152 	ifp->if_baudrate = ifmedia_baudrate(sc->sc_media.ifm_cur->ifm_media);
2153 
2154 	return (0);
2155 }
2156 
2157 static void
2158 wi_media_status(ifp, imr)
2159 	struct ifnet *ifp;
2160 	struct ifmediareq *imr;
2161 {
2162 	struct wi_softc *sc = ifp->if_softc;
2163 
2164 	if (sc->sc_enabled == 0) {
2165 		imr->ifm_active = IFM_IEEE80211|IFM_NONE;
2166 		imr->ifm_status = 0;
2167 		return;
2168 	}
2169 
2170 	imr->ifm_active = sc->sc_media.ifm_cur->ifm_media;
2171 	imr->ifm_status = IFM_AVALID|IFM_ACTIVE;
2172 }
2173 
2174 static int
2175 wi_set_nwkey(sc, nwkey)
2176 	struct wi_softc *sc;
2177 	struct ieee80211_nwkey *nwkey;
2178 {
2179 	int i, error;
2180 	size_t len;
2181 	struct wi_req wreq;
2182 	struct wi_ltv_keys *wk = (struct wi_ltv_keys *)&wreq;
2183 
2184 	if (!sc->wi_has_wep)
2185 		return ENODEV;
2186 	if (nwkey->i_defkid <= 0 ||
2187 	    nwkey->i_defkid > IEEE80211_WEP_NKID)
2188 		return EINVAL;
2189 	memcpy(wk, &sc->wi_keys, sizeof(*wk));
2190 	for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2191 		if (nwkey->i_key[i].i_keydat == NULL)
2192 			continue;
2193 		len = nwkey->i_key[i].i_keylen;
2194 		if (len > sizeof(wk->wi_keys[i].wi_keydat))
2195 			return EINVAL;
2196 		error = copyin(nwkey->i_key[i].i_keydat,
2197 		    wk->wi_keys[i].wi_keydat, len);
2198 		if (error)
2199 			return error;
2200 		wk->wi_keys[i].wi_keylen = htole16(len);
2201 	}
2202 
2203 	wk->wi_len = (sizeof(*wk) / 2) + 1;
2204 	wk->wi_type = WI_RID_DEFLT_CRYPT_KEYS;
2205 	if (sc->sc_enabled != 0) {
2206 		error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
2207 		if (error)
2208 			return error;
2209 	}
2210 	error = wi_setdef(sc, &wreq);
2211 	if (error)
2212 		return error;
2213 
2214 	wreq.wi_len = 2;
2215 	wreq.wi_type = WI_RID_TX_CRYPT_KEY;
2216 	wreq.wi_val[0] = htole16(nwkey->i_defkid - 1);
2217 	if (sc->sc_enabled != 0) {
2218 		error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
2219 		if (error)
2220 			return error;
2221 	}
2222 	error = wi_setdef(sc, &wreq);
2223 	if (error)
2224 		return error;
2225 
2226 	wreq.wi_type = WI_RID_ENCRYPTION;
2227 	wreq.wi_val[0] = htole16(nwkey->i_wepon);
2228 	if (sc->sc_enabled != 0) {
2229 		error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
2230 		if (error)
2231 			return error;
2232 	}
2233 	error = wi_setdef(sc, &wreq);
2234 	if (error)
2235 		return error;
2236 
2237 	if (sc->sc_enabled != 0)
2238 		wi_init(&sc->sc_ethercom.ec_if);
2239 	return 0;
2240 }
2241 
2242 static int
2243 wi_get_nwkey(sc, nwkey)
2244 	struct wi_softc *sc;
2245 	struct ieee80211_nwkey *nwkey;
2246 {
2247 	int i, len, error;
2248 	struct wi_ltv_keys *wk = &sc->wi_keys;
2249 
2250 	if (!sc->wi_has_wep)
2251 		return ENODEV;
2252 	nwkey->i_wepon = sc->wi_use_wep;
2253 	nwkey->i_defkid = sc->wi_tx_key + 1;
2254 
2255 	/* do not show any keys to non-root user */
2256 	error = suser(curproc->p_ucred, &curproc->p_acflag);
2257 	for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2258 		if (nwkey->i_key[i].i_keydat == NULL)
2259 			continue;
2260 		/* error holds results of suser() for the first time */
2261 		if (error)
2262 			return error;
2263 		len = le16toh(wk->wi_keys[i].wi_keylen);
2264 		if (nwkey->i_key[i].i_keylen < len)
2265 			return ENOSPC;
2266 		nwkey->i_key[i].i_keylen = len;
2267 		error = copyout(wk->wi_keys[i].wi_keydat,
2268 		    nwkey->i_key[i].i_keydat, len);
2269 		if (error)
2270 			return error;
2271 	}
2272 	return 0;
2273 }
2274 
2275 static int
2276 wi_set_pm(struct wi_softc *sc, struct ieee80211_power *power)
2277 {
2278 
2279 	sc->wi_pm_enabled = power->i_enabled;
2280 	sc->wi_max_sleep = power->i_maxsleep;
2281 
2282 	if (sc->sc_enabled)
2283 		return (wi_init(&sc->sc_ethercom.ec_if));
2284 
2285 	return (0);
2286 }
2287 
2288 static int
2289 wi_get_pm(struct wi_softc *sc, struct ieee80211_power *power)
2290 {
2291 
2292 	power->i_enabled = sc->wi_pm_enabled;
2293 	power->i_maxsleep = sc->wi_max_sleep;
2294 
2295 	return (0);
2296 }
2297