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