if_an.c revision 89063
1/*
2 * Copyright (c) 1997, 1998, 1999
3 *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by Bill Paul.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * $FreeBSD: head/sys/dev/an/if_an.c 89063 2002-01-08 10:25:12Z msmith $
33 */
34
35/*
36 * Aironet 4500/4800 802.11 PCMCIA/ISA/PCI driver for FreeBSD.
37 *
38 * Written by Bill Paul <wpaul@ctr.columbia.edu>
39 * Electrical Engineering Department
40 * Columbia University, New York City
41 */
42
43/*
44 * The Aironet 4500/4800 series cards come in PCMCIA, ISA and PCI form.
45 * This driver supports all three device types (PCI devices are supported
46 * through an extra PCI shim: /sys/pci/if_an_p.c). ISA devices can be
47 * supported either using hard-coded IO port/IRQ settings or via Plug
48 * and Play. The 4500 series devices support 1Mbps and 2Mbps data rates.
49 * The 4800 devices support 1, 2, 5.5 and 11Mbps rates.
50 *
51 * Like the WaveLAN/IEEE cards, the Aironet NICs are all essentially
52 * PCMCIA devices. The ISA and PCI cards are a combination of a PCMCIA
53 * device and a PCMCIA to ISA or PCMCIA to PCI adapter card. There are
54 * a couple of important differences though:
55 *
56 * - Lucent ISA card looks to the host like a PCMCIA controller with
57 *   a PCMCIA WaveLAN card inserted. This means that even desktop
58 *   machines need to be configured with PCMCIA support in order to
59 *   use WaveLAN/IEEE ISA cards. The Aironet cards on the other hand
60 *   actually look like normal ISA and PCI devices to the host, so
61 *   no PCMCIA controller support is needed
62 *
63 * The latter point results in a small gotcha. The Aironet PCMCIA
64 * cards can be configured for one of two operating modes depending
65 * on how the Vpp1 and Vpp2 programming voltages are set when the
66 * card is activated. In order to put the card in proper PCMCIA
67 * operation (where the CIS table is visible and the interface is
68 * programmed for PCMCIA operation), both Vpp1 and Vpp2 have to be
69 * set to 5 volts. FreeBSD by default doesn't set the Vpp voltages,
70 * which leaves the card in ISA/PCI mode, which prevents it from
71 * being activated as an PCMCIA device.
72 *
73 * Note that some PCMCIA controller software packages for Windows NT
74 * fail to set the voltages as well.
75 *
76 * The Aironet devices can operate in both station mode and access point
77 * mode. Typically, when programmed for station mode, the card can be set
78 * to automatically perform encapsulation/decapsulation of Ethernet II
79 * and 802.3 frames within 802.11 frames so that the host doesn't have
80 * to do it itself. This driver doesn't program the card that way: the
81 * driver handles all of the encapsulation/decapsulation itself.
82 */
83
84#include "opt_inet.h"
85
86#ifdef INET
87#define ANCACHE			/* enable signal strength cache */
88#endif
89
90#include <sys/param.h>
91#include <sys/systm.h>
92#include <sys/sockio.h>
93#include <sys/mbuf.h>
94#include <sys/proc.h>
95#include <sys/kernel.h>
96#include <sys/socket.h>
97#ifdef ANCACHE
98#include <sys/syslog.h>
99#include <sys/sysctl.h>
100#endif
101
102#include <sys/module.h>
103#include <sys/sysctl.h>
104#include <sys/bus.h>
105#include <machine/bus.h>
106#include <sys/rman.h>
107#include <sys/lock.h>
108#include <sys/mutex.h>
109#include <machine/resource.h>
110
111#include <net/if.h>
112#include <net/if_arp.h>
113#include <net/ethernet.h>
114#include <net/if_dl.h>
115#include <net/if_types.h>
116#include <net/if_ieee80211.h>
117#include <net/if_media.h>
118
119#ifdef INET
120#include <netinet/in.h>
121#include <netinet/in_systm.h>
122#include <netinet/in_var.h>
123#include <netinet/ip.h>
124#endif
125
126#include <net/bpf.h>
127
128#include <machine/md_var.h>
129
130#include <dev/an/if_aironet_ieee.h>
131#include <dev/an/if_anreg.h>
132
133#if !defined(lint)
134static const char rcsid[] =
135  "$FreeBSD: head/sys/dev/an/if_an.c 89063 2002-01-08 10:25:12Z msmith $";
136#endif
137
138/* These are global because we need them in sys/pci/if_an_p.c. */
139static void an_reset		__P((struct an_softc *));
140static int an_ioctl		__P((struct ifnet *, u_long, caddr_t));
141static void an_init		__P((void *));
142static int an_init_tx_ring	__P((struct an_softc *));
143static void an_start		__P((struct ifnet *));
144static void an_watchdog		__P((struct ifnet *));
145static void an_rxeof		__P((struct an_softc *));
146static void an_txeof		__P((struct an_softc *, int));
147
148static void an_promisc		__P((struct an_softc *, int));
149static int an_cmd		__P((struct an_softc *, int, int));
150static int an_read_record	__P((struct an_softc *, struct an_ltv_gen *));
151static int an_write_record	__P((struct an_softc *, struct an_ltv_gen *));
152static int an_read_data		__P((struct an_softc *, int,
153					int, caddr_t, int));
154static int an_write_data	__P((struct an_softc *, int,
155					int, caddr_t, int));
156static int an_seek		__P((struct an_softc *, int, int, int));
157static int an_alloc_nicmem	__P((struct an_softc *, int, int *));
158static void an_stats_update	__P((void *));
159static void an_setdef		__P((struct an_softc *, struct an_req *));
160#ifdef ANCACHE
161static void an_cache_store	__P((struct an_softc *, struct ether_header *,
162					struct mbuf *, unsigned short));
163#endif
164
165/* function definitions for use with the Cisco's Linux configuration
166   utilities
167*/
168
169static int readrids             __P((struct ifnet*, struct aironet_ioctl*));
170static int writerids            __P((struct ifnet*, struct aironet_ioctl*));
171static int flashcard            __P((struct ifnet*, struct aironet_ioctl*));
172
173static int cmdreset             __P((struct ifnet *));
174static int setflashmode         __P((struct ifnet *));
175static int flashgchar           __P((struct ifnet *,int,int));
176static int flashpchar           __P((struct ifnet *,int,int));
177static int flashputbuf          __P((struct ifnet *));
178static int flashrestart         __P((struct ifnet *));
179static int WaitBusy             __P((struct ifnet *, int));
180static int unstickbusy          __P((struct ifnet *));
181
182static void an_dump_record	__P((struct an_softc *,struct an_ltv_gen *,
183				    char *));
184
185static int an_media_change	__P((struct ifnet *));
186static void an_media_status	__P((struct ifnet *, struct ifmediareq *));
187
188static int	an_dump = 0;
189
190static char an_conf[256];
191
192/* sysctl vars */
193SYSCTL_NODE(_machdep, OID_AUTO, an, CTLFLAG_RD, 0, "dump RID");
194
195static int
196sysctl_an_dump(SYSCTL_HANDLER_ARGS)
197{
198	int	error, r, last;
199	char 	*s = an_conf;
200
201	last = an_dump;
202	bzero(an_conf, sizeof(an_conf));
203
204	switch (an_dump) {
205	case 0:
206		strcat(an_conf, "off");
207		break;
208	case 1:
209		strcat(an_conf, "type");
210		break;
211	case 2:
212		strcat(an_conf, "dump");
213		break;
214	default:
215		snprintf(an_conf, 5, "%x", an_dump);
216		break;
217	}
218
219	error = sysctl_handle_string(oidp, an_conf, sizeof(an_conf), req);
220
221	if (strncmp(an_conf,"off", 4) == 0) {
222		an_dump = 0;
223 	}
224	if (strncmp(an_conf,"dump", 4) == 0) {
225		an_dump = 1;
226	}
227	if (strncmp(an_conf,"type", 4) == 0) {
228		an_dump = 2;
229	}
230	if (*s == 'f') {
231		r = 0;
232		for (;;s++) {
233			if ((*s >= '0') && (*s <= '9')) {
234				r = r * 16 + (*s - '0');
235			} else if ((*s >= 'a') && (*s <= 'f')) {
236				r = r * 16 + (*s - 'a' + 10);
237			} else {
238				break;
239			}
240		}
241		an_dump = r;
242	}
243	if (an_dump != last)
244		printf("Sysctl changed for Aironet driver\n");
245
246	return error;
247}
248
249SYSCTL_PROC(_machdep, OID_AUTO, an_dump, CTLTYPE_STRING | CTLFLAG_RW,
250            0, sizeof(an_conf), sysctl_an_dump, "A", "");
251
252/*
253 * We probe for an Aironet 4500/4800 card by attempting to
254 * read the default SSID list. On reset, the first entry in
255 * the SSID list will contain the name "tsunami." If we don't
256 * find this, then there's no card present.
257 */
258int
259an_probe(dev)
260	device_t		dev;
261{
262        struct an_softc *sc = device_get_softc(dev);
263	struct an_ltv_ssidlist	ssid;
264	int	error;
265
266	bzero((char *)&ssid, sizeof(ssid));
267
268	error = an_alloc_port(dev, 0, AN_IOSIZ);
269	if (error != 0)
270		return (0);
271
272	/* can't do autoprobing */
273	if (rman_get_start(sc->port_res) == -1)
274		return(0);
275
276	/*
277	 * We need to fake up a softc structure long enough
278	 * to be able to issue commands and call some of the
279	 * other routines.
280	 */
281	sc->an_bhandle = rman_get_bushandle(sc->port_res);
282	sc->an_btag = rman_get_bustag(sc->port_res);
283	sc->an_unit = device_get_unit(dev);
284
285	ssid.an_len = sizeof(ssid);
286	ssid.an_type = AN_RID_SSIDLIST;
287
288        /* Make sure interrupts are disabled. */
289        CSR_WRITE_2(sc, AN_INT_EN, 0);
290        CSR_WRITE_2(sc, AN_EVENT_ACK, 0xFFFF);
291
292	an_reset(sc);
293
294	if (an_cmd(sc, AN_CMD_READCFG, 0))
295		return(0);
296
297	if (an_read_record(sc, (struct an_ltv_gen *)&ssid))
298		return(0);
299
300	/* See if the ssid matches what we expect ... but doesn't have to */
301	if (strcmp(ssid.an_ssid1, AN_DEF_SSID))
302		return(0);
303
304	return(AN_IOSIZ);
305}
306
307/*
308 * Allocate a port resource with the given resource id.
309 */
310int
311an_alloc_port(dev, rid, size)
312	device_t dev;
313	int rid;
314	int size;
315{
316	struct an_softc *sc = device_get_softc(dev);
317	struct resource *res;
318
319	res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
320				 0ul, ~0ul, size, RF_ACTIVE);
321	if (res) {
322		sc->port_rid = rid;
323		sc->port_res = res;
324		return (0);
325	} else {
326		return (ENOENT);
327	}
328}
329
330/*
331 * Allocate an irq resource with the given resource id.
332 */
333int
334an_alloc_irq(dev, rid, flags)
335	device_t dev;
336	int rid;
337	int flags;
338{
339	struct an_softc *sc = device_get_softc(dev);
340	struct resource *res;
341
342	res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
343				 0ul, ~0ul, 1, (RF_ACTIVE | flags));
344	if (res) {
345		sc->irq_rid = rid;
346		sc->irq_res = res;
347		return (0);
348	} else {
349		return (ENOENT);
350	}
351}
352
353/*
354 * Release all resources
355 */
356void
357an_release_resources(dev)
358	device_t dev;
359{
360	struct an_softc *sc = device_get_softc(dev);
361
362	if (sc->port_res) {
363		bus_release_resource(dev, SYS_RES_IOPORT,
364				     sc->port_rid, sc->port_res);
365		sc->port_res = 0;
366	}
367	if (sc->irq_res) {
368		bus_release_resource(dev, SYS_RES_IRQ,
369				     sc->irq_rid, sc->irq_res);
370		sc->irq_res = 0;
371	}
372}
373
374int
375an_attach(sc, unit, flags)
376	struct an_softc *sc;
377	int unit;
378	int flags;
379{
380	struct ifnet		*ifp = &sc->arpcom.ac_if;
381
382	mtx_init(&sc->an_mtx, device_get_nameunit(sc->an_dev), MTX_DEF |
383	    MTX_RECURSE);
384	AN_LOCK(sc);
385
386	sc->an_gone = 0;
387	sc->an_associated = 0;
388	sc->an_monitor = 0;
389	sc->an_was_monitor = 0;
390
391	/* Reset the NIC. */
392	an_reset(sc);
393
394	/* Load factory config */
395	if (an_cmd(sc, AN_CMD_READCFG, 0)) {
396		printf("an%d: failed to load config data\n", sc->an_unit);
397		AN_UNLOCK(sc);
398		mtx_destroy(&sc->an_mtx);
399		return(EIO);
400	}
401
402	/* Read the current configuration */
403	sc->an_config.an_type = AN_RID_GENCONFIG;
404	sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
405	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_config)) {
406		printf("an%d: read record failed\n", sc->an_unit);
407		AN_UNLOCK(sc);
408		mtx_destroy(&sc->an_mtx);
409		return(EIO);
410	}
411
412	/* Read the card capabilities */
413	sc->an_caps.an_type = AN_RID_CAPABILITIES;
414	sc->an_caps.an_len = sizeof(struct an_ltv_caps);
415	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_caps)) {
416		printf("an%d: read record failed\n", sc->an_unit);
417		AN_UNLOCK(sc);
418		mtx_destroy(&sc->an_mtx);
419		return(EIO);
420	}
421
422	/* Read ssid list */
423	sc->an_ssidlist.an_type = AN_RID_SSIDLIST;
424	sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist);
425	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) {
426		printf("an%d: read record failed\n", sc->an_unit);
427		AN_UNLOCK(sc);
428		mtx_destroy(&sc->an_mtx);
429		return(EIO);
430	}
431
432	/* Read AP list */
433	sc->an_aplist.an_type = AN_RID_APLIST;
434	sc->an_aplist.an_len = sizeof(struct an_ltv_aplist);
435	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) {
436		printf("an%d: read record failed\n", sc->an_unit);
437		AN_UNLOCK(sc);
438		mtx_destroy(&sc->an_mtx);
439		return(EIO);
440	}
441
442	bcopy((char *)&sc->an_caps.an_oemaddr,
443	   (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
444
445	printf("an%d: Ethernet address: %6D\n", sc->an_unit,
446	    sc->arpcom.ac_enaddr, ":");
447
448	ifp->if_softc = sc;
449	ifp->if_unit = sc->an_unit = unit;
450	ifp->if_name = "an";
451	ifp->if_mtu = ETHERMTU;
452	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
453	ifp->if_ioctl = an_ioctl;
454	ifp->if_output = ether_output;
455	ifp->if_start = an_start;
456	ifp->if_watchdog = an_watchdog;
457	ifp->if_init = an_init;
458	ifp->if_baudrate = 10000000;
459	ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
460
461	bzero(sc->an_config.an_nodename, sizeof(sc->an_config.an_nodename));
462	bcopy(AN_DEFAULT_NODENAME, sc->an_config.an_nodename,
463	    sizeof(AN_DEFAULT_NODENAME) - 1);
464
465	bzero(sc->an_ssidlist.an_ssid1, sizeof(sc->an_ssidlist.an_ssid1));
466	bcopy(AN_DEFAULT_NETNAME, sc->an_ssidlist.an_ssid1,
467	    sizeof(AN_DEFAULT_NETNAME) - 1);
468	sc->an_ssidlist.an_ssid1_len = strlen(AN_DEFAULT_NETNAME);
469
470	sc->an_config.an_opmode =
471	    AN_OPMODE_INFRASTRUCTURE_STATION;
472
473	sc->an_tx_rate = 0;
474	bzero((char *)&sc->an_stats, sizeof(sc->an_stats));
475
476	ifmedia_init(&sc->an_ifmedia, 0, an_media_change, an_media_status);
477#define	ADD(m, c)	ifmedia_add(&sc->an_ifmedia, (m), (c), NULL)
478	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
479	    IFM_IEEE80211_ADHOC, 0), 0);
480	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0);
481	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
482	    IFM_IEEE80211_ADHOC, 0), 0);
483	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0);
484	if (sc->an_caps.an_rates[2] == AN_RATE_5_5MBPS) {
485		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
486		    IFM_IEEE80211_ADHOC, 0), 0);
487		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 0, 0), 0);
488	}
489	if (sc->an_caps.an_rates[3] == AN_RATE_11MBPS) {
490		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
491		    IFM_IEEE80211_ADHOC, 0), 0);
492		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0);
493	}
494	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO,
495	    IFM_IEEE80211_ADHOC, 0), 0);
496	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0);
497#undef	ADD
498	ifmedia_set(&sc->an_ifmedia, IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO,
499	    0, 0));
500
501	/*
502	 * Call MI attach routine.
503	 */
504	ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
505	callout_handle_init(&sc->an_stat_ch);
506	AN_UNLOCK(sc);
507
508	return(0);
509}
510
511static void
512an_rxeof(sc)
513	struct an_softc *sc;
514{
515	struct ifnet   *ifp;
516	struct ether_header *eh;
517	struct ieee80211_frame *ih;
518	struct an_rxframe rx_frame;
519	struct an_rxframe_802_3 rx_frame_802_3;
520	struct mbuf    *m;
521	int             len, id, error = 0;
522	int             ieee80211_header_len;
523	u_char          *bpf_buf;
524	u_short         fc1;
525
526	ifp = &sc->arpcom.ac_if;
527
528	id = CSR_READ_2(sc, AN_RX_FID);
529
530	if (sc->an_monitor && (ifp->if_flags & IFF_PROMISC)) {
531		/* read raw 802.11 packet */
532	        bpf_buf = sc->buf_802_11;
533
534		/* read header */
535		if (an_read_data(sc, id, 0x0, (caddr_t)&rx_frame,
536				 sizeof(rx_frame))) {
537			ifp->if_ierrors++;
538			return;
539		}
540
541		/*
542		 * skip beacon by default since this increases the
543		 * system load a lot
544		 */
545
546		if (!(sc->an_monitor & AN_MONITOR_INCLUDE_BEACON) &&
547		    (rx_frame.an_frame_ctl & IEEE80211_FC0_SUBTYPE_BEACON)) {
548			return;
549		}
550
551		if (sc->an_monitor & AN_MONITOR_AIRONET_HEADER) {
552			len = rx_frame.an_rx_payload_len
553				+ sizeof(rx_frame);
554			/* Check for insane frame length */
555			if (len > sizeof(sc->buf_802_11)) {
556				printf("an%d: oversized packet received (%d, %d)\n",
557				       sc->an_unit, len, MCLBYTES);
558				ifp->if_ierrors++;
559				return;
560			}
561
562			bcopy((char *)&rx_frame,
563			      bpf_buf, sizeof(rx_frame));
564
565			error = an_read_data(sc, id, sizeof(rx_frame),
566					     (caddr_t)bpf_buf+sizeof(rx_frame),
567					     rx_frame.an_rx_payload_len);
568		} else {
569			fc1=rx_frame.an_frame_ctl >> 8;
570			ieee80211_header_len = sizeof(struct ieee80211_frame);
571			if ((fc1 & IEEE80211_FC1_DIR_TODS) &&
572			    (fc1 & IEEE80211_FC1_DIR_FROMDS)) {
573				ieee80211_header_len += ETHER_ADDR_LEN;
574			}
575
576			len = rx_frame.an_rx_payload_len
577				+ ieee80211_header_len;
578			/* Check for insane frame length */
579			if (len > sizeof(sc->buf_802_11)) {
580				printf("an%d: oversized packet received (%d, %d)\n",
581				       sc->an_unit, len, MCLBYTES);
582				ifp->if_ierrors++;
583				return;
584			}
585
586			ih = (struct ieee80211_frame *)bpf_buf;
587
588			bcopy((char *)&rx_frame.an_frame_ctl,
589			      (char *)ih, ieee80211_header_len);
590
591			error = an_read_data(sc, id, sizeof(rx_frame) +
592					     rx_frame.an_gaplen,
593					     (caddr_t)ih +ieee80211_header_len,
594					     rx_frame.an_rx_payload_len);
595		}
596		/* dump raw 802.11 packet to bpf and skip ip stack */
597		if (ifp->if_bpf != NULL) {
598			bpf_tap(ifp, bpf_buf, len);
599		}
600	} else {
601		MGETHDR(m, M_DONTWAIT, MT_DATA);
602		if (m == NULL) {
603			ifp->if_ierrors++;
604			return;
605		}
606		MCLGET(m, M_DONTWAIT);
607		if (!(m->m_flags & M_EXT)) {
608			m_freem(m);
609			ifp->if_ierrors++;
610			return;
611		}
612		m->m_pkthdr.rcvif = ifp;
613		/* Read Ethernet encapsulated packet */
614
615#ifdef ANCACHE
616		/* Read NIC frame header */
617		if (an_read_data(sc, id, 0, (caddr_t) & rx_frame, sizeof(rx_frame))) {
618			ifp->if_ierrors++;
619			return;
620		}
621#endif
622		/* Read in the 802_3 frame header */
623		if (an_read_data(sc, id, 0x34, (caddr_t) & rx_frame_802_3,
624				 sizeof(rx_frame_802_3))) {
625			ifp->if_ierrors++;
626			return;
627		}
628		if (rx_frame_802_3.an_rx_802_3_status != 0) {
629			ifp->if_ierrors++;
630			return;
631		}
632		/* Check for insane frame length */
633		if (rx_frame_802_3.an_rx_802_3_payload_len > MCLBYTES) {
634			ifp->if_ierrors++;
635			return;
636		}
637		m->m_pkthdr.len = m->m_len =
638			rx_frame_802_3.an_rx_802_3_payload_len + 12;
639
640		eh = mtod(m, struct ether_header *);
641
642		bcopy((char *)&rx_frame_802_3.an_rx_dst_addr,
643		      (char *)&eh->ether_dhost, ETHER_ADDR_LEN);
644		bcopy((char *)&rx_frame_802_3.an_rx_src_addr,
645		      (char *)&eh->ether_shost, ETHER_ADDR_LEN);
646
647		/* in mbuf header type is just before payload */
648		error = an_read_data(sc, id, 0x44, (caddr_t)&(eh->ether_type),
649				     rx_frame_802_3.an_rx_802_3_payload_len);
650
651		if (error) {
652			m_freem(m);
653			ifp->if_ierrors++;
654			return;
655		}
656		ifp->if_ipackets++;
657
658		/* Receive packet. */
659		m_adj(m, sizeof(struct ether_header));
660#ifdef ANCACHE
661		an_cache_store(sc, eh, m, rx_frame.an_rx_signal_strength);
662#endif
663		ether_input(ifp, eh, m);
664	}
665}
666
667static void
668an_txeof(sc, status)
669	struct an_softc		*sc;
670	int			status;
671{
672	struct ifnet		*ifp;
673	int			id, i;
674
675	ifp = &sc->arpcom.ac_if;
676
677	ifp->if_timer = 0;
678	ifp->if_flags &= ~IFF_OACTIVE;
679
680	id = CSR_READ_2(sc, AN_TX_CMP_FID);
681
682	if (status & AN_EV_TX_EXC) {
683		ifp->if_oerrors++;
684	} else
685		ifp->if_opackets++;
686
687	for (i = 0; i < AN_TX_RING_CNT; i++) {
688		if (id == sc->an_rdata.an_tx_ring[i]) {
689			sc->an_rdata.an_tx_ring[i] = 0;
690			break;
691		}
692	}
693
694	AN_INC(sc->an_rdata.an_tx_cons, AN_TX_RING_CNT);
695
696	return;
697}
698
699/*
700 * We abuse the stats updater to check the current NIC status. This
701 * is important because we don't want to allow transmissions until
702 * the NIC has synchronized to the current cell (either as the master
703 * in an ad-hoc group, or as a station connected to an access point).
704 */
705void
706an_stats_update(xsc)
707	void			*xsc;
708{
709	struct an_softc		*sc;
710	struct ifnet		*ifp;
711
712	sc = xsc;
713	AN_LOCK(sc);
714	ifp = &sc->arpcom.ac_if;
715
716	sc->an_status.an_type = AN_RID_STATUS;
717	sc->an_status.an_len = sizeof(struct an_ltv_status);
718	an_read_record(sc, (struct an_ltv_gen *)&sc->an_status);
719
720	if (sc->an_status.an_opmode & AN_STATUS_OPMODE_IN_SYNC)
721		sc->an_associated = 1;
722	else
723		sc->an_associated = 0;
724
725	/* Don't do this while we're transmitting */
726	if (ifp->if_flags & IFF_OACTIVE) {
727		sc->an_stat_ch = timeout(an_stats_update, sc, hz);
728		AN_UNLOCK(sc);
729		return;
730	}
731
732	sc->an_stats.an_len = sizeof(struct an_ltv_stats);
733	sc->an_stats.an_type = AN_RID_32BITS_CUM;
734	an_read_record(sc, (struct an_ltv_gen *)&sc->an_stats.an_len);
735
736	sc->an_stat_ch = timeout(an_stats_update, sc, hz);
737	AN_UNLOCK(sc);
738
739	return;
740}
741
742void
743an_intr(xsc)
744	void			*xsc;
745{
746	struct an_softc		*sc;
747	struct ifnet		*ifp;
748	u_int16_t		status;
749
750	sc = (struct an_softc*)xsc;
751
752	AN_LOCK(sc);
753
754	if (sc->an_gone) {
755		AN_UNLOCK(sc);
756		return;
757	}
758
759	ifp = &sc->arpcom.ac_if;
760
761	/* Disable interrupts. */
762	CSR_WRITE_2(sc, AN_INT_EN, 0);
763
764	status = CSR_READ_2(sc, AN_EVENT_STAT);
765	CSR_WRITE_2(sc, AN_EVENT_ACK, ~AN_INTRS);
766
767	if (status & AN_EV_AWAKE) {
768		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_AWAKE);
769	}
770
771	if (status & AN_EV_LINKSTAT) {
772		if (CSR_READ_2(sc, AN_LINKSTAT) == AN_LINKSTAT_ASSOCIATED)
773			sc->an_associated = 1;
774		else
775			sc->an_associated = 0;
776		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_LINKSTAT);
777	}
778
779	if (status & AN_EV_RX) {
780		an_rxeof(sc);
781		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX);
782	}
783
784	if (status & AN_EV_TX) {
785		an_txeof(sc, status);
786		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_TX);
787	}
788
789	if (status & AN_EV_TX_EXC) {
790		an_txeof(sc, status);
791		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_TX_EXC);
792	}
793
794	if (status & AN_EV_ALLOC)
795		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_ALLOC);
796
797	/* Re-enable interrupts. */
798	CSR_WRITE_2(sc, AN_INT_EN, AN_INTRS);
799
800	if ((ifp->if_flags & IFF_UP) && (ifp->if_snd.ifq_head != NULL))
801		an_start(ifp);
802
803	AN_UNLOCK(sc);
804
805	return;
806}
807
808static int
809an_cmd(sc, cmd, val)
810	struct an_softc		*sc;
811	int			cmd;
812	int			val;
813{
814	int			i, s = 0;
815
816	CSR_WRITE_2(sc, AN_PARAM0, val);
817	CSR_WRITE_2(sc, AN_PARAM1, 0);
818	CSR_WRITE_2(sc, AN_PARAM2, 0);
819	CSR_WRITE_2(sc, AN_COMMAND, cmd);
820
821	for (i = 0; i < AN_TIMEOUT; i++) {
822		if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_CMD)
823			break;
824		else {
825			if (CSR_READ_2(sc, AN_COMMAND) == cmd)
826				CSR_WRITE_2(sc, AN_COMMAND, cmd);
827		}
828	}
829
830	for (i = 0; i < AN_TIMEOUT; i++) {
831		CSR_READ_2(sc, AN_RESP0);
832		CSR_READ_2(sc, AN_RESP1);
833		CSR_READ_2(sc, AN_RESP2);
834		s = CSR_READ_2(sc, AN_STATUS);
835		if ((s & AN_STAT_CMD_CODE) == (cmd & AN_STAT_CMD_CODE))
836			break;
837	}
838
839	/* Ack the command */
840	CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CMD);
841
842	if (CSR_READ_2(sc, AN_COMMAND) & AN_CMD_BUSY)
843		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CLR_STUCK_BUSY);
844
845	if (i == AN_TIMEOUT)
846		return(ETIMEDOUT);
847
848	return(0);
849}
850
851/*
852 * This reset sequence may look a little strange, but this is the
853 * most reliable method I've found to really kick the NIC in the
854 * head and force it to reboot correctly.
855 */
856static void
857an_reset(sc)
858	struct an_softc		*sc;
859{
860	if (sc->an_gone)
861		return;
862
863	an_cmd(sc, AN_CMD_ENABLE, 0);
864	an_cmd(sc, AN_CMD_FW_RESTART, 0);
865	an_cmd(sc, AN_CMD_NOOP2, 0);
866
867	if (an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0) == ETIMEDOUT)
868		printf("an%d: reset failed\n", sc->an_unit);
869
870	an_cmd(sc, AN_CMD_DISABLE, 0);
871
872	return;
873}
874
875/*
876 * Read an LTV record from the NIC.
877 */
878static int
879an_read_record(sc, ltv)
880	struct an_softc		*sc;
881	struct an_ltv_gen	*ltv;
882{
883	u_int16_t		*ptr;
884	u_int8_t		*ptr2;
885	int			i, len;
886
887	if (ltv->an_len < 4 || ltv->an_type == 0)
888		return(EINVAL);
889
890	/* Tell the NIC to enter record read mode. */
891	if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) {
892		printf("an%d: RID access failed\n", sc->an_unit);
893		return(EIO);
894	}
895
896	/* Seek to the record. */
897	if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) {
898		printf("an%d: seek to record failed\n", sc->an_unit);
899		return(EIO);
900	}
901
902	/*
903	 * Read the length and record type and make sure they
904	 * match what we expect (this verifies that we have enough
905	 * room to hold all of the returned data).
906	 * Length includes type but not length.
907	 */
908	len = CSR_READ_2(sc, AN_DATA1);
909	if (len > (ltv->an_len - 2)) {
910		printf("an%d: record length mismatch -- expected %d, "
911		    "got %d for Rid %x\n", sc->an_unit,
912		    ltv->an_len - 2, len, ltv->an_type);
913		len = ltv->an_len - 2;
914	} else {
915		ltv->an_len = len + 2;
916	}
917
918	/* Now read the data. */
919	len -= 2;	/* skip the type */
920	ptr = &ltv->an_val;
921	for (i = len; i > 1; i -= 2)
922		*ptr++ = CSR_READ_2(sc, AN_DATA1);
923	if (i) {
924		ptr2 = (u_int8_t *)ptr;
925		*ptr2 = CSR_READ_1(sc, AN_DATA1);
926	}
927	if (an_dump)
928		an_dump_record(sc, ltv, "Read");
929
930	return(0);
931}
932
933/*
934 * Same as read, except we inject data instead of reading it.
935 */
936static int
937an_write_record(sc, ltv)
938	struct an_softc		*sc;
939	struct an_ltv_gen	*ltv;
940{
941	u_int16_t		*ptr;
942	u_int8_t		*ptr2;
943	int			i, len;
944
945	if (an_dump)
946		an_dump_record(sc, ltv, "Write");
947
948	if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type))
949		return(EIO);
950
951	if (an_seek(sc, ltv->an_type, 0, AN_BAP1))
952		return(EIO);
953
954	/*
955	 * Length includes type but not length.
956	 */
957	len = ltv->an_len - 2;
958	CSR_WRITE_2(sc, AN_DATA1, len);
959
960	len -= 2;	/* skip the type */
961	ptr = &ltv->an_val;
962	for (i = len; i > 1; i -= 2)
963		CSR_WRITE_2(sc, AN_DATA1, *ptr++);
964	if (i) {
965		ptr2 = (u_int8_t *)ptr;
966		CSR_WRITE_1(sc, AN_DATA0, *ptr2);
967	}
968
969	if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_WRITE, ltv->an_type))
970		return(EIO);
971
972	return(0);
973}
974
975static void
976an_dump_record(sc, ltv, string)
977	struct an_softc		*sc;
978	struct an_ltv_gen	*ltv;
979	char			*string;
980{
981	u_int8_t		*ptr2;
982	int			len;
983	int			i;
984	int			count = 0;
985	char			buf[17], temp;
986
987	len = ltv->an_len - 4;
988	printf("an%d: RID %4x, Length %4d, Mode %s\n",
989		sc->an_unit, ltv->an_type, ltv->an_len - 4, string);
990
991	if (an_dump == 1 || (an_dump == ltv->an_type)) {
992		printf("an%d:\t", sc->an_unit);
993		bzero(buf,sizeof(buf));
994
995		ptr2 = (u_int8_t *)&ltv->an_val;
996		for (i = len; i > 0; i--) {
997			printf("%02x ", *ptr2);
998
999			temp = *ptr2++;
1000			if (temp >= ' ' && temp <= '~')
1001				buf[count] = temp;
1002			else if (temp >= 'A' && temp <= 'Z')
1003				buf[count] = temp;
1004			else
1005				buf[count] = '.';
1006			if (++count == 16) {
1007				count = 0;
1008				printf("%s\n",buf);
1009				printf("an%d:\t", sc->an_unit);
1010				bzero(buf,sizeof(buf));
1011			}
1012		}
1013		for (; count != 16; count++) {
1014			printf("   ");
1015		}
1016		printf(" %s\n",buf);
1017	}
1018}
1019
1020static int
1021an_seek(sc, id, off, chan)
1022	struct an_softc		*sc;
1023	int			id, off, chan;
1024{
1025	int			i;
1026	int			selreg, offreg;
1027
1028	switch (chan) {
1029	case AN_BAP0:
1030		selreg = AN_SEL0;
1031		offreg = AN_OFF0;
1032		break;
1033	case AN_BAP1:
1034		selreg = AN_SEL1;
1035		offreg = AN_OFF1;
1036		break;
1037	default:
1038		printf("an%d: invalid data path: %x\n", sc->an_unit, chan);
1039		return(EIO);
1040	}
1041
1042	CSR_WRITE_2(sc, selreg, id);
1043	CSR_WRITE_2(sc, offreg, off);
1044
1045	for (i = 0; i < AN_TIMEOUT; i++) {
1046		if (!(CSR_READ_2(sc, offreg) & (AN_OFF_BUSY|AN_OFF_ERR)))
1047			break;
1048	}
1049
1050	if (i == AN_TIMEOUT)
1051		return(ETIMEDOUT);
1052
1053	return(0);
1054}
1055
1056static int
1057an_read_data(sc, id, off, buf, len)
1058	struct an_softc		*sc;
1059	int			id, off;
1060	caddr_t			buf;
1061	int			len;
1062{
1063	int			i;
1064	u_int16_t		*ptr;
1065	u_int8_t		*ptr2;
1066
1067	if (off != -1) {
1068		if (an_seek(sc, id, off, AN_BAP1))
1069			return(EIO);
1070	}
1071
1072	ptr = (u_int16_t *)buf;
1073	for (i = len; i > 1; i -= 2)
1074		*ptr++ = CSR_READ_2(sc, AN_DATA1);
1075	if (i) {
1076		ptr2 = (u_int8_t *)ptr;
1077		*ptr2 = CSR_READ_1(sc, AN_DATA1);
1078	}
1079
1080	return(0);
1081}
1082
1083static int
1084an_write_data(sc, id, off, buf, len)
1085	struct an_softc		*sc;
1086	int			id, off;
1087	caddr_t			buf;
1088	int			len;
1089{
1090	int			i;
1091	u_int16_t		*ptr;
1092	u_int8_t		*ptr2;
1093
1094	if (off != -1) {
1095		if (an_seek(sc, id, off, AN_BAP0))
1096			return(EIO);
1097	}
1098
1099	ptr = (u_int16_t *)buf;
1100	for (i = len; i > 1; i -= 2)
1101		CSR_WRITE_2(sc, AN_DATA0, *ptr++);
1102	if (i) {
1103	        ptr2 = (u_int8_t *)ptr;
1104	        CSR_WRITE_1(sc, AN_DATA0, *ptr2);
1105	}
1106
1107	return(0);
1108}
1109
1110/*
1111 * Allocate a region of memory inside the NIC and zero
1112 * it out.
1113 */
1114static int
1115an_alloc_nicmem(sc, len, id)
1116	struct an_softc		*sc;
1117	int			len;
1118	int			*id;
1119{
1120	int			i;
1121
1122	if (an_cmd(sc, AN_CMD_ALLOC_MEM, len)) {
1123		printf("an%d: failed to allocate %d bytes on NIC\n",
1124		    sc->an_unit, len);
1125		return(ENOMEM);
1126	}
1127
1128	for (i = 0; i < AN_TIMEOUT; i++) {
1129		if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_ALLOC)
1130			break;
1131	}
1132
1133	if (i == AN_TIMEOUT)
1134		return(ETIMEDOUT);
1135
1136	CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_ALLOC);
1137	*id = CSR_READ_2(sc, AN_ALLOC_FID);
1138
1139	if (an_seek(sc, *id, 0, AN_BAP0))
1140		return(EIO);
1141
1142	for (i = 0; i < len / 2; i++)
1143		CSR_WRITE_2(sc, AN_DATA0, 0);
1144
1145	return(0);
1146}
1147
1148static void
1149an_setdef(sc, areq)
1150	struct an_softc		*sc;
1151	struct an_req		*areq;
1152{
1153	struct sockaddr_dl	*sdl;
1154	struct ifaddr		*ifa;
1155	struct ifnet		*ifp;
1156	struct an_ltv_genconfig	*cfg;
1157	struct an_ltv_ssidlist	*ssid;
1158	struct an_ltv_aplist	*ap;
1159	struct an_ltv_gen	*sp;
1160
1161	ifp = &sc->arpcom.ac_if;
1162
1163	switch (areq->an_type) {
1164	case AN_RID_GENCONFIG:
1165		cfg = (struct an_ltv_genconfig *)areq;
1166
1167		ifa = ifaddr_byindex(ifp->if_index);
1168		sdl = (struct sockaddr_dl *)ifa->ifa_addr;
1169		bcopy((char *)&cfg->an_macaddr, (char *)&sc->arpcom.ac_enaddr,
1170		    ETHER_ADDR_LEN);
1171		bcopy((char *)&cfg->an_macaddr, LLADDR(sdl), ETHER_ADDR_LEN);
1172
1173		bcopy((char *)cfg, (char *)&sc->an_config,
1174			sizeof(struct an_ltv_genconfig));
1175		break;
1176	case AN_RID_SSIDLIST:
1177		ssid = (struct an_ltv_ssidlist *)areq;
1178		bcopy((char *)ssid, (char *)&sc->an_ssidlist,
1179			sizeof(struct an_ltv_ssidlist));
1180		break;
1181	case AN_RID_APLIST:
1182		ap = (struct an_ltv_aplist *)areq;
1183		bcopy((char *)ap, (char *)&sc->an_aplist,
1184			sizeof(struct an_ltv_aplist));
1185		break;
1186	case AN_RID_TX_SPEED:
1187		sp = (struct an_ltv_gen *)areq;
1188		sc->an_tx_rate = sp->an_val;
1189		break;
1190	case AN_RID_WEP_TEMP:
1191	case AN_RID_WEP_PERM:
1192	case AN_RID_LEAPUSERNAME:
1193	case AN_RID_LEAPPASSWORD:
1194		/* Disable the MAC. */
1195		an_cmd(sc, AN_CMD_DISABLE, 0);
1196
1197		/* Write the key */
1198		an_write_record(sc, (struct an_ltv_gen *)areq);
1199
1200		/* Turn the MAC back on. */
1201		an_cmd(sc, AN_CMD_ENABLE, 0);
1202
1203		break;
1204	case AN_RID_MONITOR_MODE:
1205		cfg = (struct an_ltv_genconfig *)areq;
1206		bpfdetach(ifp);
1207		if (ng_ether_detach_p != NULL)
1208			(*ng_ether_detach_p) (ifp);
1209		sc->an_monitor = cfg->an_len;
1210
1211		if (sc->an_monitor & AN_MONITOR) {
1212			if (sc->an_monitor & AN_MONITOR_AIRONET_HEADER) {
1213				bpfattach(ifp, DLT_AIRONET_HEADER,
1214					sizeof(struct ether_header));
1215			} else {
1216				bpfattach(ifp, DLT_IEEE802_11,
1217					sizeof(struct ether_header));
1218			}
1219		} else {
1220			bpfattach(ifp, DLT_EN10MB,
1221				  sizeof(struct ether_header));
1222			if (ng_ether_attach_p != NULL)
1223				(*ng_ether_attach_p) (ifp);
1224		}
1225		break;
1226	default:
1227		printf("an%d: unknown RID: %x\n", sc->an_unit, areq->an_type);
1228		return;
1229		break;
1230	}
1231
1232
1233	/* Reinitialize the card. */
1234	if (ifp->if_flags)
1235		an_init(sc);
1236
1237	return;
1238}
1239
1240/*
1241 * Derived from Linux driver to enable promiscious mode.
1242 */
1243
1244static void
1245an_promisc(sc, promisc)
1246	struct an_softc		*sc;
1247	int			promisc;
1248{
1249	if (sc->an_was_monitor)
1250		an_reset(sc);
1251	if (sc->an_monitor || sc->an_was_monitor)
1252		an_init(sc);
1253
1254	sc->an_was_monitor = sc->an_monitor;
1255	an_cmd(sc, AN_CMD_SET_MODE, promisc ? 0xffff : 0);
1256
1257	return;
1258}
1259
1260static int
1261an_ioctl(ifp, command, data)
1262	struct ifnet		*ifp;
1263	u_long			command;
1264	caddr_t			data;
1265{
1266	int			error = 0;
1267	int			len;
1268	int			i;
1269	struct an_softc		*sc;
1270	struct ifreq		*ifr;
1271	struct proc		*p = curproc;
1272	struct ieee80211req	*ireq;
1273	u_int8_t		tmpstr[IEEE80211_NWID_LEN*2];
1274	u_int8_t		*tmpptr;
1275	struct an_ltv_genconfig	*config;
1276	struct an_ltv_key	*key;
1277	struct an_ltv_status	*status;
1278	struct an_ltv_ssidlist	*ssids;
1279	int			mode;
1280	struct aironet_ioctl	l_ioctl;
1281
1282	sc = ifp->if_softc;
1283	AN_LOCK(sc);
1284	ifr = (struct ifreq *)data;
1285	ireq = (struct ieee80211req *)data;
1286
1287	config = (struct an_ltv_genconfig *)&sc->areq;
1288	key = (struct an_ltv_key *)&sc->areq;
1289	status = (struct an_ltv_status *)&sc->areq;
1290	ssids = (struct an_ltv_ssidlist *)&sc->areq;
1291
1292	if (sc->an_gone) {
1293		error = ENODEV;
1294		goto out;
1295	}
1296
1297	switch (command) {
1298	case SIOCSIFADDR:
1299	case SIOCGIFADDR:
1300	case SIOCSIFMTU:
1301		error = ether_ioctl(ifp, command, data);
1302		break;
1303	case SIOCSIFFLAGS:
1304		if (ifp->if_flags & IFF_UP) {
1305			if (ifp->if_flags & IFF_RUNNING &&
1306			    ifp->if_flags & IFF_PROMISC &&
1307			    !(sc->an_if_flags & IFF_PROMISC)) {
1308				an_promisc(sc, 1);
1309			} else if (ifp->if_flags & IFF_RUNNING &&
1310			    !(ifp->if_flags & IFF_PROMISC) &&
1311			    sc->an_if_flags & IFF_PROMISC) {
1312				an_promisc(sc, 0);
1313			} else
1314				an_init(sc);
1315		} else {
1316			if (ifp->if_flags & IFF_RUNNING)
1317				an_stop(sc);
1318		}
1319		sc->an_if_flags = ifp->if_flags;
1320		error = 0;
1321		break;
1322	case SIOCSIFMEDIA:
1323	case SIOCGIFMEDIA:
1324		error = ifmedia_ioctl(ifp, ifr, &sc->an_ifmedia, command);
1325		break;
1326	case SIOCADDMULTI:
1327	case SIOCDELMULTI:
1328		/* The Aironet has no multicast filter. */
1329		error = 0;
1330		break;
1331	case SIOCGAIRONET:
1332		error = copyin(ifr->ifr_data, &sc->areq, sizeof(sc->areq));
1333		if (error != 0)
1334			break;
1335#ifdef ANCACHE
1336		if (sc->areq.an_type == AN_RID_ZERO_CACHE) {
1337			sc->an_sigitems = sc->an_nextitem = 0;
1338			break;
1339		} else if (sc->areq.an_type == AN_RID_READ_CACHE) {
1340			char *pt = (char *)&sc->areq.an_val;
1341			bcopy((char *)&sc->an_sigitems, (char *)pt,
1342			    sizeof(int));
1343			pt += sizeof(int);
1344			sc->areq.an_len = sizeof(int) / 2;
1345			bcopy((char *)&sc->an_sigcache, (char *)pt,
1346			    sizeof(struct an_sigcache) * sc->an_sigitems);
1347			sc->areq.an_len += ((sizeof(struct an_sigcache) *
1348			    sc->an_sigitems) / 2) + 1;
1349		} else
1350#endif
1351		if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) {
1352			error = EINVAL;
1353			break;
1354		}
1355		error = copyout(&sc->areq, ifr->ifr_data, sizeof(sc->areq));
1356		break;
1357	case SIOCSAIRONET:
1358		if ((error = suser(p)))
1359			goto out;
1360		error = copyin(ifr->ifr_data, &sc->areq, sizeof(sc->areq));
1361		if (error != 0)
1362			break;
1363		an_setdef(sc, &sc->areq);
1364		break;
1365	case SIOCGPRIVATE_0:              /* used by Cisco client utility */
1366		copyin(ifr->ifr_data, &l_ioctl, sizeof(l_ioctl));
1367		mode = l_ioctl.command;
1368
1369		if (mode >= AIROGCAP && mode <= AIROGSTATSD32) {
1370			error = readrids(ifp, &l_ioctl);
1371		}else if (mode >= AIROPCAP && mode <= AIROPLEAPUSR) {
1372			error = writerids(ifp, &l_ioctl);
1373		}else if (mode >= AIROFLSHRST && mode <= AIRORESTART) {
1374			error = flashcard(ifp, &l_ioctl);
1375		}else{
1376			error =-1;
1377		}
1378
1379		/* copy out the updated command info */
1380		copyout(&l_ioctl, ifr->ifr_data, sizeof(l_ioctl));
1381
1382		break;
1383	case SIOCGPRIVATE_1:              /* used by Cisco client utility */
1384		copyin(ifr->ifr_data, &l_ioctl, sizeof(l_ioctl));
1385		l_ioctl.command = 0;
1386		error = AIROMAGIC;
1387		copyout(&error, l_ioctl.data, sizeof(error));
1388	        error = 0;
1389		break;
1390	case SIOCG80211:
1391		sc->areq.an_len = sizeof(sc->areq);
1392		/* was that a good idea DJA we are doing a short-cut */
1393		switch (ireq->i_type) {
1394		case IEEE80211_IOC_SSID:
1395			if (ireq->i_val == -1) {
1396				sc->areq.an_type = AN_RID_STATUS;
1397				if (an_read_record(sc,
1398				    (struct an_ltv_gen *)&sc->areq)) {
1399					error = EINVAL;
1400					break;
1401				}
1402				len = status->an_ssidlen;
1403				tmpptr = status->an_ssid;
1404			} else if (ireq->i_val >= 0) {
1405				sc->areq.an_type = AN_RID_SSIDLIST;
1406				if (an_read_record(sc,
1407				    (struct an_ltv_gen *)&sc->areq)) {
1408					error = EINVAL;
1409					break;
1410				}
1411				if (ireq->i_val == 0) {
1412					len = ssids->an_ssid1_len;
1413					tmpptr = ssids->an_ssid1;
1414				} else if (ireq->i_val == 1) {
1415					len = ssids->an_ssid2_len;
1416					tmpptr = ssids->an_ssid2;
1417				} else if (ireq->i_val == 2) {
1418					len = ssids->an_ssid3_len;
1419					tmpptr = ssids->an_ssid3;
1420				} else {
1421					error = EINVAL;
1422					break;
1423				}
1424			} else {
1425				error = EINVAL;
1426				break;
1427			}
1428			if (len > IEEE80211_NWID_LEN) {
1429				error = EINVAL;
1430				break;
1431			}
1432			ireq->i_len = len;
1433			bzero(tmpstr, IEEE80211_NWID_LEN);
1434			bcopy(tmpptr, tmpstr, len);
1435			error = copyout(tmpstr, ireq->i_data,
1436			    IEEE80211_NWID_LEN);
1437			break;
1438		case IEEE80211_IOC_NUMSSIDS:
1439			ireq->i_val = 3;
1440			break;
1441		case IEEE80211_IOC_WEP:
1442			sc->areq.an_type = AN_RID_ACTUALCFG;
1443			if (an_read_record(sc,
1444			    (struct an_ltv_gen *)&sc->areq)) {
1445				error = EINVAL;
1446				break;
1447			}
1448			if (config->an_authtype & AN_AUTHTYPE_PRIVACY_IN_USE) {
1449				if (config->an_authtype &
1450				    AN_AUTHTYPE_ALLOW_UNENCRYPTED)
1451					ireq->i_val = IEEE80211_WEP_MIXED;
1452				else
1453					ireq->i_val = IEEE80211_WEP_ON;
1454			} else {
1455				ireq->i_val = IEEE80211_WEP_OFF;
1456			}
1457			break;
1458		case IEEE80211_IOC_WEPKEY:
1459			/*
1460			 * XXX: I'm not entierly convinced this is
1461			 * correct, but it's what is implemented in
1462			 * ancontrol so it will have to do until we get
1463			 * access to actual Cisco code.
1464			 */
1465			if (ireq->i_val < 0 || ireq->i_val > 8) {
1466				error = EINVAL;
1467				break;
1468			}
1469			len = 0;
1470			if (ireq->i_val < 5) {
1471				sc->areq.an_type = AN_RID_WEP_TEMP;
1472				for (i = 0; i < 5; i++) {
1473					if (an_read_record(sc,
1474					    (struct an_ltv_gen *)&sc->areq)) {
1475						error = EINVAL;
1476						break;
1477					}
1478					if (key->kindex == 0xffff)
1479						break;
1480					if (key->kindex == ireq->i_val)
1481						len = key->klen;
1482					/* Required to get next entry */
1483					sc->areq.an_type = AN_RID_WEP_PERM;
1484				}
1485				if (error != 0)
1486					break;
1487			}
1488			/* We aren't allowed to read the value of the
1489			 * key from the card so we just output zeros
1490			 * like we would if we could read the card, but
1491			 * denied the user access.
1492			 */
1493			bzero(tmpstr, len);
1494			ireq->i_len = len;
1495			error = copyout(tmpstr, ireq->i_data, len);
1496			break;
1497		case IEEE80211_IOC_NUMWEPKEYS:
1498			ireq->i_val = 9; /* include home key */
1499			break;
1500		case IEEE80211_IOC_WEPTXKEY:
1501			/*
1502			 * For some strange reason, you have to read all
1503			 * keys before you can read the txkey.
1504			 */
1505			sc->areq.an_type = AN_RID_WEP_TEMP;
1506			for (i = 0; i < 5; i++) {
1507				if (an_read_record(sc,
1508				    (struct an_ltv_gen *) &sc->areq)) {
1509					error = EINVAL;
1510					break;
1511				}
1512				if (key->kindex == 0xffff)
1513					break;
1514				/* Required to get next entry */
1515				sc->areq.an_type = AN_RID_WEP_PERM;
1516			}
1517			if (error != 0)
1518				break;
1519
1520			sc->areq.an_type = AN_RID_WEP_PERM;
1521			key->kindex = 0xffff;
1522			if (an_read_record(sc,
1523			    (struct an_ltv_gen *)&sc->areq)) {
1524				error = EINVAL;
1525				break;
1526			}
1527			ireq->i_val = key->mac[0];
1528			/*
1529			 * Check for home mode.  Map home mode into
1530			 * 5th key since that is how it is stored on
1531			 * the card
1532			 */
1533			sc->areq.an_len  = sizeof(struct an_ltv_genconfig);
1534			sc->areq.an_type = AN_RID_GENCONFIG;
1535			if (an_read_record(sc,
1536			    (struct an_ltv_gen *)&sc->areq)) {
1537				error = EINVAL;
1538				break;
1539			}
1540			if (config->an_home_product & AN_HOME_NETWORK)
1541				ireq->i_val = 4;
1542			break;
1543		case IEEE80211_IOC_AUTHMODE:
1544			sc->areq.an_type = AN_RID_ACTUALCFG;
1545			if (an_read_record(sc,
1546			    (struct an_ltv_gen *)&sc->areq)) {
1547				error = EINVAL;
1548				break;
1549			}
1550			if ((config->an_authtype & AN_AUTHTYPE_MASK) ==
1551			    AN_AUTHTYPE_NONE) {
1552			    ireq->i_val = IEEE80211_AUTH_NONE;
1553			} else if ((config->an_authtype & AN_AUTHTYPE_MASK) ==
1554			    AN_AUTHTYPE_OPEN) {
1555			    ireq->i_val = IEEE80211_AUTH_OPEN;
1556			} else if ((config->an_authtype & AN_AUTHTYPE_MASK) ==
1557			    AN_AUTHTYPE_SHAREDKEY) {
1558			    ireq->i_val = IEEE80211_AUTH_SHARED;
1559			} else
1560				error = EINVAL;
1561			break;
1562		case IEEE80211_IOC_STATIONNAME:
1563			sc->areq.an_type = AN_RID_ACTUALCFG;
1564			if (an_read_record(sc,
1565			    (struct an_ltv_gen *)&sc->areq)) {
1566				error = EINVAL;
1567				break;
1568			}
1569			ireq->i_len = sizeof(config->an_nodename);
1570			tmpptr = config->an_nodename;
1571			bzero(tmpstr, IEEE80211_NWID_LEN);
1572			bcopy(tmpptr, tmpstr, ireq->i_len);
1573			error = copyout(tmpstr, ireq->i_data,
1574			    IEEE80211_NWID_LEN);
1575			break;
1576		case IEEE80211_IOC_CHANNEL:
1577			sc->areq.an_type = AN_RID_STATUS;
1578			if (an_read_record(sc,
1579			    (struct an_ltv_gen *)&sc->areq)) {
1580				error = EINVAL;
1581				break;
1582			}
1583			ireq->i_val = status->an_cur_channel;
1584			break;
1585		case IEEE80211_IOC_POWERSAVE:
1586			sc->areq.an_type = AN_RID_ACTUALCFG;
1587			if (an_read_record(sc,
1588			    (struct an_ltv_gen *)&sc->areq)) {
1589				error = EINVAL;
1590				break;
1591			}
1592			if (config->an_psave_mode == AN_PSAVE_NONE) {
1593				ireq->i_val = IEEE80211_POWERSAVE_OFF;
1594			} else if (config->an_psave_mode == AN_PSAVE_CAM) {
1595				ireq->i_val = IEEE80211_POWERSAVE_CAM;
1596			} else if (config->an_psave_mode == AN_PSAVE_PSP) {
1597				ireq->i_val = IEEE80211_POWERSAVE_PSP;
1598			} else if (config->an_psave_mode == AN_PSAVE_PSP_CAM) {
1599				ireq->i_val = IEEE80211_POWERSAVE_PSP_CAM;
1600			} else
1601				error = EINVAL;
1602			break;
1603		case IEEE80211_IOC_POWERSAVESLEEP:
1604			sc->areq.an_type = AN_RID_ACTUALCFG;
1605			if (an_read_record(sc,
1606			    (struct an_ltv_gen *)&sc->areq)) {
1607				error = EINVAL;
1608				break;
1609			}
1610			ireq->i_val = config->an_listen_interval;
1611			break;
1612		}
1613		break;
1614	case SIOCS80211:
1615		if ((error = suser(p)))
1616			goto out;
1617		sc->areq.an_len = sizeof(sc->areq);
1618		/*
1619		 * We need a config structure for everything but the WEP
1620		 * key management and SSIDs so we get it now so avoid
1621		 * duplicating this code every time.
1622		 */
1623		if (ireq->i_type != IEEE80211_IOC_SSID &&
1624		    ireq->i_type != IEEE80211_IOC_WEPKEY &&
1625		    ireq->i_type != IEEE80211_IOC_WEPTXKEY) {
1626			sc->areq.an_type = AN_RID_GENCONFIG;
1627			if (an_read_record(sc,
1628			    (struct an_ltv_gen *)&sc->areq)) {
1629				error = EINVAL;
1630				break;
1631			}
1632		}
1633		switch (ireq->i_type) {
1634		case IEEE80211_IOC_SSID:
1635			sc->areq.an_type = AN_RID_SSIDLIST;
1636			if (an_read_record(sc,
1637			    (struct an_ltv_gen *)&sc->areq)) {
1638				error = EINVAL;
1639				break;
1640			}
1641			if (ireq->i_len > IEEE80211_NWID_LEN) {
1642				error = EINVAL;
1643				break;
1644			}
1645			switch (ireq->i_val) {
1646			case 0:
1647				error = copyin(ireq->i_data,
1648				    ssids->an_ssid1, ireq->i_len);
1649				ssids->an_ssid1_len = ireq->i_len;
1650				break;
1651			case 1:
1652				error = copyin(ireq->i_data,
1653				    ssids->an_ssid2, ireq->i_len);
1654				ssids->an_ssid2_len = ireq->i_len;
1655				break;
1656			case 2:
1657				error = copyin(ireq->i_data,
1658				    ssids->an_ssid3, ireq->i_len);
1659				ssids->an_ssid3_len = ireq->i_len;
1660				break;
1661			default:
1662				error = EINVAL;
1663				break;
1664			}
1665			break;
1666		case IEEE80211_IOC_WEP:
1667			switch (ireq->i_val) {
1668			case IEEE80211_WEP_OFF:
1669				config->an_authtype &=
1670				    ~(AN_AUTHTYPE_PRIVACY_IN_USE |
1671				    AN_AUTHTYPE_ALLOW_UNENCRYPTED);
1672				break;
1673			case IEEE80211_WEP_ON:
1674				config->an_authtype |=
1675				    AN_AUTHTYPE_PRIVACY_IN_USE;
1676				config->an_authtype &=
1677				    ~AN_AUTHTYPE_ALLOW_UNENCRYPTED;
1678				break;
1679			case IEEE80211_WEP_MIXED:
1680				config->an_authtype |=
1681				    AN_AUTHTYPE_PRIVACY_IN_USE |
1682				    AN_AUTHTYPE_ALLOW_UNENCRYPTED;
1683				break;
1684			default:
1685				error = EINVAL;
1686				break;
1687			}
1688			break;
1689		case IEEE80211_IOC_WEPKEY:
1690			if (ireq->i_val < 0 || ireq->i_val > 7 ||
1691			    ireq->i_len > 13) {
1692				error = EINVAL;
1693				break;
1694			}
1695			error = copyin(ireq->i_data, tmpstr, 13);
1696			if (error != 0)
1697				break;
1698			bzero(&sc->areq, sizeof(struct an_ltv_key));
1699			sc->areq.an_len = sizeof(struct an_ltv_key);
1700			key->mac[0] = 1;	/* The others are 0. */
1701			key->kindex = ireq->i_val % 4;
1702			if (ireq->i_val < 4)
1703				sc->areq.an_type = AN_RID_WEP_TEMP;
1704			else
1705				sc->areq.an_type = AN_RID_WEP_PERM;
1706			key->klen = ireq->i_len;
1707			bcopy(tmpstr, key->key, key->klen);
1708			break;
1709		case IEEE80211_IOC_WEPTXKEY:
1710			/*
1711			 * Map the 5th key into the home mode
1712			 * since that is how it is stored on
1713			 * the card
1714			 */
1715			if (ireq->i_val < 0 || ireq->i_val > 4) {
1716				error = EINVAL;
1717				break;
1718			}
1719			sc->areq.an_len  = sizeof(struct an_ltv_genconfig);
1720			sc->areq.an_type = AN_RID_ACTUALCFG;
1721			if (an_read_record(sc,
1722	       		    (struct an_ltv_gen *)&sc->areq)) {
1723	       			error = EINVAL;
1724				break;
1725			}
1726			if (ireq->i_val ==  4) {
1727				config->an_home_product |= AN_HOME_NETWORK;
1728				ireq->i_val = 0;
1729			} else {
1730				config->an_home_product &= ~AN_HOME_NETWORK;
1731			}
1732
1733			sc->an_config.an_home_product
1734				= config->an_home_product;
1735			an_write_record(sc, (struct an_ltv_gen *)&sc->areq);
1736
1737			bzero(&sc->areq, sizeof(struct an_ltv_key));
1738			sc->areq.an_len = sizeof(struct an_ltv_key);
1739			sc->areq.an_type = AN_RID_WEP_PERM;
1740			key->kindex = 0xffff;
1741			key->mac[0] = ireq->i_val;
1742			break;
1743		case IEEE80211_IOC_AUTHMODE:
1744			switch (ireq->i_val) {
1745			case IEEE80211_AUTH_NONE:
1746				config->an_authtype = AN_AUTHTYPE_NONE |
1747				    (config->an_authtype & ~AN_AUTHTYPE_MASK);
1748				break;
1749			case IEEE80211_AUTH_OPEN:
1750				config->an_authtype = AN_AUTHTYPE_OPEN |
1751				    (config->an_authtype & ~AN_AUTHTYPE_MASK);
1752				break;
1753			case IEEE80211_AUTH_SHARED:
1754				config->an_authtype = AN_AUTHTYPE_SHAREDKEY |
1755				    (config->an_authtype & ~AN_AUTHTYPE_MASK);
1756				break;
1757			default:
1758				error = EINVAL;
1759			}
1760			break;
1761		case IEEE80211_IOC_STATIONNAME:
1762			if (ireq->i_len > 16) {
1763				error = EINVAL;
1764				break;
1765			}
1766			bzero(config->an_nodename, 16);
1767			error = copyin(ireq->i_data,
1768			    config->an_nodename, ireq->i_len);
1769			break;
1770		case IEEE80211_IOC_CHANNEL:
1771			/*
1772			 * The actual range is 1-14, but if you set it
1773			 * to 0 you get the default so we let that work
1774			 * too.
1775			 */
1776			if (ireq->i_val < 0 || ireq->i_val >14) {
1777				error = EINVAL;
1778				break;
1779			}
1780			config->an_ds_channel = ireq->i_val;
1781			break;
1782		case IEEE80211_IOC_POWERSAVE:
1783			switch (ireq->i_val) {
1784			case IEEE80211_POWERSAVE_OFF:
1785				config->an_psave_mode = AN_PSAVE_NONE;
1786				break;
1787			case IEEE80211_POWERSAVE_CAM:
1788				config->an_psave_mode = AN_PSAVE_CAM;
1789				break;
1790			case IEEE80211_POWERSAVE_PSP:
1791				config->an_psave_mode = AN_PSAVE_PSP;
1792				break;
1793			case IEEE80211_POWERSAVE_PSP_CAM:
1794				config->an_psave_mode = AN_PSAVE_PSP_CAM;
1795				break;
1796			default:
1797				error = EINVAL;
1798				break;
1799			}
1800			break;
1801		case IEEE80211_IOC_POWERSAVESLEEP:
1802			config->an_listen_interval = ireq->i_val;
1803			break;
1804		}
1805
1806		if (!error)
1807			an_setdef(sc, &sc->areq);
1808		break;
1809	default:
1810		error = EINVAL;
1811		break;
1812	}
1813out:
1814	AN_UNLOCK(sc);
1815
1816	return(error != 0);
1817}
1818
1819static int
1820an_init_tx_ring(sc)
1821	struct an_softc		*sc;
1822{
1823	int			i;
1824	int			id;
1825
1826	if (sc->an_gone)
1827		return (0);
1828
1829	for (i = 0; i < AN_TX_RING_CNT; i++) {
1830		if (an_alloc_nicmem(sc, 1518 +
1831		    0x44, &id))
1832			return(ENOMEM);
1833		sc->an_rdata.an_tx_fids[i] = id;
1834		sc->an_rdata.an_tx_ring[i] = 0;
1835	}
1836
1837	sc->an_rdata.an_tx_prod = 0;
1838	sc->an_rdata.an_tx_cons = 0;
1839
1840	return(0);
1841}
1842
1843static void
1844an_init(xsc)
1845	void			*xsc;
1846{
1847	struct an_softc		*sc = xsc;
1848	struct ifnet		*ifp = &sc->arpcom.ac_if;
1849
1850	AN_LOCK(sc);
1851
1852	if (sc->an_gone) {
1853		AN_UNLOCK(sc);
1854		return;
1855	}
1856
1857	if (ifp->if_flags & IFF_RUNNING)
1858		an_stop(sc);
1859
1860	sc->an_associated = 0;
1861
1862	/* Allocate the TX buffers */
1863	if (an_init_tx_ring(sc)) {
1864		an_reset(sc);
1865		if (an_init_tx_ring(sc)) {
1866			printf("an%d: tx buffer allocation "
1867			    "failed\n", sc->an_unit);
1868			AN_UNLOCK(sc);
1869			return;
1870		}
1871	}
1872
1873	/* Set our MAC address. */
1874	bcopy((char *)&sc->arpcom.ac_enaddr,
1875	    (char *)&sc->an_config.an_macaddr, ETHER_ADDR_LEN);
1876
1877	if (ifp->if_flags & IFF_BROADCAST)
1878		sc->an_config.an_rxmode = AN_RXMODE_BC_ADDR;
1879	else
1880		sc->an_config.an_rxmode = AN_RXMODE_ADDR;
1881
1882	if (ifp->if_flags & IFF_MULTICAST)
1883		sc->an_config.an_rxmode = AN_RXMODE_BC_MC_ADDR;
1884
1885	if (ifp->if_flags & IFF_PROMISC) {
1886		if (sc->an_monitor & AN_MONITOR) {
1887			if (sc->an_monitor & AN_MONITOR_ANY_BSS) {
1888				sc->an_config.an_rxmode |=
1889				    AN_RXMODE_80211_MONITOR_ANYBSS |
1890				    AN_RXMODE_NO_8023_HEADER;
1891			} else {
1892				sc->an_config.an_rxmode |=
1893				    AN_RXMODE_80211_MONITOR_CURBSS |
1894				    AN_RXMODE_NO_8023_HEADER;
1895			}
1896		}
1897	}
1898
1899	/* Set the ssid list */
1900	sc->an_ssidlist.an_type = AN_RID_SSIDLIST;
1901	sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist);
1902	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) {
1903		printf("an%d: failed to set ssid list\n", sc->an_unit);
1904		AN_UNLOCK(sc);
1905		return;
1906	}
1907
1908	/* Set the AP list */
1909	sc->an_aplist.an_type = AN_RID_APLIST;
1910	sc->an_aplist.an_len = sizeof(struct an_ltv_aplist);
1911	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) {
1912		printf("an%d: failed to set AP list\n", sc->an_unit);
1913		AN_UNLOCK(sc);
1914		return;
1915	}
1916
1917	/* Set the configuration in the NIC */
1918	sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
1919	sc->an_config.an_type = AN_RID_GENCONFIG;
1920	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_config)) {
1921		printf("an%d: failed to set configuration\n", sc->an_unit);
1922		AN_UNLOCK(sc);
1923		return;
1924	}
1925
1926	/* Enable the MAC */
1927	if (an_cmd(sc, AN_CMD_ENABLE, 0)) {
1928		printf("an%d: failed to enable MAC\n", sc->an_unit);
1929		AN_UNLOCK(sc);
1930		return;
1931	}
1932
1933	if (ifp->if_flags & IFF_PROMISC)
1934		an_cmd(sc, AN_CMD_SET_MODE, 0xffff);
1935
1936	/* enable interrupts */
1937	CSR_WRITE_2(sc, AN_INT_EN, AN_INTRS);
1938
1939	ifp->if_flags |= IFF_RUNNING;
1940	ifp->if_flags &= ~IFF_OACTIVE;
1941
1942	sc->an_stat_ch = timeout(an_stats_update, sc, hz);
1943	AN_UNLOCK(sc);
1944
1945	return;
1946}
1947
1948static void
1949an_start(ifp)
1950	struct ifnet		*ifp;
1951{
1952	struct an_softc		*sc;
1953	struct mbuf		*m0 = NULL;
1954	struct an_txframe_802_3	tx_frame_802_3;
1955	struct ether_header	*eh;
1956	int			id;
1957	int			idx;
1958	unsigned char           txcontrol;
1959
1960	sc = ifp->if_softc;
1961
1962	if (sc->an_gone)
1963		return;
1964
1965	if (ifp->if_flags & IFF_OACTIVE)
1966		return;
1967
1968	if (!sc->an_associated)
1969		return;
1970
1971	if (sc->an_monitor && (ifp->if_flags & IFF_PROMISC)) {
1972		for (;;) {
1973			IF_DEQUEUE(&ifp->if_snd, m0);
1974			if (m0 == NULL)
1975				break;
1976		}
1977		return;
1978	}
1979
1980	idx = sc->an_rdata.an_tx_prod;
1981	bzero((char *)&tx_frame_802_3, sizeof(tx_frame_802_3));
1982
1983	while (sc->an_rdata.an_tx_ring[idx] == 0) {
1984		IF_DEQUEUE(&ifp->if_snd, m0);
1985		if (m0 == NULL)
1986			break;
1987
1988		id = sc->an_rdata.an_tx_fids[idx];
1989		eh = mtod(m0, struct ether_header *);
1990
1991		bcopy((char *)&eh->ether_dhost,
1992		    (char *)&tx_frame_802_3.an_tx_dst_addr, ETHER_ADDR_LEN);
1993		bcopy((char *)&eh->ether_shost,
1994		    (char *)&tx_frame_802_3.an_tx_src_addr, ETHER_ADDR_LEN);
1995
1996		tx_frame_802_3.an_tx_802_3_payload_len =
1997		  m0->m_pkthdr.len - 12;  /* minus src/dest mac & type */
1998
1999                m_copydata(m0, sizeof(struct ether_header) - 2 ,
2000                    tx_frame_802_3.an_tx_802_3_payload_len,
2001                    (caddr_t)&sc->an_txbuf);
2002
2003		txcontrol = AN_TXCTL_8023;
2004		/* write the txcontrol only */
2005		an_write_data(sc, id, 0x08, (caddr_t)&txcontrol,
2006			      sizeof(txcontrol));
2007
2008		/* 802_3 header */
2009		an_write_data(sc, id, 0x34, (caddr_t)&tx_frame_802_3,
2010			      sizeof(struct an_txframe_802_3));
2011
2012		/* in mbuf header type is just before payload */
2013		an_write_data(sc, id, 0x44, (caddr_t)&sc->an_txbuf,
2014			    tx_frame_802_3.an_tx_802_3_payload_len);
2015
2016		/*
2017		 * If there's a BPF listner, bounce a copy of
2018		 * this frame to him.
2019		 */
2020		if (ifp->if_bpf)
2021			bpf_mtap(ifp, m0);
2022
2023		m_freem(m0);
2024		m0 = NULL;
2025
2026		sc->an_rdata.an_tx_ring[idx] = id;
2027		if (an_cmd(sc, AN_CMD_TX, id))
2028			printf("an%d: xmit failed\n", sc->an_unit);
2029
2030		AN_INC(idx, AN_TX_RING_CNT);
2031	}
2032
2033	if (m0 != NULL)
2034		ifp->if_flags |= IFF_OACTIVE;
2035
2036	sc->an_rdata.an_tx_prod = idx;
2037
2038	/*
2039	 * Set a timeout in case the chip goes out to lunch.
2040	 */
2041	ifp->if_timer = 5;
2042
2043	return;
2044}
2045
2046void
2047an_stop(sc)
2048	struct an_softc		*sc;
2049{
2050	struct ifnet		*ifp;
2051	int			i;
2052
2053	AN_LOCK(sc);
2054
2055	if (sc->an_gone) {
2056		AN_UNLOCK(sc);
2057		return;
2058	}
2059
2060	ifp = &sc->arpcom.ac_if;
2061
2062	an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0);
2063	CSR_WRITE_2(sc, AN_INT_EN, 0);
2064	an_cmd(sc, AN_CMD_DISABLE, 0);
2065
2066	for (i = 0; i < AN_TX_RING_CNT; i++)
2067		an_cmd(sc, AN_CMD_DEALLOC_MEM, sc->an_rdata.an_tx_fids[i]);
2068
2069	untimeout(an_stats_update, sc, sc->an_stat_ch);
2070
2071	ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
2072
2073	AN_UNLOCK(sc);
2074
2075	return;
2076}
2077
2078static void
2079an_watchdog(ifp)
2080	struct ifnet		*ifp;
2081{
2082	struct an_softc		*sc;
2083
2084	sc = ifp->if_softc;
2085	AN_LOCK(sc);
2086
2087	if (sc->an_gone) {
2088		AN_UNLOCK(sc);
2089		return;
2090	}
2091
2092	printf("an%d: device timeout\n", sc->an_unit);
2093
2094	an_reset(sc);
2095	an_init(sc);
2096
2097	ifp->if_oerrors++;
2098	AN_UNLOCK(sc);
2099
2100	return;
2101}
2102
2103void
2104an_shutdown(dev)
2105	device_t		dev;
2106{
2107	struct an_softc		*sc;
2108
2109	sc = device_get_softc(dev);
2110	an_stop(sc);
2111
2112	return;
2113}
2114
2115#ifdef ANCACHE
2116/* Aironet signal strength cache code.
2117 * store signal/noise/quality on per MAC src basis in
2118 * a small fixed cache.  The cache wraps if > MAX slots
2119 * used.  The cache may be zeroed out to start over.
2120 * Two simple filters exist to reduce computation:
2121 * 1. ip only (literally 0x800, ETHERTYPE_IP) which may be used
2122 * to ignore some packets.  It defaults to ip only.
2123 * it could be used to focus on broadcast, non-IP 802.11 beacons.
2124 * 2. multicast/broadcast only.  This may be used to
2125 * ignore unicast packets and only cache signal strength
2126 * for multicast/broadcast packets (beacons); e.g., Mobile-IP
2127 * beacons and not unicast traffic.
2128 *
2129 * The cache stores (MAC src(index), IP src (major clue), signal,
2130 *	quality, noise)
2131 *
2132 * No apologies for storing IP src here.  It's easy and saves much
2133 * trouble elsewhere.  The cache is assumed to be INET dependent,
2134 * although it need not be.
2135 *
2136 * Note: the Aironet only has a single byte of signal strength value
2137 * in the rx frame header, and it's not scaled to anything sensible.
2138 * This is kind of lame, but it's all we've got.
2139 */
2140
2141#ifdef documentation
2142
2143int an_sigitems;                                /* number of cached entries */
2144struct an_sigcache an_sigcache[MAXANCACHE];  /*  array of cache entries */
2145int an_nextitem;                                /*  index/# of entries */
2146
2147
2148#endif
2149
2150/* control variables for cache filtering.  Basic idea is
2151 * to reduce cost (e.g., to only Mobile-IP agent beacons
2152 * which are broadcast or multicast).  Still you might
2153 * want to measure signal strength anth unicast ping packets
2154 * on a pt. to pt. ant. setup.
2155 */
2156/* set true if you want to limit cache items to broadcast/mcast
2157 * only packets (not unicast).  Useful for mobile-ip beacons which
2158 * are broadcast/multicast at network layer.  Default is all packets
2159 * so ping/unicast anll work say anth pt. to pt. antennae setup.
2160 */
2161static int an_cache_mcastonly = 0;
2162SYSCTL_INT(_machdep, OID_AUTO, an_cache_mcastonly, CTLFLAG_RW,
2163	&an_cache_mcastonly, 0, "");
2164
2165/* set true if you want to limit cache items to IP packets only
2166*/
2167static int an_cache_iponly = 1;
2168SYSCTL_INT(_machdep, OID_AUTO, an_cache_iponly, CTLFLAG_RW,
2169	&an_cache_iponly, 0, "");
2170
2171/*
2172 * an_cache_store, per rx packet store signal
2173 * strength in MAC (src) indexed cache.
2174 */
2175static void
2176an_cache_store (sc, eh, m, rx_quality)
2177	struct an_softc *sc;
2178	struct ether_header *eh;
2179	struct mbuf *m;
2180	unsigned short rx_quality;
2181{
2182	struct ip *ip = 0;
2183	int i;
2184	static int cache_slot = 0; 	/* use this cache entry */
2185	static int wrapindex = 0;       /* next "free" cache entry */
2186	int type_ipv4 = 0;
2187
2188	/* filters:
2189	 * 1. ip only
2190	 * 2. configurable filter to throw out unicast packets,
2191	 * keep multicast only.
2192	 */
2193
2194	if ((ntohs(eh->ether_type) == ETHERTYPE_IP)) {
2195		type_ipv4 = 1;
2196	}
2197
2198	/* filter for ip packets only
2199	*/
2200	if ( an_cache_iponly && !type_ipv4) {
2201		return;
2202	}
2203
2204	/* filter for broadcast/multicast only
2205	 */
2206	if (an_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) {
2207		return;
2208	}
2209
2210#ifdef SIGDEBUG
2211	printf("an: q value %x (MSB=0x%x, LSB=0x%x) \n",
2212	    rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff);
2213#endif
2214
2215	/* find the ip header.  we want to store the ip_src
2216	 * address.
2217	 */
2218	if (type_ipv4) {
2219		ip = mtod(m, struct ip *);
2220	}
2221
2222	/* do a linear search for a matching MAC address
2223	 * in the cache table
2224	 * . MAC address is 6 bytes,
2225	 * . var w_nextitem holds total number of entries already cached
2226	 */
2227	for (i = 0; i < sc->an_nextitem; i++) {
2228		if (! bcmp(eh->ether_shost , sc->an_sigcache[i].macsrc,  6 )) {
2229			/* Match!,
2230			 * so we already have this entry,
2231			 * update the data
2232			 */
2233			break;
2234		}
2235	}
2236
2237	/* did we find a matching mac address?
2238	 * if yes, then overwrite a previously existing cache entry
2239	 */
2240	if (i < sc->an_nextitem )   {
2241		cache_slot = i;
2242	}
2243	/* else, have a new address entry,so
2244	 * add this new entry,
2245	 * if table full, then we need to replace LRU entry
2246	 */
2247	else    {
2248
2249		/* check for space in cache table
2250		 * note: an_nextitem also holds number of entries
2251		 * added in the cache table
2252		 */
2253		if ( sc->an_nextitem < MAXANCACHE ) {
2254			cache_slot = sc->an_nextitem;
2255			sc->an_nextitem++;
2256			sc->an_sigitems = sc->an_nextitem;
2257		}
2258        	/* no space found, so simply wrap anth wrap index
2259		 * and "zap" the next entry
2260		 */
2261		else {
2262			if (wrapindex == MAXANCACHE) {
2263				wrapindex = 0;
2264			}
2265			cache_slot = wrapindex++;
2266		}
2267	}
2268
2269	/* invariant: cache_slot now points at some slot
2270	 * in cache.
2271	 */
2272	if (cache_slot < 0 || cache_slot >= MAXANCACHE) {
2273		log(LOG_ERR, "an_cache_store, bad index: %d of "
2274		    "[0..%d], gross cache error\n",
2275		    cache_slot, MAXANCACHE);
2276		return;
2277	}
2278
2279	/*  store items in cache
2280	 *  .ip source address
2281	 *  .mac src
2282	 *  .signal, etc.
2283	 */
2284	if (type_ipv4) {
2285		sc->an_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr;
2286	}
2287	bcopy( eh->ether_shost, sc->an_sigcache[cache_slot].macsrc,  6);
2288
2289	sc->an_sigcache[cache_slot].signal = rx_quality;
2290
2291	return;
2292}
2293#endif
2294
2295static int
2296an_media_change(ifp)
2297	struct ifnet		*ifp;
2298{
2299	struct an_softc *sc = ifp->if_softc;
2300	int otype = sc->an_config.an_opmode;
2301	int orate = sc->an_tx_rate;
2302
2303	if ((sc->an_ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0)
2304		sc->an_config.an_opmode = AN_OPMODE_IBSS_ADHOC;
2305	else
2306		sc->an_config.an_opmode = AN_OPMODE_INFRASTRUCTURE_STATION;
2307
2308	switch (IFM_SUBTYPE(sc->an_ifmedia.ifm_cur->ifm_media)) {
2309	case IFM_IEEE80211_DS1:
2310		sc->an_tx_rate = AN_RATE_1MBPS;
2311		break;
2312	case IFM_IEEE80211_DS2:
2313		sc->an_tx_rate = AN_RATE_2MBPS;
2314		break;
2315	case IFM_IEEE80211_DS5:
2316		sc->an_tx_rate = AN_RATE_5_5MBPS;
2317		break;
2318	case IFM_IEEE80211_DS11:
2319		sc->an_tx_rate = AN_RATE_11MBPS;
2320		break;
2321	case IFM_AUTO:
2322		sc->an_tx_rate = 0;
2323		break;
2324	}
2325
2326	if (otype != sc->an_config.an_opmode ||
2327	    orate != sc->an_tx_rate)
2328		an_init(sc);
2329
2330	return(0);
2331}
2332
2333static void
2334an_media_status(ifp, imr)
2335	struct ifnet		*ifp;
2336	struct ifmediareq	*imr;
2337{
2338	struct an_ltv_status	status;
2339	struct an_softc		*sc = ifp->if_softc;
2340
2341	status.an_len = sizeof(status);
2342	status.an_type = AN_RID_STATUS;
2343	if (an_read_record(sc, (struct an_ltv_gen *)&status)) {
2344		/* If the status read fails, just lie. */
2345		imr->ifm_active = sc->an_ifmedia.ifm_cur->ifm_media;
2346		imr->ifm_status = IFM_AVALID|IFM_ACTIVE;
2347	}
2348
2349	if (sc->an_tx_rate == 0) {
2350		imr->ifm_active = IFM_IEEE80211|IFM_AUTO;
2351		if (sc->an_config.an_opmode == AN_OPMODE_IBSS_ADHOC)
2352			imr->ifm_active |= IFM_IEEE80211_ADHOC;
2353		switch (status.an_current_tx_rate) {
2354		case AN_RATE_1MBPS:
2355			imr->ifm_active |= IFM_IEEE80211_DS1;
2356			break;
2357		case AN_RATE_2MBPS:
2358			imr->ifm_active |= IFM_IEEE80211_DS2;
2359			break;
2360		case AN_RATE_5_5MBPS:
2361			imr->ifm_active |= IFM_IEEE80211_DS5;
2362			break;
2363		case AN_RATE_11MBPS:
2364			imr->ifm_active |= IFM_IEEE80211_DS11;
2365			break;
2366		}
2367	} else {
2368		imr->ifm_active = sc->an_ifmedia.ifm_cur->ifm_media;
2369	}
2370
2371	imr->ifm_status = IFM_AVALID;
2372	if (sc->an_config.an_opmode == AN_OPMODE_IBSS_ADHOC)
2373		imr->ifm_status |= IFM_ACTIVE;
2374	else if (status.an_opmode & AN_STATUS_OPMODE_ASSOCIATED)
2375			imr->ifm_status |= IFM_ACTIVE;
2376}
2377
2378/********************** Cisco utility support routines *************/
2379
2380/*
2381 * ReadRids & WriteRids derived from Cisco driver additions to Ben Reed's
2382 * Linux driver
2383 */
2384
2385static int
2386readrids(ifp, l_ioctl)
2387	struct ifnet   *ifp;
2388	struct aironet_ioctl *l_ioctl;
2389{
2390	unsigned short  rid;
2391	struct an_softc *sc;
2392
2393	switch (l_ioctl->command) {
2394	case AIROGCAP:
2395		rid = AN_RID_CAPABILITIES;
2396		break;
2397	case AIROGCFG:
2398		rid = AN_RID_GENCONFIG;
2399		break;
2400	case AIROGSLIST:
2401		rid = AN_RID_SSIDLIST;
2402		break;
2403	case AIROGVLIST:
2404		rid = AN_RID_APLIST;
2405		break;
2406	case AIROGDRVNAM:
2407		rid = AN_RID_DRVNAME;
2408		break;
2409	case AIROGEHTENC:
2410		rid = AN_RID_ENCAPPROTO;
2411		break;
2412	case AIROGWEPKTMP:
2413		rid = AN_RID_WEP_TEMP;
2414		break;
2415	case AIROGWEPKNV:
2416		rid = AN_RID_WEP_PERM;
2417		break;
2418	case AIROGSTAT:
2419		rid = AN_RID_STATUS;
2420		break;
2421	case AIROGSTATSD32:
2422		rid = AN_RID_32BITS_DELTA;
2423		break;
2424	case AIROGSTATSC32:
2425		rid = AN_RID_32BITS_CUM;
2426		break;
2427	default:
2428		rid = 999;
2429		break;
2430	}
2431
2432	if (rid == 999)	/* Is bad command */
2433		return -EINVAL;
2434
2435	sc = ifp->if_softc;
2436	sc->areq.an_len  = AN_MAX_DATALEN;
2437	sc->areq.an_type = rid;
2438
2439	an_read_record(sc, (struct an_ltv_gen *)&sc->areq);
2440
2441	l_ioctl->len = sc->areq.an_len - 4;	/* just data */
2442
2443	/* the data contains the length at first */
2444	if (copyout(&(sc->areq.an_len), l_ioctl->data,
2445		    sizeof(sc->areq.an_len))) {
2446		return -EFAULT;
2447	}
2448	/* Just copy the data back */
2449	if (copyout(&(sc->areq.an_val), l_ioctl->data + 2,
2450		    l_ioctl->len)) {
2451		return -EFAULT;
2452	}
2453	return 0;
2454}
2455
2456static int
2457writerids(ifp, l_ioctl)
2458	struct ifnet   *ifp;
2459	struct aironet_ioctl *l_ioctl;
2460{
2461	struct an_softc *sc;
2462	int             rid, command;
2463
2464	sc = ifp->if_softc;
2465	rid = 0;
2466	command = l_ioctl->command;
2467
2468	switch (command) {
2469	case AIROPSIDS:
2470		rid = AN_RID_SSIDLIST;
2471		break;
2472	case AIROPCAP:
2473		rid = AN_RID_CAPABILITIES;
2474		break;
2475	case AIROPAPLIST:
2476		rid = AN_RID_APLIST;
2477		break;
2478	case AIROPCFG:
2479		rid = AN_RID_GENCONFIG;
2480		break;
2481	case AIROPMACON:
2482		an_cmd(sc, AN_CMD_ENABLE, 0);
2483		return 0;
2484		break;
2485	case AIROPMACOFF:
2486		an_cmd(sc, AN_CMD_DISABLE, 0);
2487		return 0;
2488		break;
2489	case AIROPSTCLR:
2490		/*
2491		 * This command merely clears the counts does not actually
2492		 * store any data only reads rid. But as it changes the cards
2493		 * state, I put it in the writerid routines.
2494		 */
2495
2496		rid = AN_RID_32BITS_DELTACLR;
2497		sc = ifp->if_softc;
2498		sc->areq.an_len = AN_MAX_DATALEN;
2499		sc->areq.an_type = rid;
2500
2501		an_read_record(sc, (struct an_ltv_gen *)&sc->areq);
2502		l_ioctl->len = sc->areq.an_len - 4;	/* just data */
2503
2504		/* the data contains the length at first */
2505		if (copyout(&(sc->areq.an_len), l_ioctl->data,
2506			    sizeof(sc->areq.an_len))) {
2507			return -EFAULT;
2508		}
2509		/* Just copy the data */
2510		if (copyout(&(sc->areq.an_val), l_ioctl->data + 2,
2511			    l_ioctl->len)) {
2512			return -EFAULT;
2513		}
2514		return 0;
2515		break;
2516	case AIROPWEPKEY:
2517		rid = AN_RID_WEP_TEMP;
2518		break;
2519	case AIROPWEPKEYNV:
2520		rid = AN_RID_WEP_PERM;
2521		break;
2522	case AIROPLEAPUSR:
2523		rid = AN_RID_LEAPUSERNAME;
2524		break;
2525	case AIROPLEAPPWD:
2526		rid = AN_RID_LEAPPASSWORD;
2527		break;
2528	default:
2529		return -EOPNOTSUPP;
2530	}
2531
2532	if (rid) {
2533		if (l_ioctl->len > sizeof(sc->areq.an_val) + 4)
2534			return -EINVAL;
2535		sc->areq.an_len = l_ioctl->len + 4;	/* add type & length */
2536		sc->areq.an_type = rid;
2537
2538		/* Just copy the data back */
2539		copyin((l_ioctl->data) + 2, &sc->areq.an_val,
2540		       l_ioctl->len);
2541
2542		an_cmd(sc, AN_CMD_DISABLE, 0);
2543		an_write_record(sc, (struct an_ltv_gen *)&sc->areq);
2544		an_cmd(sc, AN_CMD_ENABLE, 0);
2545		return 0;
2546	}
2547	return -EOPNOTSUPP;
2548}
2549
2550/*
2551 * General Flash utilities derived from Cisco driver additions to Ben Reed's
2552 * Linux driver
2553 */
2554
2555#define FLASH_DELAY(x) tsleep(ifp, PZERO, "flash", ((x) / hz) + 1);
2556
2557static int
2558unstickbusy(ifp)
2559	struct ifnet   *ifp;
2560{
2561	struct an_softc *sc = ifp->if_softc;
2562
2563	if (CSR_READ_2(sc, AN_COMMAND) & AN_CMD_BUSY) {
2564		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CLR_STUCK_BUSY);
2565		return 1;
2566	}
2567	return 0;
2568}
2569
2570/*
2571 * Wait for busy completion from card wait for delay uSec's Return true for
2572 * success meaning command reg is clear
2573 */
2574
2575static int
2576WaitBusy(ifp, uSec)
2577	struct ifnet   *ifp;
2578	int             uSec;
2579{
2580	int             statword = 0xffff;
2581	int             delay = 0;
2582	struct an_softc *sc = ifp->if_softc;
2583
2584	while ((statword & AN_CMD_BUSY) && delay <= (1000 * 100)) {
2585		FLASH_DELAY(10);
2586		delay += 10;
2587		statword = CSR_READ_2(sc, AN_COMMAND);
2588
2589		if ((AN_CMD_BUSY & statword) && (delay % 200)) {
2590			unstickbusy(ifp);
2591		}
2592	}
2593
2594	return 0 == (AN_CMD_BUSY & statword);
2595}
2596
2597/*
2598 * STEP 1) Disable MAC and do soft reset on card.
2599 */
2600
2601static int
2602cmdreset(ifp)
2603	struct ifnet   *ifp;
2604{
2605	int             status;
2606	struct an_softc *sc = ifp->if_softc;
2607
2608	an_stop(sc);
2609
2610	an_cmd(sc, AN_CMD_DISABLE, 0);
2611
2612	if (!(status = WaitBusy(ifp, 600))) {
2613		printf("an%d: Waitbusy hang b4 RESET =%d\n",
2614		       sc->an_unit, status);
2615		return -EBUSY;
2616	}
2617	CSR_WRITE_2(sc, AN_COMMAND, AN_CMD_FW_RESTART);
2618
2619	FLASH_DELAY(1000);	/* WAS 600 12/7/00 */
2620
2621
2622	if (!(status = WaitBusy(ifp, 100))) {
2623		printf("an%d: Waitbusy hang AFTER RESET =%d\n",
2624		       sc->an_unit, status);
2625		return -EBUSY;
2626	}
2627	return 0;
2628}
2629
2630/*
2631 * STEP 2) Put the card in legendary flash mode
2632 */
2633#define FLASH_COMMAND  0x7e7e
2634
2635static int
2636setflashmode(ifp)
2637	struct ifnet   *ifp;
2638{
2639	int             status;
2640	struct an_softc *sc = ifp->if_softc;
2641
2642	CSR_WRITE_2(sc, AN_SW0, FLASH_COMMAND);
2643	CSR_WRITE_2(sc, AN_SW1, FLASH_COMMAND);
2644	CSR_WRITE_2(sc, AN_SW0, FLASH_COMMAND);
2645	CSR_WRITE_2(sc, AN_COMMAND, FLASH_COMMAND);
2646
2647	/*
2648	 * mdelay(500); // 500ms delay
2649	 */
2650
2651	FLASH_DELAY(500);
2652
2653	if (!(status = WaitBusy(ifp, 600))) {
2654		printf("Waitbusy hang after setflash mode\n");
2655		return -EIO;
2656	}
2657	return 0;
2658}
2659
2660/*
2661 * Get a character from the card matching matchbyte Step 3)
2662 */
2663
2664static int
2665flashgchar(ifp, matchbyte, dwelltime)
2666	struct ifnet   *ifp;
2667	int             matchbyte;
2668	int             dwelltime;
2669{
2670	int             rchar;
2671	unsigned char   rbyte = 0;
2672	int             success = -1;
2673	struct an_softc *sc = ifp->if_softc;
2674
2675
2676	do {
2677		rchar = CSR_READ_2(sc, AN_SW1);
2678
2679		if (dwelltime && !(0x8000 & rchar)) {
2680			dwelltime -= 10;
2681			FLASH_DELAY(10);
2682			continue;
2683		}
2684		rbyte = 0xff & rchar;
2685
2686		if ((rbyte == matchbyte) && (0x8000 & rchar)) {
2687			CSR_WRITE_2(sc, AN_SW1, 0);
2688			success = 1;
2689			break;
2690		}
2691		if (rbyte == 0x81 || rbyte == 0x82 || rbyte == 0x83 || rbyte == 0x1a || 0xffff == rchar)
2692			break;
2693		CSR_WRITE_2(sc, AN_SW1, 0);
2694
2695	} while (dwelltime > 0);
2696	return success;
2697}
2698
2699/*
2700 * Put character to SWS0 wait for dwelltime x 50us for  echo .
2701 */
2702
2703static int
2704flashpchar(ifp, byte, dwelltime)
2705	struct ifnet   *ifp;
2706	int             byte;
2707	int             dwelltime;
2708{
2709	int             echo;
2710	int             pollbusy, waittime;
2711	struct an_softc *sc = ifp->if_softc;
2712
2713	byte |= 0x8000;
2714
2715	if (dwelltime == 0)
2716		dwelltime = 200;
2717
2718	waittime = dwelltime;
2719
2720	/*
2721	 * Wait for busy bit d15 to go false indicating buffer empty
2722	 */
2723	do {
2724		pollbusy = CSR_READ_2(sc, AN_SW0);
2725
2726		if (pollbusy & 0x8000) {
2727			FLASH_DELAY(50);
2728			waittime -= 50;
2729			continue;
2730		} else
2731			break;
2732	}
2733	while (waittime >= 0);
2734
2735	/* timeout for busy clear wait */
2736
2737	if (waittime <= 0) {
2738		printf("an%d: flash putchar busywait timeout! \n",
2739		       sc->an_unit);
2740		return -1;
2741	}
2742	/*
2743	 * Port is clear now write byte and wait for it to echo back
2744	 */
2745	do {
2746		CSR_WRITE_2(sc, AN_SW0, byte);
2747		FLASH_DELAY(50);
2748		dwelltime -= 50;
2749		echo = CSR_READ_2(sc, AN_SW1);
2750	} while (dwelltime >= 0 && echo != byte);
2751
2752
2753	CSR_WRITE_2(sc, AN_SW1, 0);
2754
2755	return echo == byte;
2756}
2757
2758/*
2759 * Transfer 32k of firmware data from user buffer to our buffer and send to
2760 * the card
2761 */
2762
2763static char     flashbuffer[1024 * 38];	/* RAW Buffer for flash will be
2764					 * dynamic next */
2765
2766static int
2767flashputbuf(ifp)
2768	struct ifnet   *ifp;
2769{
2770	unsigned short *bufp;
2771	int             nwords;
2772	struct an_softc *sc = ifp->if_softc;
2773
2774	/* Write stuff */
2775
2776	bufp = (unsigned short *)flashbuffer;
2777
2778	CSR_WRITE_2(sc, AN_AUX_PAGE, 0x100);
2779	CSR_WRITE_2(sc, AN_AUX_OFFSET, 0);
2780
2781	for (nwords = 0; nwords != 16384; nwords++) {
2782		CSR_WRITE_2(sc, AN_AUX_DATA, bufp[nwords] & 0xffff);
2783	}
2784
2785	CSR_WRITE_2(sc, AN_SW0, 0x8000);
2786
2787	return 0;
2788}
2789
2790/*
2791 * After flashing restart the card.
2792 */
2793
2794static int
2795flashrestart(ifp)
2796	struct ifnet   *ifp;
2797{
2798	int             status = 0;
2799	struct an_softc *sc = ifp->if_softc;
2800
2801	FLASH_DELAY(1024);		/* Added 12/7/00 */
2802
2803	an_init(sc);
2804
2805	FLASH_DELAY(1024);		/* Added 12/7/00 */
2806	return status;
2807}
2808
2809/*
2810 * Entry point for flash ioclt.
2811 */
2812
2813static int
2814flashcard(ifp, l_ioctl)
2815	struct ifnet   *ifp;
2816	struct aironet_ioctl *l_ioctl;
2817{
2818	int             z = 0, status;
2819	struct an_softc	*sc;
2820
2821	sc = ifp->if_softc;
2822	status = l_ioctl->command;
2823
2824	switch (l_ioctl->command) {
2825	case AIROFLSHRST:
2826		return cmdreset(ifp);
2827		break;
2828	case AIROFLSHSTFL:
2829		return setflashmode(ifp);
2830		break;
2831	case AIROFLSHGCHR:	/* Get char from aux */
2832		copyin(l_ioctl->data, &sc->areq, l_ioctl->len);
2833		z = *(int *)&sc->areq;
2834		if ((status = flashgchar(ifp, z, 8000)) == 1)
2835			return 0;
2836		else
2837			return -1;
2838		break;
2839	case AIROFLSHPCHR:	/* Send char to card. */
2840		copyin(l_ioctl->data, &sc->areq, l_ioctl->len);
2841		z = *(int *)&sc->areq;
2842		if ((status = flashpchar(ifp, z, 8000)) == -1)
2843			return -EIO;
2844		else
2845			return 0;
2846		break;
2847	case AIROFLPUTBUF:	/* Send 32k to card */
2848		if (l_ioctl->len > sizeof(flashbuffer)) {
2849			printf("an%d: Buffer to big, %x %x\n", sc->an_unit,
2850			       l_ioctl->len, sizeof(flashbuffer));
2851			return -EINVAL;
2852		}
2853		copyin(l_ioctl->data, &flashbuffer, l_ioctl->len);
2854
2855		if ((status = flashputbuf(ifp)) != 0)
2856			return -EIO;
2857		else
2858			return 0;
2859		break;
2860	case AIRORESTART:
2861		if ((status = flashrestart(ifp)) != 0) {
2862			printf("an%d: FLASHRESTART returned %d\n",
2863			       sc->an_unit, status);
2864			return -EIO;
2865		} else
2866			return 0;
2867
2868		break;
2869	default:
2870		return -EINVAL;
2871	}
2872
2873	return -EINVAL;
2874}
2875
2876