if_an.c revision 199154
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/*
33 * Aironet 4500/4800 802.11 PCMCIA/ISA/PCI driver for FreeBSD.
34 *
35 * Written by Bill Paul <wpaul@ctr.columbia.edu>
36 * Electrical Engineering Department
37 * Columbia University, New York City
38 */
39
40#include <sys/cdefs.h>
41__FBSDID("$FreeBSD: head/sys/dev/an/if_an.c 199154 2009-11-10 22:04:19Z jhb $");
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/dev/an/if_an_pci.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/ctype.h>
92#include <sys/systm.h>
93#include <sys/sockio.h>
94#include <sys/mbuf.h>
95#include <sys/priv.h>
96#include <sys/proc.h>
97#include <sys/kernel.h>
98#include <sys/socket.h>
99#ifdef ANCACHE
100#include <sys/syslog.h>
101#endif
102#include <sys/sysctl.h>
103
104#include <sys/module.h>
105#include <sys/sysctl.h>
106#include <sys/bus.h>
107#include <machine/bus.h>
108#include <sys/rman.h>
109#include <sys/lock.h>
110#include <sys/mutex.h>
111#include <machine/resource.h>
112#include <sys/malloc.h>
113
114#include <net/if.h>
115#include <net/if_arp.h>
116#include <net/if_dl.h>
117#include <net/ethernet.h>
118#include <net/if_types.h>
119#include <net/if_media.h>
120
121#include <net80211/ieee80211_var.h>
122#include <net80211/ieee80211_ioctl.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#include <net/bpf.h>
132
133#include <machine/md_var.h>
134
135#include <dev/an/if_aironet_ieee.h>
136#include <dev/an/if_anreg.h>
137
138/* These are global because we need them in sys/pci/if_an_p.c. */
139static void an_reset(struct an_softc *);
140static int an_init_mpi350_desc(struct an_softc *);
141static int an_ioctl(struct ifnet *, u_long, caddr_t);
142static void an_init(void *);
143static void an_init_locked(struct an_softc *);
144static int an_init_tx_ring(struct an_softc *);
145static void an_start(struct ifnet *);
146static void an_start_locked(struct ifnet *);
147static void an_watchdog(struct an_softc *);
148static void an_rxeof(struct an_softc *);
149static void an_txeof(struct an_softc *, int);
150
151static void an_promisc(struct an_softc *, int);
152static int an_cmd(struct an_softc *, int, int);
153static int an_cmd_struct(struct an_softc *, struct an_command *,
154    struct an_reply *);
155static int an_read_record(struct an_softc *, struct an_ltv_gen *);
156static int an_write_record(struct an_softc *, struct an_ltv_gen *);
157static int an_read_data(struct an_softc *, int, int, caddr_t, int);
158static int an_write_data(struct an_softc *, int, int, caddr_t, int);
159static int an_seek(struct an_softc *, int, int, int);
160static int an_alloc_nicmem(struct an_softc *, int, int *);
161static int an_dma_malloc(struct an_softc *, bus_size_t, struct an_dma_alloc *,
162    int);
163static void an_dma_free(struct an_softc *, struct an_dma_alloc *);
164static void an_dma_malloc_cb(void *, bus_dma_segment_t *, int, int);
165static void an_stats_update(void *);
166static void an_setdef(struct an_softc *, struct an_req *);
167#ifdef ANCACHE
168static void an_cache_store(struct an_softc *, struct ether_header *,
169    struct mbuf *, u_int8_t, u_int8_t);
170#endif
171
172/* function definitions for use with the Cisco's Linux configuration
173   utilities
174*/
175
176static int readrids(struct ifnet*, struct aironet_ioctl*);
177static int writerids(struct ifnet*, struct aironet_ioctl*);
178static int flashcard(struct ifnet*, struct aironet_ioctl*);
179
180static int cmdreset(struct ifnet *);
181static int setflashmode(struct ifnet *);
182static int flashgchar(struct ifnet *,int,int);
183static int flashpchar(struct ifnet *,int,int);
184static int flashputbuf(struct ifnet *);
185static int flashrestart(struct ifnet *);
186static int WaitBusy(struct ifnet *, int);
187static int unstickbusy(struct ifnet *);
188
189static void an_dump_record	(struct an_softc *,struct an_ltv_gen *,
190				    char *);
191
192static int an_media_change	(struct ifnet *);
193static void an_media_status	(struct ifnet *, struct ifmediareq *);
194
195static int	an_dump = 0;
196static int	an_cache_mode = 0;
197
198#define DBM 0
199#define PERCENT 1
200#define RAW 2
201
202static char an_conf[256];
203static char an_conf_cache[256];
204
205/* sysctl vars */
206
207SYSCTL_NODE(_hw, OID_AUTO, an, CTLFLAG_RD, 0, "Wireless driver parameters");
208
209/* XXX violate ethernet/netgraph callback hooks */
210extern	void	(*ng_ether_attach_p)(struct ifnet *ifp);
211extern	void	(*ng_ether_detach_p)(struct ifnet *ifp);
212
213static int
214sysctl_an_dump(SYSCTL_HANDLER_ARGS)
215{
216	int	error, r, last;
217	char 	*s = an_conf;
218
219	last = an_dump;
220
221	switch (an_dump) {
222	case 0:
223		strcpy(an_conf, "off");
224		break;
225	case 1:
226		strcpy(an_conf, "type");
227		break;
228	case 2:
229		strcpy(an_conf, "dump");
230		break;
231	default:
232		snprintf(an_conf, 5, "%x", an_dump);
233		break;
234	}
235
236	error = sysctl_handle_string(oidp, an_conf, sizeof(an_conf), req);
237
238	if (strncmp(an_conf,"off", 3) == 0) {
239		an_dump = 0;
240 	}
241	if (strncmp(an_conf,"dump", 4) == 0) {
242		an_dump = 1;
243	}
244	if (strncmp(an_conf,"type", 4) == 0) {
245		an_dump = 2;
246	}
247	if (*s == 'f') {
248		r = 0;
249		for (;;s++) {
250			if ((*s >= '0') && (*s <= '9')) {
251				r = r * 16 + (*s - '0');
252			} else if ((*s >= 'a') && (*s <= 'f')) {
253				r = r * 16 + (*s - 'a' + 10);
254			} else {
255				break;
256			}
257		}
258		an_dump = r;
259	}
260	if (an_dump != last)
261		printf("Sysctl changed for Aironet driver\n");
262
263	return error;
264}
265
266SYSCTL_PROC(_hw_an, OID_AUTO, an_dump, CTLTYPE_STRING | CTLFLAG_RW,
267	    0, sizeof(an_conf), sysctl_an_dump, "A", "");
268
269static int
270sysctl_an_cache_mode(SYSCTL_HANDLER_ARGS)
271{
272	int	error, last;
273
274	last = an_cache_mode;
275
276	switch (an_cache_mode) {
277	case 1:
278		strcpy(an_conf_cache, "per");
279		break;
280	case 2:
281		strcpy(an_conf_cache, "raw");
282		break;
283	default:
284		strcpy(an_conf_cache, "dbm");
285		break;
286	}
287
288	error = sysctl_handle_string(oidp, an_conf_cache,
289			sizeof(an_conf_cache), req);
290
291	if (strncmp(an_conf_cache,"dbm", 3) == 0) {
292		an_cache_mode = 0;
293	}
294	if (strncmp(an_conf_cache,"per", 3) == 0) {
295		an_cache_mode = 1;
296 	}
297	if (strncmp(an_conf_cache,"raw", 3) == 0) {
298		an_cache_mode = 2;
299	}
300
301	return error;
302}
303
304SYSCTL_PROC(_hw_an, OID_AUTO, an_cache_mode, CTLTYPE_STRING | CTLFLAG_RW,
305	    0, sizeof(an_conf_cache), sysctl_an_cache_mode, "A", "");
306
307/*
308 * Setup the lock for PCI attachment since it skips the an_probe
309 * function.  We need to setup the lock in an_probe since some
310 * operations need the lock.  So we might as well create the
311 * lock in the probe.
312 */
313int
314an_pci_probe(device_t dev)
315{
316	struct an_softc *sc = device_get_softc(dev);
317
318	mtx_init(&sc->an_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
319	    MTX_DEF);
320
321	return(0);
322}
323
324/*
325 * We probe for an Aironet 4500/4800 card by attempting to
326 * read the default SSID list. On reset, the first entry in
327 * the SSID list will contain the name "tsunami." If we don't
328 * find this, then there's no card present.
329 */
330int
331an_probe(device_t dev)
332{
333	struct an_softc *sc = device_get_softc(dev);
334	struct an_ltv_ssidlist_new	ssid;
335	int	error;
336
337	bzero((char *)&ssid, sizeof(ssid));
338
339	error = an_alloc_port(dev, 0, AN_IOSIZ);
340	if (error != 0)
341		return (0);
342
343	/* can't do autoprobing */
344	if (rman_get_start(sc->port_res) == -1)
345		return(0);
346
347	/*
348	 * We need to fake up a softc structure long enough
349	 * to be able to issue commands and call some of the
350	 * other routines.
351	 */
352	sc->an_bhandle = rman_get_bushandle(sc->port_res);
353	sc->an_btag = rman_get_bustag(sc->port_res);
354
355	ssid.an_len = sizeof(ssid);
356	ssid.an_type = AN_RID_SSIDLIST;
357
358	/* Make sure interrupts are disabled. */
359	sc->mpi350 = 0;
360	CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), 0);
361	CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), 0xFFFF);
362
363	mtx_init(&sc->an_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
364	    MTX_DEF);
365	AN_LOCK(sc);
366	an_reset(sc);
367
368	if (an_cmd(sc, AN_CMD_READCFG, 0)) {
369		AN_UNLOCK(sc);
370		goto fail;
371	}
372
373	if (an_read_record(sc, (struct an_ltv_gen *)&ssid)) {
374		AN_UNLOCK(sc);
375		goto fail;
376	}
377
378	/* See if the ssid matches what we expect ... but doesn't have to */
379	if (strcmp(ssid.an_entry[0].an_ssid, AN_DEF_SSID)) {
380		AN_UNLOCK(sc);
381		goto fail;
382	}
383
384	AN_UNLOCK(sc);
385	return(AN_IOSIZ);
386fail:
387	mtx_destroy(&sc->an_mtx);
388	return(0);
389}
390
391/*
392 * Allocate a port resource with the given resource id.
393 */
394int
395an_alloc_port(device_t dev, int rid, int size)
396{
397	struct an_softc *sc = device_get_softc(dev);
398	struct resource *res;
399
400	res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
401				 0ul, ~0ul, size, RF_ACTIVE);
402	if (res) {
403		sc->port_rid = rid;
404		sc->port_res = res;
405		return (0);
406	} else {
407		return (ENOENT);
408	}
409}
410
411/*
412 * Allocate a memory resource with the given resource id.
413 */
414int an_alloc_memory(device_t dev, int rid, int size)
415{
416	struct an_softc *sc = device_get_softc(dev);
417	struct resource *res;
418
419	res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
420				 0ul, ~0ul, size, RF_ACTIVE);
421	if (res) {
422		sc->mem_rid = rid;
423		sc->mem_res = res;
424		sc->mem_used = size;
425		return (0);
426	} else {
427		return (ENOENT);
428	}
429}
430
431/*
432 * Allocate a auxilary memory resource with the given resource id.
433 */
434int an_alloc_aux_memory(device_t dev, int rid, int size)
435{
436	struct an_softc *sc = device_get_softc(dev);
437	struct resource *res;
438
439	res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
440				 0ul, ~0ul, size, RF_ACTIVE);
441	if (res) {
442		sc->mem_aux_rid = rid;
443		sc->mem_aux_res = res;
444		sc->mem_aux_used = size;
445		return (0);
446	} else {
447		return (ENOENT);
448	}
449}
450
451/*
452 * Allocate an irq resource with the given resource id.
453 */
454int
455an_alloc_irq(device_t dev, int rid, int flags)
456{
457	struct an_softc *sc = device_get_softc(dev);
458	struct resource *res;
459
460	res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
461				     (RF_ACTIVE | flags));
462	if (res) {
463		sc->irq_rid = rid;
464		sc->irq_res = res;
465		return (0);
466	} else {
467		return (ENOENT);
468	}
469}
470
471static void
472an_dma_malloc_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
473{
474	bus_addr_t *paddr = (bus_addr_t*) arg;
475	*paddr = segs->ds_addr;
476}
477
478/*
479 * Alloc DMA memory and set the pointer to it
480 */
481static int
482an_dma_malloc(struct an_softc *sc, bus_size_t size, struct an_dma_alloc *dma,
483    int mapflags)
484{
485	int r;
486
487	r = bus_dmamap_create(sc->an_dtag, BUS_DMA_NOWAIT, &dma->an_dma_map);
488	if (r != 0)
489		goto fail_0;
490
491	r = bus_dmamem_alloc(sc->an_dtag, (void**) &dma->an_dma_vaddr,
492			     BUS_DMA_NOWAIT, &dma->an_dma_map);
493	if (r != 0)
494		goto fail_1;
495
496	r = bus_dmamap_load(sc->an_dtag, dma->an_dma_map, dma->an_dma_vaddr,
497			    size,
498			    an_dma_malloc_cb,
499			    &dma->an_dma_paddr,
500			    mapflags | BUS_DMA_NOWAIT);
501	if (r != 0)
502		goto fail_2;
503
504	dma->an_dma_size = size;
505	return (0);
506
507fail_2:
508	bus_dmamap_unload(sc->an_dtag, dma->an_dma_map);
509fail_1:
510	bus_dmamem_free(sc->an_dtag, dma->an_dma_vaddr, dma->an_dma_map);
511fail_0:
512	bus_dmamap_destroy(sc->an_dtag, dma->an_dma_map);
513	dma->an_dma_map = NULL;
514	return (r);
515}
516
517static void
518an_dma_free(struct an_softc *sc, struct an_dma_alloc *dma)
519{
520	bus_dmamap_unload(sc->an_dtag, dma->an_dma_map);
521	bus_dmamem_free(sc->an_dtag, dma->an_dma_vaddr, dma->an_dma_map);
522	dma->an_dma_vaddr = 0;
523	bus_dmamap_destroy(sc->an_dtag, dma->an_dma_map);
524}
525
526/*
527 * Release all resources
528 */
529void
530an_release_resources(device_t dev)
531{
532	struct an_softc *sc = device_get_softc(dev);
533	int i;
534
535	if (sc->port_res) {
536		bus_release_resource(dev, SYS_RES_IOPORT,
537				     sc->port_rid, sc->port_res);
538		sc->port_res = 0;
539	}
540	if (sc->mem_res) {
541		bus_release_resource(dev, SYS_RES_MEMORY,
542				     sc->mem_rid, sc->mem_res);
543		sc->mem_res = 0;
544	}
545	if (sc->mem_aux_res) {
546		bus_release_resource(dev, SYS_RES_MEMORY,
547				     sc->mem_aux_rid, sc->mem_aux_res);
548		sc->mem_aux_res = 0;
549	}
550	if (sc->irq_res) {
551		bus_release_resource(dev, SYS_RES_IRQ,
552				     sc->irq_rid, sc->irq_res);
553		sc->irq_res = 0;
554	}
555	if (sc->an_rid_buffer.an_dma_paddr) {
556		an_dma_free(sc, &sc->an_rid_buffer);
557	}
558	for (i = 0; i < AN_MAX_RX_DESC; i++)
559		if (sc->an_rx_buffer[i].an_dma_paddr) {
560			an_dma_free(sc, &sc->an_rx_buffer[i]);
561		}
562	for (i = 0; i < AN_MAX_TX_DESC; i++)
563		if (sc->an_tx_buffer[i].an_dma_paddr) {
564			an_dma_free(sc, &sc->an_tx_buffer[i]);
565		}
566	if (sc->an_dtag) {
567		bus_dma_tag_destroy(sc->an_dtag);
568	}
569
570}
571
572int
573an_init_mpi350_desc(struct an_softc *sc)
574{
575	struct an_command	cmd_struct;
576	struct an_reply		reply;
577	struct an_card_rid_desc an_rid_desc;
578	struct an_card_rx_desc	an_rx_desc;
579	struct an_card_tx_desc	an_tx_desc;
580	int			i, desc;
581
582	AN_LOCK_ASSERT(sc);
583	if(!sc->an_rid_buffer.an_dma_paddr)
584		an_dma_malloc(sc, AN_RID_BUFFER_SIZE,
585				 &sc->an_rid_buffer, 0);
586	for (i = 0; i < AN_MAX_RX_DESC; i++)
587		if(!sc->an_rx_buffer[i].an_dma_paddr)
588			an_dma_malloc(sc, AN_RX_BUFFER_SIZE,
589				      &sc->an_rx_buffer[i], 0);
590	for (i = 0; i < AN_MAX_TX_DESC; i++)
591		if(!sc->an_tx_buffer[i].an_dma_paddr)
592			an_dma_malloc(sc, AN_TX_BUFFER_SIZE,
593				      &sc->an_tx_buffer[i], 0);
594
595	/*
596	 * Allocate RX descriptor
597	 */
598	bzero(&reply,sizeof(reply));
599	cmd_struct.an_cmd   = AN_CMD_ALLOC_DESC;
600	cmd_struct.an_parm0 = AN_DESCRIPTOR_RX;
601	cmd_struct.an_parm1 = AN_RX_DESC_OFFSET;
602	cmd_struct.an_parm2 = AN_MAX_RX_DESC;
603	if (an_cmd_struct(sc, &cmd_struct, &reply)) {
604		if_printf(sc->an_ifp, "failed to allocate RX descriptor\n");
605		return(EIO);
606	}
607
608	for (desc = 0; desc < AN_MAX_RX_DESC; desc++) {
609		bzero(&an_rx_desc, sizeof(an_rx_desc));
610		an_rx_desc.an_valid = 1;
611		an_rx_desc.an_len = AN_RX_BUFFER_SIZE;
612		an_rx_desc.an_done = 0;
613		an_rx_desc.an_phys = sc->an_rx_buffer[desc].an_dma_paddr;
614
615		for (i = 0; i < sizeof(an_rx_desc) / 4; i++)
616			CSR_MEM_AUX_WRITE_4(sc, AN_RX_DESC_OFFSET
617			    + (desc * sizeof(an_rx_desc))
618			    + (i * 4),
619			    ((u_int32_t *)(void *)&an_rx_desc)[i]);
620	}
621
622	/*
623	 * Allocate TX descriptor
624	 */
625
626	bzero(&reply,sizeof(reply));
627	cmd_struct.an_cmd   = AN_CMD_ALLOC_DESC;
628	cmd_struct.an_parm0 = AN_DESCRIPTOR_TX;
629	cmd_struct.an_parm1 = AN_TX_DESC_OFFSET;
630	cmd_struct.an_parm2 = AN_MAX_TX_DESC;
631	if (an_cmd_struct(sc, &cmd_struct, &reply)) {
632		if_printf(sc->an_ifp, "failed to allocate TX descriptor\n");
633		return(EIO);
634	}
635
636	for (desc = 0; desc < AN_MAX_TX_DESC; desc++) {
637		bzero(&an_tx_desc, sizeof(an_tx_desc));
638		an_tx_desc.an_offset = 0;
639		an_tx_desc.an_eoc = 0;
640		an_tx_desc.an_valid = 0;
641		an_tx_desc.an_len = 0;
642		an_tx_desc.an_phys = sc->an_tx_buffer[desc].an_dma_paddr;
643
644		for (i = 0; i < sizeof(an_tx_desc) / 4; i++)
645			CSR_MEM_AUX_WRITE_4(sc, AN_TX_DESC_OFFSET
646			    + (desc * sizeof(an_tx_desc))
647			    + (i * 4),
648			    ((u_int32_t *)(void *)&an_tx_desc)[i]);
649	}
650
651	/*
652	 * Allocate RID descriptor
653	 */
654
655	bzero(&reply,sizeof(reply));
656	cmd_struct.an_cmd   = AN_CMD_ALLOC_DESC;
657	cmd_struct.an_parm0 = AN_DESCRIPTOR_HOSTRW;
658	cmd_struct.an_parm1 = AN_HOST_DESC_OFFSET;
659	cmd_struct.an_parm2 = 1;
660	if (an_cmd_struct(sc, &cmd_struct, &reply)) {
661		if_printf(sc->an_ifp, "failed to allocate host descriptor\n");
662		return(EIO);
663	}
664
665	bzero(&an_rid_desc, sizeof(an_rid_desc));
666	an_rid_desc.an_valid = 1;
667	an_rid_desc.an_len = AN_RID_BUFFER_SIZE;
668	an_rid_desc.an_rid = 0;
669	an_rid_desc.an_phys = sc->an_rid_buffer.an_dma_paddr;
670
671	for (i = 0; i < sizeof(an_rid_desc) / 4; i++)
672		CSR_MEM_AUX_WRITE_4(sc, AN_HOST_DESC_OFFSET + i * 4,
673				    ((u_int32_t *)(void *)&an_rid_desc)[i]);
674
675	return(0);
676}
677
678int
679an_attach(struct an_softc *sc, int flags)
680{
681	struct ifnet		*ifp;
682	int			error = EIO;
683	int			i, nrate, mword;
684	u_int8_t		r;
685
686	ifp = sc->an_ifp = if_alloc(IFT_ETHER);
687	if (ifp == NULL) {
688		device_printf(sc->an_dev, "can not if_alloc()\n");
689		goto fail;
690	}
691
692	sc->an_gone = 0;
693	sc->an_associated = 0;
694	sc->an_monitor = 0;
695	sc->an_was_monitor = 0;
696	sc->an_flash_buffer = NULL;
697
698	/* Reset the NIC. */
699	AN_LOCK(sc);
700	an_reset(sc);
701	if (sc->mpi350) {
702		error = an_init_mpi350_desc(sc);
703		if (error)
704			goto fail;
705	}
706
707	/* Load factory config */
708	if (an_cmd(sc, AN_CMD_READCFG, 0)) {
709		device_printf(sc->an_dev, "failed to load config data\n");
710		goto fail;
711	}
712
713	/* Read the current configuration */
714	sc->an_config.an_type = AN_RID_GENCONFIG;
715	sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
716	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_config)) {
717		device_printf(sc->an_dev, "read record failed\n");
718		goto fail;
719	}
720
721	/* Read the card capabilities */
722	sc->an_caps.an_type = AN_RID_CAPABILITIES;
723	sc->an_caps.an_len = sizeof(struct an_ltv_caps);
724	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_caps)) {
725		device_printf(sc->an_dev, "read record failed\n");
726		goto fail;
727	}
728
729	/* Read ssid list */
730	sc->an_ssidlist.an_type = AN_RID_SSIDLIST;
731	sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist_new);
732	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) {
733		device_printf(sc->an_dev, "read record failed\n");
734		goto fail;
735	}
736
737	/* Read AP list */
738	sc->an_aplist.an_type = AN_RID_APLIST;
739	sc->an_aplist.an_len = sizeof(struct an_ltv_aplist);
740	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) {
741		device_printf(sc->an_dev, "read record failed\n");
742		goto fail;
743	}
744
745#ifdef ANCACHE
746	/* Read the RSSI <-> dBm map */
747	sc->an_have_rssimap = 0;
748	if (sc->an_caps.an_softcaps & 8) {
749		sc->an_rssimap.an_type = AN_RID_RSSI_MAP;
750		sc->an_rssimap.an_len = sizeof(struct an_ltv_rssi_map);
751		if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_rssimap)) {
752			device_printf(sc->an_dev,
753			    "unable to get RSSI <-> dBM map\n");
754		} else {
755			device_printf(sc->an_dev, "got RSSI <-> dBM map\n");
756			sc->an_have_rssimap = 1;
757		}
758	} else {
759		device_printf(sc->an_dev, "no RSSI <-> dBM map\n");
760	}
761#endif
762	AN_UNLOCK(sc);
763
764	ifp->if_softc = sc;
765	if_initname(ifp, device_get_name(sc->an_dev),
766	    device_get_unit(sc->an_dev));
767	ifp->if_mtu = ETHERMTU;
768	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
769	ifp->if_ioctl = an_ioctl;
770	ifp->if_start = an_start;
771	ifp->if_init = an_init;
772	ifp->if_baudrate = 10000000;
773	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
774	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
775	IFQ_SET_READY(&ifp->if_snd);
776
777	bzero(sc->an_config.an_nodename, sizeof(sc->an_config.an_nodename));
778	bcopy(AN_DEFAULT_NODENAME, sc->an_config.an_nodename,
779	    sizeof(AN_DEFAULT_NODENAME) - 1);
780
781	bzero(sc->an_ssidlist.an_entry[0].an_ssid,
782	      sizeof(sc->an_ssidlist.an_entry[0].an_ssid));
783	bcopy(AN_DEFAULT_NETNAME, sc->an_ssidlist.an_entry[0].an_ssid,
784	    sizeof(AN_DEFAULT_NETNAME) - 1);
785	sc->an_ssidlist.an_entry[0].an_len = strlen(AN_DEFAULT_NETNAME);
786
787	sc->an_config.an_opmode =
788	    AN_OPMODE_INFRASTRUCTURE_STATION;
789
790	sc->an_tx_rate = 0;
791	bzero((char *)&sc->an_stats, sizeof(sc->an_stats));
792
793	nrate = 8;
794
795	ifmedia_init(&sc->an_ifmedia, 0, an_media_change, an_media_status);
796	if_printf(ifp, "supported rates: ");
797#define	ADD(s, o)	ifmedia_add(&sc->an_ifmedia, \
798	IFM_MAKEWORD(IFM_IEEE80211, (s), (o), 0), 0, NULL)
799	ADD(IFM_AUTO, 0);
800	ADD(IFM_AUTO, IFM_IEEE80211_ADHOC);
801	for (i = 0; i < nrate; i++) {
802		r = sc->an_caps.an_rates[i];
803		mword = ieee80211_rate2media(NULL, r, IEEE80211_T_DS);
804		if (mword == 0)
805			continue;
806		printf("%s%d%sMbps", (i != 0 ? " " : ""),
807		    (r & IEEE80211_RATE_VAL) / 2, ((r & 0x1) != 0 ? ".5" : ""));
808		ADD(mword, 0);
809		ADD(mword, IFM_IEEE80211_ADHOC);
810	}
811	printf("\n");
812	ifmedia_set(&sc->an_ifmedia, IFM_MAKEWORD(IFM_IEEE80211,
813	    IFM_AUTO, 0, 0));
814#undef ADD
815
816	/*
817	 * Call MI attach routine.
818	 */
819
820	ether_ifattach(ifp, sc->an_caps.an_oemaddr);
821	callout_init_mtx(&sc->an_stat_ch, &sc->an_mtx, 0);
822
823	return(0);
824fail:
825	AN_UNLOCK(sc);
826	mtx_destroy(&sc->an_mtx);
827	if (ifp != NULL)
828		if_free(ifp);
829	return(error);
830}
831
832int
833an_detach(device_t dev)
834{
835	struct an_softc		*sc = device_get_softc(dev);
836	struct ifnet		*ifp = sc->an_ifp;
837
838	if (sc->an_gone) {
839		device_printf(dev,"already unloaded\n");
840		return(0);
841	}
842	AN_LOCK(sc);
843	an_stop(sc);
844	sc->an_gone = 1;
845	ifmedia_removeall(&sc->an_ifmedia);
846	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
847	AN_UNLOCK(sc);
848	ether_ifdetach(ifp);
849	bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
850	callout_drain(&sc->an_stat_ch);
851	if_free(ifp);
852	an_release_resources(dev);
853	mtx_destroy(&sc->an_mtx);
854	return (0);
855}
856
857static void
858an_rxeof(struct an_softc *sc)
859{
860	struct ifnet   *ifp;
861	struct ether_header *eh;
862	struct ieee80211_frame *ih;
863	struct an_rxframe rx_frame;
864	struct an_rxframe_802_3 rx_frame_802_3;
865	struct mbuf    *m;
866	int		len, id, error = 0, i, count = 0;
867	int		ieee80211_header_len;
868	u_char		*bpf_buf;
869	u_short		fc1;
870	struct an_card_rx_desc an_rx_desc;
871	u_int8_t	*buf;
872
873	AN_LOCK_ASSERT(sc);
874
875	ifp = sc->an_ifp;
876
877	if (!sc->mpi350) {
878		id = CSR_READ_2(sc, AN_RX_FID);
879
880		if (sc->an_monitor && (ifp->if_flags & IFF_PROMISC)) {
881			/* read raw 802.11 packet */
882			bpf_buf = sc->buf_802_11;
883
884			/* read header */
885			if (an_read_data(sc, id, 0x0, (caddr_t)&rx_frame,
886					 sizeof(rx_frame))) {
887				ifp->if_ierrors++;
888				return;
889			}
890
891			/*
892			 * skip beacon by default since this increases the
893			 * system load a lot
894			 */
895
896			if (!(sc->an_monitor & AN_MONITOR_INCLUDE_BEACON) &&
897			    (rx_frame.an_frame_ctl &
898			     IEEE80211_FC0_SUBTYPE_BEACON)) {
899				return;
900			}
901
902			if (sc->an_monitor & AN_MONITOR_AIRONET_HEADER) {
903				len = rx_frame.an_rx_payload_len
904					+ sizeof(rx_frame);
905				/* Check for insane frame length */
906				if (len > sizeof(sc->buf_802_11)) {
907					if_printf(ifp, "oversized packet "
908					       "received (%d, %d)\n",
909					       len, MCLBYTES);
910					ifp->if_ierrors++;
911					return;
912				}
913
914				bcopy((char *)&rx_frame,
915				      bpf_buf, sizeof(rx_frame));
916
917				error = an_read_data(sc, id, sizeof(rx_frame),
918					    (caddr_t)bpf_buf+sizeof(rx_frame),
919					    rx_frame.an_rx_payload_len);
920			} else {
921				fc1=rx_frame.an_frame_ctl >> 8;
922				ieee80211_header_len =
923					sizeof(struct ieee80211_frame);
924				if ((fc1 & IEEE80211_FC1_DIR_TODS) &&
925				    (fc1 & IEEE80211_FC1_DIR_FROMDS)) {
926					ieee80211_header_len += ETHER_ADDR_LEN;
927				}
928
929				len = rx_frame.an_rx_payload_len
930					+ ieee80211_header_len;
931				/* Check for insane frame length */
932				if (len > sizeof(sc->buf_802_11)) {
933					if_printf(ifp, "oversized packet "
934					       "received (%d, %d)\n",
935					       len, MCLBYTES);
936					ifp->if_ierrors++;
937					return;
938				}
939
940				ih = (struct ieee80211_frame *)bpf_buf;
941
942				bcopy((char *)&rx_frame.an_frame_ctl,
943				      (char *)ih, ieee80211_header_len);
944
945				error = an_read_data(sc, id, sizeof(rx_frame) +
946					    rx_frame.an_gaplen,
947					    (caddr_t)ih +ieee80211_header_len,
948					    rx_frame.an_rx_payload_len);
949			}
950			/* dump raw 802.11 packet to bpf and skip ip stack */
951			BPF_TAP(ifp, bpf_buf, len);
952		} else {
953			MGETHDR(m, M_DONTWAIT, MT_DATA);
954			if (m == NULL) {
955				ifp->if_ierrors++;
956				return;
957			}
958			MCLGET(m, M_DONTWAIT);
959			if (!(m->m_flags & M_EXT)) {
960				m_freem(m);
961				ifp->if_ierrors++;
962				return;
963			}
964			m->m_pkthdr.rcvif = ifp;
965			/* Read Ethernet encapsulated packet */
966
967#ifdef ANCACHE
968			/* Read NIC frame header */
969			if (an_read_data(sc, id, 0, (caddr_t)&rx_frame,
970					 sizeof(rx_frame))) {
971				m_freem(m);
972				ifp->if_ierrors++;
973				return;
974			}
975#endif
976			/* Read in the 802_3 frame header */
977			if (an_read_data(sc, id, 0x34,
978					 (caddr_t)&rx_frame_802_3,
979					 sizeof(rx_frame_802_3))) {
980				m_freem(m);
981				ifp->if_ierrors++;
982				return;
983			}
984			if (rx_frame_802_3.an_rx_802_3_status != 0) {
985				m_freem(m);
986				ifp->if_ierrors++;
987				return;
988			}
989			/* Check for insane frame length */
990			len = rx_frame_802_3.an_rx_802_3_payload_len;
991			if (len > sizeof(sc->buf_802_11)) {
992				m_freem(m);
993				if_printf(ifp, "oversized packet "
994				       "received (%d, %d)\n",
995				       len, MCLBYTES);
996				ifp->if_ierrors++;
997				return;
998			}
999			m->m_pkthdr.len = m->m_len =
1000				rx_frame_802_3.an_rx_802_3_payload_len + 12;
1001
1002			eh = mtod(m, struct ether_header *);
1003
1004			bcopy((char *)&rx_frame_802_3.an_rx_dst_addr,
1005			      (char *)&eh->ether_dhost, ETHER_ADDR_LEN);
1006			bcopy((char *)&rx_frame_802_3.an_rx_src_addr,
1007			      (char *)&eh->ether_shost, ETHER_ADDR_LEN);
1008
1009			/* in mbuf header type is just before payload */
1010			error = an_read_data(sc, id, 0x44,
1011				    (caddr_t)&(eh->ether_type),
1012				    rx_frame_802_3.an_rx_802_3_payload_len);
1013
1014			if (error) {
1015				m_freem(m);
1016				ifp->if_ierrors++;
1017				return;
1018			}
1019			ifp->if_ipackets++;
1020
1021			/* Receive packet. */
1022#ifdef ANCACHE
1023			an_cache_store(sc, eh, m,
1024				rx_frame.an_rx_signal_strength,
1025				rx_frame.an_rsvd0);
1026#endif
1027			AN_UNLOCK(sc);
1028			(*ifp->if_input)(ifp, m);
1029			AN_LOCK(sc);
1030		}
1031
1032	} else { /* MPI-350 */
1033		for (count = 0; count < AN_MAX_RX_DESC; count++){
1034			for (i = 0; i < sizeof(an_rx_desc) / 4; i++)
1035				((u_int32_t *)(void *)&an_rx_desc)[i]
1036					= CSR_MEM_AUX_READ_4(sc,
1037						AN_RX_DESC_OFFSET
1038						+ (count * sizeof(an_rx_desc))
1039						+ (i * 4));
1040
1041			if (an_rx_desc.an_done && !an_rx_desc.an_valid) {
1042				buf = sc->an_rx_buffer[count].an_dma_vaddr;
1043
1044				MGETHDR(m, M_DONTWAIT, MT_DATA);
1045				if (m == NULL) {
1046					ifp->if_ierrors++;
1047					return;
1048				}
1049				MCLGET(m, M_DONTWAIT);
1050				if (!(m->m_flags & M_EXT)) {
1051					m_freem(m);
1052					ifp->if_ierrors++;
1053					return;
1054				}
1055				m->m_pkthdr.rcvif = ifp;
1056				/* Read Ethernet encapsulated packet */
1057
1058				/*
1059				 * No ANCACHE support since we just get back
1060				 * an Ethernet packet no 802.11 info
1061				 */
1062#if 0
1063#ifdef ANCACHE
1064				/* Read NIC frame header */
1065				bcopy(buf, (caddr_t)&rx_frame,
1066				      sizeof(rx_frame));
1067#endif
1068#endif
1069				/* Check for insane frame length */
1070				len = an_rx_desc.an_len + 12;
1071				if (len > MCLBYTES) {
1072					m_freem(m);
1073					if_printf(ifp, "oversized packet "
1074					       "received (%d, %d)\n",
1075					       len, MCLBYTES);
1076					ifp->if_ierrors++;
1077					return;
1078				}
1079
1080				m->m_pkthdr.len = m->m_len =
1081					an_rx_desc.an_len + 12;
1082
1083				eh = mtod(m, struct ether_header *);
1084
1085				bcopy(buf, (char *)eh,
1086				      m->m_pkthdr.len);
1087
1088				ifp->if_ipackets++;
1089
1090				/* Receive packet. */
1091#if 0
1092#ifdef ANCACHE
1093				an_cache_store(sc, eh, m,
1094					rx_frame.an_rx_signal_strength,
1095					rx_frame.an_rsvd0);
1096#endif
1097#endif
1098				AN_UNLOCK(sc);
1099				(*ifp->if_input)(ifp, m);
1100				AN_LOCK(sc);
1101
1102				an_rx_desc.an_valid = 1;
1103				an_rx_desc.an_len = AN_RX_BUFFER_SIZE;
1104				an_rx_desc.an_done = 0;
1105				an_rx_desc.an_phys =
1106					sc->an_rx_buffer[count].an_dma_paddr;
1107
1108				for (i = 0; i < sizeof(an_rx_desc) / 4; i++)
1109					CSR_MEM_AUX_WRITE_4(sc,
1110					    AN_RX_DESC_OFFSET
1111					    + (count * sizeof(an_rx_desc))
1112					    + (i * 4),
1113					    ((u_int32_t *)(void *)&an_rx_desc)[i]);
1114
1115			} else {
1116				if_printf(ifp, "Didn't get valid RX packet "
1117				       "%x %x %d\n",
1118				       an_rx_desc.an_done,
1119				       an_rx_desc.an_valid, an_rx_desc.an_len);
1120			}
1121		}
1122	}
1123}
1124
1125static void
1126an_txeof(struct an_softc *sc, int status)
1127{
1128	struct ifnet		*ifp;
1129	int			id, i;
1130
1131	AN_LOCK_ASSERT(sc);
1132	ifp = sc->an_ifp;
1133
1134	sc->an_timer = 0;
1135	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1136
1137	if (!sc->mpi350) {
1138		id = CSR_READ_2(sc, AN_TX_CMP_FID(sc->mpi350));
1139
1140		if (status & AN_EV_TX_EXC) {
1141			ifp->if_oerrors++;
1142		} else
1143			ifp->if_opackets++;
1144
1145		for (i = 0; i < AN_TX_RING_CNT; i++) {
1146			if (id == sc->an_rdata.an_tx_ring[i]) {
1147				sc->an_rdata.an_tx_ring[i] = 0;
1148				break;
1149			}
1150		}
1151
1152		AN_INC(sc->an_rdata.an_tx_cons, AN_TX_RING_CNT);
1153	} else { /* MPI 350 */
1154		id = CSR_READ_2(sc, AN_TX_CMP_FID(sc->mpi350));
1155		if (!sc->an_rdata.an_tx_empty){
1156			if (status & AN_EV_TX_EXC) {
1157				ifp->if_oerrors++;
1158			} else
1159				ifp->if_opackets++;
1160			AN_INC(sc->an_rdata.an_tx_cons, AN_MAX_TX_DESC);
1161			if (sc->an_rdata.an_tx_prod ==
1162			    sc->an_rdata.an_tx_cons)
1163				sc->an_rdata.an_tx_empty = 1;
1164		}
1165	}
1166
1167	return;
1168}
1169
1170/*
1171 * We abuse the stats updater to check the current NIC status. This
1172 * is important because we don't want to allow transmissions until
1173 * the NIC has synchronized to the current cell (either as the master
1174 * in an ad-hoc group, or as a station connected to an access point).
1175 *
1176 * Note that this function will be called via callout(9) with a lock held.
1177 */
1178static void
1179an_stats_update(void *xsc)
1180{
1181	struct an_softc		*sc;
1182	struct ifnet		*ifp;
1183
1184	sc = xsc;
1185	AN_LOCK_ASSERT(sc);
1186	ifp = sc->an_ifp;
1187	if (sc->an_timer > 0 && --sc->an_timer == 0)
1188		an_watchdog(sc);
1189
1190	sc->an_status.an_type = AN_RID_STATUS;
1191	sc->an_status.an_len = sizeof(struct an_ltv_status);
1192	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_status))
1193		return;
1194
1195	if (sc->an_status.an_opmode & AN_STATUS_OPMODE_IN_SYNC)
1196		sc->an_associated = 1;
1197	else
1198		sc->an_associated = 0;
1199
1200	/* Don't do this while we're transmitting */
1201	if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
1202		callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc);
1203		return;
1204	}
1205
1206	sc->an_stats.an_len = sizeof(struct an_ltv_stats);
1207	sc->an_stats.an_type = AN_RID_32BITS_CUM;
1208	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_stats.an_len))
1209		return;
1210
1211	callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc);
1212
1213	return;
1214}
1215
1216void
1217an_intr(void *xsc)
1218{
1219	struct an_softc		*sc;
1220	struct ifnet		*ifp;
1221	u_int16_t		status;
1222
1223	sc = (struct an_softc*)xsc;
1224
1225	AN_LOCK(sc);
1226
1227	if (sc->an_gone) {
1228		AN_UNLOCK(sc);
1229		return;
1230	}
1231
1232	ifp = sc->an_ifp;
1233
1234	/* Disable interrupts. */
1235	CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), 0);
1236
1237	status = CSR_READ_2(sc, AN_EVENT_STAT(sc->mpi350));
1238	CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), ~AN_INTRS(sc->mpi350));
1239
1240	if (status & AN_EV_MIC) {
1241		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_MIC);
1242	}
1243
1244	if (status & AN_EV_LINKSTAT) {
1245		if (CSR_READ_2(sc, AN_LINKSTAT(sc->mpi350))
1246		    == AN_LINKSTAT_ASSOCIATED)
1247			sc->an_associated = 1;
1248		else
1249			sc->an_associated = 0;
1250		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_LINKSTAT);
1251	}
1252
1253	if (status & AN_EV_RX) {
1254		an_rxeof(sc);
1255		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_RX);
1256	}
1257
1258	if (sc->mpi350 && status & AN_EV_TX_CPY) {
1259		an_txeof(sc, status);
1260		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_TX_CPY);
1261	}
1262
1263	if (status & AN_EV_TX) {
1264		an_txeof(sc, status);
1265		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_TX);
1266	}
1267
1268	if (status & AN_EV_TX_EXC) {
1269		an_txeof(sc, status);
1270		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_TX_EXC);
1271	}
1272
1273	if (status & AN_EV_ALLOC)
1274		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_ALLOC);
1275
1276	/* Re-enable interrupts. */
1277	CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), AN_INTRS(sc->mpi350));
1278
1279	if ((ifp->if_flags & IFF_UP) && !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
1280		an_start_locked(ifp);
1281
1282	AN_UNLOCK(sc);
1283
1284	return;
1285}
1286
1287
1288static int
1289an_cmd_struct(struct an_softc *sc, struct an_command *cmd,
1290    struct an_reply *reply)
1291{
1292	int			i;
1293
1294	AN_LOCK_ASSERT(sc);
1295	for (i = 0; i != AN_TIMEOUT; i++) {
1296		if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY) {
1297			DELAY(1000);
1298		} else
1299			break;
1300	}
1301
1302	if( i == AN_TIMEOUT) {
1303		printf("BUSY\n");
1304		return(ETIMEDOUT);
1305	}
1306
1307	CSR_WRITE_2(sc, AN_PARAM0(sc->mpi350), cmd->an_parm0);
1308	CSR_WRITE_2(sc, AN_PARAM1(sc->mpi350), cmd->an_parm1);
1309	CSR_WRITE_2(sc, AN_PARAM2(sc->mpi350), cmd->an_parm2);
1310	CSR_WRITE_2(sc, AN_COMMAND(sc->mpi350), cmd->an_cmd);
1311
1312	for (i = 0; i < AN_TIMEOUT; i++) {
1313		if (CSR_READ_2(sc, AN_EVENT_STAT(sc->mpi350)) & AN_EV_CMD)
1314			break;
1315		DELAY(1000);
1316	}
1317
1318	reply->an_resp0 = CSR_READ_2(sc, AN_RESP0(sc->mpi350));
1319	reply->an_resp1 = CSR_READ_2(sc, AN_RESP1(sc->mpi350));
1320	reply->an_resp2 = CSR_READ_2(sc, AN_RESP2(sc->mpi350));
1321	reply->an_status = CSR_READ_2(sc, AN_STATUS(sc->mpi350));
1322
1323	if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY)
1324		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350),
1325		    AN_EV_CLR_STUCK_BUSY);
1326
1327	/* Ack the command */
1328	CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CMD);
1329
1330	if (i == AN_TIMEOUT)
1331		return(ETIMEDOUT);
1332
1333	return(0);
1334}
1335
1336static int
1337an_cmd(struct an_softc *sc, int cmd, int val)
1338{
1339	int			i, s = 0;
1340
1341	AN_LOCK_ASSERT(sc);
1342	CSR_WRITE_2(sc, AN_PARAM0(sc->mpi350), val);
1343	CSR_WRITE_2(sc, AN_PARAM1(sc->mpi350), 0);
1344	CSR_WRITE_2(sc, AN_PARAM2(sc->mpi350), 0);
1345	CSR_WRITE_2(sc, AN_COMMAND(sc->mpi350), cmd);
1346
1347	for (i = 0; i < AN_TIMEOUT; i++) {
1348		if (CSR_READ_2(sc, AN_EVENT_STAT(sc->mpi350)) & AN_EV_CMD)
1349			break;
1350		else {
1351			if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) == cmd)
1352				CSR_WRITE_2(sc, AN_COMMAND(sc->mpi350), cmd);
1353		}
1354	}
1355
1356	for (i = 0; i < AN_TIMEOUT; i++) {
1357		CSR_READ_2(sc, AN_RESP0(sc->mpi350));
1358		CSR_READ_2(sc, AN_RESP1(sc->mpi350));
1359		CSR_READ_2(sc, AN_RESP2(sc->mpi350));
1360		s = CSR_READ_2(sc, AN_STATUS(sc->mpi350));
1361		if ((s & AN_STAT_CMD_CODE) == (cmd & AN_STAT_CMD_CODE))
1362			break;
1363	}
1364
1365	/* Ack the command */
1366	CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CMD);
1367
1368	if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY)
1369		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CLR_STUCK_BUSY);
1370
1371	if (i == AN_TIMEOUT)
1372		return(ETIMEDOUT);
1373
1374	return(0);
1375}
1376
1377/*
1378 * This reset sequence may look a little strange, but this is the
1379 * most reliable method I've found to really kick the NIC in the
1380 * head and force it to reboot correctly.
1381 */
1382static void
1383an_reset(struct an_softc *sc)
1384{
1385	if (sc->an_gone)
1386		return;
1387
1388	AN_LOCK_ASSERT(sc);
1389	an_cmd(sc, AN_CMD_ENABLE, 0);
1390	an_cmd(sc, AN_CMD_FW_RESTART, 0);
1391	an_cmd(sc, AN_CMD_NOOP2, 0);
1392
1393	if (an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0) == ETIMEDOUT)
1394		if_printf(sc->an_ifp, "reset failed\n");
1395
1396	an_cmd(sc, AN_CMD_DISABLE, 0);
1397
1398	return;
1399}
1400
1401/*
1402 * Read an LTV record from the NIC.
1403 */
1404static int
1405an_read_record(struct an_softc *sc, struct an_ltv_gen *ltv)
1406{
1407	struct an_ltv_gen	*an_ltv;
1408	struct an_card_rid_desc an_rid_desc;
1409	struct an_command	cmd;
1410	struct an_reply		reply;
1411	struct ifnet		*ifp;
1412	u_int16_t		*ptr;
1413	u_int8_t		*ptr2;
1414	int			i, len;
1415
1416	AN_LOCK_ASSERT(sc);
1417	if (ltv->an_len < 4 || ltv->an_type == 0)
1418		return(EINVAL);
1419
1420	ifp = sc->an_ifp;
1421	if (!sc->mpi350){
1422		/* Tell the NIC to enter record read mode. */
1423		if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) {
1424			if_printf(ifp, "RID access failed\n");
1425			return(EIO);
1426		}
1427
1428		/* Seek to the record. */
1429		if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) {
1430			if_printf(ifp, "seek to record failed\n");
1431			return(EIO);
1432		}
1433
1434		/*
1435		 * Read the length and record type and make sure they
1436		 * match what we expect (this verifies that we have enough
1437		 * room to hold all of the returned data).
1438		 * Length includes type but not length.
1439		 */
1440		len = CSR_READ_2(sc, AN_DATA1);
1441		if (len > (ltv->an_len - 2)) {
1442			if_printf(ifp, "record length mismatch -- expected %d, "
1443			       "got %d for Rid %x\n",
1444			       ltv->an_len - 2, len, ltv->an_type);
1445			len = ltv->an_len - 2;
1446		} else {
1447			ltv->an_len = len + 2;
1448		}
1449
1450		/* Now read the data. */
1451		len -= 2;	/* skip the type */
1452		ptr = &ltv->an_val;
1453		for (i = len; i > 1; i -= 2)
1454			*ptr++ = CSR_READ_2(sc, AN_DATA1);
1455		if (i) {
1456			ptr2 = (u_int8_t *)ptr;
1457			*ptr2 = CSR_READ_1(sc, AN_DATA1);
1458		}
1459	} else { /* MPI-350 */
1460		if (!sc->an_rid_buffer.an_dma_vaddr)
1461			return(EIO);
1462		an_rid_desc.an_valid = 1;
1463		an_rid_desc.an_len = AN_RID_BUFFER_SIZE;
1464		an_rid_desc.an_rid = 0;
1465		an_rid_desc.an_phys = sc->an_rid_buffer.an_dma_paddr;
1466		bzero(sc->an_rid_buffer.an_dma_vaddr, AN_RID_BUFFER_SIZE);
1467
1468		bzero(&cmd, sizeof(cmd));
1469		bzero(&reply, sizeof(reply));
1470		cmd.an_cmd = AN_CMD_ACCESS|AN_ACCESS_READ;
1471		cmd.an_parm0 = ltv->an_type;
1472
1473		for (i = 0; i < sizeof(an_rid_desc) / 4; i++)
1474			CSR_MEM_AUX_WRITE_4(sc, AN_HOST_DESC_OFFSET + i * 4,
1475			    ((u_int32_t *)(void *)&an_rid_desc)[i]);
1476
1477		if (an_cmd_struct(sc, &cmd, &reply)
1478		    || reply.an_status & AN_CMD_QUAL_MASK) {
1479			if_printf(ifp, "failed to read RID %x %x %x %x %x, %d\n",
1480			       ltv->an_type,
1481			       reply.an_status,
1482			       reply.an_resp0,
1483			       reply.an_resp1,
1484			       reply.an_resp2,
1485			       i);
1486			return(EIO);
1487		}
1488
1489		an_ltv = (struct an_ltv_gen *)sc->an_rid_buffer.an_dma_vaddr;
1490		if (an_ltv->an_len + 2 < an_rid_desc.an_len) {
1491			an_rid_desc.an_len = an_ltv->an_len;
1492		}
1493
1494		len = an_rid_desc.an_len;
1495		if (len > (ltv->an_len - 2)) {
1496			if_printf(ifp, "record length mismatch -- expected %d, "
1497			       "got %d for Rid %x\n",
1498			       ltv->an_len - 2, len, ltv->an_type);
1499			len = ltv->an_len - 2;
1500		} else {
1501			ltv->an_len = len + 2;
1502		}
1503		bcopy(&an_ltv->an_type,
1504		    &ltv->an_val,
1505		    len);
1506	}
1507
1508	if (an_dump)
1509		an_dump_record(sc, ltv, "Read");
1510
1511	return(0);
1512}
1513
1514/*
1515 * Same as read, except we inject data instead of reading it.
1516 */
1517static int
1518an_write_record(struct an_softc *sc, struct an_ltv_gen *ltv)
1519{
1520	struct an_card_rid_desc an_rid_desc;
1521	struct an_command	cmd;
1522	struct an_reply		reply;
1523	u_int16_t		*ptr;
1524	u_int8_t		*ptr2;
1525	int			i, len;
1526
1527	AN_LOCK_ASSERT(sc);
1528	if (an_dump)
1529		an_dump_record(sc, ltv, "Write");
1530
1531	if (!sc->mpi350){
1532		if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type))
1533			return(EIO);
1534
1535		if (an_seek(sc, ltv->an_type, 0, AN_BAP1))
1536			return(EIO);
1537
1538		/*
1539		 * Length includes type but not length.
1540		 */
1541		len = ltv->an_len - 2;
1542		CSR_WRITE_2(sc, AN_DATA1, len);
1543
1544		len -= 2;	/* skip the type */
1545		ptr = &ltv->an_val;
1546		for (i = len; i > 1; i -= 2)
1547			CSR_WRITE_2(sc, AN_DATA1, *ptr++);
1548		if (i) {
1549			ptr2 = (u_int8_t *)ptr;
1550			CSR_WRITE_1(sc, AN_DATA0, *ptr2);
1551		}
1552
1553		if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_WRITE, ltv->an_type))
1554			return(EIO);
1555	} else {
1556		/* MPI-350 */
1557
1558		for (i = 0; i != AN_TIMEOUT; i++) {
1559			if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350))
1560			    & AN_CMD_BUSY) {
1561				DELAY(10);
1562			} else
1563				break;
1564		}
1565		if (i == AN_TIMEOUT) {
1566			printf("BUSY\n");
1567		}
1568
1569		an_rid_desc.an_valid = 1;
1570		an_rid_desc.an_len = ltv->an_len - 2;
1571		an_rid_desc.an_rid = ltv->an_type;
1572		an_rid_desc.an_phys = sc->an_rid_buffer.an_dma_paddr;
1573
1574		bcopy(&ltv->an_type, sc->an_rid_buffer.an_dma_vaddr,
1575		      an_rid_desc.an_len);
1576
1577		bzero(&cmd,sizeof(cmd));
1578		bzero(&reply,sizeof(reply));
1579		cmd.an_cmd = AN_CMD_ACCESS|AN_ACCESS_WRITE;
1580		cmd.an_parm0 = ltv->an_type;
1581
1582		for (i = 0; i < sizeof(an_rid_desc) / 4; i++)
1583			CSR_MEM_AUX_WRITE_4(sc, AN_HOST_DESC_OFFSET + i * 4,
1584			    ((u_int32_t *)(void *)&an_rid_desc)[i]);
1585
1586		DELAY(100000);
1587
1588		if ((i = an_cmd_struct(sc, &cmd, &reply))) {
1589			if_printf(sc->an_ifp,
1590			    "failed to write RID 1 %x %x %x %x %x, %d\n",
1591			    ltv->an_type,
1592			    reply.an_status,
1593			    reply.an_resp0,
1594			    reply.an_resp1,
1595			    reply.an_resp2,
1596			    i);
1597			return(EIO);
1598		}
1599
1600
1601		if (reply.an_status & AN_CMD_QUAL_MASK) {
1602			if_printf(sc->an_ifp,
1603			    "failed to write RID 2 %x %x %x %x %x, %d\n",
1604			    ltv->an_type,
1605			    reply.an_status,
1606			    reply.an_resp0,
1607			    reply.an_resp1,
1608			    reply.an_resp2,
1609			    i);
1610			return(EIO);
1611		}
1612		DELAY(100000);
1613	}
1614
1615	return(0);
1616}
1617
1618static void
1619an_dump_record(struct an_softc *sc, struct an_ltv_gen *ltv, char *string)
1620{
1621	u_int8_t		*ptr2;
1622	int			len;
1623	int			i;
1624	int			count = 0;
1625	char			buf[17], temp;
1626
1627	len = ltv->an_len - 4;
1628	if_printf(sc->an_ifp, "RID %4x, Length %4d, Mode %s\n",
1629		ltv->an_type, ltv->an_len - 4, string);
1630
1631	if (an_dump == 1 || (an_dump == ltv->an_type)) {
1632		if_printf(sc->an_ifp, "\t");
1633		bzero(buf,sizeof(buf));
1634
1635		ptr2 = (u_int8_t *)&ltv->an_val;
1636		for (i = len; i > 0; i--) {
1637			printf("%02x ", *ptr2);
1638
1639			temp = *ptr2++;
1640			if (isprint(temp))
1641				buf[count] = temp;
1642			else
1643				buf[count] = '.';
1644			if (++count == 16) {
1645				count = 0;
1646				printf("%s\n",buf);
1647				if_printf(sc->an_ifp, "\t");
1648				bzero(buf,sizeof(buf));
1649			}
1650		}
1651		for (; count != 16; count++) {
1652			printf("   ");
1653		}
1654		printf(" %s\n",buf);
1655	}
1656}
1657
1658static int
1659an_seek(struct an_softc *sc, int id, int off, int chan)
1660{
1661	int			i;
1662	int			selreg, offreg;
1663
1664	switch (chan) {
1665	case AN_BAP0:
1666		selreg = AN_SEL0;
1667		offreg = AN_OFF0;
1668		break;
1669	case AN_BAP1:
1670		selreg = AN_SEL1;
1671		offreg = AN_OFF1;
1672		break;
1673	default:
1674		if_printf(sc->an_ifp, "invalid data path: %x\n", chan);
1675		return(EIO);
1676	}
1677
1678	CSR_WRITE_2(sc, selreg, id);
1679	CSR_WRITE_2(sc, offreg, off);
1680
1681	for (i = 0; i < AN_TIMEOUT; i++) {
1682		if (!(CSR_READ_2(sc, offreg) & (AN_OFF_BUSY|AN_OFF_ERR)))
1683			break;
1684	}
1685
1686	if (i == AN_TIMEOUT)
1687		return(ETIMEDOUT);
1688
1689	return(0);
1690}
1691
1692static int
1693an_read_data(struct an_softc *sc, int id, int off, caddr_t buf, int len)
1694{
1695	int			i;
1696	u_int16_t		*ptr;
1697	u_int8_t		*ptr2;
1698
1699	if (off != -1) {
1700		if (an_seek(sc, id, off, AN_BAP1))
1701			return(EIO);
1702	}
1703
1704	ptr = (u_int16_t *)buf;
1705	for (i = len; i > 1; i -= 2)
1706		*ptr++ = CSR_READ_2(sc, AN_DATA1);
1707	if (i) {
1708		ptr2 = (u_int8_t *)ptr;
1709		*ptr2 = CSR_READ_1(sc, AN_DATA1);
1710	}
1711
1712	return(0);
1713}
1714
1715static int
1716an_write_data(struct an_softc *sc, int id, int off, caddr_t buf, int len)
1717{
1718	int			i;
1719	u_int16_t		*ptr;
1720	u_int8_t		*ptr2;
1721
1722	if (off != -1) {
1723		if (an_seek(sc, id, off, AN_BAP0))
1724			return(EIO);
1725	}
1726
1727	ptr = (u_int16_t *)buf;
1728	for (i = len; i > 1; i -= 2)
1729		CSR_WRITE_2(sc, AN_DATA0, *ptr++);
1730	if (i) {
1731		ptr2 = (u_int8_t *)ptr;
1732		CSR_WRITE_1(sc, AN_DATA0, *ptr2);
1733	}
1734
1735	return(0);
1736}
1737
1738/*
1739 * Allocate a region of memory inside the NIC and zero
1740 * it out.
1741 */
1742static int
1743an_alloc_nicmem(struct an_softc *sc, int len, int *id)
1744{
1745	int			i;
1746
1747	if (an_cmd(sc, AN_CMD_ALLOC_MEM, len)) {
1748		if_printf(sc->an_ifp, "failed to allocate %d bytes on NIC\n",
1749		    len);
1750		return(ENOMEM);
1751	}
1752
1753	for (i = 0; i < AN_TIMEOUT; i++) {
1754		if (CSR_READ_2(sc, AN_EVENT_STAT(sc->mpi350)) & AN_EV_ALLOC)
1755			break;
1756	}
1757
1758	if (i == AN_TIMEOUT)
1759		return(ETIMEDOUT);
1760
1761	CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_ALLOC);
1762	*id = CSR_READ_2(sc, AN_ALLOC_FID);
1763
1764	if (an_seek(sc, *id, 0, AN_BAP0))
1765		return(EIO);
1766
1767	for (i = 0; i < len / 2; i++)
1768		CSR_WRITE_2(sc, AN_DATA0, 0);
1769
1770	return(0);
1771}
1772
1773static void
1774an_setdef(struct an_softc *sc, struct an_req *areq)
1775{
1776	struct ifnet		*ifp;
1777	struct an_ltv_genconfig	*cfg;
1778	struct an_ltv_ssidlist_new	*ssid;
1779	struct an_ltv_aplist	*ap;
1780	struct an_ltv_gen	*sp;
1781
1782	ifp = sc->an_ifp;
1783
1784	AN_LOCK_ASSERT(sc);
1785	switch (areq->an_type) {
1786	case AN_RID_GENCONFIG:
1787		cfg = (struct an_ltv_genconfig *)areq;
1788
1789		bcopy((char *)&cfg->an_macaddr, IF_LLADDR(sc->an_ifp),
1790		    ETHER_ADDR_LEN);
1791
1792		bcopy((char *)cfg, (char *)&sc->an_config,
1793			sizeof(struct an_ltv_genconfig));
1794		break;
1795	case AN_RID_SSIDLIST:
1796		ssid = (struct an_ltv_ssidlist_new *)areq;
1797		bcopy((char *)ssid, (char *)&sc->an_ssidlist,
1798			sizeof(struct an_ltv_ssidlist_new));
1799		break;
1800	case AN_RID_APLIST:
1801		ap = (struct an_ltv_aplist *)areq;
1802		bcopy((char *)ap, (char *)&sc->an_aplist,
1803			sizeof(struct an_ltv_aplist));
1804		break;
1805	case AN_RID_TX_SPEED:
1806		sp = (struct an_ltv_gen *)areq;
1807		sc->an_tx_rate = sp->an_val;
1808
1809		/* Read the current configuration */
1810		sc->an_config.an_type = AN_RID_GENCONFIG;
1811		sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
1812		an_read_record(sc, (struct an_ltv_gen *)&sc->an_config);
1813		cfg = &sc->an_config;
1814
1815		/* clear other rates and set the only one we want */
1816		bzero(cfg->an_rates, sizeof(cfg->an_rates));
1817		cfg->an_rates[0] = sc->an_tx_rate;
1818
1819		/* Save the new rate */
1820		sc->an_config.an_type = AN_RID_GENCONFIG;
1821		sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
1822		break;
1823	case AN_RID_WEP_TEMP:
1824		/* Cache the temp keys */
1825		bcopy(areq,
1826		    &sc->an_temp_keys[((struct an_ltv_key *)areq)->kindex],
1827		    sizeof(struct an_ltv_key));
1828	case AN_RID_WEP_PERM:
1829	case AN_RID_LEAPUSERNAME:
1830	case AN_RID_LEAPPASSWORD:
1831		an_init_locked(sc);
1832
1833		/* Disable the MAC. */
1834		an_cmd(sc, AN_CMD_DISABLE, 0);
1835
1836		/* Write the key */
1837		an_write_record(sc, (struct an_ltv_gen *)areq);
1838
1839		/* Turn the MAC back on. */
1840		an_cmd(sc, AN_CMD_ENABLE, 0);
1841
1842		break;
1843	case AN_RID_MONITOR_MODE:
1844		cfg = (struct an_ltv_genconfig *)areq;
1845		bpfdetach(ifp);
1846		if (ng_ether_detach_p != NULL)
1847			(*ng_ether_detach_p) (ifp);
1848		sc->an_monitor = cfg->an_len;
1849
1850		if (sc->an_monitor & AN_MONITOR) {
1851			if (sc->an_monitor & AN_MONITOR_AIRONET_HEADER) {
1852				bpfattach(ifp, DLT_AIRONET_HEADER,
1853					sizeof(struct ether_header));
1854			} else {
1855				bpfattach(ifp, DLT_IEEE802_11,
1856					sizeof(struct ether_header));
1857			}
1858		} else {
1859			bpfattach(ifp, DLT_EN10MB,
1860				  sizeof(struct ether_header));
1861			if (ng_ether_attach_p != NULL)
1862				(*ng_ether_attach_p) (ifp);
1863		}
1864		break;
1865	default:
1866		if_printf(ifp, "unknown RID: %x\n", areq->an_type);
1867		return;
1868	}
1869
1870
1871	/* Reinitialize the card. */
1872	if (ifp->if_flags)
1873		an_init_locked(sc);
1874
1875	return;
1876}
1877
1878/*
1879 * Derived from Linux driver to enable promiscious mode.
1880 */
1881
1882static void
1883an_promisc(struct an_softc *sc, int promisc)
1884{
1885	AN_LOCK_ASSERT(sc);
1886	if (sc->an_was_monitor) {
1887		an_reset(sc);
1888		if (sc->mpi350)
1889			an_init_mpi350_desc(sc);
1890	}
1891	if (sc->an_monitor || sc->an_was_monitor)
1892		an_init_locked(sc);
1893
1894	sc->an_was_monitor = sc->an_monitor;
1895	an_cmd(sc, AN_CMD_SET_MODE, promisc ? 0xffff : 0);
1896
1897	return;
1898}
1899
1900static int
1901an_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
1902{
1903	int			error = 0;
1904	int			len;
1905	int			i, max;
1906	struct an_softc		*sc;
1907	struct ifreq		*ifr;
1908	struct thread		*td = curthread;
1909	struct ieee80211req	*ireq;
1910	struct ieee80211_channel	ch;
1911	u_int8_t		tmpstr[IEEE80211_NWID_LEN*2];
1912	u_int8_t		*tmpptr;
1913	struct an_ltv_genconfig	*config;
1914	struct an_ltv_key	*key;
1915	struct an_ltv_status	*status;
1916	struct an_ltv_ssidlist_new	*ssids;
1917	int			mode;
1918	struct aironet_ioctl	l_ioctl;
1919
1920	sc = ifp->if_softc;
1921	ifr = (struct ifreq *)data;
1922	ireq = (struct ieee80211req *)data;
1923
1924	config = (struct an_ltv_genconfig *)&sc->areq;
1925	key = (struct an_ltv_key *)&sc->areq;
1926	status = (struct an_ltv_status *)&sc->areq;
1927	ssids = (struct an_ltv_ssidlist_new *)&sc->areq;
1928
1929	if (sc->an_gone) {
1930		error = ENODEV;
1931		goto out;
1932	}
1933
1934	switch (command) {
1935	case SIOCSIFFLAGS:
1936		AN_LOCK(sc);
1937		if (ifp->if_flags & IFF_UP) {
1938			if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
1939			    ifp->if_flags & IFF_PROMISC &&
1940			    !(sc->an_if_flags & IFF_PROMISC)) {
1941				an_promisc(sc, 1);
1942			} else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
1943			    !(ifp->if_flags & IFF_PROMISC) &&
1944			    sc->an_if_flags & IFF_PROMISC) {
1945				an_promisc(sc, 0);
1946			} else
1947				an_init_locked(sc);
1948		} else {
1949			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1950				an_stop(sc);
1951		}
1952		sc->an_if_flags = ifp->if_flags;
1953		AN_UNLOCK(sc);
1954		error = 0;
1955		break;
1956	case SIOCSIFMEDIA:
1957	case SIOCGIFMEDIA:
1958		error = ifmedia_ioctl(ifp, ifr, &sc->an_ifmedia, command);
1959		break;
1960	case SIOCADDMULTI:
1961	case SIOCDELMULTI:
1962		/* The Aironet has no multicast filter. */
1963		error = 0;
1964		break;
1965	case SIOCGAIRONET:
1966		error = copyin(ifr->ifr_data, &sc->areq, sizeof(sc->areq));
1967		if (error != 0)
1968			break;
1969		AN_LOCK(sc);
1970#ifdef ANCACHE
1971		if (sc->areq.an_type == AN_RID_ZERO_CACHE) {
1972			error = priv_check(td, PRIV_DRIVER);
1973			if (error)
1974				break;
1975			sc->an_sigitems = sc->an_nextitem = 0;
1976			break;
1977		} else if (sc->areq.an_type == AN_RID_READ_CACHE) {
1978			char *pt = (char *)&sc->areq.an_val;
1979			bcopy((char *)&sc->an_sigitems, (char *)pt,
1980			    sizeof(int));
1981			pt += sizeof(int);
1982			sc->areq.an_len = sizeof(int) / 2;
1983			bcopy((char *)&sc->an_sigcache, (char *)pt,
1984			    sizeof(struct an_sigcache) * sc->an_sigitems);
1985			sc->areq.an_len += ((sizeof(struct an_sigcache) *
1986			    sc->an_sigitems) / 2) + 1;
1987		} else
1988#endif
1989		if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) {
1990			AN_UNLOCK(sc);
1991			error = EINVAL;
1992			break;
1993		}
1994		AN_UNLOCK(sc);
1995		error = copyout(&sc->areq, ifr->ifr_data, sizeof(sc->areq));
1996		break;
1997	case SIOCSAIRONET:
1998		if ((error = priv_check(td, PRIV_DRIVER)))
1999			goto out;
2000		AN_LOCK(sc);
2001		error = copyin(ifr->ifr_data, &sc->areq, sizeof(sc->areq));
2002		if (error != 0)
2003			break;
2004		an_setdef(sc, &sc->areq);
2005		AN_UNLOCK(sc);
2006		break;
2007	case SIOCGPRIVATE_0:		/* used by Cisco client utility */
2008		if ((error = priv_check(td, PRIV_DRIVER)))
2009			goto out;
2010		error = copyin(ifr->ifr_data, &l_ioctl, sizeof(l_ioctl));
2011		if (error)
2012			goto out;
2013		mode = l_ioctl.command;
2014
2015		AN_LOCK(sc);
2016		if (mode >= AIROGCAP && mode <= AIROGSTATSD32) {
2017			error = readrids(ifp, &l_ioctl);
2018		} else if (mode >= AIROPCAP && mode <= AIROPLEAPUSR) {
2019			error = writerids(ifp, &l_ioctl);
2020		} else if (mode >= AIROFLSHRST && mode <= AIRORESTART) {
2021			error = flashcard(ifp, &l_ioctl);
2022		} else {
2023			error =-1;
2024		}
2025		AN_UNLOCK(sc);
2026		if (!error) {
2027			/* copy out the updated command info */
2028			error = copyout(&l_ioctl, ifr->ifr_data, sizeof(l_ioctl));
2029		}
2030		break;
2031	case SIOCGPRIVATE_1:		/* used by Cisco client utility */
2032		if ((error = priv_check(td, PRIV_DRIVER)))
2033			goto out;
2034		error = copyin(ifr->ifr_data, &l_ioctl, sizeof(l_ioctl));
2035		if (error)
2036			goto out;
2037		l_ioctl.command = 0;
2038		error = AIROMAGIC;
2039		(void) copyout(&error, l_ioctl.data, sizeof(error));
2040		error = 0;
2041		break;
2042	case SIOCG80211:
2043		sc->areq.an_len = sizeof(sc->areq);
2044		/* was that a good idea DJA we are doing a short-cut */
2045		switch (ireq->i_type) {
2046		case IEEE80211_IOC_SSID:
2047			AN_LOCK(sc);
2048			if (ireq->i_val == -1) {
2049				sc->areq.an_type = AN_RID_STATUS;
2050				if (an_read_record(sc,
2051				    (struct an_ltv_gen *)&sc->areq)) {
2052					error = EINVAL;
2053					AN_UNLOCK(sc);
2054					break;
2055				}
2056				len = status->an_ssidlen;
2057				tmpptr = status->an_ssid;
2058			} else if (ireq->i_val >= 0) {
2059				sc->areq.an_type = AN_RID_SSIDLIST;
2060				if (an_read_record(sc,
2061				    (struct an_ltv_gen *)&sc->areq)) {
2062					error = EINVAL;
2063					AN_UNLOCK(sc);
2064					break;
2065				}
2066				max = (sc->areq.an_len - 4)
2067				    / sizeof(struct an_ltv_ssid_entry);
2068				if ( max > MAX_SSIDS ) {
2069					printf("To many SSIDs only using "
2070					    "%d of %d\n",
2071					    MAX_SSIDS, max);
2072					max = MAX_SSIDS;
2073				}
2074				if (ireq->i_val > max) {
2075					error = EINVAL;
2076					AN_UNLOCK(sc);
2077					break;
2078				} else {
2079					len = ssids->an_entry[ireq->i_val].an_len;
2080					tmpptr = ssids->an_entry[ireq->i_val].an_ssid;
2081				}
2082			} else {
2083				error = EINVAL;
2084				AN_UNLOCK(sc);
2085				break;
2086			}
2087			if (len > IEEE80211_NWID_LEN) {
2088				error = EINVAL;
2089				AN_UNLOCK(sc);
2090				break;
2091			}
2092			AN_UNLOCK(sc);
2093			ireq->i_len = len;
2094			bzero(tmpstr, IEEE80211_NWID_LEN);
2095			bcopy(tmpptr, tmpstr, len);
2096			error = copyout(tmpstr, ireq->i_data,
2097			    IEEE80211_NWID_LEN);
2098			break;
2099		case IEEE80211_IOC_NUMSSIDS:
2100			AN_LOCK(sc);
2101			sc->areq.an_len = sizeof(sc->areq);
2102			sc->areq.an_type = AN_RID_SSIDLIST;
2103			if (an_read_record(sc,
2104			    (struct an_ltv_gen *)&sc->areq)) {
2105				AN_UNLOCK(sc);
2106				error = EINVAL;
2107				break;
2108			}
2109			max = (sc->areq.an_len - 4)
2110			    / sizeof(struct an_ltv_ssid_entry);
2111			AN_UNLOCK(sc);
2112			if ( max > MAX_SSIDS ) {
2113				printf("To many SSIDs only using "
2114				    "%d of %d\n",
2115				    MAX_SSIDS, max);
2116				max = MAX_SSIDS;
2117			}
2118			ireq->i_val = max;
2119			break;
2120		case IEEE80211_IOC_WEP:
2121			AN_LOCK(sc);
2122			sc->areq.an_type = AN_RID_ACTUALCFG;
2123			if (an_read_record(sc,
2124			    (struct an_ltv_gen *)&sc->areq)) {
2125				error = EINVAL;
2126				AN_UNLOCK(sc);
2127				break;
2128			}
2129			AN_UNLOCK(sc);
2130			if (config->an_authtype & AN_AUTHTYPE_PRIVACY_IN_USE) {
2131				if (config->an_authtype &
2132				    AN_AUTHTYPE_ALLOW_UNENCRYPTED)
2133					ireq->i_val = IEEE80211_WEP_MIXED;
2134				else
2135					ireq->i_val = IEEE80211_WEP_ON;
2136			} else {
2137				ireq->i_val = IEEE80211_WEP_OFF;
2138			}
2139			break;
2140		case IEEE80211_IOC_WEPKEY:
2141			/*
2142			 * XXX: I'm not entierly convinced this is
2143			 * correct, but it's what is implemented in
2144			 * ancontrol so it will have to do until we get
2145			 * access to actual Cisco code.
2146			 */
2147			if (ireq->i_val < 0 || ireq->i_val > 8) {
2148				error = EINVAL;
2149				break;
2150			}
2151			len = 0;
2152			if (ireq->i_val < 5) {
2153				AN_LOCK(sc);
2154				sc->areq.an_type = AN_RID_WEP_TEMP;
2155				for (i = 0; i < 5; i++) {
2156					if (an_read_record(sc,
2157					    (struct an_ltv_gen *)&sc->areq)) {
2158						error = EINVAL;
2159						break;
2160					}
2161					if (key->kindex == 0xffff)
2162						break;
2163					if (key->kindex == ireq->i_val)
2164						len = key->klen;
2165					/* Required to get next entry */
2166					sc->areq.an_type = AN_RID_WEP_PERM;
2167				}
2168				AN_UNLOCK(sc);
2169				if (error != 0) {
2170					break;
2171				}
2172			}
2173			/* We aren't allowed to read the value of the
2174			 * key from the card so we just output zeros
2175			 * like we would if we could read the card, but
2176			 * denied the user access.
2177			 */
2178			bzero(tmpstr, len);
2179			ireq->i_len = len;
2180			error = copyout(tmpstr, ireq->i_data, len);
2181			break;
2182		case IEEE80211_IOC_NUMWEPKEYS:
2183			ireq->i_val = 9; /* include home key */
2184			break;
2185		case IEEE80211_IOC_WEPTXKEY:
2186			/*
2187			 * For some strange reason, you have to read all
2188			 * keys before you can read the txkey.
2189			 */
2190			AN_LOCK(sc);
2191			sc->areq.an_type = AN_RID_WEP_TEMP;
2192			for (i = 0; i < 5; i++) {
2193				if (an_read_record(sc,
2194				    (struct an_ltv_gen *) &sc->areq)) {
2195					error = EINVAL;
2196					break;
2197				}
2198				if (key->kindex == 0xffff) {
2199					break;
2200				}
2201				/* Required to get next entry */
2202				sc->areq.an_type = AN_RID_WEP_PERM;
2203			}
2204			if (error != 0) {
2205				AN_UNLOCK(sc);
2206				break;
2207			}
2208
2209			sc->areq.an_type = AN_RID_WEP_PERM;
2210			key->kindex = 0xffff;
2211			if (an_read_record(sc,
2212			    (struct an_ltv_gen *)&sc->areq)) {
2213				error = EINVAL;
2214				AN_UNLOCK(sc);
2215				break;
2216			}
2217			ireq->i_val = key->mac[0];
2218			/*
2219			 * Check for home mode.  Map home mode into
2220			 * 5th key since that is how it is stored on
2221			 * the card
2222			 */
2223			sc->areq.an_len  = sizeof(struct an_ltv_genconfig);
2224			sc->areq.an_type = AN_RID_GENCONFIG;
2225			if (an_read_record(sc,
2226			    (struct an_ltv_gen *)&sc->areq)) {
2227				error = EINVAL;
2228				AN_UNLOCK(sc);
2229				break;
2230			}
2231			if (config->an_home_product & AN_HOME_NETWORK)
2232				ireq->i_val = 4;
2233			AN_UNLOCK(sc);
2234			break;
2235		case IEEE80211_IOC_AUTHMODE:
2236			AN_LOCK(sc);
2237			sc->areq.an_type = AN_RID_ACTUALCFG;
2238			if (an_read_record(sc,
2239			    (struct an_ltv_gen *)&sc->areq)) {
2240				error = EINVAL;
2241				AN_UNLOCK(sc);
2242				break;
2243			}
2244			AN_UNLOCK(sc);
2245			if ((config->an_authtype & AN_AUTHTYPE_MASK) ==
2246			    AN_AUTHTYPE_NONE) {
2247			    ireq->i_val = IEEE80211_AUTH_NONE;
2248			} else if ((config->an_authtype & AN_AUTHTYPE_MASK) ==
2249			    AN_AUTHTYPE_OPEN) {
2250			    ireq->i_val = IEEE80211_AUTH_OPEN;
2251			} else if ((config->an_authtype & AN_AUTHTYPE_MASK) ==
2252			    AN_AUTHTYPE_SHAREDKEY) {
2253			    ireq->i_val = IEEE80211_AUTH_SHARED;
2254			} else
2255				error = EINVAL;
2256			break;
2257		case IEEE80211_IOC_STATIONNAME:
2258			AN_LOCK(sc);
2259			sc->areq.an_type = AN_RID_ACTUALCFG;
2260			if (an_read_record(sc,
2261			    (struct an_ltv_gen *)&sc->areq)) {
2262				error = EINVAL;
2263				AN_UNLOCK(sc);
2264				break;
2265			}
2266			AN_UNLOCK(sc);
2267			ireq->i_len = sizeof(config->an_nodename);
2268			tmpptr = config->an_nodename;
2269			bzero(tmpstr, IEEE80211_NWID_LEN);
2270			bcopy(tmpptr, tmpstr, ireq->i_len);
2271			error = copyout(tmpstr, ireq->i_data,
2272			    IEEE80211_NWID_LEN);
2273			break;
2274		case IEEE80211_IOC_CHANNEL:
2275			AN_LOCK(sc);
2276			sc->areq.an_type = AN_RID_STATUS;
2277			if (an_read_record(sc,
2278			    (struct an_ltv_gen *)&sc->areq)) {
2279				error = EINVAL;
2280				AN_UNLOCK(sc);
2281				break;
2282			}
2283			AN_UNLOCK(sc);
2284			ireq->i_val = status->an_cur_channel;
2285			break;
2286		case IEEE80211_IOC_CURCHAN:
2287			AN_LOCK(sc);
2288			sc->areq.an_type = AN_RID_STATUS;
2289			if (an_read_record(sc,
2290			    (struct an_ltv_gen *)&sc->areq)) {
2291				error = EINVAL;
2292				AN_UNLOCK(sc);
2293				break;
2294			}
2295			AN_UNLOCK(sc);
2296			bzero(&ch, sizeof(ch));
2297			ch.ic_freq = ieee80211_ieee2mhz(status->an_cur_channel,
2298			    IEEE80211_CHAN_B);
2299			ch.ic_flags = IEEE80211_CHAN_B;
2300			ch.ic_ieee = status->an_cur_channel;
2301			error = copyout(&ch, ireq->i_data, sizeof(ch));
2302			break;
2303		case IEEE80211_IOC_POWERSAVE:
2304			AN_LOCK(sc);
2305			sc->areq.an_type = AN_RID_ACTUALCFG;
2306			if (an_read_record(sc,
2307			    (struct an_ltv_gen *)&sc->areq)) {
2308				error = EINVAL;
2309				AN_UNLOCK(sc);
2310				break;
2311			}
2312			AN_UNLOCK(sc);
2313			if (config->an_psave_mode == AN_PSAVE_NONE) {
2314				ireq->i_val = IEEE80211_POWERSAVE_OFF;
2315			} else if (config->an_psave_mode == AN_PSAVE_CAM) {
2316				ireq->i_val = IEEE80211_POWERSAVE_CAM;
2317			} else if (config->an_psave_mode == AN_PSAVE_PSP) {
2318				ireq->i_val = IEEE80211_POWERSAVE_PSP;
2319			} else if (config->an_psave_mode == AN_PSAVE_PSP_CAM) {
2320				ireq->i_val = IEEE80211_POWERSAVE_PSP_CAM;
2321			} else
2322				error = EINVAL;
2323			break;
2324		case IEEE80211_IOC_POWERSAVESLEEP:
2325			AN_LOCK(sc);
2326			sc->areq.an_type = AN_RID_ACTUALCFG;
2327			if (an_read_record(sc,
2328			    (struct an_ltv_gen *)&sc->areq)) {
2329				error = EINVAL;
2330				AN_UNLOCK(sc);
2331				break;
2332			}
2333			AN_UNLOCK(sc);
2334			ireq->i_val = config->an_listen_interval;
2335			break;
2336		}
2337		break;
2338	case SIOCS80211:
2339		if ((error = priv_check(td, PRIV_NET80211_MANAGE)))
2340			goto out;
2341		AN_LOCK(sc);
2342		sc->areq.an_len = sizeof(sc->areq);
2343		/*
2344		 * We need a config structure for everything but the WEP
2345		 * key management and SSIDs so we get it now so avoid
2346		 * duplicating this code every time.
2347		 */
2348		if (ireq->i_type != IEEE80211_IOC_SSID &&
2349		    ireq->i_type != IEEE80211_IOC_WEPKEY &&
2350		    ireq->i_type != IEEE80211_IOC_WEPTXKEY) {
2351			sc->areq.an_type = AN_RID_GENCONFIG;
2352			if (an_read_record(sc,
2353			    (struct an_ltv_gen *)&sc->areq)) {
2354				error = EINVAL;
2355				AN_UNLOCK(sc);
2356				break;
2357			}
2358		}
2359		switch (ireq->i_type) {
2360		case IEEE80211_IOC_SSID:
2361			sc->areq.an_len = sizeof(sc->areq);
2362			sc->areq.an_type = AN_RID_SSIDLIST;
2363			if (an_read_record(sc,
2364			    (struct an_ltv_gen *)&sc->areq)) {
2365				error = EINVAL;
2366				AN_UNLOCK(sc);
2367				break;
2368			}
2369			if (ireq->i_len > IEEE80211_NWID_LEN) {
2370				error = EINVAL;
2371				AN_UNLOCK(sc);
2372				break;
2373			}
2374			max = (sc->areq.an_len - 4)
2375			    / sizeof(struct an_ltv_ssid_entry);
2376			if ( max > MAX_SSIDS ) {
2377				printf("To many SSIDs only using "
2378				    "%d of %d\n",
2379				    MAX_SSIDS, max);
2380				max = MAX_SSIDS;
2381			}
2382			if (ireq->i_val > max) {
2383				error = EINVAL;
2384				AN_UNLOCK(sc);
2385				break;
2386			} else {
2387				error = copyin(ireq->i_data,
2388				    ssids->an_entry[ireq->i_val].an_ssid,
2389				    ireq->i_len);
2390				ssids->an_entry[ireq->i_val].an_len
2391				    = ireq->i_len;
2392				sc->areq.an_len = sizeof(sc->areq);
2393				sc->areq.an_type = AN_RID_SSIDLIST;
2394				an_setdef(sc, &sc->areq);
2395				AN_UNLOCK(sc);
2396				break;
2397			}
2398			break;
2399		case IEEE80211_IOC_WEP:
2400			switch (ireq->i_val) {
2401			case IEEE80211_WEP_OFF:
2402				config->an_authtype &=
2403				    ~(AN_AUTHTYPE_PRIVACY_IN_USE |
2404				    AN_AUTHTYPE_ALLOW_UNENCRYPTED);
2405				break;
2406			case IEEE80211_WEP_ON:
2407				config->an_authtype |=
2408				    AN_AUTHTYPE_PRIVACY_IN_USE;
2409				config->an_authtype &=
2410				    ~AN_AUTHTYPE_ALLOW_UNENCRYPTED;
2411				break;
2412			case IEEE80211_WEP_MIXED:
2413				config->an_authtype |=
2414				    AN_AUTHTYPE_PRIVACY_IN_USE |
2415				    AN_AUTHTYPE_ALLOW_UNENCRYPTED;
2416				break;
2417			default:
2418				error = EINVAL;
2419				break;
2420			}
2421			if (error != EINVAL)
2422				an_setdef(sc, &sc->areq);
2423			AN_UNLOCK(sc);
2424			break;
2425		case IEEE80211_IOC_WEPKEY:
2426			if (ireq->i_val < 0 || ireq->i_val > 8 ||
2427			    ireq->i_len > 13) {
2428				error = EINVAL;
2429				AN_UNLOCK(sc);
2430				break;
2431			}
2432			error = copyin(ireq->i_data, tmpstr, 13);
2433			if (error != 0) {
2434				AN_UNLOCK(sc);
2435				break;
2436			}
2437			/*
2438			 * Map the 9th key into the home mode
2439			 * since that is how it is stored on
2440			 * the card
2441			 */
2442			bzero(&sc->areq, sizeof(struct an_ltv_key));
2443			sc->areq.an_len = sizeof(struct an_ltv_key);
2444			key->mac[0] = 1;	/* The others are 0. */
2445			if (ireq->i_val < 4) {
2446				sc->areq.an_type = AN_RID_WEP_TEMP;
2447				key->kindex = ireq->i_val;
2448			} else {
2449				sc->areq.an_type = AN_RID_WEP_PERM;
2450				key->kindex = ireq->i_val - 4;
2451			}
2452			key->klen = ireq->i_len;
2453			bcopy(tmpstr, key->key, key->klen);
2454			an_setdef(sc, &sc->areq);
2455			AN_UNLOCK(sc);
2456			break;
2457		case IEEE80211_IOC_WEPTXKEY:
2458			if (ireq->i_val < 0 || ireq->i_val > 4) {
2459				error = EINVAL;
2460				AN_UNLOCK(sc);
2461				break;
2462			}
2463
2464			/*
2465			 * Map the 5th key into the home mode
2466			 * since that is how it is stored on
2467			 * the card
2468			 */
2469			sc->areq.an_len  = sizeof(struct an_ltv_genconfig);
2470			sc->areq.an_type = AN_RID_ACTUALCFG;
2471			if (an_read_record(sc,
2472			    (struct an_ltv_gen *)&sc->areq)) {
2473				error = EINVAL;
2474				AN_UNLOCK(sc);
2475				break;
2476			}
2477			if (ireq->i_val ==  4) {
2478				config->an_home_product |= AN_HOME_NETWORK;
2479				ireq->i_val = 0;
2480			} else {
2481				config->an_home_product &= ~AN_HOME_NETWORK;
2482			}
2483
2484			sc->an_config.an_home_product
2485				= config->an_home_product;
2486
2487			/* update configuration */
2488			an_init_locked(sc);
2489
2490			bzero(&sc->areq, sizeof(struct an_ltv_key));
2491			sc->areq.an_len = sizeof(struct an_ltv_key);
2492			sc->areq.an_type = AN_RID_WEP_PERM;
2493			key->kindex = 0xffff;
2494			key->mac[0] = ireq->i_val;
2495			an_setdef(sc, &sc->areq);
2496			AN_UNLOCK(sc);
2497			break;
2498		case IEEE80211_IOC_AUTHMODE:
2499			switch (ireq->i_val) {
2500			case IEEE80211_AUTH_NONE:
2501				config->an_authtype = AN_AUTHTYPE_NONE |
2502				    (config->an_authtype & ~AN_AUTHTYPE_MASK);
2503				break;
2504			case IEEE80211_AUTH_OPEN:
2505				config->an_authtype = AN_AUTHTYPE_OPEN |
2506				    (config->an_authtype & ~AN_AUTHTYPE_MASK);
2507				break;
2508			case IEEE80211_AUTH_SHARED:
2509				config->an_authtype = AN_AUTHTYPE_SHAREDKEY |
2510				    (config->an_authtype & ~AN_AUTHTYPE_MASK);
2511				break;
2512			default:
2513				error = EINVAL;
2514			}
2515			if (error != EINVAL) {
2516				an_setdef(sc, &sc->areq);
2517			}
2518			AN_UNLOCK(sc);
2519			break;
2520		case IEEE80211_IOC_STATIONNAME:
2521			if (ireq->i_len > 16) {
2522				error = EINVAL;
2523				AN_UNLOCK(sc);
2524				break;
2525			}
2526			bzero(config->an_nodename, 16);
2527			error = copyin(ireq->i_data,
2528			    config->an_nodename, ireq->i_len);
2529			an_setdef(sc, &sc->areq);
2530			AN_UNLOCK(sc);
2531			break;
2532		case IEEE80211_IOC_CHANNEL:
2533			/*
2534			 * The actual range is 1-14, but if you set it
2535			 * to 0 you get the default so we let that work
2536			 * too.
2537			 */
2538			if (ireq->i_val < 0 || ireq->i_val >14) {
2539				error = EINVAL;
2540				AN_UNLOCK(sc);
2541				break;
2542			}
2543			config->an_ds_channel = ireq->i_val;
2544			an_setdef(sc, &sc->areq);
2545			AN_UNLOCK(sc);
2546			break;
2547		case IEEE80211_IOC_POWERSAVE:
2548			switch (ireq->i_val) {
2549			case IEEE80211_POWERSAVE_OFF:
2550				config->an_psave_mode = AN_PSAVE_NONE;
2551				break;
2552			case IEEE80211_POWERSAVE_CAM:
2553				config->an_psave_mode = AN_PSAVE_CAM;
2554				break;
2555			case IEEE80211_POWERSAVE_PSP:
2556				config->an_psave_mode = AN_PSAVE_PSP;
2557				break;
2558			case IEEE80211_POWERSAVE_PSP_CAM:
2559				config->an_psave_mode = AN_PSAVE_PSP_CAM;
2560				break;
2561			default:
2562				error = EINVAL;
2563				break;
2564			}
2565			an_setdef(sc, &sc->areq);
2566			AN_UNLOCK(sc);
2567			break;
2568		case IEEE80211_IOC_POWERSAVESLEEP:
2569			config->an_listen_interval = ireq->i_val;
2570			an_setdef(sc, &sc->areq);
2571			AN_UNLOCK(sc);
2572			break;
2573		default:
2574			AN_UNLOCK(sc);
2575			break;
2576		}
2577
2578		/*
2579		if (!error) {
2580			AN_LOCK(sc);
2581			an_setdef(sc, &sc->areq);
2582			AN_UNLOCK(sc);
2583		}
2584		*/
2585		break;
2586	default:
2587		error = ether_ioctl(ifp, command, data);
2588		break;
2589	}
2590out:
2591
2592	return(error != 0);
2593}
2594
2595static int
2596an_init_tx_ring(struct an_softc *sc)
2597{
2598	int			i;
2599	int			id;
2600
2601	if (sc->an_gone)
2602		return (0);
2603
2604	if (!sc->mpi350) {
2605		for (i = 0; i < AN_TX_RING_CNT; i++) {
2606			if (an_alloc_nicmem(sc, 1518 +
2607			    0x44, &id))
2608				return(ENOMEM);
2609			sc->an_rdata.an_tx_fids[i] = id;
2610			sc->an_rdata.an_tx_ring[i] = 0;
2611		}
2612	}
2613
2614	sc->an_rdata.an_tx_prod = 0;
2615	sc->an_rdata.an_tx_cons = 0;
2616	sc->an_rdata.an_tx_empty = 1;
2617
2618	return(0);
2619}
2620
2621static void
2622an_init(void *xsc)
2623{
2624	struct an_softc		*sc = xsc;
2625
2626	AN_LOCK(sc);
2627	an_init_locked(sc);
2628	AN_UNLOCK(sc);
2629}
2630
2631static void
2632an_init_locked(struct an_softc *sc)
2633{
2634	struct ifnet *ifp;
2635
2636	AN_LOCK_ASSERT(sc);
2637	ifp = sc->an_ifp;
2638	if (sc->an_gone)
2639		return;
2640
2641	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
2642		an_stop(sc);
2643
2644	sc->an_associated = 0;
2645
2646	/* Allocate the TX buffers */
2647	if (an_init_tx_ring(sc)) {
2648		an_reset(sc);
2649		if (sc->mpi350)
2650			an_init_mpi350_desc(sc);
2651		if (an_init_tx_ring(sc)) {
2652			if_printf(ifp, "tx buffer allocation failed\n");
2653			return;
2654		}
2655	}
2656
2657	/* Set our MAC address. */
2658	bcopy((char *)IF_LLADDR(sc->an_ifp),
2659	    (char *)&sc->an_config.an_macaddr, ETHER_ADDR_LEN);
2660
2661	if (ifp->if_flags & IFF_BROADCAST)
2662		sc->an_config.an_rxmode = AN_RXMODE_BC_ADDR;
2663	else
2664		sc->an_config.an_rxmode = AN_RXMODE_ADDR;
2665
2666	if (ifp->if_flags & IFF_MULTICAST)
2667		sc->an_config.an_rxmode = AN_RXMODE_BC_MC_ADDR;
2668
2669	if (ifp->if_flags & IFF_PROMISC) {
2670		if (sc->an_monitor & AN_MONITOR) {
2671			if (sc->an_monitor & AN_MONITOR_ANY_BSS) {
2672				sc->an_config.an_rxmode |=
2673				    AN_RXMODE_80211_MONITOR_ANYBSS |
2674				    AN_RXMODE_NO_8023_HEADER;
2675			} else {
2676				sc->an_config.an_rxmode |=
2677				    AN_RXMODE_80211_MONITOR_CURBSS |
2678				    AN_RXMODE_NO_8023_HEADER;
2679			}
2680		}
2681	}
2682
2683#ifdef ANCACHE
2684	if (sc->an_have_rssimap)
2685		sc->an_config.an_rxmode |= AN_RXMODE_NORMALIZED_RSSI;
2686#endif
2687
2688	/* Set the ssid list */
2689	sc->an_ssidlist.an_type = AN_RID_SSIDLIST;
2690	sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist_new);
2691	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) {
2692		if_printf(ifp, "failed to set ssid list\n");
2693		return;
2694	}
2695
2696	/* Set the AP list */
2697	sc->an_aplist.an_type = AN_RID_APLIST;
2698	sc->an_aplist.an_len = sizeof(struct an_ltv_aplist);
2699	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) {
2700		if_printf(ifp, "failed to set AP list\n");
2701		return;
2702	}
2703
2704	/* Set the configuration in the NIC */
2705	sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
2706	sc->an_config.an_type = AN_RID_GENCONFIG;
2707	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_config)) {
2708		if_printf(ifp, "failed to set configuration\n");
2709		return;
2710	}
2711
2712	/* Enable the MAC */
2713	if (an_cmd(sc, AN_CMD_ENABLE, 0)) {
2714		if_printf(ifp, "failed to enable MAC\n");
2715		return;
2716	}
2717
2718	if (ifp->if_flags & IFF_PROMISC)
2719		an_cmd(sc, AN_CMD_SET_MODE, 0xffff);
2720
2721	/* enable interrupts */
2722	CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), AN_INTRS(sc->mpi350));
2723
2724	ifp->if_drv_flags |= IFF_DRV_RUNNING;
2725	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
2726
2727	callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc);
2728
2729	return;
2730}
2731
2732static void
2733an_start(struct ifnet *ifp)
2734{
2735	struct an_softc		*sc;
2736
2737	sc = ifp->if_softc;
2738	AN_LOCK(sc);
2739	an_start_locked(ifp);
2740	AN_UNLOCK(sc);
2741}
2742
2743static void
2744an_start_locked(struct ifnet *ifp)
2745{
2746	struct an_softc		*sc;
2747	struct mbuf		*m0 = NULL;
2748	struct an_txframe_802_3	tx_frame_802_3;
2749	struct ether_header	*eh;
2750	int			id, idx, i;
2751	unsigned char		txcontrol;
2752	struct an_card_tx_desc an_tx_desc;
2753	u_int8_t		*buf;
2754
2755	sc = ifp->if_softc;
2756
2757	AN_LOCK_ASSERT(sc);
2758	if (sc->an_gone)
2759		return;
2760
2761	if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
2762		return;
2763
2764	if (!sc->an_associated)
2765		return;
2766
2767	/* We can't send in monitor mode so toss any attempts. */
2768	if (sc->an_monitor && (ifp->if_flags & IFF_PROMISC)) {
2769		for (;;) {
2770			IFQ_DRV_DEQUEUE(&ifp->if_snd, m0);
2771			if (m0 == NULL)
2772				break;
2773			m_freem(m0);
2774		}
2775		return;
2776	}
2777
2778	idx = sc->an_rdata.an_tx_prod;
2779
2780	if (!sc->mpi350) {
2781		bzero((char *)&tx_frame_802_3, sizeof(tx_frame_802_3));
2782
2783		while (sc->an_rdata.an_tx_ring[idx] == 0) {
2784			IFQ_DRV_DEQUEUE(&ifp->if_snd, m0);
2785			if (m0 == NULL)
2786				break;
2787
2788			id = sc->an_rdata.an_tx_fids[idx];
2789			eh = mtod(m0, struct ether_header *);
2790
2791			bcopy((char *)&eh->ether_dhost,
2792			      (char *)&tx_frame_802_3.an_tx_dst_addr,
2793			      ETHER_ADDR_LEN);
2794			bcopy((char *)&eh->ether_shost,
2795			      (char *)&tx_frame_802_3.an_tx_src_addr,
2796			      ETHER_ADDR_LEN);
2797
2798			/* minus src/dest mac & type */
2799			tx_frame_802_3.an_tx_802_3_payload_len =
2800				m0->m_pkthdr.len - 12;
2801
2802			m_copydata(m0, sizeof(struct ether_header) - 2 ,
2803				   tx_frame_802_3.an_tx_802_3_payload_len,
2804				   (caddr_t)&sc->an_txbuf);
2805
2806			txcontrol = AN_TXCTL_8023;
2807			/* write the txcontrol only */
2808			an_write_data(sc, id, 0x08, (caddr_t)&txcontrol,
2809				      sizeof(txcontrol));
2810
2811			/* 802_3 header */
2812			an_write_data(sc, id, 0x34, (caddr_t)&tx_frame_802_3,
2813				      sizeof(struct an_txframe_802_3));
2814
2815			/* in mbuf header type is just before payload */
2816			an_write_data(sc, id, 0x44, (caddr_t)&sc->an_txbuf,
2817				      tx_frame_802_3.an_tx_802_3_payload_len);
2818
2819			/*
2820			 * If there's a BPF listner, bounce a copy of
2821			 * this frame to him.
2822			 */
2823			BPF_MTAP(ifp, m0);
2824
2825			m_freem(m0);
2826			m0 = NULL;
2827
2828			sc->an_rdata.an_tx_ring[idx] = id;
2829			if (an_cmd(sc, AN_CMD_TX, id))
2830				if_printf(ifp, "xmit failed\n");
2831
2832			AN_INC(idx, AN_TX_RING_CNT);
2833
2834			/*
2835			 * Set a timeout in case the chip goes out to lunch.
2836			 */
2837			sc->an_timer = 5;
2838		}
2839	} else { /* MPI-350 */
2840		/* Disable interrupts. */
2841		CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), 0);
2842
2843		while (sc->an_rdata.an_tx_empty ||
2844		    idx != sc->an_rdata.an_tx_cons) {
2845			IFQ_DRV_DEQUEUE(&ifp->if_snd, m0);
2846			if (m0 == NULL) {
2847				break;
2848			}
2849			buf = sc->an_tx_buffer[idx].an_dma_vaddr;
2850
2851			eh = mtod(m0, struct ether_header *);
2852
2853			/* DJA optimize this to limit bcopy */
2854			bcopy((char *)&eh->ether_dhost,
2855			      (char *)&tx_frame_802_3.an_tx_dst_addr,
2856			      ETHER_ADDR_LEN);
2857			bcopy((char *)&eh->ether_shost,
2858			      (char *)&tx_frame_802_3.an_tx_src_addr,
2859			      ETHER_ADDR_LEN);
2860
2861			/* minus src/dest mac & type */
2862			tx_frame_802_3.an_tx_802_3_payload_len =
2863				m0->m_pkthdr.len - 12;
2864
2865			m_copydata(m0, sizeof(struct ether_header) - 2 ,
2866				   tx_frame_802_3.an_tx_802_3_payload_len,
2867				   (caddr_t)&sc->an_txbuf);
2868
2869			txcontrol = AN_TXCTL_8023;
2870			/* write the txcontrol only */
2871			bcopy((caddr_t)&txcontrol, &buf[0x08],
2872			      sizeof(txcontrol));
2873
2874			/* 802_3 header */
2875			bcopy((caddr_t)&tx_frame_802_3, &buf[0x34],
2876			      sizeof(struct an_txframe_802_3));
2877
2878			/* in mbuf header type is just before payload */
2879			bcopy((caddr_t)&sc->an_txbuf, &buf[0x44],
2880			      tx_frame_802_3.an_tx_802_3_payload_len);
2881
2882
2883			bzero(&an_tx_desc, sizeof(an_tx_desc));
2884			an_tx_desc.an_offset = 0;
2885			an_tx_desc.an_eoc = 1;
2886			an_tx_desc.an_valid = 1;
2887			an_tx_desc.an_len =  0x44 +
2888			    tx_frame_802_3.an_tx_802_3_payload_len;
2889			an_tx_desc.an_phys
2890			    = sc->an_tx_buffer[idx].an_dma_paddr;
2891			for (i = 0; i < sizeof(an_tx_desc) / 4 ; i++) {
2892				CSR_MEM_AUX_WRITE_4(sc, AN_TX_DESC_OFFSET
2893				    /* zero for now */
2894				    + (0 * sizeof(an_tx_desc))
2895				    + (i * 4),
2896				    ((u_int32_t *)(void *)&an_tx_desc)[i]);
2897			}
2898
2899			/*
2900			 * If there's a BPF listner, bounce a copy of
2901			 * this frame to him.
2902			 */
2903			BPF_MTAP(ifp, m0);
2904
2905			m_freem(m0);
2906			m0 = NULL;
2907			AN_INC(idx, AN_MAX_TX_DESC);
2908			sc->an_rdata.an_tx_empty = 0;
2909			CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_ALLOC);
2910
2911			/*
2912			 * Set a timeout in case the chip goes out to lunch.
2913			 */
2914			sc->an_timer = 5;
2915		}
2916
2917		/* Re-enable interrupts. */
2918		CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), AN_INTRS(sc->mpi350));
2919	}
2920
2921	if (m0 != NULL)
2922		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
2923
2924	sc->an_rdata.an_tx_prod = idx;
2925
2926	return;
2927}
2928
2929void
2930an_stop(struct an_softc *sc)
2931{
2932	struct ifnet		*ifp;
2933	int			i;
2934
2935	AN_LOCK_ASSERT(sc);
2936
2937	if (sc->an_gone)
2938		return;
2939
2940	ifp = sc->an_ifp;
2941
2942	an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0);
2943	CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), 0);
2944	an_cmd(sc, AN_CMD_DISABLE, 0);
2945
2946	for (i = 0; i < AN_TX_RING_CNT; i++)
2947		an_cmd(sc, AN_CMD_DEALLOC_MEM, sc->an_rdata.an_tx_fids[i]);
2948
2949	callout_stop(&sc->an_stat_ch);
2950
2951	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING|IFF_DRV_OACTIVE);
2952
2953	if (sc->an_flash_buffer) {
2954		free(sc->an_flash_buffer, M_DEVBUF);
2955		sc->an_flash_buffer = NULL;
2956	}
2957}
2958
2959static void
2960an_watchdog(struct an_softc *sc)
2961{
2962	struct ifnet *ifp;
2963
2964	AN_LOCK_ASSERT(sc);
2965
2966	if (sc->an_gone)
2967		return;
2968
2969	ifp = sc->an_ifp;
2970	if_printf(ifp, "device timeout\n");
2971
2972	an_reset(sc);
2973	if (sc->mpi350)
2974		an_init_mpi350_desc(sc);
2975	an_init_locked(sc);
2976
2977	ifp->if_oerrors++;
2978}
2979
2980int
2981an_shutdown(device_t dev)
2982{
2983	struct an_softc		*sc;
2984
2985	sc = device_get_softc(dev);
2986	AN_LOCK(sc);
2987	an_stop(sc);
2988	sc->an_gone = 1;
2989	AN_UNLOCK(sc);
2990
2991	return (0);
2992}
2993
2994void
2995an_resume(device_t dev)
2996{
2997	struct an_softc		*sc;
2998	struct ifnet		*ifp;
2999	int			i;
3000
3001	sc = device_get_softc(dev);
3002	AN_LOCK(sc);
3003	ifp = sc->an_ifp;
3004
3005	sc->an_gone = 0;
3006	an_reset(sc);
3007	if (sc->mpi350)
3008		an_init_mpi350_desc(sc);
3009	an_init_locked(sc);
3010
3011	/* Recovery temporary keys */
3012	for (i = 0; i < 4; i++) {
3013		sc->areq.an_type = AN_RID_WEP_TEMP;
3014		sc->areq.an_len = sizeof(struct an_ltv_key);
3015		bcopy(&sc->an_temp_keys[i],
3016		    &sc->areq, sizeof(struct an_ltv_key));
3017		an_setdef(sc, &sc->areq);
3018	}
3019
3020	if (ifp->if_flags & IFF_UP)
3021		an_start_locked(ifp);
3022	AN_UNLOCK(sc);
3023
3024	return;
3025}
3026
3027#ifdef ANCACHE
3028/* Aironet signal strength cache code.
3029 * store signal/noise/quality on per MAC src basis in
3030 * a small fixed cache.  The cache wraps if > MAX slots
3031 * used.  The cache may be zeroed out to start over.
3032 * Two simple filters exist to reduce computation:
3033 * 1. ip only (literally 0x800, ETHERTYPE_IP) which may be used
3034 * to ignore some packets.  It defaults to ip only.
3035 * it could be used to focus on broadcast, non-IP 802.11 beacons.
3036 * 2. multicast/broadcast only.  This may be used to
3037 * ignore unicast packets and only cache signal strength
3038 * for multicast/broadcast packets (beacons); e.g., Mobile-IP
3039 * beacons and not unicast traffic.
3040 *
3041 * The cache stores (MAC src(index), IP src (major clue), signal,
3042 *	quality, noise)
3043 *
3044 * No apologies for storing IP src here.  It's easy and saves much
3045 * trouble elsewhere.  The cache is assumed to be INET dependent,
3046 * although it need not be.
3047 *
3048 * Note: the Aironet only has a single byte of signal strength value
3049 * in the rx frame header, and it's not scaled to anything sensible.
3050 * This is kind of lame, but it's all we've got.
3051 */
3052
3053#ifdef documentation
3054
3055int an_sigitems;				/* number of cached entries */
3056struct an_sigcache an_sigcache[MAXANCACHE];	/* array of cache entries */
3057int an_nextitem;				/* index/# of entries */
3058
3059
3060#endif
3061
3062/* control variables for cache filtering.  Basic idea is
3063 * to reduce cost (e.g., to only Mobile-IP agent beacons
3064 * which are broadcast or multicast).  Still you might
3065 * want to measure signal strength anth unicast ping packets
3066 * on a pt. to pt. ant. setup.
3067 */
3068/* set true if you want to limit cache items to broadcast/mcast
3069 * only packets (not unicast).  Useful for mobile-ip beacons which
3070 * are broadcast/multicast at network layer.  Default is all packets
3071 * so ping/unicast anll work say anth pt. to pt. antennae setup.
3072 */
3073static int an_cache_mcastonly = 0;
3074SYSCTL_INT(_hw_an, OID_AUTO, an_cache_mcastonly, CTLFLAG_RW,
3075	&an_cache_mcastonly, 0, "");
3076
3077/* set true if you want to limit cache items to IP packets only
3078*/
3079static int an_cache_iponly = 1;
3080SYSCTL_INT(_hw_an, OID_AUTO, an_cache_iponly, CTLFLAG_RW,
3081	&an_cache_iponly, 0, "");
3082
3083/*
3084 * an_cache_store, per rx packet store signal
3085 * strength in MAC (src) indexed cache.
3086 */
3087static void
3088an_cache_store(struct an_softc *sc, struct ether_header *eh, struct mbuf *m,
3089    u_int8_t rx_rssi, u_int8_t rx_quality)
3090{
3091	struct ip *ip = 0;
3092	int i;
3093	static int cache_slot = 0; 	/* use this cache entry */
3094	static int wrapindex = 0;	/* next "free" cache entry */
3095	int type_ipv4 = 0;
3096
3097	/* filters:
3098	 * 1. ip only
3099	 * 2. configurable filter to throw out unicast packets,
3100	 * keep multicast only.
3101	 */
3102
3103	if ((ntohs(eh->ether_type) == ETHERTYPE_IP)) {
3104		type_ipv4 = 1;
3105	}
3106
3107	/* filter for ip packets only
3108	*/
3109	if ( an_cache_iponly && !type_ipv4) {
3110		return;
3111	}
3112
3113	/* filter for broadcast/multicast only
3114	 */
3115	if (an_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) {
3116		return;
3117	}
3118
3119#ifdef SIGDEBUG
3120	if_printf(sc->an_ifp, "q value %x (MSB=0x%x, LSB=0x%x) \n",
3121		rx_rssi & 0xffff, rx_rssi >> 8, rx_rssi & 0xff);
3122#endif
3123
3124	/* find the ip header.  we want to store the ip_src
3125	 * address.
3126	 */
3127	if (type_ipv4) {
3128		ip = mtod(m, struct ip *);
3129	}
3130
3131	/* do a linear search for a matching MAC address
3132	 * in the cache table
3133	 * . MAC address is 6 bytes,
3134	 * . var w_nextitem holds total number of entries already cached
3135	 */
3136	for (i = 0; i < sc->an_nextitem; i++) {
3137		if (! bcmp(eh->ether_shost , sc->an_sigcache[i].macsrc,  6 )) {
3138			/* Match!,
3139			 * so we already have this entry,
3140			 * update the data
3141			 */
3142			break;
3143		}
3144	}
3145
3146	/* did we find a matching mac address?
3147	 * if yes, then overwrite a previously existing cache entry
3148	 */
3149	if (i < sc->an_nextitem )   {
3150		cache_slot = i;
3151	}
3152	/* else, have a new address entry,so
3153	 * add this new entry,
3154	 * if table full, then we need to replace LRU entry
3155	 */
3156	else    {
3157
3158		/* check for space in cache table
3159		 * note: an_nextitem also holds number of entries
3160		 * added in the cache table
3161		 */
3162		if ( sc->an_nextitem < MAXANCACHE ) {
3163			cache_slot = sc->an_nextitem;
3164			sc->an_nextitem++;
3165			sc->an_sigitems = sc->an_nextitem;
3166		}
3167		/* no space found, so simply wrap anth wrap index
3168		 * and "zap" the next entry
3169		 */
3170		else {
3171			if (wrapindex == MAXANCACHE) {
3172				wrapindex = 0;
3173			}
3174			cache_slot = wrapindex++;
3175		}
3176	}
3177
3178	/* invariant: cache_slot now points at some slot
3179	 * in cache.
3180	 */
3181	if (cache_slot < 0 || cache_slot >= MAXANCACHE) {
3182		log(LOG_ERR, "an_cache_store, bad index: %d of "
3183		    "[0..%d], gross cache error\n",
3184		    cache_slot, MAXANCACHE);
3185		return;
3186	}
3187
3188	/*  store items in cache
3189	 *  .ip source address
3190	 *  .mac src
3191	 *  .signal, etc.
3192	 */
3193	if (type_ipv4) {
3194		sc->an_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr;
3195	}
3196	bcopy( eh->ether_shost, sc->an_sigcache[cache_slot].macsrc,  6);
3197
3198
3199	switch (an_cache_mode) {
3200	case DBM:
3201		if (sc->an_have_rssimap) {
3202			sc->an_sigcache[cache_slot].signal =
3203				- sc->an_rssimap.an_entries[rx_rssi].an_rss_dbm;
3204			sc->an_sigcache[cache_slot].quality =
3205				- sc->an_rssimap.an_entries[rx_quality].an_rss_dbm;
3206		} else {
3207			sc->an_sigcache[cache_slot].signal = rx_rssi - 100;
3208			sc->an_sigcache[cache_slot].quality = rx_quality - 100;
3209		}
3210		break;
3211	case PERCENT:
3212		if (sc->an_have_rssimap) {
3213			sc->an_sigcache[cache_slot].signal =
3214				sc->an_rssimap.an_entries[rx_rssi].an_rss_pct;
3215			sc->an_sigcache[cache_slot].quality =
3216				sc->an_rssimap.an_entries[rx_quality].an_rss_pct;
3217		} else {
3218			if (rx_rssi > 100)
3219				rx_rssi = 100;
3220			if (rx_quality > 100)
3221				rx_quality = 100;
3222			sc->an_sigcache[cache_slot].signal = rx_rssi;
3223			sc->an_sigcache[cache_slot].quality = rx_quality;
3224		}
3225		break;
3226	case RAW:
3227		sc->an_sigcache[cache_slot].signal = rx_rssi;
3228		sc->an_sigcache[cache_slot].quality = rx_quality;
3229		break;
3230	}
3231
3232	sc->an_sigcache[cache_slot].noise = 0;
3233
3234	return;
3235}
3236#endif
3237
3238static int
3239an_media_change(struct ifnet *ifp)
3240{
3241	struct an_softc *sc = ifp->if_softc;
3242	struct an_ltv_genconfig	*cfg;
3243	int otype = sc->an_config.an_opmode;
3244	int orate = sc->an_tx_rate;
3245
3246	AN_LOCK(sc);
3247	sc->an_tx_rate = ieee80211_media2rate(
3248		IFM_SUBTYPE(sc->an_ifmedia.ifm_cur->ifm_media));
3249	if (sc->an_tx_rate < 0)
3250		sc->an_tx_rate = 0;
3251
3252	if (orate != sc->an_tx_rate) {
3253		/* Read the current configuration */
3254		sc->an_config.an_type = AN_RID_GENCONFIG;
3255		sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
3256		an_read_record(sc, (struct an_ltv_gen *)&sc->an_config);
3257		cfg = &sc->an_config;
3258
3259		/* clear other rates and set the only one we want */
3260		bzero(cfg->an_rates, sizeof(cfg->an_rates));
3261		cfg->an_rates[0] = sc->an_tx_rate;
3262
3263		/* Save the new rate */
3264		sc->an_config.an_type = AN_RID_GENCONFIG;
3265		sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
3266	}
3267
3268	if ((sc->an_ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0)
3269		sc->an_config.an_opmode &= ~AN_OPMODE_INFRASTRUCTURE_STATION;
3270	else
3271		sc->an_config.an_opmode |= AN_OPMODE_INFRASTRUCTURE_STATION;
3272
3273	if (otype != sc->an_config.an_opmode ||
3274	    orate != sc->an_tx_rate)
3275		an_init_locked(sc);
3276	AN_UNLOCK(sc);
3277
3278	return(0);
3279}
3280
3281static void
3282an_media_status(struct ifnet *ifp, struct ifmediareq *imr)
3283{
3284	struct an_ltv_status	status;
3285	struct an_softc		*sc = ifp->if_softc;
3286
3287	imr->ifm_active = IFM_IEEE80211;
3288
3289	AN_LOCK(sc);
3290	status.an_len = sizeof(status);
3291	status.an_type = AN_RID_STATUS;
3292	if (an_read_record(sc, (struct an_ltv_gen *)&status)) {
3293		/* If the status read fails, just lie. */
3294		imr->ifm_active = sc->an_ifmedia.ifm_cur->ifm_media;
3295		imr->ifm_status = IFM_AVALID|IFM_ACTIVE;
3296	}
3297
3298	if (sc->an_tx_rate == 0) {
3299		imr->ifm_active = IFM_IEEE80211|IFM_AUTO;
3300	}
3301
3302	if (sc->an_config.an_opmode == AN_OPMODE_IBSS_ADHOC)
3303		imr->ifm_active |= IFM_IEEE80211_ADHOC;
3304	imr->ifm_active |= ieee80211_rate2media(NULL,
3305		status.an_current_tx_rate, IEEE80211_T_DS);
3306	imr->ifm_status = IFM_AVALID;
3307	if (status.an_opmode & AN_STATUS_OPMODE_ASSOCIATED)
3308		imr->ifm_status |= IFM_ACTIVE;
3309	AN_UNLOCK(sc);
3310}
3311
3312/********************** Cisco utility support routines *************/
3313
3314/*
3315 * ReadRids & WriteRids derived from Cisco driver additions to Ben Reed's
3316 * Linux driver
3317 */
3318
3319static int
3320readrids(struct ifnet *ifp, struct aironet_ioctl *l_ioctl)
3321{
3322	unsigned short  rid;
3323	struct an_softc *sc;
3324	int error;
3325
3326	switch (l_ioctl->command) {
3327	case AIROGCAP:
3328		rid = AN_RID_CAPABILITIES;
3329		break;
3330	case AIROGCFG:
3331		rid = AN_RID_GENCONFIG;
3332		break;
3333	case AIROGSLIST:
3334		rid = AN_RID_SSIDLIST;
3335		break;
3336	case AIROGVLIST:
3337		rid = AN_RID_APLIST;
3338		break;
3339	case AIROGDRVNAM:
3340		rid = AN_RID_DRVNAME;
3341		break;
3342	case AIROGEHTENC:
3343		rid = AN_RID_ENCAPPROTO;
3344		break;
3345	case AIROGWEPKTMP:
3346		rid = AN_RID_WEP_TEMP;
3347		break;
3348	case AIROGWEPKNV:
3349		rid = AN_RID_WEP_PERM;
3350		break;
3351	case AIROGSTAT:
3352		rid = AN_RID_STATUS;
3353		break;
3354	case AIROGSTATSD32:
3355		rid = AN_RID_32BITS_DELTA;
3356		break;
3357	case AIROGSTATSC32:
3358		rid = AN_RID_32BITS_CUM;
3359		break;
3360	default:
3361		rid = 999;
3362		break;
3363	}
3364
3365	if (rid == 999)	/* Is bad command */
3366		return -EINVAL;
3367
3368	sc = ifp->if_softc;
3369	sc->areq.an_len  = AN_MAX_DATALEN;
3370	sc->areq.an_type = rid;
3371
3372	an_read_record(sc, (struct an_ltv_gen *)&sc->areq);
3373
3374	l_ioctl->len = sc->areq.an_len - 4;	/* just data */
3375
3376	AN_UNLOCK(sc);
3377	/* the data contains the length at first */
3378	if (copyout(&(sc->areq.an_len), l_ioctl->data,
3379		    sizeof(sc->areq.an_len))) {
3380		error = -EFAULT;
3381		goto lock_exit;
3382	}
3383	/* Just copy the data back */
3384	if (copyout(&(sc->areq.an_val), l_ioctl->data + 2,
3385		    l_ioctl->len)) {
3386		error = -EFAULT;
3387		goto lock_exit;
3388	}
3389	error = 0;
3390lock_exit:
3391	AN_LOCK(sc);
3392	return (error);
3393}
3394
3395static int
3396writerids(struct ifnet *ifp, struct aironet_ioctl *l_ioctl)
3397{
3398	struct an_softc *sc;
3399	int		rid, command, error;
3400
3401	sc = ifp->if_softc;
3402	AN_LOCK_ASSERT(sc);
3403	rid = 0;
3404	command = l_ioctl->command;
3405
3406	switch (command) {
3407	case AIROPSIDS:
3408		rid = AN_RID_SSIDLIST;
3409		break;
3410	case AIROPCAP:
3411		rid = AN_RID_CAPABILITIES;
3412		break;
3413	case AIROPAPLIST:
3414		rid = AN_RID_APLIST;
3415		break;
3416	case AIROPCFG:
3417		rid = AN_RID_GENCONFIG;
3418		break;
3419	case AIROPMACON:
3420		an_cmd(sc, AN_CMD_ENABLE, 0);
3421		return 0;
3422		break;
3423	case AIROPMACOFF:
3424		an_cmd(sc, AN_CMD_DISABLE, 0);
3425		return 0;
3426		break;
3427	case AIROPSTCLR:
3428		/*
3429		 * This command merely clears the counts does not actually
3430		 * store any data only reads rid. But as it changes the cards
3431		 * state, I put it in the writerid routines.
3432		 */
3433
3434		rid = AN_RID_32BITS_DELTACLR;
3435		sc = ifp->if_softc;
3436		sc->areq.an_len = AN_MAX_DATALEN;
3437		sc->areq.an_type = rid;
3438
3439		an_read_record(sc, (struct an_ltv_gen *)&sc->areq);
3440		l_ioctl->len = sc->areq.an_len - 4;	/* just data */
3441
3442		AN_UNLOCK(sc);
3443		/* the data contains the length at first */
3444		error = copyout(&(sc->areq.an_len), l_ioctl->data,
3445			    sizeof(sc->areq.an_len));
3446		if (error) {
3447			AN_LOCK(sc);
3448			return -EFAULT;
3449		}
3450		/* Just copy the data */
3451		error = copyout(&(sc->areq.an_val), l_ioctl->data + 2,
3452			    l_ioctl->len);
3453		AN_LOCK(sc);
3454		if (error)
3455			return -EFAULT;
3456		return 0;
3457		break;
3458	case AIROPWEPKEY:
3459		rid = AN_RID_WEP_TEMP;
3460		break;
3461	case AIROPWEPKEYNV:
3462		rid = AN_RID_WEP_PERM;
3463		break;
3464	case AIROPLEAPUSR:
3465		rid = AN_RID_LEAPUSERNAME;
3466		break;
3467	case AIROPLEAPPWD:
3468		rid = AN_RID_LEAPPASSWORD;
3469		break;
3470	default:
3471		return -EOPNOTSUPP;
3472	}
3473
3474	if (rid) {
3475		if (l_ioctl->len > sizeof(sc->areq.an_val) + 4)
3476			return -EINVAL;
3477		sc->areq.an_len = l_ioctl->len + 4;	/* add type & length */
3478		sc->areq.an_type = rid;
3479
3480		/* Just copy the data back */
3481		AN_UNLOCK(sc);
3482		error = copyin((l_ioctl->data) + 2, &sc->areq.an_val,
3483		       l_ioctl->len);
3484		AN_LOCK(sc);
3485		if (error)
3486			return -EFAULT;
3487
3488		an_cmd(sc, AN_CMD_DISABLE, 0);
3489		an_write_record(sc, (struct an_ltv_gen *)&sc->areq);
3490		an_cmd(sc, AN_CMD_ENABLE, 0);
3491		return 0;
3492	}
3493	return -EOPNOTSUPP;
3494}
3495
3496/*
3497 * General Flash utilities derived from Cisco driver additions to Ben Reed's
3498 * Linux driver
3499 */
3500
3501#define FLASH_DELAY(_sc, x)	msleep(ifp, &(_sc)->an_mtx, PZERO, \
3502	"flash", ((x) / hz) + 1);
3503#define FLASH_COMMAND	0x7e7e
3504#define FLASH_SIZE	32 * 1024
3505
3506static int
3507unstickbusy(struct ifnet *ifp)
3508{
3509	struct an_softc *sc = ifp->if_softc;
3510
3511	if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY) {
3512		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350),
3513			    AN_EV_CLR_STUCK_BUSY);
3514		return 1;
3515	}
3516	return 0;
3517}
3518
3519/*
3520 * Wait for busy completion from card wait for delay uSec's Return true for
3521 * success meaning command reg is clear
3522 */
3523
3524static int
3525WaitBusy(struct ifnet *ifp, int uSec)
3526{
3527	int		statword = 0xffff;
3528	int		delay = 0;
3529	struct an_softc	*sc = ifp->if_softc;
3530
3531	while ((statword & AN_CMD_BUSY) && delay <= (1000 * 100)) {
3532		FLASH_DELAY(sc, 10);
3533		delay += 10;
3534		statword = CSR_READ_2(sc, AN_COMMAND(sc->mpi350));
3535
3536		if ((AN_CMD_BUSY & statword) && (delay % 200)) {
3537			unstickbusy(ifp);
3538		}
3539	}
3540
3541	return 0 == (AN_CMD_BUSY & statword);
3542}
3543
3544/*
3545 * STEP 1) Disable MAC and do soft reset on card.
3546 */
3547
3548static int
3549cmdreset(struct ifnet *ifp)
3550{
3551	int		status;
3552	struct an_softc	*sc = ifp->if_softc;
3553
3554	AN_LOCK(sc);
3555	an_stop(sc);
3556
3557	an_cmd(sc, AN_CMD_DISABLE, 0);
3558
3559	if (!(status = WaitBusy(ifp, AN_TIMEOUT))) {
3560		if_printf(ifp, "Waitbusy hang b4 RESET =%d\n", status);
3561		AN_UNLOCK(sc);
3562		return -EBUSY;
3563	}
3564	CSR_WRITE_2(sc, AN_COMMAND(sc->mpi350), AN_CMD_FW_RESTART);
3565
3566	FLASH_DELAY(sc, 1000);	/* WAS 600 12/7/00 */
3567
3568
3569	if (!(status = WaitBusy(ifp, 100))) {
3570		if_printf(ifp, "Waitbusy hang AFTER RESET =%d\n", status);
3571		AN_UNLOCK(sc);
3572		return -EBUSY;
3573	}
3574	AN_UNLOCK(sc);
3575	return 0;
3576}
3577
3578/*
3579 * STEP 2) Put the card in legendary flash mode
3580 */
3581
3582static int
3583setflashmode(struct ifnet *ifp)
3584{
3585	int		status;
3586	struct an_softc	*sc = ifp->if_softc;
3587
3588	CSR_WRITE_2(sc, AN_SW0(sc->mpi350), FLASH_COMMAND);
3589	CSR_WRITE_2(sc, AN_SW1(sc->mpi350), FLASH_COMMAND);
3590	CSR_WRITE_2(sc, AN_SW0(sc->mpi350), FLASH_COMMAND);
3591	CSR_WRITE_2(sc, AN_COMMAND(sc->mpi350), FLASH_COMMAND);
3592
3593	/*
3594	 * mdelay(500); // 500ms delay
3595	 */
3596
3597	FLASH_DELAY(sc, 500);
3598
3599	if (!(status = WaitBusy(ifp, AN_TIMEOUT))) {
3600		printf("Waitbusy hang after setflash mode\n");
3601		return -EIO;
3602	}
3603	return 0;
3604}
3605
3606/*
3607 * Get a character from the card matching matchbyte Step 3)
3608 */
3609
3610static int
3611flashgchar(struct ifnet *ifp, int matchbyte, int dwelltime)
3612{
3613	int		rchar;
3614	unsigned char	rbyte = 0;
3615	int		success = -1;
3616	struct an_softc	*sc = ifp->if_softc;
3617
3618
3619	do {
3620		rchar = CSR_READ_2(sc, AN_SW1(sc->mpi350));
3621
3622		if (dwelltime && !(0x8000 & rchar)) {
3623			dwelltime -= 10;
3624			FLASH_DELAY(sc, 10);
3625			continue;
3626		}
3627		rbyte = 0xff & rchar;
3628
3629		if ((rbyte == matchbyte) && (0x8000 & rchar)) {
3630			CSR_WRITE_2(sc, AN_SW1(sc->mpi350), 0);
3631			success = 1;
3632			break;
3633		}
3634		if (rbyte == 0x81 || rbyte == 0x82 || rbyte == 0x83 || rbyte == 0x1a || 0xffff == rchar)
3635			break;
3636		CSR_WRITE_2(sc, AN_SW1(sc->mpi350), 0);
3637
3638	} while (dwelltime > 0);
3639	return success;
3640}
3641
3642/*
3643 * Put character to SWS0 wait for dwelltime x 50us for  echo .
3644 */
3645
3646static int
3647flashpchar(struct ifnet *ifp, int byte, int dwelltime)
3648{
3649	int		echo;
3650	int		pollbusy, waittime;
3651	struct an_softc	*sc = ifp->if_softc;
3652
3653	byte |= 0x8000;
3654
3655	if (dwelltime == 0)
3656		dwelltime = 200;
3657
3658	waittime = dwelltime;
3659
3660	/*
3661	 * Wait for busy bit d15 to go false indicating buffer empty
3662	 */
3663	do {
3664		pollbusy = CSR_READ_2(sc, AN_SW0(sc->mpi350));
3665
3666		if (pollbusy & 0x8000) {
3667			FLASH_DELAY(sc, 50);
3668			waittime -= 50;
3669			continue;
3670		} else
3671			break;
3672	}
3673	while (waittime >= 0);
3674
3675	/* timeout for busy clear wait */
3676
3677	if (waittime <= 0) {
3678		if_printf(ifp, "flash putchar busywait timeout!\n");
3679		return -1;
3680	}
3681	/*
3682	 * Port is clear now write byte and wait for it to echo back
3683	 */
3684	do {
3685		CSR_WRITE_2(sc, AN_SW0(sc->mpi350), byte);
3686		FLASH_DELAY(sc, 50);
3687		dwelltime -= 50;
3688		echo = CSR_READ_2(sc, AN_SW1(sc->mpi350));
3689	} while (dwelltime >= 0 && echo != byte);
3690
3691
3692	CSR_WRITE_2(sc, AN_SW1(sc->mpi350), 0);
3693
3694	return echo == byte;
3695}
3696
3697/*
3698 * Transfer 32k of firmware data from user buffer to our buffer and send to
3699 * the card
3700 */
3701
3702static int
3703flashputbuf(struct ifnet *ifp)
3704{
3705	unsigned short *bufp;
3706	int		nwords;
3707	struct an_softc	*sc = ifp->if_softc;
3708
3709	/* Write stuff */
3710
3711	bufp = sc->an_flash_buffer;
3712
3713	if (!sc->mpi350) {
3714		CSR_WRITE_2(sc, AN_AUX_PAGE, 0x100);
3715		CSR_WRITE_2(sc, AN_AUX_OFFSET, 0);
3716
3717		for (nwords = 0; nwords != FLASH_SIZE / 2; nwords++) {
3718			CSR_WRITE_2(sc, AN_AUX_DATA, bufp[nwords] & 0xffff);
3719		}
3720	} else {
3721		for (nwords = 0; nwords != FLASH_SIZE / 4; nwords++) {
3722			CSR_MEM_AUX_WRITE_4(sc, 0x8000,
3723				((u_int32_t *)bufp)[nwords] & 0xffff);
3724		}
3725	}
3726
3727	CSR_WRITE_2(sc, AN_SW0(sc->mpi350), 0x8000);
3728
3729	return 0;
3730}
3731
3732/*
3733 * After flashing restart the card.
3734 */
3735
3736static int
3737flashrestart(struct ifnet *ifp)
3738{
3739	int		status = 0;
3740	struct an_softc	*sc = ifp->if_softc;
3741
3742	FLASH_DELAY(sc, 1024);		/* Added 12/7/00 */
3743
3744	an_init_locked(sc);
3745
3746	FLASH_DELAY(sc, 1024);		/* Added 12/7/00 */
3747	return status;
3748}
3749
3750/*
3751 * Entry point for flash ioclt.
3752 */
3753
3754static int
3755flashcard(struct ifnet *ifp, struct aironet_ioctl *l_ioctl)
3756{
3757	int		z = 0, status;
3758	struct an_softc	*sc;
3759
3760	sc = ifp->if_softc;
3761	if (sc->mpi350) {
3762		if_printf(ifp, "flashing not supported on MPI 350 yet\n");
3763		return(-1);
3764	}
3765	status = l_ioctl->command;
3766
3767	switch (l_ioctl->command) {
3768	case AIROFLSHRST:
3769		return cmdreset(ifp);
3770		break;
3771	case AIROFLSHSTFL:
3772		if (sc->an_flash_buffer) {
3773			free(sc->an_flash_buffer, M_DEVBUF);
3774			sc->an_flash_buffer = NULL;
3775		}
3776		sc->an_flash_buffer = malloc(FLASH_SIZE, M_DEVBUF, M_WAITOK);
3777		if (sc->an_flash_buffer)
3778			return setflashmode(ifp);
3779		else
3780			return ENOBUFS;
3781		break;
3782	case AIROFLSHGCHR:	/* Get char from aux */
3783		AN_UNLOCK(sc);
3784		status = copyin(l_ioctl->data, &sc->areq, l_ioctl->len);
3785		AN_LOCK(sc);
3786		if (status)
3787			return status;
3788		z = *(int *)&sc->areq;
3789		if ((status = flashgchar(ifp, z, 8000)) == 1)
3790			return 0;
3791		else
3792			return -1;
3793	case AIROFLSHPCHR:	/* Send char to card. */
3794		AN_UNLOCK(sc);
3795		status = copyin(l_ioctl->data, &sc->areq, l_ioctl->len);
3796		AN_LOCK(sc);
3797		if (status)
3798			return status;
3799		z = *(int *)&sc->areq;
3800		if ((status = flashpchar(ifp, z, 8000)) == -1)
3801			return -EIO;
3802		else
3803			return 0;
3804		break;
3805	case AIROFLPUTBUF:	/* Send 32k to card */
3806		if (l_ioctl->len > FLASH_SIZE) {
3807			if_printf(ifp, "Buffer to big, %x %x\n",
3808			       l_ioctl->len, FLASH_SIZE);
3809			return -EINVAL;
3810		}
3811		AN_UNLOCK(sc);
3812		status = copyin(l_ioctl->data, sc->an_flash_buffer, l_ioctl->len);
3813		AN_LOCK(sc);
3814		if (status)
3815			return status;
3816
3817		if ((status = flashputbuf(ifp)) != 0)
3818			return -EIO;
3819		else
3820			return 0;
3821		break;
3822	case AIRORESTART:
3823		if ((status = flashrestart(ifp)) != 0) {
3824			if_printf(ifp, "FLASHRESTART returned %d\n", status);
3825			return -EIO;
3826		} else
3827			return 0;
3828
3829		break;
3830	default:
3831		return -EINVAL;
3832	}
3833
3834	return -EINVAL;
3835}
3836