xref: /netbsd-src/sys/dev/ic/an.c (revision 5aefcfdc06931dd97e76246d2fe0302f7b3fe094)
1 /*	$NetBSD: an.c,v 1.10 2000/12/21 15:37:18 onoe 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 	eh = mtod(m, struct ether_header *);
407 
408 #ifdef ANCACHE
409 	/* Read NIC frame header */
410 	if (an_read_data(sc, id, 0, (caddr_t)&rx_frame, sizeof(rx_frame))) {
411 		ifp->if_ierrors++;
412 		return;
413 	}
414 #endif
415 	/* Read in the 802_3 frame header */
416 	if (an_read_data(sc, id, 0x34, (caddr_t)&rx_frame_802_3,
417 			 sizeof(rx_frame_802_3))) {
418 		ifp->if_ierrors++;
419 		return;
420 	}
421 
422 	if (rx_frame_802_3.an_rx_802_3_status != 0) {
423 		ifp->if_ierrors++;
424 		return;
425 	}
426 
427 	/* Check for insane frame length */
428 	if (rx_frame_802_3.an_rx_802_3_payload_len > MCLBYTES) {
429 		ifp->if_ierrors++;
430 		return;
431 	}
432 
433 	m->m_pkthdr.len = m->m_len =
434 	    rx_frame_802_3.an_rx_802_3_payload_len + 12;
435 
436 
437 	bcopy((char *)&rx_frame_802_3.an_rx_dst_addr,
438 	    (char *)&eh->ether_dhost, ETHER_ADDR_LEN);
439 	bcopy((char *)&rx_frame_802_3.an_rx_src_addr,
440 	    (char *)&eh->ether_shost, ETHER_ADDR_LEN);
441 
442 	/* in mbuf header type is just before payload */
443 	error = an_read_data(sc, id, 0x44, (caddr_t)&(eh->ether_type),
444 			     rx_frame_802_3.an_rx_802_3_payload_len);
445 
446 	if (error) {
447 		m_freem(m);
448 		ifp->if_ierrors++;
449 		return;
450 	}
451 
452 	ifp->if_ipackets++;
453 
454 	/* Receive packet. */
455 #ifdef ANCACHE
456 	an_cache_store(sc, eh, m, rx_frame.an_rx_signal_strength);
457 #endif
458 #if NBPFILTER > 0
459 	if (ifp->if_bpf)
460 		bpf_mtap(ifp->if_bpf, m);
461 #endif
462 	(*ifp->if_input)(ifp, m);
463 }
464 
465 static void an_txeof(sc, status)
466 	struct an_softc		*sc;
467 	int			status;
468 {
469 	struct ifnet		*ifp;
470 	int			id;
471 
472 	/* TX DONE enable lan monitor DJA
473 	   an_enable_sniff();
474 	 */
475 
476 	ifp = &sc->arpcom.ec_if;
477 
478 	ifp->if_timer = 0;
479 	ifp->if_flags &= ~IFF_OACTIVE;
480 
481 	id = CSR_READ_2(sc, AN_TX_CMP_FID);
482 
483 	if (status & AN_EV_TX_EXC) {
484 		ifp->if_oerrors++;
485 	} else
486 		ifp->if_opackets++;
487 
488 #if 0 /*XXX*/
489 	if (id != sc->an_rdata.an_tx_ring[sc->an_rdata.an_tx_cons])
490 		printf("%s: id mismatch: expected %x, got %x\n",
491 		    sc->an_dev.dv_xname,
492 		    sc->an_rdata.an_tx_ring[sc->an_rdata.an_tx_cons], id);
493 #endif
494 
495 	sc->an_rdata.an_tx_ring[sc->an_rdata.an_tx_cons] = 0;
496 	AN_INC(sc->an_rdata.an_tx_cons, AN_TX_RING_CNT);
497 
498 	return;
499 }
500 
501 /*
502  * We abuse the stats updater to check the current NIC status. This
503  * is important because we don't want to allow transmissions until
504  * the NIC has synchronized to the current cell (either as the master
505  * in an ad-hoc group, or as a station connected to an access point).
506  */
507 void an_stats_update(xsc)
508 	void			*xsc;
509 {
510 	struct an_softc		*sc;
511 	struct ifnet		*ifp;
512 
513 	sc = xsc;
514 	ifp = &sc->arpcom.ec_if;
515 
516 	sc->an_status.an_type = AN_RID_STATUS;
517 	sc->an_status.an_len = sizeof(struct an_ltv_status);
518 	an_read_record(sc, (struct an_ltv_gen *)&sc->an_status);
519 
520 	if (sc->an_status.an_opmode & AN_STATUS_OPMODE_IN_SYNC)
521 		sc->an_associated = 1;
522 	else
523 		sc->an_associated = 0;
524 
525 	/* Don't do this while we're transmitting */
526 	if (ifp->if_flags & IFF_OACTIVE) {
527 		callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc);
528 		return;
529 	}
530 
531 	sc->an_stats.an_len = sizeof(struct an_ltv_stats);
532 	sc->an_stats.an_type = AN_RID_32BITS_CUM;
533 	an_read_record(sc, (struct an_ltv_gen *)&sc->an_stats.an_len);
534 
535 	callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc);
536 
537 	return;
538 }
539 
540 int an_intr(void *arg)
541 {
542 	struct an_softc		*sc = arg;
543 	struct ifnet		*ifp;
544 	u_int16_t		status;
545 
546 	if (!sc->sc_enabled)
547 		return 0;
548 
549 	ifp = &sc->arpcom.ec_if;
550 
551 	if (!(ifp->if_flags & IFF_UP)) {
552 		CSR_WRITE_2(sc, AN_EVENT_ACK, 0xFFFF);
553 		CSR_WRITE_2(sc, AN_INT_EN, 0);
554 		return 0;
555 	}
556 
557 	/* Disable interrupts. */
558 	CSR_WRITE_2(sc, AN_INT_EN, 0);
559 
560 	status = CSR_READ_2(sc, AN_EVENT_STAT);
561 	CSR_WRITE_2(sc, AN_EVENT_ACK, ~AN_INTRS);
562 
563 	if (status & AN_EV_AWAKE) {
564 		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_AWAKE);
565 	}
566 
567 	if (status & AN_EV_LINKSTAT) {
568 		if (CSR_READ_2(sc, AN_LINKSTAT) == AN_LINKSTAT_ASSOCIATED)
569 			sc->an_associated = 1;
570 		else
571 			sc->an_associated = 0;
572 		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_LINKSTAT);
573 	}
574 
575 	if (status & AN_EV_RX) {
576 		an_rxeof(sc);
577 		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX);
578 	}
579 
580 	if (status & AN_EV_TX) {
581 		an_txeof(sc, status);
582 		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_TX);
583 	}
584 
585 	if (status & AN_EV_TX_EXC) {
586 		an_txeof(sc, status);
587 		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_TX_EXC);
588 	}
589 
590 	if (status & AN_EV_ALLOC)
591 		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_ALLOC);
592 
593 	if (status & AN_EV_CMD) {
594 		wakeup(sc);
595 		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CMD);
596 	}
597 
598 	/* Re-enable interrupts. */
599 	CSR_WRITE_2(sc, AN_INT_EN, AN_INTRS);
600 
601 	if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
602 		an_start(ifp);
603 
604 	return 1;
605 }
606 
607 static int
608 an_cmd(struct an_softc *sc, int cmd, int val)
609 {
610 	int i, stat;
611 
612 	/* make sure that previous command completed */
613 	if (CSR_READ_2(sc, AN_COMMAND) & AN_CMD_BUSY) {
614 		printf("%s: command busy\n", sc->an_dev.dv_xname);
615 		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CLR_STUCK_BUSY);
616 	}
617 
618 	CSR_WRITE_2(sc, AN_PARAM0, val);
619 	CSR_WRITE_2(sc, AN_PARAM1, 0);
620 	CSR_WRITE_2(sc, AN_PARAM2, 0);
621 	CSR_WRITE_2(sc, AN_COMMAND, cmd);
622 
623 	for (i = 0; i < AN_TIMEOUT; i++) {
624 		if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_CMD)
625 			break;
626 		/* make sure the command is accepted */
627 		if (CSR_READ_2(sc, AN_COMMAND) == cmd)
628 			CSR_WRITE_2(sc, AN_COMMAND, cmd);
629 		DELAY(10);
630 	}
631 
632 	stat = CSR_READ_2(sc, AN_STATUS);
633 #if 0
634 	CSR_READ_2(sc, AN_RESP0);
635 	CSR_READ_2(sc, AN_RESP1);
636 	CSR_READ_2(sc, AN_RESP2);
637 #endif
638 
639 	/* clear stuck command busy if necessary */
640 	if (CSR_READ_2(sc, AN_COMMAND) & AN_CMD_BUSY)
641 		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CLR_STUCK_BUSY);
642 
643 	/* Ack the command */
644 	CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CMD);
645 
646 	if (i == AN_TIMEOUT)
647 		return ETIMEDOUT;
648 	if (stat & AN_STAT_CMD_RESULT)
649 		return EIO;
650 
651 	return 0;
652 }
653 
654 /*
655  * This reset sequence may look a little strange, but this is the
656  * most reliable method I've found to really kick the NIC in the
657  * head and force it to reboot correctly.
658  */
659 static void
660 an_reset(struct an_softc *sc)
661 {
662 	if (!sc->sc_enabled)
663 		return;
664 
665 	an_cmd(sc, AN_CMD_ENABLE, 0);
666 	an_cmd(sc, AN_CMD_FW_RESTART, 0);
667 	an_cmd(sc, AN_CMD_NOOP2, 0);
668 
669 	if (an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0) == ETIMEDOUT)
670 		printf("%s: reset failed\n", sc->an_dev.dv_xname);
671 
672 	an_cmd(sc, AN_CMD_DISABLE, 0);
673 
674 	return;
675 }
676 
677 /*
678  * Wait for firmware come up after power enabled.
679  */
680 static void
681 an_wait(struct an_softc *sc)
682 {
683 	int i;
684 
685 	if (!sc->sc_enabled)
686 		return;
687 
688 	CSR_WRITE_2(sc, AN_COMMAND, AN_CMD_NOOP2);
689 	for (i = 0; i < 3*hz; i++) {
690 		if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_CMD)
691 			break;
692 		(void)tsleep(sc, PWAIT, "anatch", 1);
693 	}
694 	CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CMD);
695 }
696 
697 /*
698  * Read an LTV record from the NIC.
699  */
700 static int an_read_record(sc, ltv)
701 	struct an_softc		*sc;
702 	struct an_ltv_gen	*ltv;
703 {
704 	u_int16_t		*ptr;
705 	int			i, len;
706 
707 	if (ltv->an_len == 0 || ltv->an_type == 0)
708 		return(EINVAL);
709 
710 	/* Tell the NIC to enter record read mode. */
711 	if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) {
712 		printf("%s: RID 0x%04x access failed\n", sc->an_dev.dv_xname,
713 		    ltv->an_type);
714 		return(EIO);
715 	}
716 
717 	/* Seek to the record. */
718 	if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) {
719 		printf("%s: RID 0x%04x seek to record failed\n",
720 		    sc->an_dev.dv_xname, ltv->an_type);
721 		return(EIO);
722 	}
723 
724 	/*
725 	 * Read the length and record type and make sure they
726 	 * match what we expect (this verifies that we have enough
727 	 * room to hold all of the returned data).
728 	 */
729 	len = CSR_READ_2(sc, AN_DATA1);
730 	if (len > ltv->an_len) {
731 		printf("%s: RID 0x%04x record length mismatch -- expected %d, "
732 		    "got %d\n", sc->an_dev.dv_xname,
733 		    ltv->an_type, ltv->an_len, len);
734 		return(ENOSPC);
735 	}
736 
737 	ltv->an_len = len;
738 
739 	/* Now read the data. */
740 	ptr = &ltv->an_val;
741 	for (i = 0; i < (ltv->an_len - 2) >> 1; i++)
742 		ptr[i] = CSR_READ_2(sc, AN_DATA1);
743 
744 	return(0);
745 }
746 
747 /*
748  * Same as read, except we inject data instead of reading it.
749  */
750 static int an_write_record(sc, ltv)
751 	struct an_softc		*sc;
752 	struct an_ltv_gen	*ltv;
753 {
754 	u_int16_t		*ptr;
755 	int			i;
756 
757 	if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type))
758 		return(EIO);
759 
760 	if (an_seek(sc, ltv->an_type, 0, AN_BAP1))
761 		return(EIO);
762 
763 	CSR_WRITE_2(sc, AN_DATA1, ltv->an_len-2);
764 
765 	ptr = &ltv->an_val;
766 	for (i = 0; i < (ltv->an_len - 4) >> 1; i++)
767 		CSR_WRITE_2(sc, AN_DATA1, ptr[i]);
768 
769 	if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_WRITE, ltv->an_type))
770 		return(EIO);
771 
772 	return(0);
773 }
774 
775 static int an_seek(sc, id, off, chan)
776 	struct an_softc		*sc;
777 	int			id, off, chan;
778 {
779 	int			i;
780 	int			selreg, offreg;
781 
782 	switch (chan) {
783 	case AN_BAP0:
784 		selreg = AN_SEL0;
785 		offreg = AN_OFF0;
786 		break;
787 	case AN_BAP1:
788 		selreg = AN_SEL1;
789 		offreg = AN_OFF1;
790 		break;
791 	default:
792 		printf("%s: invalid data path: %x\n", sc->an_dev.dv_xname, chan);
793 		return(EIO);
794 	}
795 
796 	CSR_WRITE_2(sc, selreg, id);
797 	CSR_WRITE_2(sc, offreg, off);
798 
799 	for (i = 0; i < AN_TIMEOUT; i++) {
800 		if (!(CSR_READ_2(sc, offreg) & (AN_OFF_BUSY|AN_OFF_ERR)))
801 			break;
802 		DELAY(10);
803 	}
804 
805 	if (i == AN_TIMEOUT)
806 		return(ETIMEDOUT);
807 
808 	return(0);
809 }
810 
811 static int an_read_data(sc, id, off, buf, len)
812 	struct an_softc		*sc;
813 	int			id, off;
814 	caddr_t			buf;
815 	int			len;
816 {
817 	int			i;
818 	u_int16_t		*ptr;
819 	u_int8_t		*ptr2;
820 
821 	if (off != -1) {
822 		if (an_seek(sc, id, off, AN_BAP1))
823 			return(EIO);
824 	}
825 
826 	ptr = (u_int16_t *)buf;
827 	for (i = 0; i < len / 2; i++)
828 		ptr[i] = CSR_READ_2(sc, AN_DATA1);
829 	i*=2;
830 	if (i<len){
831 	        ptr2 = (u_int8_t *)buf;
832 	        ptr2[i] = CSR_READ_1(sc, AN_DATA1);
833 	}
834 
835 	return(0);
836 }
837 
838 static int an_write_data(sc, id, off, buf, len)
839 	struct an_softc		*sc;
840 	int			id, off;
841 	caddr_t			buf;
842 	int			len;
843 {
844 	int			i;
845 	u_int16_t		*ptr;
846 	u_int8_t		*ptr2;
847 
848 	if (off != -1) {
849 		if (an_seek(sc, id, off, AN_BAP0))
850 			return(EIO);
851 	}
852 
853 	ptr = (u_int16_t *)buf;
854 	for (i = 0; i < (len / 2); i++)
855 		CSR_WRITE_2(sc, AN_DATA0, ptr[i]);
856 	i*=2;
857 	if (i<len){
858 	        ptr2 = (u_int8_t *)buf;
859 	        CSR_WRITE_1(sc, AN_DATA0, ptr2[i]);
860 	}
861 
862 	return(0);
863 }
864 
865 /*
866  * Allocate a region of memory inside the NIC and zero
867  * it out.
868  */
869 static int an_alloc_nicmem(sc, len, id)
870 	struct an_softc		*sc;
871 	int			len;
872 	int			*id;
873 {
874 	int			i;
875 
876 	if (an_cmd(sc, AN_CMD_ALLOC_MEM, len)) {
877 		printf("%s: failed to allocate %d bytes on NIC\n",
878 		    sc->an_dev.dv_xname, len);
879 		return(ENOMEM);
880 	}
881 
882 	for (i = 0; i < AN_TIMEOUT; i++) {
883 		if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_ALLOC)
884 			break;
885 		DELAY(10);
886 	}
887 
888 	if (i == AN_TIMEOUT)
889 		return(ETIMEDOUT);
890 
891 	CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_ALLOC);
892 	*id = CSR_READ_2(sc, AN_ALLOC_FID);
893 
894 	if (an_seek(sc, *id, 0, AN_BAP0))
895 		return(EIO);
896 
897 	for (i = 0; i < len / 2; i++)
898 		CSR_WRITE_2(sc, AN_DATA0, 0);
899 
900 	return(0);
901 }
902 
903 static void an_setdef(sc, areq)
904 	struct an_softc		*sc;
905 	struct an_req		*areq;
906 {
907 	struct ifnet		*ifp;
908 	struct an_ltv_genconfig	*cfg;
909 	struct an_ltv_ssidlist	*ssid;
910 	struct an_ltv_aplist	*ap;
911 	struct an_ltv_gen	*sp;
912 
913 	ifp = &sc->arpcom.ec_if;
914 
915 	switch (areq->an_type) {
916 	case AN_RID_GENCONFIG:
917 		cfg = (struct an_ltv_genconfig *)areq;
918 
919 		bcopy((char *)&cfg->an_macaddr,
920 		    (char *)&sc->an_caps.an_oemaddr, ETHER_ADDR_LEN);
921 		bcopy((char *)&cfg->an_macaddr, LLADDR(ifp->if_sadl),
922 		    ETHER_ADDR_LEN);
923 
924 		bcopy((char *)cfg, (char *)&sc->an_config,
925 			sizeof(struct an_ltv_genconfig));
926 		break;
927 	case AN_RID_SSIDLIST:
928 		ssid = (struct an_ltv_ssidlist *)areq;
929 		bcopy((char *)ssid, (char *)&sc->an_ssidlist,
930 			sizeof(struct an_ltv_ssidlist));
931 		break;
932 	case AN_RID_APLIST:
933 		ap = (struct an_ltv_aplist *)areq;
934 		bcopy((char *)ap, (char *)&sc->an_aplist,
935 			sizeof(struct an_ltv_aplist));
936 		break;
937 	case AN_RID_TX_SPEED:
938 		sp = (struct an_ltv_gen *)areq;
939 		sc->an_tx_rate = sp->an_val;
940 		break;
941 	case AN_RID_WEP_VOLATILE:
942 		memcpy(&sc->an_temp_keys, areq, sizeof(sc->an_temp_keys));
943 
944 		/* Disable the MAC. */
945 		an_cmd(sc, AN_CMD_DISABLE, 0);
946 
947 		/* Just write the Key, we don't want to save it */
948 		an_write_record(sc, (struct an_ltv_gen *)areq);
949 
950 		/* Turn the MAC back on. */
951 		an_cmd(sc, AN_CMD_ENABLE, 0);
952 
953 		break;
954 	case AN_RID_WEP_PERSISTENT:
955 
956 		/* Disable the MAC. */
957 		an_cmd(sc, AN_CMD_DISABLE, 0);
958 
959 		/* Just write the Key, the card will save it in this mode */
960 		an_write_record(sc, (struct an_ltv_gen *)areq);
961 
962 		/* Turn the MAC back on. */
963 		an_cmd(sc, AN_CMD_ENABLE, 0);
964 
965 		break;
966 	default:
967 		printf("%s: unknown RID: %x\n", sc->an_dev.dv_xname, areq->an_type);
968 		return;
969 		break;
970 	}
971 
972 
973 	/* Reinitialize the card. */
974 	if (ifp->if_flags & IFF_UP)
975 		an_init(ifp);
976 
977 	return;
978 }
979 
980 /*
981  * We can't change the NIC configuration while the MAC is enabled,
982  * so in order to turn on RX monitor mode, we have to turn the MAC
983  * off first.
984  */
985 static void an_promisc(sc, promisc)
986 	struct an_softc		*sc;
987 	int			promisc;
988 {
989 	/* Disable the MAC. */
990 	an_cmd(sc, AN_CMD_DISABLE, 0);
991 
992 	/* Set RX mode. */
993 	if (promisc &&
994 	    !(sc->an_config.an_rxmode & AN_RXMODE_LAN_MONITOR_CURBSS)
995 	    ) {
996 		sc->an_rxmode = sc->an_config.an_rxmode;
997 		/* kills card DJA, if in sniff mode can't TX packets
998 		sc->an_config.an_rxmode |=
999 		    AN_RXMODE_LAN_MONITOR_CURBSS;
1000 		*/
1001 	} else {
1002 		sc->an_config.an_rxmode = sc->an_rxmode;
1003 	}
1004 
1005 	/* Transfer the configuration to the NIC */
1006 	sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
1007 	sc->an_config.an_type = AN_RID_GENCONFIG;
1008 	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_config)) {
1009 		printf("%s: failed to set configuration\n", sc->an_dev.dv_xname);
1010 		return;
1011 	}
1012 	/* Turn the MAC back on. */
1013 	an_cmd(sc, AN_CMD_ENABLE, 0);
1014 
1015 	return;
1016 }
1017 
1018 static int an_ioctl(ifp, command, data)
1019 	struct ifnet		*ifp;
1020 	u_long			command;
1021 	caddr_t			data;
1022 {
1023 	int			i, s;
1024 	int			error = 0;
1025 	struct an_softc		*sc;
1026 	struct an_req		areq;
1027 	struct ifreq		*ifr;
1028 	struct an_ltv_wepkey	*akey;
1029 	struct ieee80211_nwid	nwid;
1030 	struct ieee80211_nwkey	*nwkey;
1031 	struct ieee80211_power	*power;
1032 
1033 	sc = ifp->if_softc;
1034 	ifr = (struct ifreq *)data;
1035 	s = splnet();
1036 
1037 	switch(command) {
1038 	case SIOCSIFFLAGS:
1039 		if ((ifp->if_flags & sc->an_if_flags &
1040 		    (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) {
1041 			if (ifp->if_flags & IFF_PROMISC &&
1042 			    !(sc->an_if_flags & IFF_PROMISC)) {
1043 				an_promisc(sc, 1);
1044 				break;
1045 			}
1046 			if (!(ifp->if_flags & IFF_PROMISC) &&
1047 			    sc->an_if_flags & IFF_PROMISC) {
1048 				an_promisc(sc, 0);
1049 				break;
1050 			}
1051 		}
1052 		error = ether_ioctl(ifp, command, data);
1053 		sc->an_if_flags = ifp->if_flags;
1054 		break;
1055 	case SIOCGAIRONET:
1056 		error = copyin(ifr->ifr_data, &areq, sizeof(areq));
1057 		if (error)
1058 			break;
1059 #ifdef ANCACHE
1060 		if (areq.an_type == AN_RID_ZERO_CACHE) {
1061 			sc->an_sigitems = sc->an_nextitem = 0;
1062 			break;
1063 		} else if (areq.an_type == AN_RID_READ_CACHE) {
1064 			char *pt = (char *)&areq.an_val;
1065 			bcopy((char *)&sc->an_sigitems, (char *)pt,
1066 			    sizeof(int));
1067 			pt += sizeof(int);
1068 			areq.an_len = sizeof(int) / 2;
1069 			bcopy((char *)&sc->an_sigcache, (char *)pt,
1070 			    sizeof(struct an_sigcache) * sc->an_sigitems);
1071 			areq.an_len += ((sizeof(struct an_sigcache) *
1072 			    sc->an_sigitems) / 2) + 1;
1073 		} else
1074 #endif
1075 		if (an_read_record(sc, (struct an_ltv_gen *)&areq)) {
1076 			error = EINVAL;
1077 			break;
1078 		}
1079 		error = copyout(&areq, ifr->ifr_data, sizeof(areq));
1080 		break;
1081 	case SIOCSAIRONET:
1082 		if ((error = suser(curproc->p_ucred, &curproc->p_acflag)))
1083 			goto out;
1084 		error = copyin(ifr->ifr_data, &areq, sizeof(areq));
1085 		if (error)
1086 			break;
1087 		an_setdef(sc, &areq);
1088 		break;
1089 	case SIOCS80211NWID:
1090 		error = copyin(ifr->ifr_data, &nwid, sizeof(nwid));
1091 		if (error)
1092 			break;
1093 		if (nwid.i_len > IEEE80211_NWID_LEN) {
1094 			error = EINVAL;
1095 			break;
1096 		}
1097 		if (sc->an_ssidlist.an_ssid1_len == nwid.i_len &&
1098 		    memcmp(sc->an_ssidlist.an_ssid1, nwid.i_nwid, nwid.i_len)
1099 		    == 0)
1100 			break;
1101 		memset(sc->an_ssidlist.an_ssid1, 0, IEEE80211_NWID_LEN);
1102 		sc->an_ssidlist.an_ssid1_len = nwid.i_len;
1103 		memcpy(sc->an_ssidlist.an_ssid1, nwid.i_nwid, nwid.i_len);
1104 		if (sc->sc_enabled)
1105 			an_init(ifp);
1106 		break;
1107 	case SIOCG80211NWID:
1108 		memset(&nwid, 0, sizeof(nwid));
1109 		if ((ifp->if_flags & IFF_RUNNING) && sc->an_associated) {
1110 			nwid.i_len = sc->an_status.an_ssidlen;
1111 			memcpy(nwid.i_nwid, sc->an_status.an_ssid, nwid.i_len);
1112 		} else {
1113 			nwid.i_len = sc->an_ssidlist.an_ssid1_len;
1114 			memcpy(nwid.i_nwid, sc->an_ssidlist.an_ssid1,
1115 			    nwid.i_len);
1116 		}
1117 		error = copyout(&nwid, ifr->ifr_data, sizeof(nwid));
1118 		break;
1119 	case SIOCS80211NWKEY:
1120 		nwkey = (struct ieee80211_nwkey *)data;
1121 		sc->an_config.an_authtype &= AN_AUTHTYPE_MASK;
1122 		if (nwkey->i_wepon)
1123 			sc->an_config.an_authtype |= (AN_AUTHTYPE_MASK + 1);
1124 		akey = (struct an_ltv_wepkey *)&areq;
1125 		memset(akey, 0, sizeof(struct an_ltv_wepkey));
1126 		akey->an_type = AN_RID_WEP_VOLATILE;
1127 		akey->an_len = sizeof(struct an_ltv_wepkey);
1128 		akey->an_key_index = 0;
1129 		akey->an_mac_addr[0] = 1;	/* default mac */
1130 		akey->an_key_len = nwkey->i_key[0].i_keylen;
1131 		if (akey->an_key_len > sizeof(akey->an_key)) {
1132 			error = EINVAL;
1133 			break;
1134 		}
1135 		if (nwkey->i_key[0].i_keydat != NULL) {
1136 			if ((error = copyin(nwkey->i_key[0].i_keydat,
1137 			    akey->an_key, akey->an_key_len)) != 0)
1138 				break;
1139 		}
1140 		memcpy(&sc->an_temp_keys, akey, sizeof(struct an_ltv_wepkey));
1141 		if (sc->sc_enabled)
1142 			an_init(ifp);
1143 		break;
1144 	case SIOCG80211NWKEY:
1145 		nwkey = (struct ieee80211_nwkey *)data;
1146 		nwkey->i_wepon =
1147 		    sc->an_config.an_authtype & ~AN_AUTHTYPE_MASK ? 1 : 0;
1148 		nwkey->i_defkid = 1;
1149 		if (nwkey->i_key[0].i_keydat == NULL)
1150 			break;
1151 		/* do not show any keys to non-root user */
1152 		if ((error = suser(curproc->p_ucred, &curproc->p_acflag)) != 0)
1153 			break;
1154 		akey = &sc->an_temp_keys;
1155 		nwkey->i_key[0].i_keylen = akey->an_key_len;
1156 		for (i = 1; i < IEEE80211_WEP_NKID; i++)
1157 			nwkey->i_key[i].i_keylen = 0;
1158 		error = copyout(akey->an_key, nwkey->i_key[0].i_keydat,
1159 		    akey->an_key_len);
1160 		break;
1161 	case SIOCS80211POWER:
1162 		power = (struct ieee80211_power *)data;
1163 		sc->an_config.an_psave_mode = power->i_enabled ?
1164 		    AN_PSAVE_PSP : AN_PSAVE_NONE;
1165 		sc->an_config.an_listen_interval = power->i_maxsleep;
1166 		if (sc->sc_enabled)
1167 			an_init(ifp);
1168 		break;
1169 	case SIOCG80211POWER:
1170 		power = (struct ieee80211_power *)data;
1171 		power->i_enabled =
1172 		    sc->an_config.an_psave_mode != AN_PSAVE_NONE ? 1 : 0;
1173 		power->i_maxsleep = sc->an_config.an_listen_interval;
1174 		break;
1175 #ifdef IFM_IEEE80211
1176 	case SIOCSIFMEDIA:
1177 	case SIOCGIFMEDIA:
1178 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, command);
1179 		break;
1180 #endif
1181 	default:
1182 		error = ether_ioctl(ifp, command, data);
1183 		break;
1184 	}
1185 out:
1186 	splx(s);
1187 	return(error);
1188 }
1189 
1190 #ifdef IFM_IEEE80211
1191 static int
1192 an_media_change(ifp)
1193 	struct ifnet *ifp;
1194 {
1195 	struct an_softc *sc = ifp->if_softc;
1196 	struct ifmedia_entry *ime;
1197 	int error;
1198 
1199 	error = 0;
1200 	ime = sc->sc_media.ifm_cur;
1201 	switch (IFM_SUBTYPE(ime->ifm_media)) {
1202 	case IFM_AUTO:
1203 		sc->an_tx_rate = 0;
1204 		break;
1205 	case IFM_IEEE80211_DS1:
1206 		sc->an_tx_rate = AN_RATE_1MBPS;
1207 		break;
1208 	case IFM_IEEE80211_DS2:
1209 		sc->an_tx_rate = AN_RATE_2MBPS;
1210 		break;
1211 	case IFM_IEEE80211_DS5:
1212 		sc->an_tx_rate = AN_RATE_5_5MBPS;
1213 		break;
1214 	case IFM_IEEE80211_DS11:
1215 		sc->an_tx_rate = AN_RATE_11MBPS;
1216 		break;
1217 	}
1218 	if (ime->ifm_media & IFM_IEEE80211_ADHOC)
1219 		sc->an_config.an_opmode = AN_OPMODE_IBSS_ADHOC;
1220 	else
1221 		sc->an_config.an_opmode = AN_OPMODE_INFRASTRUCTURE_STATION;
1222 	/*
1223 	 * XXX: how to set txrate for the firmware?
1224 	 * There is a struct defined as an_txframe, which is used nowhere.
1225 	 * Perhaps we need to change the transmit mode from 802.3 to native.
1226 	 */
1227 	if (sc->sc_enabled)
1228 		an_init(ifp);
1229 	return error;
1230 }
1231 
1232 static void
1233 an_media_status(ifp, imr)
1234 	struct ifnet *ifp;
1235 	struct ifmediareq *imr;
1236 {
1237 	struct an_softc *sc = ifp->if_softc;
1238 
1239 	imr->ifm_status = IFM_AVALID;
1240 	if (sc->an_associated)
1241 		imr->ifm_status |= IFM_ACTIVE;
1242 	imr->ifm_active = IFM_IEEE80211;
1243 	switch (sc->an_tx_rate) {
1244 	case 0:
1245 		imr->ifm_active |= IFM_AUTO;
1246 		break;
1247 	case AN_RATE_1MBPS:
1248 		imr->ifm_active |= IFM_IEEE80211_DS1;
1249 		break;
1250 	case AN_RATE_2MBPS:
1251 		imr->ifm_active |= IFM_IEEE80211_DS2;
1252 		break;
1253 	case AN_RATE_5_5MBPS:
1254 		imr->ifm_active |= IFM_IEEE80211_DS5;
1255 		break;
1256 	case AN_RATE_11MBPS:
1257 		imr->ifm_active |= IFM_IEEE80211_DS11;
1258 		break;
1259 	}
1260 	if ((sc->an_config.an_opmode & 0x0f) == AN_OPMODE_IBSS_ADHOC)
1261 		imr->ifm_active |= IFM_IEEE80211_ADHOC;
1262 }
1263 #endif /* IFM_IEEE80211 */
1264 
1265 static int an_init_tx_ring(sc)
1266 	struct an_softc		*sc;
1267 {
1268 	int			i;
1269 	int			id;
1270 
1271 	if (!sc->sc_enabled)
1272 		return (0);
1273 
1274 	for (i = 0; i < AN_TX_RING_CNT; i++) {
1275 		if (an_alloc_nicmem(sc, 1518 +
1276 		    0x44, &id))
1277 			return(ENOMEM);
1278 		sc->an_rdata.an_tx_fids[i] = id;
1279 		sc->an_rdata.an_tx_ring[i] = 0;
1280 	}
1281 
1282 	sc->an_rdata.an_tx_prod = 0;
1283 	sc->an_rdata.an_tx_cons = 0;
1284 
1285 	return(0);
1286 }
1287 
1288 static int
1289 an_init(struct ifnet *ifp)
1290 {
1291 	struct an_softc *sc = (struct an_softc *)ifp->if_softc;
1292 
1293 	if (ifp->if_flags & IFF_RUNNING)
1294 		an_stop(ifp, 0);
1295 	else if (sc->sc_enabled) {
1296 		/* re-enable to power on after resume ... */
1297 		if (sc->sc_disable)
1298 			(*sc->sc_disable)(sc);
1299 		sc->sc_enabled = 0;
1300 	}
1301 
1302 	sc->an_associated = 0;
1303 
1304 	if (!sc->sc_enabled) {
1305 		if (sc->sc_enable)
1306 			(*sc->sc_enable)(sc);
1307 		sc->sc_enabled = 1;
1308 		an_wait(sc);
1309 	}
1310 
1311 	/* Allocate the TX buffers */
1312 	if (an_init_tx_ring(sc)) {
1313 		an_reset(sc);
1314 		if (an_init_tx_ring(sc)) {
1315 			printf("%s: tx buffer allocation "
1316 			    "failed\n", sc->an_dev.dv_xname);
1317 			return ENOMEM;
1318 		}
1319 	}
1320 
1321 	/* Set our MAC address. */
1322 	bcopy((char *)&sc->an_caps.an_oemaddr,
1323 	    (char *)&sc->an_config.an_macaddr, ETHER_ADDR_LEN);
1324 
1325 	if (ifp->if_flags & IFF_BROADCAST)
1326 		sc->an_config.an_rxmode = AN_RXMODE_BC_ADDR;
1327 	else
1328 		sc->an_config.an_rxmode = AN_RXMODE_ADDR;
1329 
1330 	if (ifp->if_flags & IFF_MULTICAST)
1331 		sc->an_config.an_rxmode = AN_RXMODE_BC_MC_ADDR;
1332 
1333 	/* Initialize promisc mode. */
1334 	/* Kills card DJA can't TX packet in sniff mode
1335  	if (ifp->if_flags & IFF_PROMISC)
1336 		sc->an_config.an_rxmode |= AN_RXMODE_LAN_MONITOR_CURBSS;
1337 	*/
1338 
1339 	sc->an_rxmode = sc->an_config.an_rxmode;
1340 
1341 	/* Set the ssid list */
1342 	sc->an_ssidlist.an_type = AN_RID_SSIDLIST;
1343 	sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist);
1344 	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) {
1345 		printf("%s: failed to set ssid list\n", sc->an_dev.dv_xname);
1346 		return ENXIO;
1347 	}
1348 
1349 	/* Set the AP list */
1350 	sc->an_aplist.an_type = AN_RID_APLIST;
1351 	sc->an_aplist.an_len = sizeof(struct an_ltv_aplist);
1352 	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) {
1353 		printf("%s: failed to set AP list\n", sc->an_dev.dv_xname);
1354 		return ENXIO;
1355 	}
1356 
1357 	/* Set the configuration in the NIC */
1358 	sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
1359 	sc->an_config.an_type = AN_RID_GENCONFIG;
1360 	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_config)) {
1361 		printf("%s: failed to set configuration\n", sc->an_dev.dv_xname);
1362 		return ENXIO;
1363 	}
1364 
1365 	/* Set the WEP Keys */
1366 	if ((sc->an_config.an_authtype & ~AN_AUTHTYPE_MASK) != 0) {
1367 		sc->an_temp_keys.an_len = sizeof(struct an_ltv_wepkey);
1368 		sc->an_temp_keys.an_type = AN_RID_WEP_VOLATILE;
1369 		an_write_record(sc, (struct an_ltv_gen *)&sc->an_temp_keys);
1370 	}
1371 
1372 	/* Enable the MAC */
1373 	if (an_cmd(sc, AN_CMD_ENABLE, 0)) {
1374 		printf("%s: failed to enable MAC\n", sc->an_dev.dv_xname);
1375 		return ENXIO;
1376 	}
1377 
1378 	/* enable interrupts */
1379 	CSR_WRITE_2(sc, AN_INT_EN, AN_INTRS);
1380 
1381 	ifp->if_flags |= IFF_RUNNING;
1382 	ifp->if_flags &= ~IFF_OACTIVE;
1383 
1384 	callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc);
1385 	return 0;
1386 }
1387 
1388 static void an_start(ifp)
1389 	struct ifnet		*ifp;
1390 {
1391 	struct an_softc		*sc;
1392 	struct mbuf		*m0 = NULL;
1393 	struct an_txframe_802_3	tx_frame_802_3;
1394 	struct ether_header	*eh;
1395 	int			id;
1396 	int			idx;
1397 	unsigned char           txcontrol;
1398 
1399 	sc = ifp->if_softc;
1400 
1401 	if (!sc->sc_enabled)
1402 		return;
1403 
1404 	if (ifp->if_flags & IFF_OACTIVE)
1405 		return;
1406 
1407 	if (!sc->an_associated)
1408 		return;
1409 
1410 	idx = sc->an_rdata.an_tx_prod;
1411 	bzero((char *)&tx_frame_802_3, sizeof(tx_frame_802_3));
1412 
1413 	while(sc->an_rdata.an_tx_ring[idx] == 0) {
1414 		IFQ_DEQUEUE(&ifp->if_snd, m0);
1415 		if (m0 == NULL)
1416 			break;
1417 
1418 		id = sc->an_rdata.an_tx_fids[idx];
1419 		eh = mtod(m0, struct ether_header *);
1420 
1421 		bcopy((char *)&eh->ether_dhost,
1422 		    (char *)&tx_frame_802_3.an_tx_dst_addr, ETHER_ADDR_LEN);
1423 		bcopy((char *)&eh->ether_shost,
1424 		    (char *)&tx_frame_802_3.an_tx_src_addr, ETHER_ADDR_LEN);
1425 
1426 		tx_frame_802_3.an_tx_802_3_payload_len =
1427 		  m0->m_pkthdr.len - 12;  /* minus src/dest mac & type */
1428 
1429                 m_copydata(m0, sizeof(struct ether_header) - 2 ,
1430                     tx_frame_802_3.an_tx_802_3_payload_len,
1431                     (caddr_t)&sc->an_txbuf);
1432 
1433 		txcontrol=AN_TXCTL_8023;
1434 		/* write the txcontrol only */
1435 		an_write_data(sc, id, 0x08, (caddr_t)&txcontrol,
1436 			      sizeof(txcontrol));
1437 
1438 		/* 802_3 header */
1439 		an_write_data(sc, id, 0x34, (caddr_t)&tx_frame_802_3,
1440 			      sizeof(struct an_txframe_802_3));
1441 
1442 		/* in mbuf header type is just before payload */
1443 		an_write_data(sc, id, 0x44, (caddr_t)&sc->an_txbuf,
1444 			    tx_frame_802_3.an_tx_802_3_payload_len);
1445 #if NBPFILTER > 0
1446 		/*
1447 		 * If there's a BPF listner, bounce a copy of
1448 		 * this frame to him.
1449 		 */
1450 		if (ifp->if_bpf)
1451 			bpf_mtap(ifp->if_bpf, m0);
1452 #endif
1453 
1454 		m_freem(m0);
1455 		m0 = NULL;
1456 
1457 		/* TX START disable lan monitor ? DJA
1458 		   an_disable_sniff():
1459 		 */
1460 		sc->an_rdata.an_tx_ring[idx] = id;
1461 		if (an_cmd(sc, AN_CMD_TX, id))
1462 			printf("%s: xmit failed\n", sc->an_dev.dv_xname);
1463 
1464 		AN_INC(idx, AN_TX_RING_CNT);
1465 	}
1466 
1467 	if (m0 != NULL)
1468 		ifp->if_flags |= IFF_OACTIVE;
1469 
1470 	sc->an_rdata.an_tx_prod = idx;
1471 
1472 	/*
1473 	 * Set a timeout in case the chip goes out to lunch.
1474 	 */
1475 	ifp->if_timer = 5;
1476 
1477 	return;
1478 }
1479 
1480 void an_stop(ifp, disable)
1481 	struct ifnet		*ifp;
1482 	int disable;
1483 {
1484 	struct an_softc		*sc = (struct an_softc *)ifp->if_softc;
1485 	int			i;
1486 
1487 	callout_stop(&sc->an_stat_ch);
1488 	if (!sc->sc_enabled)
1489 		return;
1490 
1491 	an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0);
1492 	CSR_WRITE_2(sc, AN_INT_EN, 0);
1493 	an_cmd(sc, AN_CMD_DISABLE, 0);
1494 
1495 	for (i = 0; i < AN_TX_RING_CNT; i++)
1496 		an_cmd(sc, AN_CMD_DEALLOC_MEM, sc->an_rdata.an_tx_fids[i]);
1497 
1498 	ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
1499 	ifp->if_timer = 0;
1500 
1501 	if (disable) {
1502 		if (sc->sc_disable)
1503 			(*sc->sc_disable)(sc);
1504 		sc->sc_enabled = 0;
1505 	}
1506 
1507 	return;
1508 }
1509 
1510 static void an_watchdog(ifp)
1511 	struct ifnet		*ifp;
1512 {
1513 	struct an_softc		*sc;
1514 
1515 	sc = ifp->if_softc;
1516 	if (!sc->sc_enabled)
1517 		return;
1518 
1519 	printf("%s: device timeout\n", sc->an_dev.dv_xname);
1520 
1521 	an_reset(sc);
1522 	an_init(ifp);
1523 
1524 	ifp->if_oerrors++;
1525 	return;
1526 }
1527 
1528 #ifdef ANCACHE
1529 /* Aironet signal strength cache code.
1530  * store signal/noise/quality on per MAC src basis in
1531  * a small fixed cache.  The cache wraps if > MAX slots
1532  * used.  The cache may be zeroed out to start over.
1533  * Two simple filters exist to reduce computation:
1534  * 1. ip only (literally 0x800) which may be used
1535  * to ignore some packets.  It defaults to ip only.
1536  * it could be used to focus on broadcast, non-IP 802.11 beacons.
1537  * 2. multicast/broadcast only.  This may be used to
1538  * ignore unicast packets and only cache signal strength
1539  * for multicast/broadcast packets (beacons); e.g., Mobile-IP
1540  * beacons and not unicast traffic.
1541  *
1542  * The cache stores (MAC src(index), IP src (major clue), signal,
1543  *	quality, noise)
1544  *
1545  * No apologies for storing IP src here.  It's easy and saves much
1546  * trouble elsewhere.  The cache is assumed to be INET dependent,
1547  * although it need not be.
1548  *
1549  * Note: the Aironet only has a single byte of signal strength value
1550  * in the rx frame header, and it's not scaled to anything sensible.
1551  * This is kind of lame, but it's all we've got.
1552  */
1553 
1554 #ifdef documentation
1555 
1556 int an_sigitems;                                /* number of cached entries */
1557 struct an_sigcache an_sigcache[MAXANCACHE];  /*  array of cache entries */
1558 int an_nextitem;                                /*  index/# of entries */
1559 
1560 
1561 #endif
1562 
1563 /* control variables for cache filtering.  Basic idea is
1564  * to reduce cost (e.g., to only Mobile-IP agent beacons
1565  * which are broadcast or multicast).  Still you might
1566  * want to measure signal strength anth unicast ping packets
1567  * on a pt. to pt. ant. setup.
1568  */
1569 /* set true if you want to limit cache items to broadcast/mcast
1570  * only packets (not unicast).  Useful for mobile-ip beacons which
1571  * are broadcast/multicast at network layer.  Default is all packets
1572  * so ping/unicast anll work say anth pt. to pt. antennae setup.
1573  */
1574 static int an_cache_mcastonly = 0;
1575 #if 0
1576 SYSCTL_INT(_machdep, OID_AUTO, an_cache_mcastonly, CTLFLAG_RW,
1577 	&an_cache_mcastonly, 0, "");
1578 #endif
1579 
1580 /* set true if you want to limit cache items to IP packets only
1581 */
1582 static int an_cache_iponly = 1;
1583 #if 0
1584 SYSCTL_INT(_machdep, OID_AUTO, an_cache_iponly, CTLFLAG_RW,
1585 	&an_cache_iponly, 0, "");
1586 #endif
1587 
1588 /*
1589  * an_cache_store, per rx packet store signal
1590  * strength in MAC (src) indexed cache.
1591  */
1592 static
1593 void an_cache_store (sc, eh, m, rx_quality)
1594 	struct an_softc *sc;
1595 	struct ether_header *eh;
1596 	struct mbuf *m;
1597 	unsigned short rx_quality;
1598 {
1599 	struct ip *ip = 0;
1600 	int i;
1601 	static int cache_slot = 0; 	/* use this cache entry */
1602 	static int wrapindex = 0;       /* next "free" cache entry */
1603 	int saanp=0;
1604 
1605 	/* filters:
1606 	 * 1. ip only
1607 	 * 2. configurable filter to throw out unicast packets,
1608 	 * keep multicast only.
1609 	 */
1610 
1611 	if ((ntohs(eh->ether_type) == 0x800)) {
1612 		saanp = 1;
1613 	}
1614 
1615 	/* filter for ip packets only
1616 	*/
1617 	if ( an_cache_iponly && !saanp) {
1618 		return;
1619 	}
1620 
1621 	/* filter for broadcast/multicast only
1622 	 */
1623 	if (an_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) {
1624 		return;
1625 	}
1626 
1627 #ifdef SIGDEBUG
1628 	printf("an: q value %x (MSB=0x%x, LSB=0x%x) \n",
1629 	    rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff);
1630 #endif
1631 
1632 	/* find the ip header.  we want to store the ip_src
1633 	 * address.
1634 	 */
1635 	if (saanp) {
1636 		ip = mtod(m, struct ip *);
1637 	}
1638 
1639 	/* do a linear search for a matching MAC address
1640 	 * in the cache table
1641 	 * . MAC address is 6 bytes,
1642 	 * . var w_nextitem holds total number of entries already cached
1643 	 */
1644 	for(i = 0; i < sc->an_nextitem; i++) {
1645 		if (! bcmp(eh->ether_shost , sc->an_sigcache[i].macsrc,  6 )) {
1646 			/* Match!,
1647 			 * so we already have this entry,
1648 			 * update the data
1649 			 */
1650 			break;
1651 		}
1652 	}
1653 
1654 	/* did we find a matching mac address?
1655 	 * if yes, then overwrite a previously existing cache entry
1656 	 */
1657 	if (i < sc->an_nextitem )   {
1658 		cache_slot = i;
1659 	}
1660 	/* else, have a new address entry,so
1661 	 * add this new entry,
1662 	 * if table full, then we need to replace LRU entry
1663 	 */
1664 	else    {
1665 
1666 		/* check for space in cache table
1667 		 * note: an_nextitem also holds number of entries
1668 		 * added in the cache table
1669 		 */
1670 		if ( sc->an_nextitem < MAXANCACHE ) {
1671 			cache_slot = sc->an_nextitem;
1672 			sc->an_nextitem++;
1673 			sc->an_sigitems = sc->an_nextitem;
1674 		}
1675         	/* no space found, so simply wrap anth wrap index
1676 		 * and "zap" the next entry
1677 		 */
1678 		else {
1679 			if (wrapindex == MAXANCACHE) {
1680 				wrapindex = 0;
1681 			}
1682 			cache_slot = wrapindex++;
1683 		}
1684 	}
1685 
1686 	/* invariant: cache_slot now points at some slot
1687 	 * in cache.
1688 	 */
1689 	if (cache_slot < 0 || cache_slot >= MAXANCACHE) {
1690 		log(LOG_ERR, "an_cache_store, bad index: %d of "
1691 		    "[0..%d], gross cache error\n",
1692 		    cache_slot, MAXANCACHE);
1693 		return;
1694 	}
1695 
1696 	/*  store items in cache
1697 	 *  .ip source address
1698 	 *  .mac src
1699 	 *  .signal, etc.
1700 	 */
1701 	if (saanp) {
1702 		sc->an_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr;
1703 	}
1704 	bcopy( eh->ether_shost, sc->an_sigcache[cache_slot].macsrc,  6);
1705 
1706 	sc->an_sigcache[cache_slot].signal = rx_quality;
1707 
1708 	return;
1709 }
1710 #endif
1711