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