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