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