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