xref: /openbsd/sys/dev/ic/if_wi.c (revision d485f761)
1 /*	$OpenBSD: if_wi.c,v 1.17 2001/10/25 16:39:25 mickey Exp $	*/
2 
3 /*
4  * Copyright (c) 1997, 1998, 1999
5  *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by Bill Paul.
18  * 4. Neither the name of the author nor the names of any co-contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
26  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32  * THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  *	From: if_wi.c,v 1.7 1999/07/04 14:40:22 wpaul Exp $
35  */
36 
37 /*
38  * Lucent WaveLAN/IEEE 802.11 driver for OpenBSD.
39  *
40  * Originally written by Bill Paul <wpaul@ctr.columbia.edu>
41  * Electrical Engineering Department
42  * Columbia University, New York City
43  */
44 
45 /*
46  * The WaveLAN/IEEE adapter is the second generation of the WaveLAN
47  * from Lucent. Unlike the older cards, the new ones are programmed
48  * entirely via a firmware-driven controller called the Hermes.
49  * Unfortunately, Lucent will not release the Hermes programming manual
50  * without an NDA (if at all). What they do release is an API library
51  * called the HCF (Hardware Control Functions) which is supposed to
52  * do the device-specific operations of a device driver for you. The
53  * publically available version of the HCF library (the 'HCF Light') is
54  * a) extremely gross, b) lacks certain features, particularly support
55  * for 802.11 frames, and c) is contaminated by the GNU Public License.
56  *
57  * This driver does not use the HCF or HCF Light at all. Instead, it
58  * programs the Hermes controller directly, using information gleaned
59  * from the HCF Light code and corresponding documentation.
60  */
61 
62 #define WI_HERMES_AUTOINC_WAR	/* Work around data write autoinc bug. */
63 #define WI_HERMES_STATS_WAR	/* Work around stats counter bug. */
64 
65 #include "bpfilter.h"
66 
67 #include <sys/param.h>
68 #include <sys/systm.h>
69 #include <sys/sockio.h>
70 #include <sys/mbuf.h>
71 #include <sys/malloc.h>
72 #include <sys/kernel.h>
73 #include <sys/proc.h>
74 #include <sys/socket.h>
75 #include <sys/device.h>
76 
77 #include <net/if.h>
78 #include <net/if_dl.h>
79 #include <net/if_media.h>
80 #include <net/if_types.h>
81 
82 #ifdef INET
83 #include <netinet/in.h>
84 #include <netinet/in_systm.h>
85 #include <netinet/in_var.h>
86 #include <netinet/ip.h>
87 #include <netinet/if_ether.h>
88 #endif
89 
90 #if NBPFILTER > 0
91 #include <net/bpf.h>
92 #endif
93 
94 #include <machine/bus.h>
95 
96 #include <dev/ic/if_wireg.h>
97 #include <dev/ic/if_wi_ieee.h>
98 #include <dev/ic/if_wivar.h>
99 
100 #define BPF_MTAP(if,mbuf) bpf_mtap((if)->if_bpf, (mbuf))
101 #define BPFATTACH(if_bpf,if,dlt,sz)
102 #define STATIC
103 
104 #ifdef WIDEBUG
105 
106 u_int32_t	widebug = WIDEBUG;
107 
108 #define WID_INTR	0x01
109 #define WID_START	0x02
110 #define WID_IOCTL	0x04
111 #define WID_INIT	0x08
112 #define WID_STOP	0x10
113 #define WID_RESET	0x20
114 
115 #define DPRINTF(mask,args) if (widebug & (mask)) printf args;
116 
117 #else	/* !WIDEBUG */
118 #define DPRINTF(mask,args)
119 #endif	/* WIDEBUG */
120 
121 #if !defined(lint) && !defined(__OpenBSD__)
122 static const char rcsid[] =
123 	"$OpenBSD: if_wi.c,v 1.17 2001/10/25 16:39:25 mickey Exp $";
124 #endif	/* lint */
125 
126 #ifdef foo
127 static u_int8_t	wi_mcast_addr[6] = { 0x01, 0x60, 0x1D, 0x00, 0x01, 0x00 };
128 #endif
129 
130 STATIC void wi_reset		__P((struct wi_softc *));
131 STATIC int wi_ioctl		__P((struct ifnet *, u_long, caddr_t));
132 STATIC void wi_start		__P((struct ifnet *));
133 STATIC void wi_watchdog		__P((struct ifnet *));
134 STATIC void wi_shutdown		__P((void *));
135 STATIC void wi_rxeof		__P((struct wi_softc *));
136 STATIC void wi_txeof		__P((struct wi_softc *, int));
137 STATIC void wi_update_stats	__P((struct wi_softc *));
138 STATIC void wi_setmulti		__P((struct wi_softc *));
139 
140 STATIC int wi_cmd		__P((struct wi_softc *, int, int));
141 STATIC int wi_read_record	__P((struct wi_softc *, struct wi_ltv_gen *));
142 STATIC int wi_write_record	__P((struct wi_softc *, struct wi_ltv_gen *));
143 STATIC int wi_read_data		__P((struct wi_softc *, int,
144 					int, caddr_t, int));
145 STATIC int wi_write_data	__P((struct wi_softc *, int,
146 					int, caddr_t, int));
147 STATIC int wi_seek		__P((struct wi_softc *, int, int, int));
148 STATIC int wi_alloc_nicmem	__P((struct wi_softc *, int, int *));
149 STATIC void wi_inquire		__P((void *));
150 STATIC void wi_setdef		__P((struct wi_softc *, struct wi_req *));
151 STATIC int wi_mgmt_xmit		__P((struct wi_softc *, caddr_t, int));
152 STATIC void wi_get_id		__P((struct wi_softc *, int));
153 
154 int	wi_intr			__P((void *));
155 int	wi_attach		__P((struct wi_softc *, int));
156 void	wi_init			__P((void *));
157 void	wi_stop			__P((struct wi_softc *));
158 
159 /* Autoconfig definition of driver back-end */
160 struct cfdriver wi_cd = {
161 	NULL, "wi", DV_IFNET
162 };
163 
164 int
165 wi_attach(sc, print_cis)
166 	struct wi_softc *sc;
167 	int print_cis;
168 {
169 	struct wi_ltv_macaddr	mac;
170 	struct wi_ltv_gen	gen;
171 	struct ifnet		*ifp;
172 	int			error;
173 
174 	sc->wi_gone = 0;
175 
176 	wi_reset(sc);
177 
178 	/* Read the station address. */
179 	mac.wi_type = WI_RID_MAC_NODE;
180 	mac.wi_len = 4;
181 	error = wi_read_record(sc, (struct wi_ltv_gen *)&mac);
182 	if (error) {
183 		printf(": unable to read station address\n");
184 		return (error);
185 	}
186 	bcopy((char *)&mac.wi_mac_addr, (char *)&sc->arpcom.ac_enaddr,
187 	    ETHER_ADDR_LEN);
188 
189 	wi_get_id(sc, print_cis);
190 	printf("address %s", ether_sprintf(sc->arpcom.ac_enaddr));
191 
192 	ifp = &sc->arpcom.ac_if;
193 	bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
194 	ifp->if_softc = sc;
195 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
196 	ifp->if_ioctl = wi_ioctl;
197 	ifp->if_start = wi_start;
198 	ifp->if_watchdog = wi_watchdog;
199 	ifp->if_baudrate = 10000000;
200 	IFQ_SET_READY(&ifp->if_snd);
201 
202 	bzero(sc->wi_node_name, sizeof(sc->wi_node_name));
203 	bcopy(WI_DEFAULT_NODENAME, sc->wi_node_name,
204 	    sizeof(WI_DEFAULT_NODENAME) - 1);
205 
206 	bzero(sc->wi_net_name, sizeof(sc->wi_net_name));
207 	bcopy(WI_DEFAULT_NETNAME, sc->wi_net_name,
208 	    sizeof(WI_DEFAULT_NETNAME) - 1);
209 
210 	bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name));
211 	bcopy(WI_DEFAULT_IBSS, sc->wi_ibss_name,
212 	    sizeof(WI_DEFAULT_IBSS) - 1);
213 
214 	sc->wi_portnum = WI_DEFAULT_PORT;
215 	sc->wi_ptype = WI_PORTTYPE_BSS;
216 	sc->wi_ap_density = WI_DEFAULT_AP_DENSITY;
217 	sc->wi_rts_thresh = WI_DEFAULT_RTS_THRESH;
218 	sc->wi_tx_rate = WI_DEFAULT_TX_RATE;
219 	sc->wi_max_data_len = WI_DEFAULT_DATALEN;
220 	sc->wi_create_ibss = WI_DEFAULT_CREATE_IBSS;
221 	sc->wi_pm_enabled = WI_DEFAULT_PM_ENABLED;
222 	sc->wi_max_sleep = WI_DEFAULT_MAX_SLEEP;
223 	sc->wi_roaming = WI_DEFAULT_ROAMING;
224 	sc->wi_authtype = WI_DEFAULT_AUTHTYPE;
225 
226 	/*
227 	 * Read the default channel from the NIC. This may vary
228 	 * depending on the country where the NIC was purchased, so
229 	 * we can't hard-code a default and expect it to work for
230 	 * everyone.
231 	 */
232 	gen.wi_type = WI_RID_OWN_CHNL;
233 	gen.wi_len = 2;
234 	if (wi_read_record(sc, &gen) == 0)
235 		sc->wi_channel = letoh16(gen.wi_val);
236 	else
237 		sc->wi_channel = 3;
238 
239 	/*
240 	 * Find out if we support WEP on this card.
241 	 */
242 	gen.wi_type = WI_RID_WEP_AVAIL;
243 	gen.wi_len = 2;
244 	if (wi_read_record(sc, &gen) == 0)
245 		sc->wi_has_wep = letoh16(gen.wi_val);
246 	timeout_set(&sc->sc_timo, wi_inquire, sc);
247 
248 	bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats));
249 
250 	/*
251 	 * Call MI attach routines.
252 	 */
253 	if_attach(ifp);
254 	ether_ifattach(ifp);
255 	printf("\n");
256 
257 #if NBPFILTER > 0
258 	BPFATTACH(&sc->arpcom.ac_if.if_bpf, ifp, DLT_EN10MB,
259 	    sizeof(struct ether_header));
260 #endif
261 
262 	shutdownhook_establish(wi_shutdown, sc);
263 
264 	wi_init(sc);
265 	wi_stop(sc);
266 
267 	return (0);
268 }
269 
270 int
271 wi_intr(vsc)
272 	void			*vsc;
273 {
274 	struct wi_softc		*sc = vsc;
275 	struct ifnet		*ifp;
276 	u_int16_t		status;
277 
278 	DPRINTF(WID_INTR, ("wi_intr: sc %p\n", sc));
279 
280 	ifp = &sc->arpcom.ac_if;
281 
282 	if (!(ifp->if_flags & IFF_UP)) {
283 		CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
284 		CSR_WRITE_2(sc, WI_INT_EN, 0);
285 		return (0);
286 	}
287 
288 	/* Disable interrupts. */
289 	CSR_WRITE_2(sc, WI_INT_EN, 0);
290 
291 	status = CSR_READ_2(sc, WI_EVENT_STAT);
292 	CSR_WRITE_2(sc, WI_EVENT_ACK, ~WI_INTRS);
293 
294 	if (status & WI_EV_RX) {
295 		wi_rxeof(sc);
296 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
297 	}
298 
299 	if (status & WI_EV_TX) {
300 		wi_txeof(sc, status);
301 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX);
302 	}
303 
304 	if (status & WI_EV_ALLOC) {
305 		int			id;
306 		id = CSR_READ_2(sc, WI_ALLOC_FID);
307 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
308 		if (id == sc->wi_tx_data_id)
309 			wi_txeof(sc, status);
310 	}
311 
312 	if (status & WI_EV_INFO) {
313 		wi_update_stats(sc);
314 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO);
315 	}
316 
317 	if (status & WI_EV_TX_EXC) {
318 		wi_txeof(sc, status);
319 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX_EXC);
320 	}
321 
322 	if (status & WI_EV_INFO_DROP) {
323 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO_DROP);
324 	}
325 
326 	/* Re-enable interrupts. */
327 	CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
328 
329 	if (!IFQ_IS_EMPTY(&ifp->if_snd))
330 		wi_start(ifp);
331 
332 	return (1);
333 }
334 
335 STATIC void
336 wi_rxeof(sc)
337 	struct wi_softc		*sc;
338 {
339 	struct ifnet		*ifp;
340 	struct ether_header	*eh;
341 	struct wi_frame		rx_frame;
342 	struct mbuf		*m;
343 	int			id;
344 
345 	ifp = &sc->arpcom.ac_if;
346 
347 	id = CSR_READ_2(sc, WI_RX_FID);
348 
349 	/* First read in the frame header */
350 	if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame, sizeof(rx_frame))) {
351 		ifp->if_ierrors++;
352 		return;
353 	}
354 
355 	if (rx_frame.wi_status & htole16(WI_STAT_ERRSTAT)) {
356 		ifp->if_ierrors++;
357 		return;
358 	}
359 
360 	MGETHDR(m, M_DONTWAIT, MT_DATA);
361 	if (m == NULL) {
362 		ifp->if_ierrors++;
363 		return;
364 	}
365 	MCLGET(m, M_DONTWAIT);
366 	if (!(m->m_flags & M_EXT)) {
367 		m_freem(m);
368 		ifp->if_ierrors++;
369 		return;
370 	}
371 
372 	eh = mtod(m, struct ether_header *);
373 	m->m_pkthdr.rcvif = ifp;
374 
375 	if (rx_frame.wi_status == htole16(WI_STAT_1042) ||
376 	    rx_frame.wi_status == htole16(WI_STAT_TUNNEL) ||
377 	    rx_frame.wi_status == htole16(WI_STAT_WMP_MSG)) {
378 		if ((letoh16(rx_frame.wi_dat_len) + WI_SNAPHDR_LEN) > MCLBYTES) {
379 			printf(WI_PRT_FMT ": oversized packet received "
380 			    "(wi_dat_len=%d, wi_status=0x%x)\n",
381 			    WI_PRT_ARG(sc), letoh16(rx_frame.wi_dat_len),
382 			    letoh16(rx_frame.wi_status));
383 			m_freem(m);
384 			ifp->if_ierrors++;
385 			return;
386 		}
387 		m->m_pkthdr.len = m->m_len =
388 		    letoh16(rx_frame.wi_dat_len) + WI_SNAPHDR_LEN;
389 
390 		bcopy((char *)&rx_frame.wi_addr1,
391 		    (char *)&eh->ether_dhost, ETHER_ADDR_LEN);
392 		bcopy((char *)&rx_frame.wi_addr2,
393 		    (char *)&eh->ether_shost, ETHER_ADDR_LEN);
394 		bcopy((char *)&rx_frame.wi_type,
395 		    (char *)&eh->ether_type, sizeof(u_int16_t));
396 
397 		if (wi_read_data(sc, id, WI_802_11_OFFSET,
398 		    mtod(m, caddr_t) + sizeof(struct ether_header),
399 		    m->m_len + 2)) {
400 			m_freem(m);
401 			ifp->if_ierrors++;
402 			return;
403 		}
404 	} else {
405 		if ((letoh16(rx_frame.wi_dat_len) +
406 		    sizeof(struct ether_header)) > MCLBYTES) {
407 			printf(WI_PRT_FMT ": oversized packet received "
408 			    "(wi_dat_len=%d, wi_status=0x%x)\n",
409 			    WI_PRT_ARG(sc), letoh16(rx_frame.wi_dat_len),
410 			    letoh16(rx_frame.wi_status));
411 			m_freem(m);
412 			ifp->if_ierrors++;
413 			return;
414 		}
415 		m->m_pkthdr.len = m->m_len =
416 		    letoh16(rx_frame.wi_dat_len) + sizeof(struct ether_header);
417 
418 		if (wi_read_data(sc, id, WI_802_3_OFFSET,
419 		    mtod(m, caddr_t), m->m_len + 2)) {
420 			m_freem(m);
421 			ifp->if_ierrors++;
422 			return;
423 		}
424 	}
425 
426 	ifp->if_ipackets++;
427 
428 #if NBPFILTER > 0
429 	/* Handle BPF listeners. */
430 	if (ifp->if_bpf)
431 		BPF_MTAP(ifp, m);
432 #endif
433 
434 	/* Receive packet. */
435 	ether_input_mbuf(ifp, m);
436 
437 	return;
438 }
439 
440 STATIC void
441 wi_txeof(sc, status)
442 	struct wi_softc		*sc;
443 	int			status;
444 {
445 	struct ifnet		*ifp;
446 
447 	ifp = &sc->arpcom.ac_if;
448 
449 	ifp->if_timer = 0;
450 	ifp->if_flags &= ~IFF_OACTIVE;
451 
452 	if (status & WI_EV_TX_EXC)
453 		ifp->if_oerrors++;
454 	else
455 		ifp->if_opackets++;
456 
457 	return;
458 }
459 
460 void
461 wi_inquire(xsc)
462 	void			*xsc;
463 {
464 	struct wi_softc		*sc;
465 	struct ifnet		*ifp;
466 	int s, rv;
467 
468 	sc = xsc;
469 	ifp = &sc->arpcom.ac_if;
470 
471 	timeout_add(&sc->sc_timo, hz * 60);
472 
473 	/* Don't do this while we're transmitting */
474 	if (ifp->if_flags & IFF_OACTIVE)
475 		return;
476 
477 	s = splnet();
478 	rv = wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_COUNTERS);
479 	splx(s);
480 	if (rv)
481 		printf(WI_PRT_FMT ": wi_cmd failed with %d\n", WI_PRT_ARG(sc),
482 		    rv);
483 
484 	return;
485 }
486 
487 void
488 wi_update_stats(sc)
489 	struct wi_softc		*sc;
490 {
491 	struct wi_ltv_gen	gen;
492 	u_int16_t		id;
493 	struct ifnet		*ifp;
494 	u_int32_t		*ptr;
495 	int			len, i;
496 	u_int16_t		t;
497 
498 	ifp = &sc->arpcom.ac_if;
499 
500 	id = CSR_READ_2(sc, WI_INFO_FID);
501 
502 	wi_read_data(sc, id, 0, (char *)&gen, 4);
503 
504 	if (gen.wi_type != WI_INFO_COUNTERS)
505 		return;
506 
507 	/* Some card versions have a larger stats structure */
508 	len = (gen.wi_len - 1 < sizeof(sc->wi_stats) / 4) ?
509 	    gen.wi_len - 1 : sizeof(sc->wi_stats) / 4;
510 
511 	ptr = (u_int32_t *)&sc->wi_stats;
512 
513 	for (i = 0; i < len; i++) {
514 		t = CSR_READ_2(sc, WI_DATA1);
515 #ifdef WI_HERMES_STATS_WAR
516 		if (t > 0xF000)
517 			t = ~t & 0xFFFF;
518 #endif
519 		ptr[i] += t;
520 	}
521 
522 	ifp->if_collisions = sc->wi_stats.wi_tx_single_retries +
523 	    sc->wi_stats.wi_tx_multi_retries +
524 	    sc->wi_stats.wi_tx_retry_limit;
525 
526 	return;
527 }
528 
529 STATIC int
530 wi_cmd(sc, cmd, val)
531 	struct wi_softc		*sc;
532 	int			cmd;
533 	int			val;
534 {
535 	int			i, s = 0;
536 
537 	/* Wait for the busy bit to clear. */
538 	for (i = 0; i < WI_TIMEOUT; i++) {
539 		if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY))
540 			break;
541 		DELAY(1);
542 	}
543 
544 	CSR_WRITE_2(sc, WI_PARAM0, val);
545 	CSR_WRITE_2(sc, WI_PARAM1, 0);
546 	CSR_WRITE_2(sc, WI_PARAM2, 0);
547 	CSR_WRITE_2(sc, WI_COMMAND, cmd);
548 
549 	for (i = WI_TIMEOUT; i--; DELAY(1)) {
550 		/*
551 		 * Wait for 'command complete' bit to be
552 		 * set in the event status register.
553 		 */
554 		s = CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_CMD;
555 		if (s) {
556 			/* Ack the event and read result code. */
557 			s = CSR_READ_2(sc, WI_STATUS);
558 			CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
559 #ifdef foo
560 			if ((s & WI_CMD_CODE_MASK) != (cmd & WI_CMD_CODE_MASK))
561 				return(EIO);
562 #endif
563 			if (s & WI_STAT_CMD_RESULT)
564 				return(EIO);
565 			break;
566 		}
567 	}
568 
569 	if (i < 0)
570 		return(ETIMEDOUT);
571 
572 	return(0);
573 }
574 
575 STATIC void
576 wi_reset(sc)
577 	struct wi_softc		*sc;
578 {
579 	DPRINTF(WID_RESET, ("wi_reset: sc %p\n", sc));
580 
581 	if (wi_cmd(sc, WI_CMD_INI, 0))
582 		printf(WI_PRT_FMT ": init failed\n", WI_PRT_ARG(sc));
583 	CSR_WRITE_2(sc, WI_INT_EN, 0);
584 	CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
585 
586 	/* Calibrate timer. */
587 	WI_SETVAL(WI_RID_TICK_TIME, 8);
588 
589 	return;
590 }
591 
592 /*
593  * Read an LTV record from the NIC.
594  */
595 STATIC int
596 wi_read_record(sc, ltv)
597 	struct wi_softc		*sc;
598 	struct wi_ltv_gen	*ltv;
599 {
600 	u_int8_t		*ptr;
601 	int			len, code;
602 	struct wi_ltv_gen	*oltv, p2ltv;
603 
604 	if (sc->sc_prism2) {
605 		oltv = ltv;
606 		switch (ltv->wi_type) {
607 		case WI_RID_ENCRYPTION:
608 			p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
609 			p2ltv.wi_len = 2;
610 			ltv = &p2ltv;
611 			break;
612 		case WI_RID_TX_CRYPT_KEY:
613 			p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
614 			p2ltv.wi_len = 2;
615 			ltv = &p2ltv;
616 			break;
617 		}
618 	}
619 
620 	/* Tell the NIC to enter record read mode. */
621 	if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type))
622 		return(EIO);
623 
624 	/* Seek to the record. */
625 	if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
626 		return(EIO);
627 
628 	/*
629 	 * Read the length and record type and make sure they
630 	 * match what we expect (this verifies that we have enough
631 	 * room to hold all of the returned data).
632 	 */
633 	len = CSR_READ_2(sc, WI_DATA1);
634 	if (len > ltv->wi_len)
635 		return(ENOSPC);
636 	code = CSR_READ_2(sc, WI_DATA1);
637 	if (code != ltv->wi_type)
638 		return(EIO);
639 
640 	ltv->wi_len = len;
641 	ltv->wi_type = code;
642 
643 	/* Now read the data. */
644 	ptr = (u_int8_t *)&ltv->wi_val;
645 	if (ltv->wi_len > 1)
646 		CSR_READ_RAW_2(sc, WI_DATA1, ptr, (ltv->wi_len-1)*2);
647 
648 	if (sc->sc_prism2) {
649 		int v;
650 
651 		switch (oltv->wi_type) {
652 		case WI_RID_TX_RATE:
653 		case WI_RID_CUR_TX_RATE:
654 			switch (letoh16(ltv->wi_val)) {
655 			case 1: v = 1; break;
656 			case 2: v = 2; break;
657 			case 3:	v = 6; break;
658 			case 4: v = 5; break;
659 			case 7: v = 7; break;
660 			case 8: v = 11; break;
661 			case 15: v = 3; break;
662 			default: v = 0x100 + letoh16(ltv->wi_val); break;
663 			}
664 			oltv->wi_val = htole16(v);
665 			break;
666 		case WI_RID_ENCRYPTION:
667 			oltv->wi_len = 2;
668 			if (ltv->wi_val & htole16(0x01))
669 				oltv->wi_val = htole16(1);
670 			else
671 				oltv->wi_val = htole16(0);
672 			break;
673 		case WI_RID_TX_CRYPT_KEY:
674 			oltv->wi_len = 2;
675 			oltv->wi_val = ltv->wi_val;
676 			break;
677 		case WI_RID_AUTH_CNTL:
678 			oltv->wi_len = 2;
679 			if (ltv->wi_val & htole16(0x01))
680 				oltv->wi_val = htole16(1);
681 			else if (ltv->wi_val & htole16(0x02))
682 				oltv->wi_val = htole16(2);
683 			break;
684 		}
685 	}
686 
687 	return(0);
688 }
689 
690 /*
691  * Same as read, except we inject data instead of reading it.
692  */
693 STATIC int
694 wi_write_record(sc, ltv)
695 	struct wi_softc		*sc;
696 	struct wi_ltv_gen	*ltv;
697 {
698 	u_int8_t		*ptr;
699 	int			i;
700 	struct wi_ltv_gen	p2ltv;
701 
702 	if (sc->sc_prism2) {
703 		int v;
704 
705 		switch (ltv->wi_type) {
706 		case WI_RID_TX_RATE:
707 			p2ltv.wi_type = WI_RID_TX_RATE;
708 			p2ltv.wi_len = 2;
709 			switch (letoh16(ltv->wi_val)) {
710 			case 1: v = 1; break;
711 			case 2: v = 2; break;
712 			case 3:	v = 15; break;
713 			case 5: v = 4; break;
714 			case 6: v = 3; break;
715 			case 7: v = 7; break;
716 			case 11: v = 8; break;
717 			default: return EINVAL;
718 			}
719 			p2ltv.wi_val = htole16(v);
720 			ltv = &p2ltv;
721 			break;
722 		case WI_RID_ENCRYPTION:
723 			p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
724 			p2ltv.wi_len = 2;
725 			if (ltv->wi_val & htole16(0x01))
726 				p2ltv.wi_val = htole16(0x03);
727 			else
728 				p2ltv.wi_val = htole16(0x90);
729 			ltv = &p2ltv;
730 			break;
731 		case WI_RID_TX_CRYPT_KEY:
732 			p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
733 			p2ltv.wi_len = 2;
734 			p2ltv.wi_val = ltv->wi_val;
735 			ltv = &p2ltv;
736 			break;
737 		case WI_RID_DEFLT_CRYPT_KEYS: {
738 				int error;
739 				struct wi_ltv_str ws;
740 				struct wi_ltv_keys *wk = (struct wi_ltv_keys *)ltv;
741 				for (i = 0; i < 4; i++) {
742 					ws.wi_len = 4;
743 					ws.wi_type = WI_RID_P2_CRYPT_KEY0 + i;
744 					bcopy(&wk->wi_keys[i].wi_keydat,
745 					    ws.wi_str, 5);
746 					ws.wi_str[5] = '\0';
747 					error = wi_write_record(sc,
748 					    (struct wi_ltv_gen *)&ws);
749 					if (error)
750 						return (error);
751 				}
752 			}
753 			return (0);
754 		case WI_RID_AUTH_CNTL:
755 			p2ltv.wi_type = WI_RID_AUTH_CNTL;
756 			p2ltv.wi_len = 2;
757 			if (ltv->wi_val == htole16(1))
758 				p2ltv.wi_val = htole16(0x01);
759 			else if (ltv->wi_val == htole16(2))
760 				p2ltv.wi_val = htole16(0x02);
761 			ltv = &p2ltv;
762 			break;
763 		}
764 	}
765 
766 	if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
767 		return(EIO);
768 
769 	CSR_WRITE_2(sc, WI_DATA1, ltv->wi_len);
770 	CSR_WRITE_2(sc, WI_DATA1, ltv->wi_type);
771 
772 	ptr = (u_int8_t *)&ltv->wi_val;
773 	if (ltv->wi_len > 1)
774 		CSR_WRITE_RAW_2(sc, WI_DATA1, ptr, (ltv->wi_len-1) *2);
775 
776 	if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_WRITE, ltv->wi_type))
777 		return(EIO);
778 
779 	return(0);
780 }
781 
782 STATIC int
783 wi_seek(sc, id, off, chan)
784 	struct wi_softc		*sc;
785 	int			id, off, chan;
786 {
787 	int			i;
788 	int			selreg, offreg;
789 
790 	switch (chan) {
791 	case WI_BAP0:
792 		selreg = WI_SEL0;
793 		offreg = WI_OFF0;
794 		break;
795 	case WI_BAP1:
796 		selreg = WI_SEL1;
797 		offreg = WI_OFF1;
798 		break;
799 	default:
800 		printf(WI_PRT_FMT ": invalid data path: %x\n", WI_PRT_ARG(sc),
801 		    chan);
802 		return(EIO);
803 	}
804 
805 	CSR_WRITE_2(sc, selreg, id);
806 	CSR_WRITE_2(sc, offreg, off);
807 
808 	for (i = WI_TIMEOUT; i--; DELAY(1))
809 		if (!(CSR_READ_2(sc, offreg) & (WI_OFF_BUSY|WI_OFF_ERR)))
810 			break;
811 
812 	if (i < 0)
813 		return(ETIMEDOUT);
814 
815 	return(0);
816 }
817 
818 STATIC int
819 wi_read_data(sc, id, off, buf, len)
820 	struct wi_softc		*sc;
821 	int			id, off;
822 	caddr_t			buf;
823 	int			len;
824 {
825 	u_int8_t		*ptr;
826 
827 	if (wi_seek(sc, id, off, WI_BAP1))
828 		return(EIO);
829 
830 	ptr = (u_int8_t *)buf;
831 	CSR_READ_RAW_2(sc, WI_DATA1, ptr, len);
832 
833 	return(0);
834 }
835 
836 /*
837  * According to the comments in the HCF Light code, there is a bug in
838  * the Hermes (or possibly in certain Hermes firmware revisions) where
839  * the chip's internal autoincrement counter gets thrown off during
840  * data writes: the autoincrement is missed, causing one data word to
841  * be overwritten and subsequent words to be written to the wrong memory
842  * locations. The end result is that we could end up transmitting bogus
843  * frames without realizing it. The workaround for this is to write a
844  * couple of extra guard words after the end of the transfer, then
845  * attempt to read then back. If we fail to locate the guard words where
846  * we expect them, we preform the transfer over again.
847  */
848 STATIC int
849 wi_write_data(sc, id, off, buf, len)
850 	struct wi_softc		*sc;
851 	int			id, off;
852 	caddr_t			buf;
853 	int			len;
854 {
855 	u_int8_t		*ptr;
856 
857 #ifdef WI_HERMES_AUTOINC_WAR
858 again:
859 #endif
860 
861 	if (wi_seek(sc, id, off, WI_BAP0))
862 		return(EIO);
863 
864 	ptr = (u_int8_t *)buf;
865 	CSR_WRITE_RAW_2(sc, WI_DATA0, ptr, len);
866 
867 #ifdef WI_HERMES_AUTOINC_WAR
868 	CSR_WRITE_2(sc, WI_DATA0, 0x1234);
869 	CSR_WRITE_2(sc, WI_DATA0, 0x5678);
870 
871 	if (wi_seek(sc, id, off + len, WI_BAP0))
872 		return(EIO);
873 
874 	if (CSR_READ_2(sc, WI_DATA0) != 0x1234 ||
875 	    CSR_READ_2(sc, WI_DATA0) != 0x5678)
876 		goto again;
877 #endif
878 
879 	return(0);
880 }
881 
882 /*
883  * Allocate a region of memory inside the NIC and zero
884  * it out.
885  */
886 STATIC int
887 wi_alloc_nicmem(sc, len, id)
888 	struct wi_softc		*sc;
889 	int			len;
890 	int			*id;
891 {
892 	int			i;
893 
894 	if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len)) {
895 		printf(WI_PRT_FMT ": failed to allocate %d bytes on NIC\n",
896 		    WI_PRT_ARG(sc), len);
897 		return(ENOMEM);
898 	}
899 
900 	for (i = WI_TIMEOUT; i--; DELAY(1)) {
901 		if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC)
902 			break;
903 	}
904 
905 	if (i < 0)
906 		return(ETIMEDOUT);
907 
908 	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
909 	*id = CSR_READ_2(sc, WI_ALLOC_FID);
910 
911 	if (wi_seek(sc, *id, 0, WI_BAP0))
912 		return(EIO);
913 
914 	for (i = 0; i < len / 2; i++)
915 		CSR_WRITE_2(sc, WI_DATA0, 0);
916 
917 	return(0);
918 }
919 
920 STATIC void
921 wi_setmulti(sc)
922 	struct wi_softc		*sc;
923 {
924 	struct ifnet		*ifp;
925 	int			i = 0;
926 	struct wi_ltv_mcast	mcast;
927 	struct ether_multistep	step;
928 	struct ether_multi	*enm;
929 
930 	ifp = &sc->arpcom.ac_if;
931 
932 	bzero((char *)&mcast, sizeof(mcast));
933 
934 	mcast.wi_type = WI_RID_MCAST_LIST;
935 	mcast.wi_len = ((ETHER_ADDR_LEN / 2) * 16) + 1;
936 
937 	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
938 		wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
939 		return;
940 	}
941 
942 	ETHER_FIRST_MULTI(step, &sc->arpcom, enm);
943 	while (enm != NULL) {
944 		if (i >= 16) {
945 			bzero((char *)&mcast, sizeof(mcast));
946 			break;
947 		}
948 
949 		/* Punt on ranges. */
950 		if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
951 		    sizeof(enm->enm_addrlo)) != 0)
952 			break;
953 		bcopy(enm->enm_addrlo, (char *)&mcast.wi_mcast[i],
954 		    ETHER_ADDR_LEN);
955 		i++;
956 		ETHER_NEXT_MULTI(step, enm);
957 	}
958 
959 	mcast.wi_len = (i * 3) + 1;
960 	wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
961 
962 	return;
963 }
964 
965 STATIC void
966 wi_setdef(sc, wreq)
967 	struct wi_softc		*sc;
968 	struct wi_req		*wreq;
969 {
970 	struct sockaddr_dl	*sdl;
971 	struct ifaddr		*ifa;
972 	struct ifnet		*ifp;
973 	extern struct ifaddr	**ifnet_addrs;
974 
975 	ifp = &sc->arpcom.ac_if;
976 
977 	switch(wreq->wi_type) {
978 	case WI_RID_MAC_NODE:
979 		ifa = ifnet_addrs[ifp->if_index];
980 		sdl = (struct sockaddr_dl *)ifa->ifa_addr;
981 		bcopy((char *)&wreq->wi_val, LLADDR(sdl), ETHER_ADDR_LEN);
982 		bcopy((char *)&wreq->wi_val, (char *)&sc->arpcom.ac_enaddr,
983 		    ETHER_ADDR_LEN);
984 		break;
985 	case WI_RID_PORTTYPE:
986 		sc->wi_ptype = letoh16(wreq->wi_val[0]);
987 		break;
988 	case WI_RID_TX_RATE:
989 		sc->wi_tx_rate = letoh16(wreq->wi_val[0]);
990 		break;
991 	case WI_RID_MAX_DATALEN:
992 		sc->wi_max_data_len = letoh16(wreq->wi_val[0]);
993 		break;
994 	case WI_RID_RTS_THRESH:
995 		sc->wi_rts_thresh = letoh16(wreq->wi_val[0]);
996 		break;
997 	case WI_RID_SYSTEM_SCALE:
998 		sc->wi_ap_density = letoh16(wreq->wi_val[0]);
999 		break;
1000 	case WI_RID_CREATE_IBSS:
1001 		sc->wi_create_ibss = letoh16(wreq->wi_val[0]);
1002 		break;
1003 	case WI_RID_OWN_CHNL:
1004 		sc->wi_channel = letoh16(wreq->wi_val[0]);
1005 		break;
1006 	case WI_RID_NODENAME:
1007 		bzero(sc->wi_node_name, sizeof(sc->wi_node_name));
1008 		bcopy((char *)&wreq->wi_val[1], sc->wi_node_name, 30);
1009 		break;
1010 	case WI_RID_DESIRED_SSID:
1011 		bzero(sc->wi_net_name, sizeof(sc->wi_net_name));
1012 		bcopy((char *)&wreq->wi_val[1], sc->wi_net_name, 30);
1013 		break;
1014 	case WI_RID_OWN_SSID:
1015 		bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name));
1016 		bcopy((char *)&wreq->wi_val[1], sc->wi_ibss_name, 30);
1017 		break;
1018 	case WI_RID_PM_ENABLED:
1019 		sc->wi_pm_enabled = letoh16(wreq->wi_val[0]);
1020 		break;
1021 	case WI_RID_MICROWAVE_OVEN:
1022 		sc->wi_mor_enabled = letoh16(wreq->wi_val[0]);
1023 		break;
1024 	case WI_RID_MAX_SLEEP:
1025 		sc->wi_max_sleep = letoh16(wreq->wi_val[0]);
1026 		break;
1027 	case WI_RID_AUTH_CNTL:
1028 		sc->wi_authtype = letoh16(wreq->wi_val[0]);
1029 		break;
1030 	case WI_RID_ROAMING_MODE:
1031 		sc->wi_roaming = letoh16(wreq->wi_val[0]);
1032 		break;
1033 	case WI_RID_ENCRYPTION:
1034 		sc->wi_use_wep = letoh16(wreq->wi_val[0]);
1035 		break;
1036 	case WI_RID_TX_CRYPT_KEY:
1037 		sc->wi_tx_key = letoh16(wreq->wi_val[0]);
1038 		break;
1039 	case WI_RID_DEFLT_CRYPT_KEYS:
1040 		bcopy((char *)wreq, (char *)&sc->wi_keys,
1041 		    sizeof(struct wi_ltv_keys));
1042 		break;
1043 	default:
1044 		break;
1045 	}
1046 
1047 	/* Reinitialize WaveLAN. */
1048 	wi_init(sc);
1049 
1050 	return;
1051 }
1052 
1053 STATIC int
1054 wi_ioctl(ifp, command, data)
1055 	struct ifnet		*ifp;
1056 	u_long			command;
1057 	caddr_t			data;
1058 {
1059 	int			s, error = 0;
1060 	struct wi_softc		*sc;
1061 	struct wi_req		wreq;
1062 	struct ifreq		*ifr;
1063 	struct proc		*p = curproc;
1064 	struct ifaddr		*ifa = (struct ifaddr *)data;
1065 
1066 	s = splimp();
1067 
1068 	sc = ifp->if_softc;
1069 	ifr = (struct ifreq *)data;
1070 
1071 	if (sc->wi_gone) {
1072 		splx(s);
1073 		return(ENODEV);
1074 	}
1075 
1076 	DPRINTF (WID_IOCTL, ("wi_ioctl: command %lu data %p\n",
1077 	    command, data));
1078 
1079 	if ((error = ether_ioctl(ifp, &sc->arpcom, command, data)) > 0) {
1080 		splx(s);
1081 		return error;
1082 	}
1083 
1084 	switch(command) {
1085 	case SIOCSIFADDR:
1086 		ifp->if_flags |= IFF_UP;
1087 		switch (ifa->ifa_addr->sa_family) {
1088 #ifdef INET
1089 		case AF_INET:
1090 			wi_init(sc);
1091 			arp_ifinit(&sc->arpcom, ifa);
1092 			break;
1093 #endif	/* INET */
1094 		default:
1095 			wi_init(sc);
1096 			break;
1097 		}
1098 		break;
1099 
1100 	case SIOCSIFMTU:
1101 		if (ifr->ifr_mtu > ETHERMTU || ifr->ifr_mtu < ETHERMIN) {
1102 			error = EINVAL;
1103 		} else if (ifp->if_mtu != ifr->ifr_mtu) {
1104 			ifp->if_mtu = ifr->ifr_mtu;
1105 		}
1106 		break;
1107 
1108 	case SIOCSIFFLAGS:
1109 		if (ifp->if_flags & IFF_UP) {
1110 			if (ifp->if_flags & IFF_RUNNING &&
1111 			    ifp->if_flags & IFF_PROMISC &&
1112 			    !(sc->wi_if_flags & IFF_PROMISC)) {
1113 				WI_SETVAL(WI_RID_PROMISC, 1);
1114 			} else if (ifp->if_flags & IFF_RUNNING &&
1115 			    !(ifp->if_flags & IFF_PROMISC) &&
1116 			    sc->wi_if_flags & IFF_PROMISC) {
1117 				WI_SETVAL(WI_RID_PROMISC, 0);
1118 			}
1119 			wi_init(sc);
1120 		} else {
1121 			if (ifp->if_flags & IFF_RUNNING) {
1122 				wi_stop(sc);
1123 			}
1124 		}
1125 		sc->wi_if_flags = ifp->if_flags;
1126 		error = 0;
1127 		break;
1128 	case SIOCADDMULTI:
1129 	case SIOCDELMULTI:
1130 		/* Update our multicast list. */
1131 		error = (command == SIOCADDMULTI) ?
1132 		    ether_addmulti(ifr, &sc->arpcom) :
1133 		    ether_delmulti(ifr, &sc->arpcom);
1134 		if (error == ENETRESET) {
1135 			/*
1136 			 * Multicast list has changed; set the hardware filter
1137 			 * accordingly.
1138 			 */
1139 			wi_setmulti(sc);
1140 			error = 0;
1141 		}
1142 		break;
1143 	case SIOCGWAVELAN:
1144 		error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1145 		if (error)
1146 			break;
1147 		if (wreq.wi_type == WI_RID_IFACE_STATS) {
1148 			/* XXX native byte order */
1149 			bcopy((char *)&sc->wi_stats, (char *)&wreq.wi_val,
1150 			    sizeof(sc->wi_stats));
1151 			wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1;
1152 		} else if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS) {
1153 			/* For non-root user, return all-zeroes keys */
1154 			if (suser(p->p_ucred, &p->p_acflag))
1155 				bzero((char *)&wreq,
1156 					sizeof(struct wi_ltv_keys));
1157 			else
1158 				bcopy((char *)&sc->wi_keys, (char *)&wreq,
1159 					sizeof(struct wi_ltv_keys));
1160 		} else {
1161 			if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) {
1162 				error = EINVAL;
1163 				break;
1164 			}
1165 		}
1166 		error = copyout(&wreq, ifr->ifr_data, sizeof(wreq));
1167 		break;
1168 	case SIOCSWAVELAN:
1169 		error = suser(p->p_ucred, &p->p_acflag);
1170 		if (error)
1171 			break;
1172 		error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1173 		if (error)
1174 			break;
1175 		if (wreq.wi_type == WI_RID_IFACE_STATS) {
1176 			error = EINVAL;
1177 			break;
1178 		} else if (wreq.wi_type == WI_RID_MGMT_XMIT) {
1179 			error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val,
1180 			    wreq.wi_len);
1181 		} else {
1182 			error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
1183 			if (!error)
1184 				wi_setdef(sc, &wreq);
1185 		}
1186 		break;
1187 	default:
1188 		error = EINVAL;
1189 		break;
1190 	}
1191 
1192 	splx(s);
1193 	return(error);
1194 }
1195 
1196 STATIC void
1197 wi_init(xsc)
1198 	void			*xsc;
1199 {
1200 	struct wi_softc		*sc = xsc;
1201 	struct ifnet		*ifp = &sc->arpcom.ac_if;
1202 	int			s;
1203 	struct wi_ltv_macaddr	mac;
1204 	int			id = 0;
1205 
1206 	if (sc->wi_gone)
1207 		return;
1208 
1209 	DPRINTF(WID_INIT, ("wi_init: sc %p\n", sc));
1210 
1211 	s = splimp();
1212 
1213 	if (ifp->if_flags & IFF_RUNNING)
1214 		wi_stop(sc);
1215 
1216 	wi_reset(sc);
1217 
1218 	/* Program max data length. */
1219 	WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len);
1220 
1221 	/* Enable/disable IBSS creation. */
1222 	WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss);
1223 
1224 	/* Set the port type. */
1225 	WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype);
1226 
1227 	/* Program the RTS/CTS threshold. */
1228 	WI_SETVAL(WI_RID_RTS_THRESH, sc->wi_rts_thresh);
1229 
1230 	/* Program the TX rate */
1231 	WI_SETVAL(WI_RID_TX_RATE, sc->wi_tx_rate);
1232 
1233 	/* Access point density */
1234 	WI_SETVAL(WI_RID_SYSTEM_SCALE, sc->wi_ap_density);
1235 
1236 	/* Power Management Enabled */
1237 	WI_SETVAL(WI_RID_PM_ENABLED, sc->wi_pm_enabled);
1238 
1239 	/* Power Managment Max Sleep */
1240 	WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep);
1241 
1242 	/* Roaming type */
1243 	WI_SETVAL(WI_RID_ROAMING_MODE, sc->wi_roaming);
1244 
1245 	/* Specify the IBSS name */
1246 	WI_SETSTR(WI_RID_OWN_SSID, sc->wi_ibss_name);
1247 
1248 	/* Specify the network name */
1249 	WI_SETSTR(WI_RID_DESIRED_SSID, sc->wi_net_name);
1250 
1251 	/* Specify the frequency to use */
1252 	WI_SETVAL(WI_RID_OWN_CHNL, sc->wi_channel);
1253 
1254 	/* Program the nodename. */
1255 	WI_SETSTR(WI_RID_NODENAME, sc->wi_node_name);
1256 
1257 	/* Set our MAC address. */
1258 	mac.wi_len = 4;
1259 	mac.wi_type = WI_RID_MAC_NODE;
1260 	bcopy((char *)&sc->arpcom.ac_enaddr,
1261 	   (char *)&mac.wi_mac_addr, ETHER_ADDR_LEN);
1262 	wi_write_record(sc, (struct wi_ltv_gen *)&mac);
1263 
1264 	/* Initialize promisc mode. */
1265 	if (ifp->if_flags & IFF_PROMISC) {
1266 		WI_SETVAL(WI_RID_PROMISC, 1);
1267 	} else {
1268 		WI_SETVAL(WI_RID_PROMISC, 0);
1269 	}
1270 
1271 	/* Configure WEP. */
1272 	if (sc->wi_has_wep) {
1273 		WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep);
1274 		WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key);
1275 		sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1;
1276 		sc->wi_keys.wi_type = WI_RID_DEFLT_CRYPT_KEYS;
1277 		wi_write_record(sc, (struct wi_ltv_gen *)&sc->wi_keys);
1278 		if (sc->sc_prism2 && sc->wi_use_wep) {
1279 			/*
1280 			 * For Prism2 Firmware version less than 0.8 variant3.
1281 			 * If promiscuous mode is disabled, the Prism2 chip
1282 			 * does not work with WEP .
1283 			 * I'm currently investigating the details of this.
1284 			 * (ichiro@netbsd.org)
1285 			 */
1286 			 if (sc->sc_prism2_ver < 83 ) {
1287 				/* firm ver < 0.8 variant 3 */
1288 				WI_SETVAL(WI_RID_PROMISC, 1);
1289 			 }
1290 			 WI_SETVAL(WI_RID_AUTH_CNTL, sc->wi_authtype);
1291 		}
1292 	}
1293 
1294 	/* Set multicast filter. */
1295 	wi_setmulti(sc);
1296 
1297 	/* Enable desired port */
1298 	wi_cmd(sc, WI_CMD_ENABLE | sc->wi_portnum, 0);
1299 
1300 	if (wi_alloc_nicmem(sc, 1518 + sizeof(struct wi_frame) + 8, &id))
1301 		printf(WI_PRT_FMT ": tx buffer allocation failed\n",
1302 		    WI_PRT_ARG(sc));
1303 	sc->wi_tx_data_id = id;
1304 
1305 	if (wi_alloc_nicmem(sc, 1518 + sizeof(struct wi_frame) + 8, &id))
1306 		printf(WI_PRT_FMT ": mgmt. buffer allocation failed\n",
1307 		    WI_PRT_ARG(sc));
1308 	sc->wi_tx_mgmt_id = id;
1309 
1310 	/* enable interrupts */
1311 	CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
1312 
1313 	splx(s);
1314 
1315 	ifp->if_flags |= IFF_RUNNING;
1316 	ifp->if_flags &= ~IFF_OACTIVE;
1317 
1318 	timeout_add(&sc->sc_timo, hz * 60);
1319 
1320 	return;
1321 }
1322 
1323 STATIC void
1324 wi_start(ifp)
1325 	struct ifnet		*ifp;
1326 {
1327 	struct wi_softc		*sc;
1328 	struct mbuf		*m0;
1329 	struct wi_frame		tx_frame;
1330 	struct ether_header	*eh;
1331 	int			id;
1332 
1333 	sc = ifp->if_softc;
1334 
1335 	DPRINTF(WID_START, ("wi_start: ifp %p sc %p\n", ifp, sc));
1336 
1337 	if (sc->wi_gone)
1338 		return;
1339 
1340 	if (ifp->if_flags & IFF_OACTIVE)
1341 		return;
1342 
1343 	IFQ_DEQUEUE(&ifp->if_snd, m0);
1344 	if (m0 == NULL)
1345 		return;
1346 
1347 	bzero((char *)&tx_frame, sizeof(tx_frame));
1348 	id = sc->wi_tx_data_id;
1349 	eh = mtod(m0, struct ether_header *);
1350 
1351 	/*
1352 	 * Use RFC1042 encoding for IP and ARP datagrams,
1353 	 * 802.3 for anything else.
1354 	 */
1355 	if (ntohs(eh->ether_type) == ETHERTYPE_IP ||
1356 	    ntohs(eh->ether_type) == ETHERTYPE_ARP ||
1357 	    ntohs(eh->ether_type) == ETHERTYPE_REVARP ||
1358 	    ntohs(eh->ether_type) == ETHERTYPE_IPV6) {
1359 		bcopy((char *)&eh->ether_dhost,
1360 		    (char *)&tx_frame.wi_addr1, ETHER_ADDR_LEN);
1361 		bcopy((char *)&eh->ether_shost,
1362 		    (char *)&tx_frame.wi_addr2, ETHER_ADDR_LEN);
1363 		bcopy((char *)&eh->ether_dhost,
1364 		    (char *)&tx_frame.wi_dst_addr, ETHER_ADDR_LEN);
1365 		bcopy((char *)&eh->ether_shost,
1366 		    (char *)&tx_frame.wi_src_addr, ETHER_ADDR_LEN);
1367 
1368 		tx_frame.wi_dat_len = htole16(m0->m_pkthdr.len - WI_SNAPHDR_LEN);
1369 		tx_frame.wi_frame_ctl = htole16(WI_FTYPE_DATA);
1370 		tx_frame.wi_dat[0] = htons(WI_SNAP_WORD0);
1371 		tx_frame.wi_dat[1] = htons(WI_SNAP_WORD1);
1372 		tx_frame.wi_len = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN);
1373 		tx_frame.wi_type = eh->ether_type;
1374 
1375 		m_copydata(m0, sizeof(struct ether_header),
1376 		    m0->m_pkthdr.len - sizeof(struct ether_header),
1377 		    (caddr_t)&sc->wi_txbuf);
1378 
1379 		wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
1380 		    sizeof(struct wi_frame));
1381 		wi_write_data(sc, id, WI_802_11_OFFSET, (caddr_t)&sc->wi_txbuf,
1382 		    (m0->m_pkthdr.len - sizeof(struct ether_header)) + 2);
1383 	} else {
1384 		tx_frame.wi_dat_len = htole16(m0->m_pkthdr.len);
1385 
1386 		m_copydata(m0, 0, m0->m_pkthdr.len, (caddr_t)&sc->wi_txbuf);
1387 
1388 		wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
1389 		    sizeof(struct wi_frame));
1390 		wi_write_data(sc, id, WI_802_3_OFFSET, (caddr_t)&sc->wi_txbuf,
1391 		    m0->m_pkthdr.len + 2);
1392 	}
1393 
1394 #if NBPFILTER > 0
1395 	/*
1396 	 * If there's a BPF listner, bounce a copy of
1397 	 * this frame to him.
1398 	 */
1399 	if (ifp->if_bpf)
1400 		BPF_MTAP(ifp, m0);
1401 #endif
1402 
1403 	m_freem(m0);
1404 
1405 	if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id))
1406 		printf(WI_PRT_FMT ": xmit failed\n", WI_PRT_ARG(sc));
1407 
1408 	ifp->if_flags |= IFF_OACTIVE;
1409 
1410 	/*
1411 	 * Set a timeout in case the chip goes out to lunch.
1412 	 */
1413 	ifp->if_timer = 5;
1414 
1415 	return;
1416 }
1417 
1418 STATIC int
1419 wi_mgmt_xmit(sc, data, len)
1420 	struct wi_softc		*sc;
1421 	caddr_t			data;
1422 	int			len;
1423 {
1424 	struct wi_frame		tx_frame;
1425 	int			id;
1426 	struct wi_80211_hdr	*hdr;
1427 	caddr_t			dptr;
1428 
1429 	if (sc->wi_gone)
1430 		return(ENODEV);
1431 
1432 	hdr = (struct wi_80211_hdr *)data;
1433 	dptr = data + sizeof(struct wi_80211_hdr);
1434 
1435 	bzero((char *)&tx_frame, sizeof(tx_frame));
1436 	id = sc->wi_tx_mgmt_id;
1437 
1438 	bcopy((char *)hdr, (char *)&tx_frame.wi_frame_ctl,
1439 	   sizeof(struct wi_80211_hdr));
1440 
1441 	tx_frame.wi_dat_len = htole16(len - WI_SNAPHDR_LEN);
1442 	tx_frame.wi_len = htons(len - WI_SNAPHDR_LEN);
1443 
1444 	wi_write_data(sc, id, 0, (caddr_t)&tx_frame, sizeof(struct wi_frame));
1445 	wi_write_data(sc, id, WI_802_11_OFFSET_RAW, dptr,
1446 	    (len - sizeof(struct wi_80211_hdr)) + 2);
1447 
1448 	if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id)) {
1449 		printf(WI_PRT_FMT ": xmit failed\n", WI_PRT_ARG(sc));
1450 		return(EIO);
1451 	}
1452 
1453 	return(0);
1454 }
1455 
1456 STATIC void
1457 wi_stop(sc)
1458 	struct wi_softc		*sc;
1459 {
1460 	struct ifnet		*ifp;
1461 
1462 	if (sc->wi_gone)
1463 		return;
1464 
1465 	DPRINTF(WID_STOP, ("wi_stop: sc %p\n", sc));
1466 
1467 	ifp = &sc->arpcom.ac_if;
1468 
1469 	CSR_WRITE_2(sc, WI_INT_EN, 0);
1470 	wi_cmd(sc, WI_CMD_DISABLE|sc->wi_portnum, 0);
1471 
1472 	timeout_del(&sc->sc_timo);
1473 
1474 	ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
1475 	ifp->if_timer = 0;
1476 
1477 	return;
1478 }
1479 
1480 STATIC void
1481 wi_watchdog(ifp)
1482 	struct ifnet		*ifp;
1483 {
1484 	struct wi_softc		*sc;
1485 
1486 	sc = ifp->if_softc;
1487 
1488 	printf(WI_PRT_FMT ": device timeout\n", WI_PRT_ARG(sc));
1489 
1490 	wi_init(sc);
1491 
1492 	ifp->if_oerrors++;
1493 
1494 	return;
1495 }
1496 
1497 STATIC void
1498 wi_shutdown(arg)
1499 	void			*arg;
1500 {
1501 	struct wi_softc		*sc;
1502 
1503 	sc = arg;
1504 	wi_stop(sc);
1505 
1506 	return;
1507 }
1508 
1509 STATIC void
1510 wi_get_id(sc, print_cis)
1511 	struct wi_softc *sc;
1512 	int print_cis;
1513 {
1514 	struct wi_ltv_ver       ver;
1515 	struct wi_ltv_cis	cis;
1516 	const char		*p;
1517 
1518 	if (print_cis) {
1519 		/*
1520 		 * For PCI attachments the CIS strings won't have been printed
1521 		 * so print them here.
1522 		 */
1523 		cis.wi_type = WI_RID_CIS;
1524 		cis.wi_len = sizeof(cis.wi_cis);
1525 		if (wi_read_record(sc, (struct wi_ltv_gen *)&cis) == 0) {
1526 			char *cis_strings[3];
1527 
1528 			cis_strings[0] = (char *)&cis.wi_cis[11];
1529 			cis_strings[1] = cis_strings[0] +
1530 			    strlen(cis_strings[0]) + 1;
1531 			cis_strings[2] = cis_strings[1] +
1532 			    strlen(cis_strings[1]) + 1;
1533 			printf("\n%s: \"%s, %s, %s\"", WI_PRT_ARG(sc),
1534 			    cis_strings[0], cis_strings[1], cis_strings[2]);
1535 		}
1536 	}
1537 
1538 	/* get chip identity */
1539 	bzero(&ver, sizeof(ver));
1540 	ver.wi_type = WI_RID_CARD_ID;
1541 	ver.wi_len = 5;
1542 	wi_read_record(sc, (struct wi_ltv_gen *)&ver);
1543 	switch (letoh16(ver.wi_ver[0])) {
1544 		case WI_NIC_EVB2:
1545 			p = "PRISM I HFA3841(EVB2)";
1546 			sc->sc_prism2 = 1;
1547 			break;
1548 		case WI_NIC_HWB3763:
1549 			p = "PRISM II HWB3763 rev.B";
1550 			sc->sc_prism2 = 1;
1551 			break;
1552 		case WI_NIC_HWB3163:
1553 			p = "PRISM II HWB3163 rev.A";
1554 			sc->sc_prism2 = 1;
1555 			break;
1556 		case WI_NIC_HWB3163B:
1557 			p = "PRISM II HWB3163 rev.B";
1558 			sc->sc_prism2 = 1;
1559 			break;
1560 		case WI_NIC_EVB3:
1561 			p = "PRISM II  HFA3842(EVB3)";
1562 			sc->sc_prism2 = 1;
1563 			break;
1564 		case WI_NIC_HWB1153:
1565 			p = "PRISM I HFA1153";
1566 			sc->sc_prism2 = 1;
1567 			break;
1568 		case WI_NIC_P2_SST:
1569 			p = "PRISM II HWB3163 SST-flash";
1570 			sc->sc_prism2 = 1;
1571 			break;
1572 		case WI_NIC_PRISM2_5:
1573 			p = "PRISM 2.5 ISL3873";
1574 			sc->sc_prism2 = 1;
1575 			break;
1576 		case WI_NIC_3874A:
1577 			p = "PRISM 2.5 ISL3874A(PCI)";
1578 			sc->sc_prism2 = 1;
1579 			break;
1580 		default:
1581 			p = "Lucent chip or unknown chip";
1582 			sc->sc_prism2 = 0;
1583 			break;
1584 	}
1585 
1586 	/* get firmware version */
1587 	bzero(&ver, sizeof(ver));
1588 	ver.wi_type = WI_RID_STA_IDENTITY;
1589 	ver.wi_len = 5;
1590 	wi_read_record(sc, (struct wi_ltv_gen *)&ver);
1591 	ver.wi_ver[1] = letoh16(ver.wi_ver[1]);
1592 	ver.wi_ver[2] = letoh16(ver.wi_ver[2]);
1593 	ver.wi_ver[3] = letoh16(ver.wi_ver[3]);
1594 	if (sc->sc_prism2) {
1595 		printf("\n%s: %s, Firmware %i.%i variant %i, ",
1596 		    WI_PRT_ARG(sc), p, ver.wi_ver[2],
1597 		    ver.wi_ver[3], ver.wi_ver[1]);
1598 		sc->sc_prism2_ver = ver.wi_ver[2] * 100 +
1599 				    ver.wi_ver[3] *  10 + ver.wi_ver[1];
1600 	} else {
1601 		printf("\n%s: Firmware %i.%i variant %i, ", WI_PRT_ARG(sc),
1602 		    ver.wi_ver[2], ver.wi_ver[3], ver.wi_ver[1]);
1603 	}
1604 
1605 	return;
1606 }
1607