xref: /netbsd-src/sys/dev/ic/an.c (revision 17dd36da8292193180754d5047c0926dbb56818c)
1 /*	$NetBSD: an.c,v 1.11 2001/03/08 16:33:43 thorpej Exp $	*/
2 /*
3  * Copyright (c) 1997, 1998, 1999
4  *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *	This product includes software developed by Bill Paul.
17  * 4. Neither the name of the author nor the names of any co-contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31  * THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * $FreeBSD: src/sys/dev/an/if_an.c,v 1.12 2000/11/13 23:04:12 wpaul Exp $
34  */
35 
36 /*
37  * Aironet 4500/4800 802.11 PCMCIA/ISA/PCI driver for FreeBSD.
38  *
39  * Written by Bill Paul <wpaul@ctr.columbia.edu>
40  * Electrical Engineering Department
41  * Columbia University, New York City
42  */
43 
44 /*
45  * The Aironet 4500/4800 series cards some in PCMCIA, ISA and PCI form.
46  * This driver supports all three device types (PCI devices are supported
47  * through an extra PCI shim: /sys/pci/if_an_p.c). ISA devices can be
48  * supported either using hard-coded IO port/IRQ settings or via Plug
49  * and Play. The 4500 series devices support 1Mbps and 2Mbps data rates.
50  * The 4800 devices support 1, 2, 5.5 and 11Mbps rates.
51  *
52  * Like the WaveLAN/IEEE cards, the Aironet NICs are all essentially
53  * PCMCIA devices. The ISA and PCI cards are a combination of a PCMCIA
54  * device and a PCMCIA to ISA or PCMCIA to PCI adapter card. There are
55  * a couple of important differences though:
56  *
57  * - Lucent doesn't currently offer a PCI card, however Aironet does
58  * - Lucent ISA card looks to the host like a PCMCIA controller with
59  *   a PCMCIA WaveLAN card inserted. This means that even desktop
60  *   machines need to be configured with PCMCIA support in order to
61  *   use WaveLAN/IEEE ISA cards. The Aironet cards on the other hand
62  *   actually look like normal ISA and PCI devices to the host, so
63  *   no PCMCIA controller support is needed
64  *
65  * The latter point results in a small gotcha. The Aironet PCMCIA
66  * cards can be configured for one of two operating modes depending
67  * on how the Vpp1 and Vpp2 programming voltages are set when the
68  * card is activated. In order to put the card in proper PCMCIA
69  * operation (where the CIS table is visible and the interface is
70  * programmed for PCMCIA operation), both Vpp1 and Vpp2 have to be
71  * set to 5 volts. FreeBSD by default doesn't set the Vpp voltages,
72  * which leaves the card in ISA/PCI mode, which prevents it from
73  * being activated as an PCMCIA device. Consequently, /sys/pccard/pccard.c
74  * has to be patched slightly in order to enable the Vpp voltages in
75  * order to make the Aironet PCMCIA cards work.
76  *
77  * Note that some PCMCIA controller software packages for Windows NT
78  * fail to set the voltages as well.
79  *
80  * The Aironet devices can operate in both station mode and access point
81  * mode. Typically, when programmed for station mode, the card can be set
82  * to automatically perform encapsulation/decapsulation of Ethernet II
83  * and 802.3 frames within 802.11 frames so that the host doesn't have
84  * to do it itself. This driver doesn't program the card that way: the
85  * driver handles all of the encapsulation/decapsulation itself.
86  */
87 
88 /*
89  * Ported to NetBSD from FreeBSD by Atsushi Onoe at the San Diego
90  * IETF meeting.
91  */
92 
93 #include "opt_inet.h"
94 #include "bpfilter.h"
95 
96 #ifdef INET
97 #define ANCACHE			/* enable signal strength cache */
98 #endif
99 
100 #include <sys/param.h>
101 #include <sys/callout.h>
102 #include <sys/systm.h>
103 #include <sys/sockio.h>
104 #include <sys/mbuf.h>
105 #include <sys/kernel.h>
106 #include <sys/ucred.h>
107 #include <sys/socket.h>
108 #include <sys/device.h>
109 #ifdef ANCACHE
110 #include <sys/syslog.h>
111 #include <sys/sysctl.h>
112 #endif
113 
114 #include <machine/bus.h>
115 
116 #include <net/if.h>
117 #include <net/if_arp.h>
118 #include <net/if_dl.h>
119 #include <net/if_ether.h>
120 #include <net/if_ieee80211.h>
121 #include <net/if_types.h>
122 #include <net/if_media.h>
123 
124 #ifdef INET
125 #include <netinet/in.h>
126 #include <netinet/in_systm.h>
127 #include <netinet/in_var.h>
128 #include <netinet/ip.h>
129 #endif
130 
131 #if NBPFILTER > 0
132 #include <net/bpf.h>
133 #endif
134 
135 #include <dev/ic/anreg.h>
136 #include <dev/ic/anvar.h>
137 
138 #if !defined(lint)
139 static const char rcsid[] =
140   "$FreeBSD: src/sys/dev/an/if_an.c,v 1.12 2000/11/13 23:04:12 wpaul Exp $";
141 #endif
142 
143 /* These are global because we need them in sys/pci/if_an_p.c. */
144 static void an_reset		__P((struct an_softc *));
145 static void an_wait		__P((struct an_softc *));
146 static int an_ioctl		__P((struct ifnet *, u_long, caddr_t));
147 static int an_init		__P((struct ifnet *));
148 static void an_stop		__P((struct ifnet *, int));
149 static int an_init_tx_ring	__P((struct an_softc *));
150 static void an_start		__P((struct ifnet *));
151 static void an_watchdog		__P((struct ifnet *));
152 static void an_rxeof		__P((struct an_softc *));
153 static void an_txeof		__P((struct an_softc *, int));
154 
155 static void an_promisc		__P((struct an_softc *, int));
156 static int an_cmd		__P((struct an_softc *, int, int));
157 static int an_read_record	__P((struct an_softc *, struct an_ltv_gen *));
158 static int an_write_record	__P((struct an_softc *, struct an_ltv_gen *));
159 static int an_read_data		__P((struct an_softc *, int,
160 					int, caddr_t, int));
161 static int an_write_data	__P((struct an_softc *, int,
162 					int, caddr_t, int));
163 static int an_seek		__P((struct an_softc *, int, int, int));
164 static int an_alloc_nicmem	__P((struct an_softc *, int, int *));
165 static void an_stats_update	__P((void *));
166 static void an_setdef		__P((struct an_softc *, struct an_req *));
167 #ifdef ANCACHE
168 static void an_cache_store	__P((struct an_softc *, struct ether_header *,
169 					struct mbuf *, unsigned short));
170 #endif
171 #ifdef IFM_IEEE80211
172 static int an_media_change __P((struct ifnet *ifp));
173 static void an_media_status __P((struct ifnet *ifp, struct ifmediareq *imr));
174 #endif
175 
176 int
177 an_attach(struct an_softc *sc)
178 {
179 	struct ifnet		*ifp = &sc->arpcom.ec_if;
180 	int i, s;
181 #ifdef IFM_IEEE80211
182 	int mtype;
183 	struct ifmediareq imr;
184 #endif
185 
186 	s = splnet();
187 	sc->an_associated = 0;
188 	an_wait(sc);
189 
190 	/* Load factory config */
191 	if (an_cmd(sc, AN_CMD_READCFG, 0)) {
192 		splx(s);
193 		printf("%s: failed to load config data\n", sc->an_dev.dv_xname);
194 		return(EIO);
195 	}
196 
197 	/* Read the current configuration */
198 	sc->an_config.an_type = AN_RID_GENCONFIG;
199 	sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
200 	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_config)) {
201 		splx(s);
202 		printf("%s: read record failed\n", sc->an_dev.dv_xname);
203 		return(EIO);
204 	}
205 
206 	/* Read the card capabilities */
207 	sc->an_caps.an_type = AN_RID_CAPABILITIES;
208 	sc->an_caps.an_len = sizeof(struct an_ltv_caps);
209 	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_caps)) {
210 		splx(s);
211 		printf("%s: read record failed\n", sc->an_dev.dv_xname);
212 		return(EIO);
213 	}
214 
215 	/* Read ssid list */
216 	sc->an_ssidlist.an_type = AN_RID_SSIDLIST;
217 	sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist);
218 	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) {
219 		splx(s);
220 		printf("%s: read record failed\n", sc->an_dev.dv_xname);
221 		return(EIO);
222 	}
223 
224 	/* Read AP list */
225 	sc->an_aplist.an_type = AN_RID_APLIST;
226 	sc->an_aplist.an_len = sizeof(struct an_ltv_aplist);
227 	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) {
228 		splx(s);
229 		printf("%s: read record failed\n", sc->an_dev.dv_xname);
230 		return(EIO);
231 	}
232 
233 	printf("%s: 802.11 address: %s\n", sc->an_dev.dv_xname,
234 	    ether_sprintf(sc->an_caps.an_oemaddr));
235 
236 	ifp->if_softc = sc;
237 	ifp->if_flags =
238 	    IFF_BROADCAST | IFF_NOTRAILERS | IFF_SIMPLEX | IFF_MULTICAST;
239 	ifp->if_ioctl = an_ioctl;
240 	ifp->if_start = an_start;
241 	ifp->if_init = an_init;
242 	ifp->if_stop = an_stop;
243 	ifp->if_watchdog = an_watchdog;
244 	IFQ_SET_READY(&ifp->if_snd);
245 
246 	memcpy(ifp->if_xname, sc->an_dev.dv_xname, IFNAMSIZ);
247 
248 	bzero(sc->an_config.an_nodename, sizeof(sc->an_config.an_nodename));
249 	bcopy(AN_DEFAULT_NODENAME, sc->an_config.an_nodename,
250 	    sizeof(AN_DEFAULT_NODENAME) - 1);
251 
252 	bzero(sc->an_ssidlist.an_ssid1, sizeof(sc->an_ssidlist.an_ssid1));
253 	bcopy(AN_DEFAULT_NETNAME, sc->an_ssidlist.an_ssid1,
254 	    sizeof(AN_DEFAULT_NETNAME) - 1);
255 	sc->an_ssidlist.an_ssid1_len = strlen(AN_DEFAULT_NETNAME);
256 
257 	sc->an_config.an_opmode = AN_OPMODE_INFRASTRUCTURE_STATION;
258 
259 	sc->an_tx_rate = 0;
260 	bzero((char *)&sc->an_stats, sizeof(sc->an_stats));
261 
262 	/*
263 	 * Call MI attach routine.
264 	 */
265 	if_attach(ifp);
266 	ether_ifattach(ifp, sc->an_caps.an_oemaddr);
267 
268 #ifdef IFM_IEEE80211
269 	ifmedia_init(&sc->sc_media, 0, an_media_change, an_media_status);
270 	ifmedia_add(&sc->sc_media, IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO,
271 	    0, 0), 0, NULL);
272 	ifmedia_add(&sc->sc_media, IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO,
273 	    IFM_IEEE80211_ADHOC, 0), 0, NULL);
274 	for (i = 0; i < sizeof(sc->an_caps.an_rates); i++) {
275 		switch (sc->an_caps.an_rates[i]) {
276 		case AN_RATE_1MBPS:
277 			mtype = IFM_IEEE80211_DS1;
278 			break;
279 		case AN_RATE_2MBPS:
280 			mtype = IFM_IEEE80211_DS2;
281 			break;
282 		case AN_RATE_5_5MBPS:
283 			mtype = IFM_IEEE80211_DS5;
284 			break;
285 		case AN_RATE_11MBPS:
286 			mtype = IFM_IEEE80211_DS11;
287 			break;
288 		default:
289 			continue;
290 		}
291 		ifmedia_add(&sc->sc_media, IFM_MAKEWORD(IFM_IEEE80211, mtype,
292 		    0, 0), 0, NULL);
293 		ifmedia_add(&sc->sc_media, IFM_MAKEWORD(IFM_IEEE80211, mtype,
294 		    IFM_IEEE80211_ADHOC, 0), 0, NULL);
295 	}
296 	an_media_status(ifp, &imr);
297 	ifmedia_set(&sc->sc_media, imr.ifm_active);
298 #endif
299 	callout_init(&sc->an_stat_ch);
300 	splx(s);
301 
302 	return(0);
303 }
304 
305 int
306 an_detach(struct an_softc *sc)
307 {
308 	struct ifnet *ifp = &sc->arpcom.ec_if;
309 	int s;
310 
311 	s = splnet();
312 	an_stop(ifp, 1);
313 	ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
314 	ether_ifdetach(ifp);
315 	if_detach(ifp);
316 	splx(s);
317 	return 0;
318 }
319 
320 int
321 an_activate(struct device *self, enum devact act)
322 {
323 	struct an_softc *sc = (struct an_softc *)self;
324 	int s, error = 0;
325 
326 	s = splnet();
327 	switch (act) {
328 	case DVACT_ACTIVATE:
329 		error = EOPNOTSUPP;
330 		break;
331 
332 	case DVACT_DEACTIVATE:
333 		if_deactivate(&sc->arpcom.ec_if);
334 		break;
335 	}
336 	splx(s);
337 
338 	return error;
339 }
340 
341 void
342 an_power(int why, void *arg)
343 {
344 	int s;
345 	struct an_softc *sc = arg;
346 	struct ifnet *ifp = &sc->arpcom.ec_if;
347 
348 	if (!sc->sc_enabled)
349 		return;
350 
351 	s = splnet();
352 	switch (why) {
353 	case PWR_SUSPEND:
354 	case PWR_STANDBY:
355 		an_stop(ifp, 0);
356 		break;
357 	case PWR_RESUME:
358 		break;
359 	case PWR_SOFTSUSPEND:
360 	case PWR_SOFTSTANDBY:
361 	case PWR_SOFTRESUME:
362 		break;
363 	}
364 	splx(s);
365 }
366 
367 void
368 an_shutdown(void *arg)
369 {
370 	struct an_softc		*sc = arg;
371 
372 	an_stop(&sc->arpcom.ec_if, 1);
373 	return;
374 }
375 
376 static void an_rxeof(sc)
377 	struct an_softc		*sc;
378 {
379 	struct ifnet		*ifp;
380 	struct ether_header	*eh;
381 #ifdef ANCACHE
382 	struct an_rxframe	rx_frame;
383 #endif
384 	struct an_rxframe_802_3	rx_frame_802_3;
385 	struct mbuf		*m;
386 	int			id, error = 0;
387 
388 	ifp = &sc->arpcom.ec_if;
389 
390 	id = CSR_READ_2(sc, AN_RX_FID);
391 
392 	MGETHDR(m, M_DONTWAIT, MT_DATA);
393 	if (m == NULL) {
394 		ifp->if_ierrors++;
395 		return;
396 	}
397 	MCLGET(m, M_DONTWAIT);
398 	if (!(m->m_flags & M_EXT)) {
399 		m_freem(m);
400 		ifp->if_ierrors++;
401 		return;
402 	}
403 
404 	m->m_pkthdr.rcvif = ifp;
405 
406 	/* Align the data after the ethernet header */
407 	m->m_data = (caddr_t) ALIGN(m->m_data + sizeof(struct ether_header)) -
408 	    sizeof(struct ether_header);
409 
410 	eh = mtod(m, struct ether_header *);
411 
412 #ifdef ANCACHE
413 	/* Read NIC frame header */
414 	if (an_read_data(sc, id, 0, (caddr_t)&rx_frame, sizeof(rx_frame))) {
415 		ifp->if_ierrors++;
416 		return;
417 	}
418 #endif
419 	/* Read in the 802_3 frame header */
420 	if (an_read_data(sc, id, 0x34, (caddr_t)&rx_frame_802_3,
421 			 sizeof(rx_frame_802_3))) {
422 		ifp->if_ierrors++;
423 		return;
424 	}
425 
426 	if (rx_frame_802_3.an_rx_802_3_status != 0) {
427 		ifp->if_ierrors++;
428 		return;
429 	}
430 
431 	/* Check for insane frame length */
432 	if (rx_frame_802_3.an_rx_802_3_payload_len > MCLBYTES) {
433 		ifp->if_ierrors++;
434 		return;
435 	}
436 
437 	m->m_pkthdr.len = m->m_len =
438 	    rx_frame_802_3.an_rx_802_3_payload_len + 12;
439 
440 
441 	bcopy((char *)&rx_frame_802_3.an_rx_dst_addr,
442 	    (char *)&eh->ether_dhost, ETHER_ADDR_LEN);
443 	bcopy((char *)&rx_frame_802_3.an_rx_src_addr,
444 	    (char *)&eh->ether_shost, ETHER_ADDR_LEN);
445 
446 	/* in mbuf header type is just before payload */
447 	error = an_read_data(sc, id, 0x44, (caddr_t)&(eh->ether_type),
448 			     rx_frame_802_3.an_rx_802_3_payload_len);
449 
450 	if (error) {
451 		m_freem(m);
452 		ifp->if_ierrors++;
453 		return;
454 	}
455 
456 	ifp->if_ipackets++;
457 
458 	/* Receive packet. */
459 #ifdef ANCACHE
460 	an_cache_store(sc, eh, m, rx_frame.an_rx_signal_strength);
461 #endif
462 #if NBPFILTER > 0
463 	if (ifp->if_bpf)
464 		bpf_mtap(ifp->if_bpf, m);
465 #endif
466 	(*ifp->if_input)(ifp, m);
467 }
468 
469 static void an_txeof(sc, status)
470 	struct an_softc		*sc;
471 	int			status;
472 {
473 	struct ifnet		*ifp;
474 	int			id;
475 
476 	/* TX DONE enable lan monitor DJA
477 	   an_enable_sniff();
478 	 */
479 
480 	ifp = &sc->arpcom.ec_if;
481 
482 	ifp->if_timer = 0;
483 	ifp->if_flags &= ~IFF_OACTIVE;
484 
485 	id = CSR_READ_2(sc, AN_TX_CMP_FID);
486 
487 	if (status & AN_EV_TX_EXC) {
488 		ifp->if_oerrors++;
489 	} else
490 		ifp->if_opackets++;
491 
492 #if 0 /*XXX*/
493 	if (id != sc->an_rdata.an_tx_ring[sc->an_rdata.an_tx_cons])
494 		printf("%s: id mismatch: expected %x, got %x\n",
495 		    sc->an_dev.dv_xname,
496 		    sc->an_rdata.an_tx_ring[sc->an_rdata.an_tx_cons], id);
497 #endif
498 
499 	sc->an_rdata.an_tx_ring[sc->an_rdata.an_tx_cons] = 0;
500 	AN_INC(sc->an_rdata.an_tx_cons, AN_TX_RING_CNT);
501 
502 	return;
503 }
504 
505 /*
506  * We abuse the stats updater to check the current NIC status. This
507  * is important because we don't want to allow transmissions until
508  * the NIC has synchronized to the current cell (either as the master
509  * in an ad-hoc group, or as a station connected to an access point).
510  */
511 void an_stats_update(xsc)
512 	void			*xsc;
513 {
514 	struct an_softc		*sc;
515 	struct ifnet		*ifp;
516 
517 	sc = xsc;
518 	ifp = &sc->arpcom.ec_if;
519 
520 	sc->an_status.an_type = AN_RID_STATUS;
521 	sc->an_status.an_len = sizeof(struct an_ltv_status);
522 	an_read_record(sc, (struct an_ltv_gen *)&sc->an_status);
523 
524 	if (sc->an_status.an_opmode & AN_STATUS_OPMODE_IN_SYNC)
525 		sc->an_associated = 1;
526 	else
527 		sc->an_associated = 0;
528 
529 	/* Don't do this while we're transmitting */
530 	if (ifp->if_flags & IFF_OACTIVE) {
531 		callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc);
532 		return;
533 	}
534 
535 	sc->an_stats.an_len = sizeof(struct an_ltv_stats);
536 	sc->an_stats.an_type = AN_RID_32BITS_CUM;
537 	an_read_record(sc, (struct an_ltv_gen *)&sc->an_stats.an_len);
538 
539 	callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc);
540 
541 	return;
542 }
543 
544 int an_intr(void *arg)
545 {
546 	struct an_softc		*sc = arg;
547 	struct ifnet		*ifp;
548 	u_int16_t		status;
549 
550 	if (!sc->sc_enabled)
551 		return 0;
552 
553 	ifp = &sc->arpcom.ec_if;
554 
555 	if (!(ifp->if_flags & IFF_UP)) {
556 		CSR_WRITE_2(sc, AN_EVENT_ACK, 0xFFFF);
557 		CSR_WRITE_2(sc, AN_INT_EN, 0);
558 		return 0;
559 	}
560 
561 	/* Disable interrupts. */
562 	CSR_WRITE_2(sc, AN_INT_EN, 0);
563 
564 	status = CSR_READ_2(sc, AN_EVENT_STAT);
565 	CSR_WRITE_2(sc, AN_EVENT_ACK, ~AN_INTRS);
566 
567 	if (status & AN_EV_AWAKE) {
568 		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_AWAKE);
569 	}
570 
571 	if (status & AN_EV_LINKSTAT) {
572 		if (CSR_READ_2(sc, AN_LINKSTAT) == AN_LINKSTAT_ASSOCIATED)
573 			sc->an_associated = 1;
574 		else
575 			sc->an_associated = 0;
576 		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_LINKSTAT);
577 	}
578 
579 	if (status & AN_EV_RX) {
580 		an_rxeof(sc);
581 		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX);
582 	}
583 
584 	if (status & AN_EV_TX) {
585 		an_txeof(sc, status);
586 		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_TX);
587 	}
588 
589 	if (status & AN_EV_TX_EXC) {
590 		an_txeof(sc, status);
591 		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_TX_EXC);
592 	}
593 
594 	if (status & AN_EV_ALLOC)
595 		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_ALLOC);
596 
597 	if (status & AN_EV_CMD) {
598 		wakeup(sc);
599 		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CMD);
600 	}
601 
602 	/* Re-enable interrupts. */
603 	CSR_WRITE_2(sc, AN_INT_EN, AN_INTRS);
604 
605 	if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
606 		an_start(ifp);
607 
608 	return 1;
609 }
610 
611 static int
612 an_cmd(struct an_softc *sc, int cmd, int val)
613 {
614 	int i, stat;
615 
616 	/* make sure that previous command completed */
617 	if (CSR_READ_2(sc, AN_COMMAND) & AN_CMD_BUSY) {
618 		printf("%s: command busy\n", sc->an_dev.dv_xname);
619 		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CLR_STUCK_BUSY);
620 	}
621 
622 	CSR_WRITE_2(sc, AN_PARAM0, val);
623 	CSR_WRITE_2(sc, AN_PARAM1, 0);
624 	CSR_WRITE_2(sc, AN_PARAM2, 0);
625 	CSR_WRITE_2(sc, AN_COMMAND, cmd);
626 
627 	for (i = 0; i < AN_TIMEOUT; i++) {
628 		if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_CMD)
629 			break;
630 		/* make sure the command is accepted */
631 		if (CSR_READ_2(sc, AN_COMMAND) == cmd)
632 			CSR_WRITE_2(sc, AN_COMMAND, cmd);
633 		DELAY(10);
634 	}
635 
636 	stat = CSR_READ_2(sc, AN_STATUS);
637 #if 0
638 	CSR_READ_2(sc, AN_RESP0);
639 	CSR_READ_2(sc, AN_RESP1);
640 	CSR_READ_2(sc, AN_RESP2);
641 #endif
642 
643 	/* clear stuck command busy if necessary */
644 	if (CSR_READ_2(sc, AN_COMMAND) & AN_CMD_BUSY)
645 		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CLR_STUCK_BUSY);
646 
647 	/* Ack the command */
648 	CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CMD);
649 
650 	if (i == AN_TIMEOUT)
651 		return ETIMEDOUT;
652 	if (stat & AN_STAT_CMD_RESULT)
653 		return EIO;
654 
655 	return 0;
656 }
657 
658 /*
659  * This reset sequence may look a little strange, but this is the
660  * most reliable method I've found to really kick the NIC in the
661  * head and force it to reboot correctly.
662  */
663 static void
664 an_reset(struct an_softc *sc)
665 {
666 	if (!sc->sc_enabled)
667 		return;
668 
669 	an_cmd(sc, AN_CMD_ENABLE, 0);
670 	an_cmd(sc, AN_CMD_FW_RESTART, 0);
671 	an_cmd(sc, AN_CMD_NOOP2, 0);
672 
673 	if (an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0) == ETIMEDOUT)
674 		printf("%s: reset failed\n", sc->an_dev.dv_xname);
675 
676 	an_cmd(sc, AN_CMD_DISABLE, 0);
677 
678 	return;
679 }
680 
681 /*
682  * Wait for firmware come up after power enabled.
683  */
684 static void
685 an_wait(struct an_softc *sc)
686 {
687 	int i;
688 
689 	if (!sc->sc_enabled)
690 		return;
691 
692 	CSR_WRITE_2(sc, AN_COMMAND, AN_CMD_NOOP2);
693 	for (i = 0; i < 3*hz; i++) {
694 		if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_CMD)
695 			break;
696 		(void)tsleep(sc, PWAIT, "anatch", 1);
697 	}
698 	CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CMD);
699 }
700 
701 /*
702  * Read an LTV record from the NIC.
703  */
704 static int an_read_record(sc, ltv)
705 	struct an_softc		*sc;
706 	struct an_ltv_gen	*ltv;
707 {
708 	u_int16_t		*ptr;
709 	int			i, len;
710 
711 	if (ltv->an_len == 0 || ltv->an_type == 0)
712 		return(EINVAL);
713 
714 	/* Tell the NIC to enter record read mode. */
715 	if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) {
716 		printf("%s: RID 0x%04x access failed\n", sc->an_dev.dv_xname,
717 		    ltv->an_type);
718 		return(EIO);
719 	}
720 
721 	/* Seek to the record. */
722 	if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) {
723 		printf("%s: RID 0x%04x seek to record failed\n",
724 		    sc->an_dev.dv_xname, ltv->an_type);
725 		return(EIO);
726 	}
727 
728 	/*
729 	 * Read the length and record type and make sure they
730 	 * match what we expect (this verifies that we have enough
731 	 * room to hold all of the returned data).
732 	 */
733 	len = CSR_READ_2(sc, AN_DATA1);
734 	if (len > ltv->an_len) {
735 		printf("%s: RID 0x%04x record length mismatch -- expected %d, "
736 		    "got %d\n", sc->an_dev.dv_xname,
737 		    ltv->an_type, ltv->an_len, len);
738 		return(ENOSPC);
739 	}
740 
741 	ltv->an_len = len;
742 
743 	/* Now read the data. */
744 	ptr = &ltv->an_val;
745 	for (i = 0; i < (ltv->an_len - 2) >> 1; i++)
746 		ptr[i] = CSR_READ_2(sc, AN_DATA1);
747 
748 	return(0);
749 }
750 
751 /*
752  * Same as read, except we inject data instead of reading it.
753  */
754 static int an_write_record(sc, ltv)
755 	struct an_softc		*sc;
756 	struct an_ltv_gen	*ltv;
757 {
758 	u_int16_t		*ptr;
759 	int			i;
760 
761 	if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type))
762 		return(EIO);
763 
764 	if (an_seek(sc, ltv->an_type, 0, AN_BAP1))
765 		return(EIO);
766 
767 	CSR_WRITE_2(sc, AN_DATA1, ltv->an_len-2);
768 
769 	ptr = &ltv->an_val;
770 	for (i = 0; i < (ltv->an_len - 4) >> 1; i++)
771 		CSR_WRITE_2(sc, AN_DATA1, ptr[i]);
772 
773 	if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_WRITE, ltv->an_type))
774 		return(EIO);
775 
776 	return(0);
777 }
778 
779 static int an_seek(sc, id, off, chan)
780 	struct an_softc		*sc;
781 	int			id, off, chan;
782 {
783 	int			i;
784 	int			selreg, offreg;
785 
786 	switch (chan) {
787 	case AN_BAP0:
788 		selreg = AN_SEL0;
789 		offreg = AN_OFF0;
790 		break;
791 	case AN_BAP1:
792 		selreg = AN_SEL1;
793 		offreg = AN_OFF1;
794 		break;
795 	default:
796 		printf("%s: invalid data path: %x\n", sc->an_dev.dv_xname, chan);
797 		return(EIO);
798 	}
799 
800 	CSR_WRITE_2(sc, selreg, id);
801 	CSR_WRITE_2(sc, offreg, off);
802 
803 	for (i = 0; i < AN_TIMEOUT; i++) {
804 		if (!(CSR_READ_2(sc, offreg) & (AN_OFF_BUSY|AN_OFF_ERR)))
805 			break;
806 		DELAY(10);
807 	}
808 
809 	if (i == AN_TIMEOUT)
810 		return(ETIMEDOUT);
811 
812 	return(0);
813 }
814 
815 static int an_read_data(sc, id, off, buf, len)
816 	struct an_softc		*sc;
817 	int			id, off;
818 	caddr_t			buf;
819 	int			len;
820 {
821 	int			i;
822 	u_int16_t		*ptr;
823 	u_int8_t		*ptr2;
824 
825 	if (off != -1) {
826 		if (an_seek(sc, id, off, AN_BAP1))
827 			return(EIO);
828 	}
829 
830 	ptr = (u_int16_t *)buf;
831 	for (i = 0; i < len / 2; i++)
832 		ptr[i] = CSR_READ_2(sc, AN_DATA1);
833 	i*=2;
834 	if (i<len){
835 	        ptr2 = (u_int8_t *)buf;
836 	        ptr2[i] = CSR_READ_1(sc, AN_DATA1);
837 	}
838 
839 	return(0);
840 }
841 
842 static int an_write_data(sc, id, off, buf, len)
843 	struct an_softc		*sc;
844 	int			id, off;
845 	caddr_t			buf;
846 	int			len;
847 {
848 	int			i;
849 	u_int16_t		*ptr;
850 	u_int8_t		*ptr2;
851 
852 	if (off != -1) {
853 		if (an_seek(sc, id, off, AN_BAP0))
854 			return(EIO);
855 	}
856 
857 	ptr = (u_int16_t *)buf;
858 	for (i = 0; i < (len / 2); i++)
859 		CSR_WRITE_2(sc, AN_DATA0, ptr[i]);
860 	i*=2;
861 	if (i<len){
862 	        ptr2 = (u_int8_t *)buf;
863 	        CSR_WRITE_1(sc, AN_DATA0, ptr2[i]);
864 	}
865 
866 	return(0);
867 }
868 
869 /*
870  * Allocate a region of memory inside the NIC and zero
871  * it out.
872  */
873 static int an_alloc_nicmem(sc, len, id)
874 	struct an_softc		*sc;
875 	int			len;
876 	int			*id;
877 {
878 	int			i;
879 
880 	if (an_cmd(sc, AN_CMD_ALLOC_MEM, len)) {
881 		printf("%s: failed to allocate %d bytes on NIC\n",
882 		    sc->an_dev.dv_xname, len);
883 		return(ENOMEM);
884 	}
885 
886 	for (i = 0; i < AN_TIMEOUT; i++) {
887 		if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_ALLOC)
888 			break;
889 		DELAY(10);
890 	}
891 
892 	if (i == AN_TIMEOUT)
893 		return(ETIMEDOUT);
894 
895 	CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_ALLOC);
896 	*id = CSR_READ_2(sc, AN_ALLOC_FID);
897 
898 	if (an_seek(sc, *id, 0, AN_BAP0))
899 		return(EIO);
900 
901 	for (i = 0; i < len / 2; i++)
902 		CSR_WRITE_2(sc, AN_DATA0, 0);
903 
904 	return(0);
905 }
906 
907 static void an_setdef(sc, areq)
908 	struct an_softc		*sc;
909 	struct an_req		*areq;
910 {
911 	struct ifnet		*ifp;
912 	struct an_ltv_genconfig	*cfg;
913 	struct an_ltv_ssidlist	*ssid;
914 	struct an_ltv_aplist	*ap;
915 	struct an_ltv_gen	*sp;
916 
917 	ifp = &sc->arpcom.ec_if;
918 
919 	switch (areq->an_type) {
920 	case AN_RID_GENCONFIG:
921 		cfg = (struct an_ltv_genconfig *)areq;
922 
923 		bcopy((char *)&cfg->an_macaddr,
924 		    (char *)&sc->an_caps.an_oemaddr, ETHER_ADDR_LEN);
925 		bcopy((char *)&cfg->an_macaddr, LLADDR(ifp->if_sadl),
926 		    ETHER_ADDR_LEN);
927 
928 		bcopy((char *)cfg, (char *)&sc->an_config,
929 			sizeof(struct an_ltv_genconfig));
930 		break;
931 	case AN_RID_SSIDLIST:
932 		ssid = (struct an_ltv_ssidlist *)areq;
933 		bcopy((char *)ssid, (char *)&sc->an_ssidlist,
934 			sizeof(struct an_ltv_ssidlist));
935 		break;
936 	case AN_RID_APLIST:
937 		ap = (struct an_ltv_aplist *)areq;
938 		bcopy((char *)ap, (char *)&sc->an_aplist,
939 			sizeof(struct an_ltv_aplist));
940 		break;
941 	case AN_RID_TX_SPEED:
942 		sp = (struct an_ltv_gen *)areq;
943 		sc->an_tx_rate = sp->an_val;
944 		break;
945 	case AN_RID_WEP_VOLATILE:
946 		memcpy(&sc->an_temp_keys, areq, sizeof(sc->an_temp_keys));
947 
948 		/* Disable the MAC. */
949 		an_cmd(sc, AN_CMD_DISABLE, 0);
950 
951 		/* Just write the Key, we don't want to save it */
952 		an_write_record(sc, (struct an_ltv_gen *)areq);
953 
954 		/* Turn the MAC back on. */
955 		an_cmd(sc, AN_CMD_ENABLE, 0);
956 
957 		break;
958 	case AN_RID_WEP_PERSISTENT:
959 
960 		/* Disable the MAC. */
961 		an_cmd(sc, AN_CMD_DISABLE, 0);
962 
963 		/* Just write the Key, the card will save it in this mode */
964 		an_write_record(sc, (struct an_ltv_gen *)areq);
965 
966 		/* Turn the MAC back on. */
967 		an_cmd(sc, AN_CMD_ENABLE, 0);
968 
969 		break;
970 	default:
971 		printf("%s: unknown RID: %x\n", sc->an_dev.dv_xname, areq->an_type);
972 		return;
973 		break;
974 	}
975 
976 
977 	/* Reinitialize the card. */
978 	if (ifp->if_flags & IFF_UP)
979 		an_init(ifp);
980 
981 	return;
982 }
983 
984 /*
985  * We can't change the NIC configuration while the MAC is enabled,
986  * so in order to turn on RX monitor mode, we have to turn the MAC
987  * off first.
988  */
989 static void an_promisc(sc, promisc)
990 	struct an_softc		*sc;
991 	int			promisc;
992 {
993 	/* Disable the MAC. */
994 	an_cmd(sc, AN_CMD_DISABLE, 0);
995 
996 	/* Set RX mode. */
997 	if (promisc &&
998 	    !(sc->an_config.an_rxmode & AN_RXMODE_LAN_MONITOR_CURBSS)
999 	    ) {
1000 		sc->an_rxmode = sc->an_config.an_rxmode;
1001 		/* kills card DJA, if in sniff mode can't TX packets
1002 		sc->an_config.an_rxmode |=
1003 		    AN_RXMODE_LAN_MONITOR_CURBSS;
1004 		*/
1005 	} else {
1006 		sc->an_config.an_rxmode = sc->an_rxmode;
1007 	}
1008 
1009 	/* Transfer the configuration to the NIC */
1010 	sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
1011 	sc->an_config.an_type = AN_RID_GENCONFIG;
1012 	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_config)) {
1013 		printf("%s: failed to set configuration\n", sc->an_dev.dv_xname);
1014 		return;
1015 	}
1016 	/* Turn the MAC back on. */
1017 	an_cmd(sc, AN_CMD_ENABLE, 0);
1018 
1019 	return;
1020 }
1021 
1022 static int an_ioctl(ifp, command, data)
1023 	struct ifnet		*ifp;
1024 	u_long			command;
1025 	caddr_t			data;
1026 {
1027 	int			i, s;
1028 	int			error = 0;
1029 	struct an_softc		*sc;
1030 	struct an_req		areq;
1031 	struct ifreq		*ifr;
1032 	struct an_ltv_wepkey	*akey;
1033 	struct ieee80211_nwid	nwid;
1034 	struct ieee80211_nwkey	*nwkey;
1035 	struct ieee80211_power	*power;
1036 
1037 	sc = ifp->if_softc;
1038 	ifr = (struct ifreq *)data;
1039 	s = splnet();
1040 
1041 	switch(command) {
1042 	case SIOCSIFFLAGS:
1043 		if ((ifp->if_flags & sc->an_if_flags &
1044 		    (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) {
1045 			if (ifp->if_flags & IFF_PROMISC &&
1046 			    !(sc->an_if_flags & IFF_PROMISC)) {
1047 				an_promisc(sc, 1);
1048 				break;
1049 			}
1050 			if (!(ifp->if_flags & IFF_PROMISC) &&
1051 			    sc->an_if_flags & IFF_PROMISC) {
1052 				an_promisc(sc, 0);
1053 				break;
1054 			}
1055 		}
1056 		error = ether_ioctl(ifp, command, data);
1057 		sc->an_if_flags = ifp->if_flags;
1058 		break;
1059 	case SIOCGAIRONET:
1060 		error = copyin(ifr->ifr_data, &areq, sizeof(areq));
1061 		if (error)
1062 			break;
1063 #ifdef ANCACHE
1064 		if (areq.an_type == AN_RID_ZERO_CACHE) {
1065 			sc->an_sigitems = sc->an_nextitem = 0;
1066 			break;
1067 		} else if (areq.an_type == AN_RID_READ_CACHE) {
1068 			char *pt = (char *)&areq.an_val;
1069 			bcopy((char *)&sc->an_sigitems, (char *)pt,
1070 			    sizeof(int));
1071 			pt += sizeof(int);
1072 			areq.an_len = sizeof(int) / 2;
1073 			bcopy((char *)&sc->an_sigcache, (char *)pt,
1074 			    sizeof(struct an_sigcache) * sc->an_sigitems);
1075 			areq.an_len += ((sizeof(struct an_sigcache) *
1076 			    sc->an_sigitems) / 2) + 1;
1077 		} else
1078 #endif
1079 		if (an_read_record(sc, (struct an_ltv_gen *)&areq)) {
1080 			error = EINVAL;
1081 			break;
1082 		}
1083 		error = copyout(&areq, ifr->ifr_data, sizeof(areq));
1084 		break;
1085 	case SIOCSAIRONET:
1086 		if ((error = suser(curproc->p_ucred, &curproc->p_acflag)))
1087 			goto out;
1088 		error = copyin(ifr->ifr_data, &areq, sizeof(areq));
1089 		if (error)
1090 			break;
1091 		an_setdef(sc, &areq);
1092 		break;
1093 	case SIOCS80211NWID:
1094 		error = copyin(ifr->ifr_data, &nwid, sizeof(nwid));
1095 		if (error)
1096 			break;
1097 		if (nwid.i_len > IEEE80211_NWID_LEN) {
1098 			error = EINVAL;
1099 			break;
1100 		}
1101 		if (sc->an_ssidlist.an_ssid1_len == nwid.i_len &&
1102 		    memcmp(sc->an_ssidlist.an_ssid1, nwid.i_nwid, nwid.i_len)
1103 		    == 0)
1104 			break;
1105 		memset(sc->an_ssidlist.an_ssid1, 0, IEEE80211_NWID_LEN);
1106 		sc->an_ssidlist.an_ssid1_len = nwid.i_len;
1107 		memcpy(sc->an_ssidlist.an_ssid1, nwid.i_nwid, nwid.i_len);
1108 		if (sc->sc_enabled)
1109 			an_init(ifp);
1110 		break;
1111 	case SIOCG80211NWID:
1112 		memset(&nwid, 0, sizeof(nwid));
1113 		if ((ifp->if_flags & IFF_RUNNING) && sc->an_associated) {
1114 			nwid.i_len = sc->an_status.an_ssidlen;
1115 			memcpy(nwid.i_nwid, sc->an_status.an_ssid, nwid.i_len);
1116 		} else {
1117 			nwid.i_len = sc->an_ssidlist.an_ssid1_len;
1118 			memcpy(nwid.i_nwid, sc->an_ssidlist.an_ssid1,
1119 			    nwid.i_len);
1120 		}
1121 		error = copyout(&nwid, ifr->ifr_data, sizeof(nwid));
1122 		break;
1123 	case SIOCS80211NWKEY:
1124 		nwkey = (struct ieee80211_nwkey *)data;
1125 		sc->an_config.an_authtype &= AN_AUTHTYPE_MASK;
1126 		if (nwkey->i_wepon)
1127 			sc->an_config.an_authtype |= (AN_AUTHTYPE_MASK + 1);
1128 		akey = (struct an_ltv_wepkey *)&areq;
1129 		memset(akey, 0, sizeof(struct an_ltv_wepkey));
1130 		akey->an_type = AN_RID_WEP_VOLATILE;
1131 		akey->an_len = sizeof(struct an_ltv_wepkey);
1132 		akey->an_key_index = 0;
1133 		akey->an_mac_addr[0] = 1;	/* default mac */
1134 		akey->an_key_len = nwkey->i_key[0].i_keylen;
1135 		if (akey->an_key_len > sizeof(akey->an_key)) {
1136 			error = EINVAL;
1137 			break;
1138 		}
1139 		if (nwkey->i_key[0].i_keydat != NULL) {
1140 			if ((error = copyin(nwkey->i_key[0].i_keydat,
1141 			    akey->an_key, akey->an_key_len)) != 0)
1142 				break;
1143 		}
1144 		memcpy(&sc->an_temp_keys, akey, sizeof(struct an_ltv_wepkey));
1145 		if (sc->sc_enabled)
1146 			an_init(ifp);
1147 		break;
1148 	case SIOCG80211NWKEY:
1149 		nwkey = (struct ieee80211_nwkey *)data;
1150 		nwkey->i_wepon =
1151 		    sc->an_config.an_authtype & ~AN_AUTHTYPE_MASK ? 1 : 0;
1152 		nwkey->i_defkid = 1;
1153 		if (nwkey->i_key[0].i_keydat == NULL)
1154 			break;
1155 		/* do not show any keys to non-root user */
1156 		if ((error = suser(curproc->p_ucred, &curproc->p_acflag)) != 0)
1157 			break;
1158 		akey = &sc->an_temp_keys;
1159 		nwkey->i_key[0].i_keylen = akey->an_key_len;
1160 		for (i = 1; i < IEEE80211_WEP_NKID; i++)
1161 			nwkey->i_key[i].i_keylen = 0;
1162 		error = copyout(akey->an_key, nwkey->i_key[0].i_keydat,
1163 		    akey->an_key_len);
1164 		break;
1165 	case SIOCS80211POWER:
1166 		power = (struct ieee80211_power *)data;
1167 		sc->an_config.an_psave_mode = power->i_enabled ?
1168 		    AN_PSAVE_PSP : AN_PSAVE_NONE;
1169 		sc->an_config.an_listen_interval = power->i_maxsleep;
1170 		if (sc->sc_enabled)
1171 			an_init(ifp);
1172 		break;
1173 	case SIOCG80211POWER:
1174 		power = (struct ieee80211_power *)data;
1175 		power->i_enabled =
1176 		    sc->an_config.an_psave_mode != AN_PSAVE_NONE ? 1 : 0;
1177 		power->i_maxsleep = sc->an_config.an_listen_interval;
1178 		break;
1179 #ifdef IFM_IEEE80211
1180 	case SIOCSIFMEDIA:
1181 	case SIOCGIFMEDIA:
1182 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, command);
1183 		break;
1184 #endif
1185 	default:
1186 		error = ether_ioctl(ifp, command, data);
1187 		break;
1188 	}
1189 out:
1190 	splx(s);
1191 	return(error);
1192 }
1193 
1194 #ifdef IFM_IEEE80211
1195 static int
1196 an_media_change(ifp)
1197 	struct ifnet *ifp;
1198 {
1199 	struct an_softc *sc = ifp->if_softc;
1200 	struct ifmedia_entry *ime;
1201 	int error;
1202 
1203 	error = 0;
1204 	ime = sc->sc_media.ifm_cur;
1205 	switch (IFM_SUBTYPE(ime->ifm_media)) {
1206 	case IFM_AUTO:
1207 		sc->an_tx_rate = 0;
1208 		break;
1209 	case IFM_IEEE80211_DS1:
1210 		sc->an_tx_rate = AN_RATE_1MBPS;
1211 		break;
1212 	case IFM_IEEE80211_DS2:
1213 		sc->an_tx_rate = AN_RATE_2MBPS;
1214 		break;
1215 	case IFM_IEEE80211_DS5:
1216 		sc->an_tx_rate = AN_RATE_5_5MBPS;
1217 		break;
1218 	case IFM_IEEE80211_DS11:
1219 		sc->an_tx_rate = AN_RATE_11MBPS;
1220 		break;
1221 	}
1222 	if (ime->ifm_media & IFM_IEEE80211_ADHOC)
1223 		sc->an_config.an_opmode = AN_OPMODE_IBSS_ADHOC;
1224 	else
1225 		sc->an_config.an_opmode = AN_OPMODE_INFRASTRUCTURE_STATION;
1226 	/*
1227 	 * XXX: how to set txrate for the firmware?
1228 	 * There is a struct defined as an_txframe, which is used nowhere.
1229 	 * Perhaps we need to change the transmit mode from 802.3 to native.
1230 	 */
1231 	if (sc->sc_enabled)
1232 		an_init(ifp);
1233 	return error;
1234 }
1235 
1236 static void
1237 an_media_status(ifp, imr)
1238 	struct ifnet *ifp;
1239 	struct ifmediareq *imr;
1240 {
1241 	struct an_softc *sc = ifp->if_softc;
1242 
1243 	imr->ifm_status = IFM_AVALID;
1244 	if (sc->an_associated)
1245 		imr->ifm_status |= IFM_ACTIVE;
1246 	imr->ifm_active = IFM_IEEE80211;
1247 	switch (sc->an_tx_rate) {
1248 	case 0:
1249 		imr->ifm_active |= IFM_AUTO;
1250 		break;
1251 	case AN_RATE_1MBPS:
1252 		imr->ifm_active |= IFM_IEEE80211_DS1;
1253 		break;
1254 	case AN_RATE_2MBPS:
1255 		imr->ifm_active |= IFM_IEEE80211_DS2;
1256 		break;
1257 	case AN_RATE_5_5MBPS:
1258 		imr->ifm_active |= IFM_IEEE80211_DS5;
1259 		break;
1260 	case AN_RATE_11MBPS:
1261 		imr->ifm_active |= IFM_IEEE80211_DS11;
1262 		break;
1263 	}
1264 	if ((sc->an_config.an_opmode & 0x0f) == AN_OPMODE_IBSS_ADHOC)
1265 		imr->ifm_active |= IFM_IEEE80211_ADHOC;
1266 }
1267 #endif /* IFM_IEEE80211 */
1268 
1269 static int an_init_tx_ring(sc)
1270 	struct an_softc		*sc;
1271 {
1272 	int			i;
1273 	int			id;
1274 
1275 	if (!sc->sc_enabled)
1276 		return (0);
1277 
1278 	for (i = 0; i < AN_TX_RING_CNT; i++) {
1279 		if (an_alloc_nicmem(sc, 1518 +
1280 		    0x44, &id))
1281 			return(ENOMEM);
1282 		sc->an_rdata.an_tx_fids[i] = id;
1283 		sc->an_rdata.an_tx_ring[i] = 0;
1284 	}
1285 
1286 	sc->an_rdata.an_tx_prod = 0;
1287 	sc->an_rdata.an_tx_cons = 0;
1288 
1289 	return(0);
1290 }
1291 
1292 static int
1293 an_init(struct ifnet *ifp)
1294 {
1295 	struct an_softc *sc = (struct an_softc *)ifp->if_softc;
1296 
1297 	if (ifp->if_flags & IFF_RUNNING)
1298 		an_stop(ifp, 0);
1299 	else if (sc->sc_enabled) {
1300 		/* re-enable to power on after resume ... */
1301 		if (sc->sc_disable)
1302 			(*sc->sc_disable)(sc);
1303 		sc->sc_enabled = 0;
1304 	}
1305 
1306 	sc->an_associated = 0;
1307 
1308 	if (!sc->sc_enabled) {
1309 		if (sc->sc_enable)
1310 			(*sc->sc_enable)(sc);
1311 		sc->sc_enabled = 1;
1312 		an_wait(sc);
1313 	}
1314 
1315 	/* Allocate the TX buffers */
1316 	if (an_init_tx_ring(sc)) {
1317 		an_reset(sc);
1318 		if (an_init_tx_ring(sc)) {
1319 			printf("%s: tx buffer allocation "
1320 			    "failed\n", sc->an_dev.dv_xname);
1321 			return ENOMEM;
1322 		}
1323 	}
1324 
1325 	/* Set our MAC address. */
1326 	bcopy((char *)&sc->an_caps.an_oemaddr,
1327 	    (char *)&sc->an_config.an_macaddr, ETHER_ADDR_LEN);
1328 
1329 	if (ifp->if_flags & IFF_BROADCAST)
1330 		sc->an_config.an_rxmode = AN_RXMODE_BC_ADDR;
1331 	else
1332 		sc->an_config.an_rxmode = AN_RXMODE_ADDR;
1333 
1334 	if (ifp->if_flags & IFF_MULTICAST)
1335 		sc->an_config.an_rxmode = AN_RXMODE_BC_MC_ADDR;
1336 
1337 	/* Initialize promisc mode. */
1338 	/* Kills card DJA can't TX packet in sniff mode
1339  	if (ifp->if_flags & IFF_PROMISC)
1340 		sc->an_config.an_rxmode |= AN_RXMODE_LAN_MONITOR_CURBSS;
1341 	*/
1342 
1343 	sc->an_rxmode = sc->an_config.an_rxmode;
1344 
1345 	/* Set the ssid list */
1346 	sc->an_ssidlist.an_type = AN_RID_SSIDLIST;
1347 	sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist);
1348 	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) {
1349 		printf("%s: failed to set ssid list\n", sc->an_dev.dv_xname);
1350 		return ENXIO;
1351 	}
1352 
1353 	/* Set the AP list */
1354 	sc->an_aplist.an_type = AN_RID_APLIST;
1355 	sc->an_aplist.an_len = sizeof(struct an_ltv_aplist);
1356 	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) {
1357 		printf("%s: failed to set AP list\n", sc->an_dev.dv_xname);
1358 		return ENXIO;
1359 	}
1360 
1361 	/* Set the configuration in the NIC */
1362 	sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
1363 	sc->an_config.an_type = AN_RID_GENCONFIG;
1364 	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_config)) {
1365 		printf("%s: failed to set configuration\n", sc->an_dev.dv_xname);
1366 		return ENXIO;
1367 	}
1368 
1369 	/* Set the WEP Keys */
1370 	if ((sc->an_config.an_authtype & ~AN_AUTHTYPE_MASK) != 0) {
1371 		sc->an_temp_keys.an_len = sizeof(struct an_ltv_wepkey);
1372 		sc->an_temp_keys.an_type = AN_RID_WEP_VOLATILE;
1373 		an_write_record(sc, (struct an_ltv_gen *)&sc->an_temp_keys);
1374 	}
1375 
1376 	/* Enable the MAC */
1377 	if (an_cmd(sc, AN_CMD_ENABLE, 0)) {
1378 		printf("%s: failed to enable MAC\n", sc->an_dev.dv_xname);
1379 		return ENXIO;
1380 	}
1381 
1382 	/* enable interrupts */
1383 	CSR_WRITE_2(sc, AN_INT_EN, AN_INTRS);
1384 
1385 	ifp->if_flags |= IFF_RUNNING;
1386 	ifp->if_flags &= ~IFF_OACTIVE;
1387 
1388 	callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc);
1389 	return 0;
1390 }
1391 
1392 static void an_start(ifp)
1393 	struct ifnet		*ifp;
1394 {
1395 	struct an_softc		*sc;
1396 	struct mbuf		*m0 = NULL;
1397 	struct an_txframe_802_3	tx_frame_802_3;
1398 	struct ether_header	*eh;
1399 	int			id;
1400 	int			idx;
1401 	unsigned char           txcontrol;
1402 
1403 	sc = ifp->if_softc;
1404 
1405 	if (!sc->sc_enabled)
1406 		return;
1407 
1408 	if (ifp->if_flags & IFF_OACTIVE)
1409 		return;
1410 
1411 	if (!sc->an_associated)
1412 		return;
1413 
1414 	idx = sc->an_rdata.an_tx_prod;
1415 	bzero((char *)&tx_frame_802_3, sizeof(tx_frame_802_3));
1416 
1417 	while(sc->an_rdata.an_tx_ring[idx] == 0) {
1418 		IFQ_DEQUEUE(&ifp->if_snd, m0);
1419 		if (m0 == NULL)
1420 			break;
1421 
1422 		id = sc->an_rdata.an_tx_fids[idx];
1423 		eh = mtod(m0, struct ether_header *);
1424 
1425 		bcopy((char *)&eh->ether_dhost,
1426 		    (char *)&tx_frame_802_3.an_tx_dst_addr, ETHER_ADDR_LEN);
1427 		bcopy((char *)&eh->ether_shost,
1428 		    (char *)&tx_frame_802_3.an_tx_src_addr, ETHER_ADDR_LEN);
1429 
1430 		tx_frame_802_3.an_tx_802_3_payload_len =
1431 		  m0->m_pkthdr.len - 12;  /* minus src/dest mac & type */
1432 
1433                 m_copydata(m0, sizeof(struct ether_header) - 2 ,
1434                     tx_frame_802_3.an_tx_802_3_payload_len,
1435                     (caddr_t)&sc->an_txbuf);
1436 
1437 		txcontrol=AN_TXCTL_8023;
1438 		/* write the txcontrol only */
1439 		an_write_data(sc, id, 0x08, (caddr_t)&txcontrol,
1440 			      sizeof(txcontrol));
1441 
1442 		/* 802_3 header */
1443 		an_write_data(sc, id, 0x34, (caddr_t)&tx_frame_802_3,
1444 			      sizeof(struct an_txframe_802_3));
1445 
1446 		/* in mbuf header type is just before payload */
1447 		an_write_data(sc, id, 0x44, (caddr_t)&sc->an_txbuf,
1448 			    tx_frame_802_3.an_tx_802_3_payload_len);
1449 #if NBPFILTER > 0
1450 		/*
1451 		 * If there's a BPF listner, bounce a copy of
1452 		 * this frame to him.
1453 		 */
1454 		if (ifp->if_bpf)
1455 			bpf_mtap(ifp->if_bpf, m0);
1456 #endif
1457 
1458 		m_freem(m0);
1459 		m0 = NULL;
1460 
1461 		/* TX START disable lan monitor ? DJA
1462 		   an_disable_sniff():
1463 		 */
1464 		sc->an_rdata.an_tx_ring[idx] = id;
1465 		if (an_cmd(sc, AN_CMD_TX, id))
1466 			printf("%s: xmit failed\n", sc->an_dev.dv_xname);
1467 
1468 		AN_INC(idx, AN_TX_RING_CNT);
1469 	}
1470 
1471 	if (m0 != NULL)
1472 		ifp->if_flags |= IFF_OACTIVE;
1473 
1474 	sc->an_rdata.an_tx_prod = idx;
1475 
1476 	/*
1477 	 * Set a timeout in case the chip goes out to lunch.
1478 	 */
1479 	ifp->if_timer = 5;
1480 
1481 	return;
1482 }
1483 
1484 void an_stop(ifp, disable)
1485 	struct ifnet		*ifp;
1486 	int disable;
1487 {
1488 	struct an_softc		*sc = (struct an_softc *)ifp->if_softc;
1489 	int			i;
1490 
1491 	callout_stop(&sc->an_stat_ch);
1492 	if (!sc->sc_enabled)
1493 		return;
1494 
1495 	an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0);
1496 	CSR_WRITE_2(sc, AN_INT_EN, 0);
1497 	an_cmd(sc, AN_CMD_DISABLE, 0);
1498 
1499 	for (i = 0; i < AN_TX_RING_CNT; i++)
1500 		an_cmd(sc, AN_CMD_DEALLOC_MEM, sc->an_rdata.an_tx_fids[i]);
1501 
1502 	ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
1503 	ifp->if_timer = 0;
1504 
1505 	if (disable) {
1506 		if (sc->sc_disable)
1507 			(*sc->sc_disable)(sc);
1508 		sc->sc_enabled = 0;
1509 	}
1510 
1511 	return;
1512 }
1513 
1514 static void an_watchdog(ifp)
1515 	struct ifnet		*ifp;
1516 {
1517 	struct an_softc		*sc;
1518 
1519 	sc = ifp->if_softc;
1520 	if (!sc->sc_enabled)
1521 		return;
1522 
1523 	printf("%s: device timeout\n", sc->an_dev.dv_xname);
1524 
1525 	an_reset(sc);
1526 	an_init(ifp);
1527 
1528 	ifp->if_oerrors++;
1529 	return;
1530 }
1531 
1532 #ifdef ANCACHE
1533 /* Aironet signal strength cache code.
1534  * store signal/noise/quality on per MAC src basis in
1535  * a small fixed cache.  The cache wraps if > MAX slots
1536  * used.  The cache may be zeroed out to start over.
1537  * Two simple filters exist to reduce computation:
1538  * 1. ip only (literally 0x800) which may be used
1539  * to ignore some packets.  It defaults to ip only.
1540  * it could be used to focus on broadcast, non-IP 802.11 beacons.
1541  * 2. multicast/broadcast only.  This may be used to
1542  * ignore unicast packets and only cache signal strength
1543  * for multicast/broadcast packets (beacons); e.g., Mobile-IP
1544  * beacons and not unicast traffic.
1545  *
1546  * The cache stores (MAC src(index), IP src (major clue), signal,
1547  *	quality, noise)
1548  *
1549  * No apologies for storing IP src here.  It's easy and saves much
1550  * trouble elsewhere.  The cache is assumed to be INET dependent,
1551  * although it need not be.
1552  *
1553  * Note: the Aironet only has a single byte of signal strength value
1554  * in the rx frame header, and it's not scaled to anything sensible.
1555  * This is kind of lame, but it's all we've got.
1556  */
1557 
1558 #ifdef documentation
1559 
1560 int an_sigitems;                                /* number of cached entries */
1561 struct an_sigcache an_sigcache[MAXANCACHE];  /*  array of cache entries */
1562 int an_nextitem;                                /*  index/# of entries */
1563 
1564 
1565 #endif
1566 
1567 /* control variables for cache filtering.  Basic idea is
1568  * to reduce cost (e.g., to only Mobile-IP agent beacons
1569  * which are broadcast or multicast).  Still you might
1570  * want to measure signal strength anth unicast ping packets
1571  * on a pt. to pt. ant. setup.
1572  */
1573 /* set true if you want to limit cache items to broadcast/mcast
1574  * only packets (not unicast).  Useful for mobile-ip beacons which
1575  * are broadcast/multicast at network layer.  Default is all packets
1576  * so ping/unicast anll work say anth pt. to pt. antennae setup.
1577  */
1578 static int an_cache_mcastonly = 0;
1579 #if 0
1580 SYSCTL_INT(_machdep, OID_AUTO, an_cache_mcastonly, CTLFLAG_RW,
1581 	&an_cache_mcastonly, 0, "");
1582 #endif
1583 
1584 /* set true if you want to limit cache items to IP packets only
1585 */
1586 static int an_cache_iponly = 1;
1587 #if 0
1588 SYSCTL_INT(_machdep, OID_AUTO, an_cache_iponly, CTLFLAG_RW,
1589 	&an_cache_iponly, 0, "");
1590 #endif
1591 
1592 /*
1593  * an_cache_store, per rx packet store signal
1594  * strength in MAC (src) indexed cache.
1595  */
1596 static
1597 void an_cache_store (sc, eh, m, rx_quality)
1598 	struct an_softc *sc;
1599 	struct ether_header *eh;
1600 	struct mbuf *m;
1601 	unsigned short rx_quality;
1602 {
1603 	struct ip *ip = 0;
1604 	int i;
1605 	static int cache_slot = 0; 	/* use this cache entry */
1606 	static int wrapindex = 0;       /* next "free" cache entry */
1607 	int saanp=0;
1608 
1609 	/* filters:
1610 	 * 1. ip only
1611 	 * 2. configurable filter to throw out unicast packets,
1612 	 * keep multicast only.
1613 	 */
1614 
1615 	if ((ntohs(eh->ether_type) == 0x800)) {
1616 		saanp = 1;
1617 	}
1618 
1619 	/* filter for ip packets only
1620 	*/
1621 	if ( an_cache_iponly && !saanp) {
1622 		return;
1623 	}
1624 
1625 	/* filter for broadcast/multicast only
1626 	 */
1627 	if (an_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) {
1628 		return;
1629 	}
1630 
1631 #ifdef SIGDEBUG
1632 	printf("an: q value %x (MSB=0x%x, LSB=0x%x) \n",
1633 	    rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff);
1634 #endif
1635 
1636 	/* find the ip header.  we want to store the ip_src
1637 	 * address.
1638 	 */
1639 	if (saanp) {
1640 		ip = mtod(m, struct ip *);
1641 	}
1642 
1643 	/* do a linear search for a matching MAC address
1644 	 * in the cache table
1645 	 * . MAC address is 6 bytes,
1646 	 * . var w_nextitem holds total number of entries already cached
1647 	 */
1648 	for(i = 0; i < sc->an_nextitem; i++) {
1649 		if (! bcmp(eh->ether_shost , sc->an_sigcache[i].macsrc,  6 )) {
1650 			/* Match!,
1651 			 * so we already have this entry,
1652 			 * update the data
1653 			 */
1654 			break;
1655 		}
1656 	}
1657 
1658 	/* did we find a matching mac address?
1659 	 * if yes, then overwrite a previously existing cache entry
1660 	 */
1661 	if (i < sc->an_nextitem )   {
1662 		cache_slot = i;
1663 	}
1664 	/* else, have a new address entry,so
1665 	 * add this new entry,
1666 	 * if table full, then we need to replace LRU entry
1667 	 */
1668 	else    {
1669 
1670 		/* check for space in cache table
1671 		 * note: an_nextitem also holds number of entries
1672 		 * added in the cache table
1673 		 */
1674 		if ( sc->an_nextitem < MAXANCACHE ) {
1675 			cache_slot = sc->an_nextitem;
1676 			sc->an_nextitem++;
1677 			sc->an_sigitems = sc->an_nextitem;
1678 		}
1679         	/* no space found, so simply wrap anth wrap index
1680 		 * and "zap" the next entry
1681 		 */
1682 		else {
1683 			if (wrapindex == MAXANCACHE) {
1684 				wrapindex = 0;
1685 			}
1686 			cache_slot = wrapindex++;
1687 		}
1688 	}
1689 
1690 	/* invariant: cache_slot now points at some slot
1691 	 * in cache.
1692 	 */
1693 	if (cache_slot < 0 || cache_slot >= MAXANCACHE) {
1694 		log(LOG_ERR, "an_cache_store, bad index: %d of "
1695 		    "[0..%d], gross cache error\n",
1696 		    cache_slot, MAXANCACHE);
1697 		return;
1698 	}
1699 
1700 	/*  store items in cache
1701 	 *  .ip source address
1702 	 *  .mac src
1703 	 *  .signal, etc.
1704 	 */
1705 	if (saanp) {
1706 		sc->an_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr;
1707 	}
1708 	bcopy( eh->ether_shost, sc->an_sigcache[cache_slot].macsrc,  6);
1709 
1710 	sc->an_sigcache[cache_slot].signal = rx_quality;
1711 
1712 	return;
1713 }
1714 #endif
1715