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