2 * Copyright (c) 1997, 1998, 1999
3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
32 * $FreeBSD: src/sys/dev/an/if_an.c,v 1.2.2.13 2003/02/11 03:32:48 ambrisko Exp $
33 * $DragonFly: src/sys/dev/netif/an/if_an.c,v 1.40 2006/12/20 18:14:39 dillon Exp $
37 * Aironet 4500/4800 802.11 PCMCIA/ISA/PCI driver for FreeBSD.
39 * Written by Bill Paul <wpaul@ctr.columbia.edu>
40 * Electrical Engineering Department
41 * Columbia University, New York City
45 * The Aironet 4500/4800 series cards come in PCMCIA, ISA and PCI form.
46 * This driver supports all three device types (PCI devices are supported
47 * through an extra PCI shim: /sys/dev/an/if_an_pci.c). ISA devices can be
48 * supported either using hard-coded IO port/IRQ settings or via Plug
49 * and Play. The 4500 series devices support 1Mbps and 2Mbps data rates.
50 * The 4800 devices support 1, 2, 5.5 and 11Mbps rates.
52 * Like the WaveLAN/IEEE cards, the Aironet NICs are all essentially
53 * PCMCIA devices. The ISA and PCI cards are a combination of a PCMCIA
54 * device and a PCMCIA to ISA or PCMCIA to PCI adapter card. There are
55 * a couple of important differences though:
57 * - Lucent ISA card looks to the host like a PCMCIA controller with
58 * a PCMCIA WaveLAN card inserted. This means that even desktop
59 * machines need to be configured with PCMCIA support in order to
60 * use WaveLAN/IEEE ISA cards. The Aironet cards on the other hand
61 * actually look like normal ISA and PCI devices to the host, so
62 * no PCMCIA controller support is needed
64 * The latter point results in a small gotcha. The Aironet PCMCIA
65 * cards can be configured for one of two operating modes depending
66 * on how the Vpp1 and Vpp2 programming voltages are set when the
67 * card is activated. In order to put the card in proper PCMCIA
68 * operation (where the CIS table is visible and the interface is
69 * programmed for PCMCIA operation), both Vpp1 and Vpp2 have to be
70 * set to 5 volts. FreeBSD by default doesn't set the Vpp voltages,
71 * which leaves the card in ISA/PCI mode, which prevents it from
72 * being activated as an PCMCIA device.
74 * Note that some PCMCIA controller software packages for Windows NT
75 * fail to set the voltages as well.
77 * The Aironet devices can operate in both station mode and access point
78 * mode. Typically, when programmed for station mode, the card can be set
79 * to automatically perform encapsulation/decapsulation of Ethernet II
80 * and 802.3 frames within 802.11 frames so that the host doesn't have
81 * to do it itself. This driver doesn't program the card that way: the
82 * driver handles all of the encapsulation/decapsulation itself.
88 #define ANCACHE /* enable signal strength cache */
91 #include <sys/param.h>
92 #include <sys/systm.h>
93 #include <sys/sockio.h>
95 #include <sys/kernel.h>
97 #include <sys/ucred.h>
98 #include <sys/socket.h>
100 #include <sys/syslog.h>
102 #include <sys/sysctl.h>
103 #include <sys/thread2.h>
105 #include <sys/module.h>
106 #include <sys/sysctl.h>
108 #include <sys/rman.h>
109 #include <sys/malloc.h>
112 #include <net/ifq_var.h>
113 #include <net/if_arp.h>
114 #include <net/ethernet.h>
115 #include <net/if_dl.h>
116 #include <net/if_types.h>
117 #include <net/if_media.h>
118 #include <netproto/802_11/ieee80211.h>
119 #include <netproto/802_11/ieee80211_ioctl.h>
122 #include <netinet/in.h>
123 #include <netinet/in_systm.h>
124 #include <netinet/in_var.h>
125 #include <netinet/ip.h>
130 #include <machine/md_var.h>
132 #include "if_aironet_ieee.h"
133 #include "if_anreg.h"
135 /* These are global because we need them in sys/pci/if_an_p.c. */
136 static void an_reset (struct an_softc
*);
137 static int an_init_mpi350_desc (struct an_softc
*);
138 static int an_ioctl (struct ifnet
*, u_long
, caddr_t
,
140 static void an_init (void *);
141 static int an_init_tx_ring (struct an_softc
*);
142 static void an_start (struct ifnet
*);
143 static void an_watchdog (struct ifnet
*);
144 static void an_rxeof (struct an_softc
*);
145 static void an_txeof (struct an_softc
*, int);
147 static void an_promisc (struct an_softc
*, int);
148 static int an_cmd (struct an_softc
*, int, int);
149 static int an_cmd_struct (struct an_softc
*, struct an_command
*,
151 static int an_read_record (struct an_softc
*, struct an_ltv_gen
*);
152 static int an_write_record (struct an_softc
*, struct an_ltv_gen
*);
153 static int an_read_data (struct an_softc
*, int,
155 static int an_write_data (struct an_softc
*, int,
157 static int an_seek (struct an_softc
*, int, int, int);
158 static int an_alloc_nicmem (struct an_softc
*, int, int *);
159 static int an_dma_malloc (struct an_softc
*, bus_size_t
,
160 struct an_dma_alloc
*, int);
161 static void an_dma_free (struct an_softc
*,
162 struct an_dma_alloc
*);
163 static void an_dma_malloc_cb (void *, bus_dma_segment_t
*, int, int);
164 static void an_stats_update (void *);
165 static void an_setdef (struct an_softc
*, struct an_req
*);
167 static void an_cache_store (struct an_softc
*, struct mbuf
*,
171 /* function definitions for use with the Cisco's Linux configuration
175 static int readrids (struct ifnet
*, struct aironet_ioctl
*);
176 static int writerids (struct ifnet
*, struct aironet_ioctl
*);
177 static int flashcard (struct ifnet
*, struct aironet_ioctl
*);
179 static int cmdreset (struct ifnet
*);
180 static int setflashmode (struct ifnet
*);
181 static int flashgchar (struct ifnet
*,int,int);
182 static int flashpchar (struct ifnet
*,int,int);
183 static int flashputbuf (struct ifnet
*);
184 static int flashrestart (struct ifnet
*);
185 static int WaitBusy (struct ifnet
*, int);
186 static int unstickbusy (struct ifnet
*);
188 static void an_dump_record (struct an_softc
*,struct an_ltv_gen
*,
191 static int an_media_change (struct ifnet
*);
192 static void an_media_status (struct ifnet
*, struct ifmediareq
*);
194 static int an_dump
= 0;
195 static int an_cache_mode
= 0;
201 static char an_conf
[256];
202 static char an_conf_cache
[256];
204 DECLARE_DUMMY_MODULE(if_an
);
208 SYSCTL_NODE(_hw
, OID_AUTO
, an
, CTLFLAG_RD
, 0, "Wireless driver parameters");
211 sysctl_an_dump(SYSCTL_HANDLER_ARGS
)
220 strcpy(an_conf
, "off");
223 strcpy(an_conf
, "type");
226 strcpy(an_conf
, "dump");
229 ksnprintf(an_conf
, 5, "%x", an_dump
);
233 error
= sysctl_handle_string(oidp
, an_conf
, sizeof(an_conf
), req
);
235 if (strncmp(an_conf
,"off", 3) == 0) {
238 if (strncmp(an_conf
,"dump", 4) == 0) {
241 if (strncmp(an_conf
,"type", 4) == 0) {
247 if ((*s
>= '0') && (*s
<= '9')) {
248 r
= r
* 16 + (*s
- '0');
249 } else if ((*s
>= 'a') && (*s
<= 'f')) {
250 r
= r
* 16 + (*s
- 'a' + 10);
258 printf("Sysctl changed for Aironet driver\n");
263 SYSCTL_PROC(_hw_an
, OID_AUTO
, an_dump
, CTLTYPE_STRING
| CTLFLAG_RW
,
264 0, sizeof(an_conf
), sysctl_an_dump
, "A", "");
267 sysctl_an_cache_mode(SYSCTL_HANDLER_ARGS
)
271 last
= an_cache_mode
;
273 switch (an_cache_mode
) {
275 strcpy(an_conf_cache
, "per");
278 strcpy(an_conf_cache
, "raw");
281 strcpy(an_conf_cache
, "dbm");
285 error
= sysctl_handle_string(oidp
, an_conf_cache
,
286 sizeof(an_conf_cache
), req
);
288 if (strncmp(an_conf_cache
,"dbm", 3) == 0) {
291 if (strncmp(an_conf_cache
,"per", 3) == 0) {
294 if (strncmp(an_conf_cache
,"raw", 3) == 0) {
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", "");
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.
311 an_probe(device_t dev
)
313 struct an_softc
*sc
= device_get_softc(dev
);
314 struct an_ltv_ssidlist_new ssid
;
317 bzero((char *)&ssid
, sizeof(ssid
));
319 error
= an_alloc_port(dev
, 0, AN_IOSIZ
);
323 /* can't do autoprobing */
324 if (rman_get_start(sc
->port_res
) == -1)
328 * We need to fake up a softc structure long enough
329 * to be able to issue commands and call some of the
332 sc
->an_bhandle
= rman_get_bushandle(sc
->port_res
);
333 sc
->an_btag
= rman_get_bustag(sc
->port_res
);
335 ssid
.an_len
= sizeof(ssid
);
336 ssid
.an_type
= AN_RID_SSIDLIST
;
338 /* Make sure interrupts are disabled. */
340 CSR_WRITE_2(sc
, AN_INT_EN(sc
->mpi350
), 0);
341 CSR_WRITE_2(sc
, AN_EVENT_ACK(sc
->mpi350
), 0xFFFF);
343 if_initname(&sc
->arpcom
.ac_if
, device_get_name(dev
),
344 device_get_unit(dev
));
347 if (an_cmd(sc
, AN_CMD_READCFG
, 0))
350 if (an_read_record(sc
, (struct an_ltv_gen
*)&ssid
))
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
))
361 * Allocate a port resource with the given resource id.
364 an_alloc_port(device_t dev
, int rid
, int size
)
366 struct an_softc
*sc
= device_get_softc(dev
);
367 struct resource
*res
;
369 res
= bus_alloc_resource(dev
, SYS_RES_IOPORT
, &rid
,
370 0ul, ~0ul, size
, RF_ACTIVE
);
381 * Allocate a memory resource with the given resource id.
384 an_alloc_memory(device_t dev
, int rid
, int size
)
386 struct an_softc
*sc
= device_get_softc(dev
);
387 struct resource
*res
;
389 res
= bus_alloc_resource(dev
, SYS_RES_MEMORY
, &rid
,
390 0ul, ~0ul, size
, RF_ACTIVE
);
402 * Allocate a auxilary memory resource with the given resource id.
405 an_alloc_aux_memory(device_t dev
, int rid
, int size
)
407 struct an_softc
*sc
= device_get_softc(dev
);
408 struct resource
*res
;
410 res
= bus_alloc_resource(dev
, SYS_RES_MEMORY
, &rid
,
411 0ul, ~0ul, size
, RF_ACTIVE
);
413 sc
->mem_aux_rid
= rid
;
414 sc
->mem_aux_res
= res
;
415 sc
->mem_aux_used
= size
;
423 * Allocate an irq resource with the given resource id.
426 an_alloc_irq(device_t dev
, int rid
, int flags
)
428 struct an_softc
*sc
= device_get_softc(dev
);
429 struct resource
*res
;
431 res
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
, &rid
,
432 (RF_ACTIVE
| flags
));
443 an_dma_malloc_cb(void *arg
, bus_dma_segment_t
*segs
, int nseg
, int error
)
445 bus_addr_t
*paddr
= (bus_addr_t
*) arg
;
446 *paddr
= segs
->ds_addr
;
450 * Alloc DMA memory and set the pointer to it
453 an_dma_malloc(struct an_softc
*sc
, bus_size_t size
, struct an_dma_alloc
*dma
,
458 r
= bus_dmamap_create(sc
->an_dtag
, 0, &dma
->an_dma_map
);
462 r
= bus_dmamem_alloc(sc
->an_dtag
, (void**) &dma
->an_dma_vaddr
,
463 BUS_DMA_WAITOK
, &dma
->an_dma_map
);
467 r
= bus_dmamap_load(sc
->an_dtag
, dma
->an_dma_map
, dma
->an_dma_vaddr
,
475 dma
->an_dma_size
= size
;
479 bus_dmamap_unload(sc
->an_dtag
, dma
->an_dma_map
);
481 bus_dmamem_free(sc
->an_dtag
, dma
->an_dma_vaddr
, dma
->an_dma_map
);
483 bus_dmamap_destroy(sc
->an_dtag
, dma
->an_dma_map
);
484 dma
->an_dma_map
= NULL
;
489 an_dma_free(struct an_softc
*sc
, struct an_dma_alloc
*dma
)
491 bus_dmamap_unload(sc
->an_dtag
, dma
->an_dma_map
);
492 bus_dmamem_free(sc
->an_dtag
, dma
->an_dma_vaddr
, dma
->an_dma_map
);
493 dma
->an_dma_vaddr
= NULL
;
494 bus_dmamap_destroy(sc
->an_dtag
, dma
->an_dma_map
);
498 * Release all resources
501 an_release_resources(device_t dev
)
503 struct an_softc
*sc
= device_get_softc(dev
);
507 bus_release_resource(dev
, SYS_RES_IOPORT
,
508 sc
->port_rid
, sc
->port_res
);
512 bus_release_resource(dev
, SYS_RES_MEMORY
,
513 sc
->mem_rid
, sc
->mem_res
);
516 if (sc
->mem_aux_res
) {
517 bus_release_resource(dev
, SYS_RES_MEMORY
,
518 sc
->mem_aux_rid
, sc
->mem_aux_res
);
522 bus_release_resource(dev
, SYS_RES_IRQ
,
523 sc
->irq_rid
, sc
->irq_res
);
526 if (sc
->an_rid_buffer
.an_dma_paddr
) {
527 an_dma_free(sc
, &sc
->an_rid_buffer
);
529 for (i
= 0; i
< AN_MAX_RX_DESC
; i
++)
530 if (sc
->an_rx_buffer
[i
].an_dma_paddr
) {
531 an_dma_free(sc
, &sc
->an_rx_buffer
[i
]);
533 for (i
= 0; i
< AN_MAX_TX_DESC
; i
++)
534 if (sc
->an_tx_buffer
[i
].an_dma_paddr
) {
535 an_dma_free(sc
, &sc
->an_tx_buffer
[i
]);
538 bus_dma_tag_destroy(sc
->an_dtag
);
544 an_init_mpi350_desc(struct an_softc
*sc
)
546 struct an_command cmd_struct
;
547 struct an_reply reply
;
548 struct an_card_rid_desc an_rid_desc
;
549 struct an_card_rx_desc an_rx_desc
;
550 struct an_card_tx_desc an_tx_desc
;
553 if(!sc
->an_rid_buffer
.an_dma_paddr
)
554 an_dma_malloc(sc
, AN_RID_BUFFER_SIZE
,
555 &sc
->an_rid_buffer
, 0);
556 for (i
= 0; i
< AN_MAX_RX_DESC
; i
++)
557 if(!sc
->an_rx_buffer
[i
].an_dma_paddr
)
558 an_dma_malloc(sc
, AN_RX_BUFFER_SIZE
,
559 &sc
->an_rx_buffer
[i
], 0);
560 for (i
= 0; i
< AN_MAX_TX_DESC
; i
++)
561 if(!sc
->an_tx_buffer
[i
].an_dma_paddr
)
562 an_dma_malloc(sc
, AN_TX_BUFFER_SIZE
,
563 &sc
->an_tx_buffer
[i
], 0);
566 * Allocate RX descriptor
568 bzero(&reply
,sizeof(reply
));
569 cmd_struct
.an_cmd
= AN_CMD_ALLOC_DESC
;
570 cmd_struct
.an_parm0
= AN_DESCRIPTOR_RX
;
571 cmd_struct
.an_parm1
= AN_RX_DESC_OFFSET
;
572 cmd_struct
.an_parm2
= AN_MAX_RX_DESC
;
573 if (an_cmd_struct(sc
, &cmd_struct
, &reply
)) {
574 if_printf(&sc
->arpcom
.ac_if
,
575 "failed to allocate RX descriptor\n");
579 for (desc
= 0; desc
< AN_MAX_RX_DESC
; desc
++) {
580 bzero(&an_rx_desc
, sizeof(an_rx_desc
));
581 an_rx_desc
.an_valid
= 1;
582 an_rx_desc
.an_len
= AN_RX_BUFFER_SIZE
;
583 an_rx_desc
.an_done
= 0;
584 an_rx_desc
.an_phys
= sc
->an_rx_buffer
[desc
].an_dma_paddr
;
586 for (i
= 0; i
< sizeof(an_rx_desc
) / 4; i
++)
587 CSR_MEM_AUX_WRITE_4(sc
, AN_RX_DESC_OFFSET
588 + (desc
* sizeof(an_rx_desc
))
590 ((u_int32_t
*)&an_rx_desc
)[i
]);
594 * Allocate TX descriptor
597 bzero(&reply
,sizeof(reply
));
598 cmd_struct
.an_cmd
= AN_CMD_ALLOC_DESC
;
599 cmd_struct
.an_parm0
= AN_DESCRIPTOR_TX
;
600 cmd_struct
.an_parm1
= AN_TX_DESC_OFFSET
;
601 cmd_struct
.an_parm2
= AN_MAX_TX_DESC
;
602 if (an_cmd_struct(sc
, &cmd_struct
, &reply
)) {
603 if_printf(&sc
->arpcom
.ac_if
,
604 "failed to allocate TX descriptor\n");
608 for (desc
= 0; desc
< AN_MAX_TX_DESC
; desc
++) {
609 bzero(&an_tx_desc
, sizeof(an_tx_desc
));
610 an_tx_desc
.an_offset
= 0;
611 an_tx_desc
.an_eoc
= 0;
612 an_tx_desc
.an_valid
= 0;
613 an_tx_desc
.an_len
= 0;
614 an_tx_desc
.an_phys
= sc
->an_tx_buffer
[desc
].an_dma_paddr
;
616 for (i
= 0; i
< sizeof(an_tx_desc
) / 4; i
++)
617 CSR_MEM_AUX_WRITE_4(sc
, AN_TX_DESC_OFFSET
618 + (desc
* sizeof(an_tx_desc
))
620 ((u_int32_t
*)&an_tx_desc
)[i
]);
624 * Allocate RID descriptor
627 bzero(&reply
,sizeof(reply
));
628 cmd_struct
.an_cmd
= AN_CMD_ALLOC_DESC
;
629 cmd_struct
.an_parm0
= AN_DESCRIPTOR_HOSTRW
;
630 cmd_struct
.an_parm1
= AN_HOST_DESC_OFFSET
;
631 cmd_struct
.an_parm2
= 1;
632 if (an_cmd_struct(sc
, &cmd_struct
, &reply
)) {
633 if_printf(&sc
->arpcom
.ac_if
,
634 "failed to allocate host descriptor\n");
638 bzero(&an_rid_desc
, sizeof(an_rid_desc
));
639 an_rid_desc
.an_valid
= 1;
640 an_rid_desc
.an_len
= AN_RID_BUFFER_SIZE
;
641 an_rid_desc
.an_rid
= 0;
642 an_rid_desc
.an_phys
= sc
->an_rid_buffer
.an_dma_paddr
;
644 for (i
= 0; i
< sizeof(an_rid_desc
) / 4; i
++)
645 CSR_MEM_AUX_WRITE_4(sc
, AN_HOST_DESC_OFFSET
+ i
* 4,
646 ((u_int32_t
*)&an_rid_desc
)[i
]);
652 an_attach(struct an_softc
*sc
, device_t dev
, int flags
)
654 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
657 callout_init(&sc
->an_stat_timer
);
658 sc
->an_associated
= 0;
660 sc
->an_was_monitor
= 0;
661 sc
->an_flash_buffer
= NULL
;
664 if_initname(ifp
, device_get_name(dev
), device_get_unit(dev
));
669 error
= an_init_mpi350_desc(sc
);
674 /* Load factory config */
675 if (an_cmd(sc
, AN_CMD_READCFG
, 0)) {
676 device_printf(dev
, "failed to load config data\n");
680 /* Read the current configuration */
681 sc
->an_config
.an_type
= AN_RID_GENCONFIG
;
682 sc
->an_config
.an_len
= sizeof(struct an_ltv_genconfig
);
683 if (an_read_record(sc
, (struct an_ltv_gen
*)&sc
->an_config
)) {
684 device_printf(dev
, "read record failed\n");
688 /* Read the card capabilities */
689 sc
->an_caps
.an_type
= AN_RID_CAPABILITIES
;
690 sc
->an_caps
.an_len
= sizeof(struct an_ltv_caps
);
691 if (an_read_record(sc
, (struct an_ltv_gen
*)&sc
->an_caps
)) {
692 device_printf(dev
, "read record failed\n");
697 sc
->an_ssidlist
.an_type
= AN_RID_SSIDLIST
;
698 sc
->an_ssidlist
.an_len
= sizeof(struct an_ltv_ssidlist_new
);
699 if (an_read_record(sc
, (struct an_ltv_gen
*)&sc
->an_ssidlist
)) {
700 device_printf(dev
, "read record failed\n");
705 sc
->an_aplist
.an_type
= AN_RID_APLIST
;
706 sc
->an_aplist
.an_len
= sizeof(struct an_ltv_aplist
);
707 if (an_read_record(sc
, (struct an_ltv_gen
*)&sc
->an_aplist
)) {
708 device_printf(dev
, "read record failed\n");
713 /* Read the RSSI <-> dBm map */
714 sc
->an_have_rssimap
= 0;
715 if (sc
->an_caps
.an_softcaps
& 8) {
716 sc
->an_rssimap
.an_type
= AN_RID_RSSI_MAP
;
717 sc
->an_rssimap
.an_len
= sizeof(struct an_ltv_rssi_map
);
718 if (an_read_record(sc
, (struct an_ltv_gen
*)&sc
->an_rssimap
)) {
719 device_printf(dev
, "unable to get RSSI <-> dBM map\n");
721 device_printf(dev
, "got RSSI <-> dBM map\n");
722 sc
->an_have_rssimap
= 1;
725 device_printf(dev
, "no RSSI <-> dBM map\n");
729 ifp
->if_mtu
= ETHERMTU
;
730 ifp
->if_flags
= IFF_BROADCAST
| IFF_SIMPLEX
| IFF_MULTICAST
;
731 ifp
->if_ioctl
= an_ioctl
;
732 ifp
->if_start
= an_start
;
733 ifp
->if_watchdog
= an_watchdog
;
734 ifp
->if_init
= an_init
;
735 ifp
->if_baudrate
= 10000000;
736 ifq_set_maxlen(&ifp
->if_snd
, IFQ_MAXLEN
);
737 ifq_set_ready(&ifp
->if_snd
);
739 bzero(sc
->an_config
.an_nodename
, sizeof(sc
->an_config
.an_nodename
));
740 bcopy(AN_DEFAULT_NODENAME
, sc
->an_config
.an_nodename
,
741 sizeof(AN_DEFAULT_NODENAME
) - 1);
743 bzero(sc
->an_ssidlist
.an_entry
[0].an_ssid
,
744 sizeof(sc
->an_ssidlist
.an_entry
[0].an_ssid
));
745 bcopy(AN_DEFAULT_NETNAME
, sc
->an_ssidlist
.an_entry
[0].an_ssid
,
746 sizeof(AN_DEFAULT_NETNAME
) - 1);
747 sc
->an_ssidlist
.an_entry
[0].an_len
= strlen(AN_DEFAULT_NETNAME
);
749 sc
->an_config
.an_opmode
=
750 AN_OPMODE_INFRASTRUCTURE_STATION
;
753 bzero((char *)&sc
->an_stats
, sizeof(sc
->an_stats
));
755 ifmedia_init(&sc
->an_ifmedia
, 0, an_media_change
, an_media_status
);
756 #define ADD(m, c) ifmedia_add(&sc->an_ifmedia, (m), (c), NULL)
757 ADD(IFM_MAKEWORD(IFM_IEEE80211
, IFM_IEEE80211_DS1
,
758 IFM_IEEE80211_ADHOC
, 0), 0);
759 ADD(IFM_MAKEWORD(IFM_IEEE80211
, IFM_IEEE80211_DS1
, 0, 0), 0);
760 ADD(IFM_MAKEWORD(IFM_IEEE80211
, IFM_IEEE80211_DS2
,
761 IFM_IEEE80211_ADHOC
, 0), 0);
762 ADD(IFM_MAKEWORD(IFM_IEEE80211
, IFM_IEEE80211_DS2
, 0, 0), 0);
763 if (sc
->an_caps
.an_rates
[2] == AN_RATE_5_5MBPS
) {
764 ADD(IFM_MAKEWORD(IFM_IEEE80211
, IFM_IEEE80211_DS5
,
765 IFM_IEEE80211_ADHOC
, 0), 0);
766 ADD(IFM_MAKEWORD(IFM_IEEE80211
, IFM_IEEE80211_DS5
, 0, 0), 0);
768 if (sc
->an_caps
.an_rates
[3] == AN_RATE_11MBPS
) {
769 ADD(IFM_MAKEWORD(IFM_IEEE80211
, IFM_IEEE80211_DS11
,
770 IFM_IEEE80211_ADHOC
, 0), 0);
771 ADD(IFM_MAKEWORD(IFM_IEEE80211
, IFM_IEEE80211_DS11
, 0, 0), 0);
773 ADD(IFM_MAKEWORD(IFM_IEEE80211
, IFM_AUTO
,
774 IFM_IEEE80211_ADHOC
, 0), 0);
775 ADD(IFM_MAKEWORD(IFM_IEEE80211
, IFM_AUTO
, 0, 0), 0);
777 ifmedia_set(&sc
->an_ifmedia
, IFM_MAKEWORD(IFM_IEEE80211
, IFM_AUTO
,
781 * Call MI attach routine.
783 ether_ifattach(ifp
, sc
->an_caps
.an_oemaddr
, NULL
);
789 an_detach(device_t dev
)
791 struct an_softc
*sc
= device_get_softc(dev
);
792 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
794 lwkt_serialize_enter(ifp
->if_serializer
);
796 bus_teardown_intr(dev
, sc
->irq_res
, sc
->irq_handle
);
797 lwkt_serialize_exit(ifp
->if_serializer
);
799 ifmedia_removeall(&sc
->an_ifmedia
);
801 an_release_resources(dev
);
806 an_rxeof(struct an_softc
*sc
)
809 struct ether_header
*eh
;
810 struct ieee80211_frame
*ih
;
811 struct an_rxframe rx_frame
;
812 struct an_rxframe_802_3 rx_frame_802_3
;
814 int len
, id
, error
= 0, i
, count
= 0;
815 int ieee80211_header_len
;
818 struct an_card_rx_desc an_rx_desc
;
821 ifp
= &sc
->arpcom
.ac_if
;
824 id
= CSR_READ_2(sc
, AN_RX_FID
);
826 if (sc
->an_monitor
&& (ifp
->if_flags
& IFF_PROMISC
)) {
827 /* read raw 802.11 packet */
828 bpf_buf
= sc
->buf_802_11
;
831 if (an_read_data(sc
, id
, 0x0, (caddr_t
)&rx_frame
,
838 * skip beacon by default since this increases the
842 if (!(sc
->an_monitor
& AN_MONITOR_INCLUDE_BEACON
) &&
843 (rx_frame
.an_frame_ctl
&
844 IEEE80211_FC0_SUBTYPE_BEACON
)) {
848 if (sc
->an_monitor
& AN_MONITOR_AIRONET_HEADER
) {
849 len
= rx_frame
.an_rx_payload_len
851 /* Check for insane frame length */
852 if (len
> sizeof(sc
->buf_802_11
)) {
854 "oversized packet received "
855 "(%d, %d)\n", len
, MCLBYTES
);
860 bcopy((char *)&rx_frame
,
861 bpf_buf
, sizeof(rx_frame
));
863 error
= an_read_data(sc
, id
, sizeof(rx_frame
),
864 (caddr_t
)bpf_buf
+sizeof(rx_frame
),
865 rx_frame
.an_rx_payload_len
);
867 fc1
=rx_frame
.an_frame_ctl
>> 8;
868 ieee80211_header_len
=
869 sizeof(struct ieee80211_frame
);
870 if ((fc1
& IEEE80211_FC1_DIR_TODS
) &&
871 (fc1
& IEEE80211_FC1_DIR_FROMDS
)) {
872 ieee80211_header_len
+= ETHER_ADDR_LEN
;
875 len
= rx_frame
.an_rx_payload_len
876 + ieee80211_header_len
;
877 /* Check for insane frame length */
878 if (len
> sizeof(sc
->buf_802_11
)) {
880 "oversized packet received "
881 "(%d, %d)\n", len
, MCLBYTES
);
886 ih
= (struct ieee80211_frame
*)bpf_buf
;
888 bcopy((char *)&rx_frame
.an_frame_ctl
,
889 (char *)ih
, ieee80211_header_len
);
891 error
= an_read_data(sc
, id
, sizeof(rx_frame
) +
893 (caddr_t
)ih
+ieee80211_header_len
,
894 rx_frame
.an_rx_payload_len
);
896 BPF_TAP(ifp
, bpf_buf
, len
);
898 m
= m_getcl(MB_DONTWAIT
, MT_DATA
, M_PKTHDR
);
903 m
->m_pkthdr
.rcvif
= ifp
;
904 /* Read Ethernet encapsulated packet */
907 /* Read NIC frame header */
908 if (an_read_data(sc
, id
, 0, (caddr_t
)&rx_frame
,
914 /* Read in the 802_3 frame header */
915 if (an_read_data(sc
, id
, 0x34,
916 (caddr_t
)&rx_frame_802_3
,
917 sizeof(rx_frame_802_3
))) {
921 if (rx_frame_802_3
.an_rx_802_3_status
!= 0) {
925 /* Check for insane frame length */
926 len
= rx_frame_802_3
.an_rx_802_3_payload_len
;
927 if (len
> sizeof(sc
->buf_802_11
)) {
929 "oversized packet received (%d, %d)\n",
934 m
->m_pkthdr
.len
= m
->m_len
=
935 rx_frame_802_3
.an_rx_802_3_payload_len
+ 12;
937 eh
= mtod(m
, struct ether_header
*);
939 bcopy((char *)&rx_frame_802_3
.an_rx_dst_addr
,
940 (char *)&eh
->ether_dhost
, ETHER_ADDR_LEN
);
941 bcopy((char *)&rx_frame_802_3
.an_rx_src_addr
,
942 (char *)&eh
->ether_shost
, ETHER_ADDR_LEN
);
944 /* in mbuf header type is just before payload */
945 error
= an_read_data(sc
, id
, 0x44,
946 (caddr_t
)&(eh
->ether_type
),
947 rx_frame_802_3
.an_rx_802_3_payload_len
);
957 an_cache_store(sc
, m
,
958 rx_frame
.an_rx_signal_strength
,
961 ifp
->if_input(ifp
, m
);
964 } else { /* MPI-350 */
965 for (count
= 0; count
< AN_MAX_RX_DESC
; count
++){
966 for (i
= 0; i
< sizeof(an_rx_desc
) / 4; i
++)
967 ((u_int32_t
*)&an_rx_desc
)[i
]
968 = CSR_MEM_AUX_READ_4(sc
,
970 + (count
* sizeof(an_rx_desc
))
973 if (an_rx_desc
.an_done
&& !an_rx_desc
.an_valid
) {
974 buf
= sc
->an_rx_buffer
[count
].an_dma_vaddr
;
976 m
= m_getcl(MB_DONTWAIT
, MT_DATA
, M_PKTHDR
);
981 m
->m_pkthdr
.rcvif
= ifp
;
982 /* Read Ethernet encapsulated packet */
985 * No ANCACHE support since we just get back
986 * an Ethernet packet no 802.11 info
990 /* Read NIC frame header */
991 bcopy(buf
, (caddr_t
)&rx_frame
,
995 /* Check for insane frame length */
996 len
= an_rx_desc
.an_len
+ 12;
997 if (len
> MCLBYTES
) {
999 "oversized packet received "
1000 "(%d, %d)\n", len
, MCLBYTES
);
1005 m
->m_pkthdr
.len
= m
->m_len
=
1006 an_rx_desc
.an_len
+ 12;
1008 eh
= mtod(m
, struct ether_header
*);
1010 bcopy(buf
, (char *)eh
,
1017 an_cache_store(sc
, m
,
1018 rx_frame
.an_rx_signal_strength
,
1022 ifp
->if_input(ifp
, m
);
1024 an_rx_desc
.an_valid
= 1;
1025 an_rx_desc
.an_len
= AN_RX_BUFFER_SIZE
;
1026 an_rx_desc
.an_done
= 0;
1027 an_rx_desc
.an_phys
=
1028 sc
->an_rx_buffer
[count
].an_dma_paddr
;
1030 for (i
= 0; i
< sizeof(an_rx_desc
) / 4; i
++)
1031 CSR_MEM_AUX_WRITE_4(sc
,
1033 + (count
* sizeof(an_rx_desc
))
1035 ((u_int32_t
*)&an_rx_desc
)[i
]);
1038 if_printf(ifp
, "Didn't get valid RX packet "
1041 an_rx_desc
.an_valid
,
1049 an_txeof(struct an_softc
*sc
, int status
)
1054 ifp
= &sc
->arpcom
.ac_if
;
1057 ifp
->if_flags
&= ~IFF_OACTIVE
;
1060 id
= CSR_READ_2(sc
, AN_TX_CMP_FID(sc
->mpi350
));
1062 if (status
& AN_EV_TX_EXC
) {
1067 for (i
= 0; i
< AN_TX_RING_CNT
; i
++) {
1068 if (id
== sc
->an_rdata
.an_tx_ring
[i
]) {
1069 sc
->an_rdata
.an_tx_ring
[i
] = 0;
1074 AN_INC(sc
->an_rdata
.an_tx_cons
, AN_TX_RING_CNT
);
1075 } else { /* MPI 350 */
1076 id
= CSR_READ_2(sc
, AN_TX_CMP_FID(sc
->mpi350
));
1077 if (!sc
->an_rdata
.an_tx_empty
){
1078 if (status
& AN_EV_TX_EXC
) {
1082 AN_INC(sc
->an_rdata
.an_tx_cons
, AN_MAX_TX_DESC
);
1083 if (sc
->an_rdata
.an_tx_prod
==
1084 sc
->an_rdata
.an_tx_cons
)
1085 sc
->an_rdata
.an_tx_empty
= 1;
1091 * We abuse the stats updater to check the current NIC status. This
1092 * is important because we don't want to allow transmissions until
1093 * the NIC has synchronized to the current cell (either as the master
1094 * in an ad-hoc group, or as a station connected to an access point).
1097 an_stats_update(void *xsc
)
1099 struct an_softc
*sc
;
1103 ifp
= &sc
->arpcom
.ac_if
;
1105 lwkt_serialize_enter(sc
->arpcom
.ac_if
.if_serializer
);
1107 sc
->an_status
.an_type
= AN_RID_STATUS
;
1108 sc
->an_status
.an_len
= sizeof(struct an_ltv_status
);
1109 an_read_record(sc
, (struct an_ltv_gen
*)&sc
->an_status
);
1111 if (sc
->an_status
.an_opmode
& AN_STATUS_OPMODE_IN_SYNC
)
1112 sc
->an_associated
= 1;
1114 sc
->an_associated
= 0;
1116 /* Don't do this while we're not transmitting */
1117 if ((ifp
->if_flags
& IFF_OACTIVE
) == 0) {
1118 sc
->an_stats
.an_len
= sizeof(struct an_ltv_stats
);
1119 sc
->an_stats
.an_type
= AN_RID_32BITS_CUM
;
1120 an_read_record(sc
, (struct an_ltv_gen
*)&sc
->an_stats
.an_len
);
1123 callout_reset(&sc
->an_stat_timer
, hz
, an_stats_update
, sc
);
1125 lwkt_serialize_exit(sc
->arpcom
.ac_if
.if_serializer
);
1131 struct an_softc
*sc
;
1135 sc
= (struct an_softc
*)xsc
;
1137 ifp
= &sc
->arpcom
.ac_if
;
1139 /* Disable interrupts. */
1140 CSR_WRITE_2(sc
, AN_INT_EN(sc
->mpi350
), 0);
1142 status
= CSR_READ_2(sc
, AN_EVENT_STAT(sc
->mpi350
));
1143 CSR_WRITE_2(sc
, AN_EVENT_ACK(sc
->mpi350
), ~AN_INTRS(sc
->mpi350
));
1145 if (status
& AN_EV_MIC
)
1146 CSR_WRITE_2(sc
, AN_EVENT_ACK(sc
->mpi350
), AN_EV_MIC
);
1148 if (status
& AN_EV_LINKSTAT
) {
1149 if (CSR_READ_2(sc
, AN_LINKSTAT(sc
->mpi350
))
1150 == AN_LINKSTAT_ASSOCIATED
)
1151 sc
->an_associated
= 1;
1153 sc
->an_associated
= 0;
1154 CSR_WRITE_2(sc
, AN_EVENT_ACK(sc
->mpi350
), AN_EV_LINKSTAT
);
1157 if (status
& AN_EV_RX
) {
1159 CSR_WRITE_2(sc
, AN_EVENT_ACK(sc
->mpi350
), AN_EV_RX
);
1162 if (sc
->mpi350
&& status
& AN_EV_TX_CPY
) {
1163 an_txeof(sc
, status
);
1164 CSR_WRITE_2(sc
, AN_EVENT_ACK(sc
->mpi350
), AN_EV_TX_CPY
);
1167 if (status
& AN_EV_TX
) {
1168 an_txeof(sc
, status
);
1169 CSR_WRITE_2(sc
, AN_EVENT_ACK(sc
->mpi350
), AN_EV_TX
);
1172 if (status
& AN_EV_TX_EXC
) {
1173 an_txeof(sc
, status
);
1174 CSR_WRITE_2(sc
, AN_EVENT_ACK(sc
->mpi350
), AN_EV_TX_EXC
);
1177 if (status
& AN_EV_ALLOC
)
1178 CSR_WRITE_2(sc
, AN_EVENT_ACK(sc
->mpi350
), AN_EV_ALLOC
);
1180 /* Re-enable interrupts. */
1181 CSR_WRITE_2(sc
, AN_INT_EN(sc
->mpi350
), AN_INTRS(sc
->mpi350
));
1183 if ((ifp
->if_flags
& IFF_UP
) && !ifq_is_empty(&ifp
->if_snd
))
1190 an_cmd_struct(struct an_softc
*sc
, struct an_command
*cmd
,
1191 struct an_reply
*reply
)
1195 for (i
= 0; i
!= AN_TIMEOUT
; i
++) {
1196 if (CSR_READ_2(sc
, AN_COMMAND(sc
->mpi350
)) & AN_CMD_BUSY
) {
1201 if( i
== AN_TIMEOUT
) {
1206 CSR_WRITE_2(sc
, AN_PARAM0(sc
->mpi350
), cmd
->an_parm0
);
1207 CSR_WRITE_2(sc
, AN_PARAM1(sc
->mpi350
), cmd
->an_parm1
);
1208 CSR_WRITE_2(sc
, AN_PARAM2(sc
->mpi350
), cmd
->an_parm2
);
1209 CSR_WRITE_2(sc
, AN_COMMAND(sc
->mpi350
), cmd
->an_cmd
);
1211 for (i
= 0; i
< AN_TIMEOUT
; i
++) {
1212 if (CSR_READ_2(sc
, AN_EVENT_STAT(sc
->mpi350
)) & AN_EV_CMD
)
1217 reply
->an_resp0
= CSR_READ_2(sc
, AN_RESP0(sc
->mpi350
));
1218 reply
->an_resp1
= CSR_READ_2(sc
, AN_RESP1(sc
->mpi350
));
1219 reply
->an_resp2
= CSR_READ_2(sc
, AN_RESP2(sc
->mpi350
));
1220 reply
->an_status
= CSR_READ_2(sc
, AN_STATUS(sc
->mpi350
));
1222 if (CSR_READ_2(sc
, AN_COMMAND(sc
->mpi350
)) & AN_CMD_BUSY
)
1223 CSR_WRITE_2(sc
, AN_EVENT_ACK(sc
->mpi350
), AN_EV_CLR_STUCK_BUSY
);
1225 /* Ack the command */
1226 CSR_WRITE_2(sc
, AN_EVENT_ACK(sc
->mpi350
), AN_EV_CMD
);
1228 if (i
== AN_TIMEOUT
)
1235 an_cmd(struct an_softc
*sc
, int cmd
, int val
)
1239 CSR_WRITE_2(sc
, AN_PARAM0(sc
->mpi350
), val
);
1240 CSR_WRITE_2(sc
, AN_PARAM1(sc
->mpi350
), 0);
1241 CSR_WRITE_2(sc
, AN_PARAM2(sc
->mpi350
), 0);
1242 CSR_WRITE_2(sc
, AN_COMMAND(sc
->mpi350
), cmd
);
1244 for (i
= 0; i
< AN_TIMEOUT
; i
++) {
1245 if (CSR_READ_2(sc
, AN_EVENT_STAT(sc
->mpi350
)) & AN_EV_CMD
)
1248 if (CSR_READ_2(sc
, AN_COMMAND(sc
->mpi350
)) == cmd
)
1249 CSR_WRITE_2(sc
, AN_COMMAND(sc
->mpi350
), cmd
);
1253 for (i
= 0; i
< AN_TIMEOUT
; i
++) {
1254 CSR_READ_2(sc
, AN_RESP0(sc
->mpi350
));
1255 CSR_READ_2(sc
, AN_RESP1(sc
->mpi350
));
1256 CSR_READ_2(sc
, AN_RESP2(sc
->mpi350
));
1257 s
= CSR_READ_2(sc
, AN_STATUS(sc
->mpi350
));
1258 if ((s
& AN_STAT_CMD_CODE
) == (cmd
& AN_STAT_CMD_CODE
))
1262 /* Ack the command */
1263 CSR_WRITE_2(sc
, AN_EVENT_ACK(sc
->mpi350
), AN_EV_CMD
);
1265 if (CSR_READ_2(sc
, AN_COMMAND(sc
->mpi350
)) & AN_CMD_BUSY
)
1266 CSR_WRITE_2(sc
, AN_EVENT_ACK(sc
->mpi350
), AN_EV_CLR_STUCK_BUSY
);
1268 if (i
== AN_TIMEOUT
)
1275 * This reset sequence may look a little strange, but this is the
1276 * most reliable method I've found to really kick the NIC in the
1277 * head and force it to reboot correctly.
1280 an_reset(struct an_softc
*sc
)
1282 an_cmd(sc
, AN_CMD_ENABLE
, 0);
1283 an_cmd(sc
, AN_CMD_FW_RESTART
, 0);
1284 an_cmd(sc
, AN_CMD_NOOP2
, 0);
1286 if (an_cmd(sc
, AN_CMD_FORCE_SYNCLOSS
, 0) == ETIMEDOUT
)
1287 if_printf(&sc
->arpcom
.ac_if
, "reset failed\n");
1289 an_cmd(sc
, AN_CMD_DISABLE
, 0);
1295 * Read an LTV record from the NIC.
1298 an_read_record(struct an_softc
*sc
, struct an_ltv_gen
*ltv
)
1300 struct an_ltv_gen
*an_ltv
;
1301 struct an_card_rid_desc an_rid_desc
;
1302 struct an_command cmd
;
1303 struct an_reply reply
;
1308 if (ltv
->an_len
< 4 || ltv
->an_type
== 0)
1312 /* Tell the NIC to enter record read mode. */
1313 if (an_cmd(sc
, AN_CMD_ACCESS
|AN_ACCESS_READ
, ltv
->an_type
)) {
1314 if_printf(&sc
->arpcom
.ac_if
, "RID access failed\n");
1318 /* Seek to the record. */
1319 if (an_seek(sc
, ltv
->an_type
, 0, AN_BAP1
)) {
1320 if_printf(&sc
->arpcom
.ac_if
, "seek to record failed\n");
1325 * Read the length and record type and make sure they
1326 * match what we expect (this verifies that we have enough
1327 * room to hold all of the returned data).
1328 * Length includes type but not length.
1330 len
= CSR_READ_2(sc
, AN_DATA1
);
1331 if (len
> (ltv
->an_len
- 2)) {
1332 if_printf(&sc
->arpcom
.ac_if
,
1333 "record length mismatch -- expected %d, "
1334 "got %d for Rid %x\n",
1335 ltv
->an_len
- 2, len
, ltv
->an_type
);
1336 len
= ltv
->an_len
- 2;
1338 ltv
->an_len
= len
+ 2;
1341 /* Now read the data. */
1342 len
-= 2; /* skip the type */
1344 for (i
= len
; i
> 1; i
-= 2)
1345 *ptr
++ = CSR_READ_2(sc
, AN_DATA1
);
1347 ptr2
= (u_int8_t
*)ptr
;
1348 *ptr2
= CSR_READ_1(sc
, AN_DATA1
);
1350 } else { /* MPI-350 */
1351 if (sc
->an_rid_buffer
.an_dma_vaddr
== NULL
)
1353 an_rid_desc
.an_valid
= 1;
1354 an_rid_desc
.an_len
= AN_RID_BUFFER_SIZE
;
1355 an_rid_desc
.an_rid
= 0;
1356 an_rid_desc
.an_phys
= sc
->an_rid_buffer
.an_dma_paddr
;
1357 bzero(sc
->an_rid_buffer
.an_dma_vaddr
, AN_RID_BUFFER_SIZE
);
1359 bzero(&cmd
, sizeof(cmd
));
1360 bzero(&reply
, sizeof(reply
));
1361 cmd
.an_cmd
= AN_CMD_ACCESS
|AN_ACCESS_READ
;
1362 cmd
.an_parm0
= ltv
->an_type
;
1364 for (i
= 0; i
< sizeof(an_rid_desc
) / 4; i
++)
1365 CSR_MEM_AUX_WRITE_4(sc
, AN_HOST_DESC_OFFSET
+ i
* 4,
1366 ((u_int32_t
*)&an_rid_desc
)[i
]);
1368 if (an_cmd_struct(sc
, &cmd
, &reply
)
1369 || reply
.an_status
& AN_CMD_QUAL_MASK
) {
1370 if_printf(&sc
->arpcom
.ac_if
,
1371 "failed to read RID %x %x %x %x %x, %d\n",
1381 an_ltv
= (struct an_ltv_gen
*)sc
->an_rid_buffer
.an_dma_vaddr
;
1382 if (an_ltv
->an_len
+ 2 < an_rid_desc
.an_len
) {
1383 an_rid_desc
.an_len
= an_ltv
->an_len
;
1386 len
= an_rid_desc
.an_len
;
1387 if (len
> (ltv
->an_len
- 2)) {
1388 if_printf(&sc
->arpcom
.ac_if
,
1389 "record length mismatch -- expected %d, "
1390 "got %d for Rid %x\n",
1391 ltv
->an_len
- 2, len
, ltv
->an_type
);
1392 len
= ltv
->an_len
- 2;
1394 ltv
->an_len
= len
+ 2;
1396 bcopy(&an_ltv
->an_type
, <v
->an_val
, len
);
1400 an_dump_record(sc
, ltv
, "Read");
1406 * Same as read, except we inject data instead of reading it.
1409 an_write_record(struct an_softc
*sc
, struct an_ltv_gen
*ltv
)
1411 struct an_card_rid_desc an_rid_desc
;
1412 struct an_command cmd
;
1413 struct an_reply reply
;
1420 an_dump_record(sc
, ltv
, "Write");
1423 if (an_cmd(sc
, AN_CMD_ACCESS
|AN_ACCESS_READ
, ltv
->an_type
))
1426 if (an_seek(sc
, ltv
->an_type
, 0, AN_BAP1
))
1430 * Length includes type but not length.
1432 len
= ltv
->an_len
- 2;
1433 CSR_WRITE_2(sc
, AN_DATA1
, len
);
1435 len
-= 2; /* skip the type */
1437 for (i
= len
; i
> 1; i
-= 2)
1438 CSR_WRITE_2(sc
, AN_DATA1
, *ptr
++);
1440 ptr2
= (u_int8_t
*)ptr
;
1441 CSR_WRITE_1(sc
, AN_DATA0
, *ptr2
);
1444 if (an_cmd(sc
, AN_CMD_ACCESS
|AN_ACCESS_WRITE
, ltv
->an_type
))
1449 for (i
= 0; i
!= AN_TIMEOUT
; i
++) {
1450 if (CSR_READ_2(sc
, AN_COMMAND(sc
->mpi350
))
1456 if (i
== AN_TIMEOUT
) {
1460 an_rid_desc
.an_valid
= 1;
1461 an_rid_desc
.an_len
= ltv
->an_len
- 2;
1462 an_rid_desc
.an_rid
= ltv
->an_type
;
1463 an_rid_desc
.an_phys
= sc
->an_rid_buffer
.an_dma_paddr
;
1465 bcopy(<v
->an_type
, sc
->an_rid_buffer
.an_dma_vaddr
,
1466 an_rid_desc
.an_len
);
1468 bzero(&cmd
,sizeof(cmd
));
1469 bzero(&reply
,sizeof(reply
));
1470 cmd
.an_cmd
= AN_CMD_ACCESS
|AN_ACCESS_WRITE
;
1471 cmd
.an_parm0
= ltv
->an_type
;
1473 for (i
= 0; i
< sizeof(an_rid_desc
) / 4; i
++)
1474 CSR_MEM_AUX_WRITE_4(sc
, AN_HOST_DESC_OFFSET
+ i
* 4,
1475 ((u_int32_t
*)&an_rid_desc
)[i
]);
1477 if ((i
= an_cmd_struct(sc
, &cmd
, &reply
))) {
1478 if_printf(&sc
->arpcom
.ac_if
,
1479 "failed to write RID 1 %x %x %x %x %x, %d\n",
1489 ptr
= (u_int16_t
*)buf
;
1491 if (reply
.an_status
& AN_CMD_QUAL_MASK
) {
1492 if_printf(&sc
->arpcom
.ac_if
,
1493 "failed to write RID 2 %x %x %x %x %x, %d\n",
1508 an_dump_record(struct an_softc
*sc
, struct an_ltv_gen
*ltv
, char *string
)
1516 len
= ltv
->an_len
- 4;
1517 if_printf(&sc
->arpcom
.ac_if
, "RID %4x, Length %4d, Mode %s\n",
1518 ltv
->an_type
, ltv
->an_len
- 4, string
);
1520 if (an_dump
== 1 || (an_dump
== ltv
->an_type
)) {
1521 if_printf(&sc
->arpcom
.ac_if
, "\t");
1522 bzero(buf
,sizeof(buf
));
1524 ptr2
= (u_int8_t
*)<v
->an_val
;
1525 for (i
= len
; i
> 0; i
--) {
1526 printf("%02x ", *ptr2
);
1529 if (temp
>= ' ' && temp
<= '~')
1531 else if (temp
>= 'A' && temp
<= 'Z')
1535 if (++count
== 16) {
1538 if_printf(&sc
->arpcom
.ac_if
, "\t");
1539 bzero(buf
,sizeof(buf
));
1542 for (; count
!= 16; count
++) {
1545 printf(" %s\n",buf
);
1550 an_seek(struct an_softc
*sc
, int id
, int off
, int chan
)
1565 if_printf(&sc
->arpcom
.ac_if
, "invalid data path: %x\n", chan
);
1569 CSR_WRITE_2(sc
, selreg
, id
);
1570 CSR_WRITE_2(sc
, offreg
, off
);
1572 for (i
= 0; i
< AN_TIMEOUT
; i
++) {
1573 if (!(CSR_READ_2(sc
, offreg
) & (AN_OFF_BUSY
|AN_OFF_ERR
)))
1577 if (i
== AN_TIMEOUT
)
1584 an_read_data(struct an_softc
*sc
, int id
, int off
, caddr_t buf
, int len
)
1591 if (an_seek(sc
, id
, off
, AN_BAP1
))
1595 ptr
= (u_int16_t
*)buf
;
1596 for (i
= len
; i
> 1; i
-= 2)
1597 *ptr
++ = CSR_READ_2(sc
, AN_DATA1
);
1599 ptr2
= (u_int8_t
*)ptr
;
1600 *ptr2
= CSR_READ_1(sc
, AN_DATA1
);
1607 an_write_data(struct an_softc
*sc
, int id
, int off
, caddr_t buf
, int len
)
1614 if (an_seek(sc
, id
, off
, AN_BAP0
))
1618 ptr
= (u_int16_t
*)buf
;
1619 for (i
= len
; i
> 1; i
-= 2)
1620 CSR_WRITE_2(sc
, AN_DATA0
, *ptr
++);
1622 ptr2
= (u_int8_t
*)ptr
;
1623 CSR_WRITE_1(sc
, AN_DATA0
, *ptr2
);
1630 * Allocate a region of memory inside the NIC and zero
1634 an_alloc_nicmem(struct an_softc
*sc
, int len
, int *id
)
1638 if (an_cmd(sc
, AN_CMD_ALLOC_MEM
, len
)) {
1639 if_printf(&sc
->arpcom
.ac_if
,
1640 "failed to allocate %d bytes on NIC\n", len
);
1644 for (i
= 0; i
< AN_TIMEOUT
; i
++) {
1645 if (CSR_READ_2(sc
, AN_EVENT_STAT(sc
->mpi350
)) & AN_EV_ALLOC
)
1649 if (i
== AN_TIMEOUT
)
1652 CSR_WRITE_2(sc
, AN_EVENT_ACK(sc
->mpi350
), AN_EV_ALLOC
);
1653 *id
= CSR_READ_2(sc
, AN_ALLOC_FID
);
1655 if (an_seek(sc
, *id
, 0, AN_BAP0
))
1658 for (i
= 0; i
< len
/ 2; i
++)
1659 CSR_WRITE_2(sc
, AN_DATA0
, 0);
1665 an_setdef(struct an_softc
*sc
, struct an_req
*areq
)
1668 struct an_ltv_genconfig
*cfg
;
1669 struct an_ltv_ssidlist_new
*ssid
;
1670 struct an_ltv_aplist
*ap
;
1671 struct an_ltv_gen
*sp
;
1673 ifp
= &sc
->arpcom
.ac_if
;
1675 switch (areq
->an_type
) {
1676 case AN_RID_GENCONFIG
:
1677 cfg
= (struct an_ltv_genconfig
*)areq
;
1679 bcopy((char *)&cfg
->an_macaddr
, (char *)&sc
->arpcom
.ac_enaddr
,
1681 bcopy((char *)&cfg
->an_macaddr
, IF_LLADDR(ifp
), ETHER_ADDR_LEN
);
1683 bcopy((char *)cfg
, (char *)&sc
->an_config
,
1684 sizeof(struct an_ltv_genconfig
));
1686 case AN_RID_SSIDLIST
:
1687 ssid
= (struct an_ltv_ssidlist_new
*)areq
;
1688 bcopy((char *)ssid
, (char *)&sc
->an_ssidlist
,
1689 sizeof(struct an_ltv_ssidlist_new
));
1692 ap
= (struct an_ltv_aplist
*)areq
;
1693 bcopy((char *)ap
, (char *)&sc
->an_aplist
,
1694 sizeof(struct an_ltv_aplist
));
1696 case AN_RID_TX_SPEED
:
1697 sp
= (struct an_ltv_gen
*)areq
;
1698 sc
->an_tx_rate
= sp
->an_val
;
1700 /* Read the current configuration */
1701 sc
->an_config
.an_type
= AN_RID_GENCONFIG
;
1702 sc
->an_config
.an_len
= sizeof(struct an_ltv_genconfig
);
1703 an_read_record(sc
, (struct an_ltv_gen
*)&sc
->an_config
);
1704 cfg
= &sc
->an_config
;
1706 /* clear other rates and set the only one we want */
1707 bzero(cfg
->an_rates
, sizeof(cfg
->an_rates
));
1708 cfg
->an_rates
[0] = sc
->an_tx_rate
;
1710 /* Save the new rate */
1711 sc
->an_config
.an_type
= AN_RID_GENCONFIG
;
1712 sc
->an_config
.an_len
= sizeof(struct an_ltv_genconfig
);
1714 case AN_RID_WEP_TEMP
:
1715 /* Cache the temp keys */
1717 &sc
->an_temp_keys
[((struct an_ltv_key
*)areq
)->kindex
],
1718 sizeof(struct an_ltv_key
));
1719 case AN_RID_WEP_PERM
:
1720 case AN_RID_LEAPUSERNAME
:
1721 case AN_RID_LEAPPASSWORD
:
1724 /* Disable the MAC. */
1725 an_cmd(sc
, AN_CMD_DISABLE
, 0);
1728 an_write_record(sc
, (struct an_ltv_gen
*)areq
);
1730 /* Turn the MAC back on. */
1731 an_cmd(sc
, AN_CMD_ENABLE
, 0);
1734 case AN_RID_MONITOR_MODE
:
1735 cfg
= (struct an_ltv_genconfig
*)areq
;
1737 if (ng_ether_detach_p
!= NULL
)
1738 (*ng_ether_detach_p
) (ifp
);
1739 sc
->an_monitor
= cfg
->an_len
;
1741 if (sc
->an_monitor
& AN_MONITOR
) {
1742 if (sc
->an_monitor
& AN_MONITOR_AIRONET_HEADER
) {
1743 bpfattach(ifp
, DLT_AIRONET_HEADER
,
1744 sizeof(struct ether_header
));
1746 bpfattach(ifp
, DLT_IEEE802_11
,
1747 sizeof(struct ether_header
));
1750 bpfattach(ifp
, DLT_EN10MB
,
1751 sizeof(struct ether_header
));
1752 if (ng_ether_attach_p
!= NULL
)
1753 (*ng_ether_attach_p
) (ifp
);
1757 if_printf(ifp
, "unknown RID: %x\n", areq
->an_type
);
1762 /* Reinitialize the card. */
1770 * Derived from Linux driver to enable promiscious mode.
1774 an_promisc(struct an_softc
*sc
, int promisc
)
1776 if (sc
->an_was_monitor
)
1779 an_init_mpi350_desc(sc
);
1780 if (sc
->an_monitor
|| sc
->an_was_monitor
)
1783 sc
->an_was_monitor
= sc
->an_monitor
;
1784 an_cmd(sc
, AN_CMD_SET_MODE
, promisc
? 0xffff : 0);
1790 an_ioctl(struct ifnet
*ifp
, u_long command
, caddr_t data
, struct ucred
*cr
)
1795 struct an_softc
*sc
;
1797 struct ieee80211req
*ireq
;
1798 u_int8_t tmpstr
[IEEE80211_NWID_LEN
*2];
1800 struct an_ltv_genconfig
*config
;
1801 struct an_ltv_key
*key
;
1802 struct an_ltv_status
*status
;
1803 struct an_ltv_ssidlist_new
*ssids
;
1805 struct aironet_ioctl l_ioctl
;
1808 ifr
= (struct ifreq
*)data
;
1809 ireq
= (struct ieee80211req
*)data
;
1811 config
= (struct an_ltv_genconfig
*)&sc
->areq
;
1812 key
= (struct an_ltv_key
*)&sc
->areq
;
1813 status
= (struct an_ltv_status
*)&sc
->areq
;
1814 ssids
= (struct an_ltv_ssidlist_new
*)&sc
->areq
;
1818 if (ifp
->if_flags
& IFF_UP
) {
1819 if (ifp
->if_flags
& IFF_RUNNING
&&
1820 ifp
->if_flags
& IFF_PROMISC
&&
1821 !(sc
->an_if_flags
& IFF_PROMISC
)) {
1823 } else if (ifp
->if_flags
& IFF_RUNNING
&&
1824 !(ifp
->if_flags
& IFF_PROMISC
) &&
1825 sc
->an_if_flags
& IFF_PROMISC
) {
1830 if (ifp
->if_flags
& IFF_RUNNING
)
1833 sc
->an_if_flags
= ifp
->if_flags
;
1838 error
= ifmedia_ioctl(ifp
, ifr
, &sc
->an_ifmedia
, command
);
1842 /* The Aironet has no multicast filter. */
1846 error
= copyin(ifr
->ifr_data
, &sc
->areq
, sizeof(sc
->areq
));
1850 if (sc
->areq
.an_type
== AN_RID_ZERO_CACHE
) {
1851 error
= suser_cred(cr
, NULL_CRED_OKAY
);
1854 sc
->an_sigitems
= sc
->an_nextitem
= 0;
1856 } else if (sc
->areq
.an_type
== AN_RID_READ_CACHE
) {
1857 char *pt
= (char *)&sc
->areq
.an_val
;
1858 bcopy((char *)&sc
->an_sigitems
, (char *)pt
,
1861 sc
->areq
.an_len
= sizeof(int) / 2;
1862 bcopy((char *)&sc
->an_sigcache
, (char *)pt
,
1863 sizeof(struct an_sigcache
) * sc
->an_sigitems
);
1864 sc
->areq
.an_len
+= ((sizeof(struct an_sigcache
) *
1865 sc
->an_sigitems
) / 2) + 1;
1868 if (an_read_record(sc
, (struct an_ltv_gen
*)&sc
->areq
)) {
1872 error
= copyout(&sc
->areq
, ifr
->ifr_data
, sizeof(sc
->areq
));
1875 if ((error
= suser_cred(cr
, NULL_CRED_OKAY
)))
1877 error
= copyin(ifr
->ifr_data
, &sc
->areq
, sizeof(sc
->areq
));
1880 an_setdef(sc
, &sc
->areq
);
1882 case SIOCGPRIVATE_0
: /* used by Cisco client utility */
1883 if ((error
= suser_cred(cr
, NULL_CRED_OKAY
)))
1885 copyin(ifr
->ifr_data
, &l_ioctl
, sizeof(l_ioctl
));
1886 mode
= l_ioctl
.command
;
1888 if (mode
>= AIROGCAP
&& mode
<= AIROGSTATSD32
) {
1889 error
= readrids(ifp
, &l_ioctl
);
1890 } else if (mode
>= AIROPCAP
&& mode
<= AIROPLEAPUSR
) {
1891 error
= writerids(ifp
, &l_ioctl
);
1892 } else if (mode
>= AIROFLSHRST
&& mode
<= AIRORESTART
) {
1893 error
= flashcard(ifp
, &l_ioctl
);
1898 /* copy out the updated command info */
1899 copyout(&l_ioctl
, ifr
->ifr_data
, sizeof(l_ioctl
));
1902 case SIOCGPRIVATE_1
: /* used by Cisco client utility */
1903 if ((error
= suser_cred(cr
, NULL_CRED_OKAY
)))
1905 copyin(ifr
->ifr_data
, &l_ioctl
, sizeof(l_ioctl
));
1906 l_ioctl
.command
= 0;
1908 copyout(&error
, l_ioctl
.data
, sizeof(error
));
1912 sc
->areq
.an_len
= sizeof(sc
->areq
);
1913 /* was that a good idea DJA we are doing a short-cut */
1914 switch (ireq
->i_type
) {
1915 case IEEE80211_IOC_SSID
:
1916 if (ireq
->i_val
== -1) {
1917 sc
->areq
.an_type
= AN_RID_STATUS
;
1918 if (an_read_record(sc
,
1919 (struct an_ltv_gen
*)&sc
->areq
)) {
1923 len
= status
->an_ssidlen
;
1924 tmpptr
= status
->an_ssid
;
1925 } else if (ireq
->i_val
>= 0) {
1926 sc
->areq
.an_type
= AN_RID_SSIDLIST
;
1927 if (an_read_record(sc
,
1928 (struct an_ltv_gen
*)&sc
->areq
)) {
1932 max
= (sc
->areq
.an_len
- 4)
1933 / sizeof(struct an_ltv_ssid_entry
);
1934 if ( max
> MAX_SSIDS
) {
1935 printf("To many SSIDs only using "
1940 if (ireq
->i_val
> max
) {
1944 len
= ssids
->an_entry
[ireq
->i_val
].an_len
;
1945 tmpptr
= ssids
->an_entry
[ireq
->i_val
].an_ssid
;
1951 if (len
> IEEE80211_NWID_LEN
) {
1956 bzero(tmpstr
, IEEE80211_NWID_LEN
);
1957 bcopy(tmpptr
, tmpstr
, len
);
1958 error
= copyout(tmpstr
, ireq
->i_data
,
1959 IEEE80211_NWID_LEN
);
1961 case IEEE80211_IOC_NUMSSIDS
:
1962 sc
->areq
.an_len
= sizeof(sc
->areq
);
1963 sc
->areq
.an_type
= AN_RID_SSIDLIST
;
1964 if (an_read_record(sc
,
1965 (struct an_ltv_gen
*)&sc
->areq
)) {
1969 max
= (sc
->areq
.an_len
- 4)
1970 / sizeof(struct an_ltv_ssid_entry
);
1971 if (max
> MAX_SSIDS
) {
1972 printf("To many SSIDs only using "
1979 case IEEE80211_IOC_WEP
:
1980 sc
->areq
.an_type
= AN_RID_ACTUALCFG
;
1981 if (an_read_record(sc
,
1982 (struct an_ltv_gen
*)&sc
->areq
)) {
1986 if (config
->an_authtype
& AN_AUTHTYPE_PRIVACY_IN_USE
) {
1987 if (config
->an_authtype
&
1988 AN_AUTHTYPE_ALLOW_UNENCRYPTED
)
1989 ireq
->i_val
= IEEE80211_WEP_MIXED
;
1991 ireq
->i_val
= IEEE80211_WEP_ON
;
1993 ireq
->i_val
= IEEE80211_WEP_OFF
;
1996 case IEEE80211_IOC_WEPKEY
:
1998 * XXX: I'm not entierly convinced this is
1999 * correct, but it's what is implemented in
2000 * ancontrol so it will have to do until we get
2001 * access to actual Cisco code.
2003 if (ireq
->i_val
< 0 || ireq
->i_val
> 8) {
2008 if (ireq
->i_val
< 5) {
2009 sc
->areq
.an_type
= AN_RID_WEP_TEMP
;
2010 for (i
= 0; i
< 5; i
++) {
2011 if (an_read_record(sc
,
2012 (struct an_ltv_gen
*)&sc
->areq
)) {
2016 if (key
->kindex
== 0xffff)
2018 if (key
->kindex
== ireq
->i_val
)
2020 /* Required to get next entry */
2021 sc
->areq
.an_type
= AN_RID_WEP_PERM
;
2026 /* We aren't allowed to read the value of the
2027 * key from the card so we just output zeros
2028 * like we would if we could read the card, but
2029 * denied the user access.
2033 error
= copyout(tmpstr
, ireq
->i_data
, len
);
2035 case IEEE80211_IOC_NUMWEPKEYS
:
2036 ireq
->i_val
= 9; /* include home key */
2038 case IEEE80211_IOC_WEPTXKEY
:
2040 * For some strange reason, you have to read all
2041 * keys before you can read the txkey.
2043 sc
->areq
.an_type
= AN_RID_WEP_TEMP
;
2044 for (i
= 0; i
< 5; i
++) {
2045 if (an_read_record(sc
,
2046 (struct an_ltv_gen
*) &sc
->areq
)) {
2050 if (key
->kindex
== 0xffff)
2052 /* Required to get next entry */
2053 sc
->areq
.an_type
= AN_RID_WEP_PERM
;
2058 sc
->areq
.an_type
= AN_RID_WEP_PERM
;
2059 key
->kindex
= 0xffff;
2060 if (an_read_record(sc
,
2061 (struct an_ltv_gen
*)&sc
->areq
)) {
2065 ireq
->i_val
= key
->mac
[0];
2067 * Check for home mode. Map home mode into
2068 * 5th key since that is how it is stored on
2071 sc
->areq
.an_len
= sizeof(struct an_ltv_genconfig
);
2072 sc
->areq
.an_type
= AN_RID_GENCONFIG
;
2073 if (an_read_record(sc
,
2074 (struct an_ltv_gen
*)&sc
->areq
)) {
2078 if (config
->an_home_product
& AN_HOME_NETWORK
)
2081 case IEEE80211_IOC_AUTHMODE
:
2082 sc
->areq
.an_type
= AN_RID_ACTUALCFG
;
2083 if (an_read_record(sc
,
2084 (struct an_ltv_gen
*)&sc
->areq
)) {
2088 if ((config
->an_authtype
& AN_AUTHTYPE_MASK
) ==
2090 ireq
->i_val
= IEEE80211_AUTH_NONE
;
2091 } else if ((config
->an_authtype
& AN_AUTHTYPE_MASK
) ==
2093 ireq
->i_val
= IEEE80211_AUTH_OPEN
;
2094 } else if ((config
->an_authtype
& AN_AUTHTYPE_MASK
) ==
2095 AN_AUTHTYPE_SHAREDKEY
) {
2096 ireq
->i_val
= IEEE80211_AUTH_SHARED
;
2100 case IEEE80211_IOC_STATIONNAME
:
2101 sc
->areq
.an_type
= AN_RID_ACTUALCFG
;
2102 if (an_read_record(sc
,
2103 (struct an_ltv_gen
*)&sc
->areq
)) {
2107 ireq
->i_len
= sizeof(config
->an_nodename
);
2108 tmpptr
= config
->an_nodename
;
2109 bzero(tmpstr
, IEEE80211_NWID_LEN
);
2110 bcopy(tmpptr
, tmpstr
, ireq
->i_len
);
2111 error
= copyout(tmpstr
, ireq
->i_data
,
2112 IEEE80211_NWID_LEN
);
2114 case IEEE80211_IOC_CHANNEL
:
2115 sc
->areq
.an_type
= AN_RID_STATUS
;
2116 if (an_read_record(sc
,
2117 (struct an_ltv_gen
*)&sc
->areq
)) {
2121 ireq
->i_val
= status
->an_cur_channel
;
2123 case IEEE80211_IOC_POWERSAVE
:
2124 sc
->areq
.an_type
= AN_RID_ACTUALCFG
;
2125 if (an_read_record(sc
,
2126 (struct an_ltv_gen
*)&sc
->areq
)) {
2130 if (config
->an_psave_mode
== AN_PSAVE_NONE
) {
2131 ireq
->i_val
= IEEE80211_POWERSAVE_OFF
;
2132 } else if (config
->an_psave_mode
== AN_PSAVE_CAM
) {
2133 ireq
->i_val
= IEEE80211_POWERSAVE_CAM
;
2134 } else if (config
->an_psave_mode
== AN_PSAVE_PSP
) {
2135 ireq
->i_val
= IEEE80211_POWERSAVE_PSP
;
2136 } else if (config
->an_psave_mode
== AN_PSAVE_PSP_CAM
) {
2137 ireq
->i_val
= IEEE80211_POWERSAVE_PSP_CAM
;
2141 case IEEE80211_IOC_POWERSAVESLEEP
:
2142 sc
->areq
.an_type
= AN_RID_ACTUALCFG
;
2143 if (an_read_record(sc
,
2144 (struct an_ltv_gen
*)&sc
->areq
)) {
2148 ireq
->i_val
= config
->an_listen_interval
;
2153 if ((error
= suser_cred(cr
, NULL_CRED_OKAY
)))
2155 sc
->areq
.an_len
= sizeof(sc
->areq
);
2157 * We need a config structure for everything but the WEP
2158 * key management and SSIDs so we get it now so avoid
2159 * duplicating this code every time.
2161 if (ireq
->i_type
!= IEEE80211_IOC_SSID
&&
2162 ireq
->i_type
!= IEEE80211_IOC_WEPKEY
&&
2163 ireq
->i_type
!= IEEE80211_IOC_WEPTXKEY
) {
2164 sc
->areq
.an_type
= AN_RID_GENCONFIG
;
2165 if (an_read_record(sc
,
2166 (struct an_ltv_gen
*)&sc
->areq
)) {
2171 switch (ireq
->i_type
) {
2172 case IEEE80211_IOC_SSID
:
2173 sc
->areq
.an_len
= sizeof(sc
->areq
);
2174 sc
->areq
.an_type
= AN_RID_SSIDLIST
;
2175 if (an_read_record(sc
,
2176 (struct an_ltv_gen
*)&sc
->areq
)) {
2180 if (ireq
->i_len
> IEEE80211_NWID_LEN
) {
2184 max
= (sc
->areq
.an_len
- 4)
2185 / sizeof(struct an_ltv_ssid_entry
);
2186 if (max
> MAX_SSIDS
) {
2187 printf("To many SSIDs only using "
2192 if (ireq
->i_val
> max
) {
2196 error
= copyin(ireq
->i_data
,
2197 ssids
->an_entry
[ireq
->i_val
].an_ssid
,
2199 ssids
->an_entry
[ireq
->i_val
].an_len
2204 case IEEE80211_IOC_WEP
:
2205 switch (ireq
->i_val
) {
2206 case IEEE80211_WEP_OFF
:
2207 config
->an_authtype
&=
2208 ~(AN_AUTHTYPE_PRIVACY_IN_USE
|
2209 AN_AUTHTYPE_ALLOW_UNENCRYPTED
);
2211 case IEEE80211_WEP_ON
:
2212 config
->an_authtype
|=
2213 AN_AUTHTYPE_PRIVACY_IN_USE
;
2214 config
->an_authtype
&=
2215 ~AN_AUTHTYPE_ALLOW_UNENCRYPTED
;
2217 case IEEE80211_WEP_MIXED
:
2218 config
->an_authtype
|=
2219 AN_AUTHTYPE_PRIVACY_IN_USE
|
2220 AN_AUTHTYPE_ALLOW_UNENCRYPTED
;
2227 case IEEE80211_IOC_WEPKEY
:
2228 if (ireq
->i_val
< 0 || ireq
->i_val
> 8 ||
2233 error
= copyin(ireq
->i_data
, tmpstr
, 13);
2237 * Map the 9th key into the home mode
2238 * since that is how it is stored on
2241 bzero(&sc
->areq
, sizeof(struct an_ltv_key
));
2242 sc
->areq
.an_len
= sizeof(struct an_ltv_key
);
2243 key
->mac
[0] = 1; /* The others are 0. */
2244 if (ireq
->i_val
< 4) {
2245 sc
->areq
.an_type
= AN_RID_WEP_TEMP
;
2246 key
->kindex
= ireq
->i_val
;
2248 sc
->areq
.an_type
= AN_RID_WEP_PERM
;
2249 key
->kindex
= ireq
->i_val
- 4;
2251 key
->klen
= ireq
->i_len
;
2252 bcopy(tmpstr
, key
->key
, key
->klen
);
2254 case IEEE80211_IOC_WEPTXKEY
:
2255 if (ireq
->i_val
< 0 || ireq
->i_val
> 4) {
2261 * Map the 5th key into the home mode
2262 * since that is how it is stored on
2265 sc
->areq
.an_len
= sizeof(struct an_ltv_genconfig
);
2266 sc
->areq
.an_type
= AN_RID_ACTUALCFG
;
2267 if (an_read_record(sc
,
2268 (struct an_ltv_gen
*)&sc
->areq
)) {
2272 if (ireq
->i_val
== 4) {
2273 config
->an_home_product
|= AN_HOME_NETWORK
;
2276 config
->an_home_product
&= ~AN_HOME_NETWORK
;
2279 sc
->an_config
.an_home_product
2280 = config
->an_home_product
;
2282 /* update configuration */
2285 bzero(&sc
->areq
, sizeof(struct an_ltv_key
));
2286 sc
->areq
.an_len
= sizeof(struct an_ltv_key
);
2287 sc
->areq
.an_type
= AN_RID_WEP_PERM
;
2288 key
->kindex
= 0xffff;
2289 key
->mac
[0] = ireq
->i_val
;
2291 case IEEE80211_IOC_AUTHMODE
:
2292 switch (ireq
->i_val
) {
2293 case IEEE80211_AUTH_NONE
:
2294 config
->an_authtype
= AN_AUTHTYPE_NONE
|
2295 (config
->an_authtype
& ~AN_AUTHTYPE_MASK
);
2297 case IEEE80211_AUTH_OPEN
:
2298 config
->an_authtype
= AN_AUTHTYPE_OPEN
|
2299 (config
->an_authtype
& ~AN_AUTHTYPE_MASK
);
2301 case IEEE80211_AUTH_SHARED
:
2302 config
->an_authtype
= AN_AUTHTYPE_SHAREDKEY
|
2303 (config
->an_authtype
& ~AN_AUTHTYPE_MASK
);
2309 case IEEE80211_IOC_STATIONNAME
:
2310 if (ireq
->i_len
> 16) {
2314 bzero(config
->an_nodename
, 16);
2315 error
= copyin(ireq
->i_data
,
2316 config
->an_nodename
, ireq
->i_len
);
2318 case IEEE80211_IOC_CHANNEL
:
2320 * The actual range is 1-14, but if you set it
2321 * to 0 you get the default so we let that work
2324 if (ireq
->i_val
< 0 || ireq
->i_val
>14) {
2328 config
->an_ds_channel
= ireq
->i_val
;
2330 case IEEE80211_IOC_POWERSAVE
:
2331 switch (ireq
->i_val
) {
2332 case IEEE80211_POWERSAVE_OFF
:
2333 config
->an_psave_mode
= AN_PSAVE_NONE
;
2335 case IEEE80211_POWERSAVE_CAM
:
2336 config
->an_psave_mode
= AN_PSAVE_CAM
;
2338 case IEEE80211_POWERSAVE_PSP
:
2339 config
->an_psave_mode
= AN_PSAVE_PSP
;
2341 case IEEE80211_POWERSAVE_PSP_CAM
:
2342 config
->an_psave_mode
= AN_PSAVE_PSP_CAM
;
2349 case IEEE80211_IOC_POWERSAVESLEEP
:
2350 config
->an_listen_interval
= ireq
->i_val
;
2355 an_setdef(sc
, &sc
->areq
);
2358 error
= ether_ioctl(ifp
, command
, data
);
2366 an_init_tx_ring(struct an_softc
*sc
)
2372 for (i
= 0; i
< AN_TX_RING_CNT
; i
++) {
2373 if (an_alloc_nicmem(sc
, 1518 +
2376 sc
->an_rdata
.an_tx_fids
[i
] = id
;
2377 sc
->an_rdata
.an_tx_ring
[i
] = 0;
2381 sc
->an_rdata
.an_tx_prod
= 0;
2382 sc
->an_rdata
.an_tx_cons
= 0;
2383 sc
->an_rdata
.an_tx_empty
= 1;
2391 struct an_softc
*sc
= xsc
;
2392 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
2394 if (ifp
->if_flags
& IFF_RUNNING
)
2397 sc
->an_associated
= 0;
2399 /* Allocate the TX buffers */
2400 if (an_init_tx_ring(sc
)) {
2403 an_init_mpi350_desc(sc
);
2404 if (an_init_tx_ring(sc
)) {
2405 if_printf(ifp
, "tx buffer allocation failed\n");
2410 /* Set our MAC address. */
2411 bcopy((char *)&sc
->arpcom
.ac_enaddr
,
2412 (char *)&sc
->an_config
.an_macaddr
, ETHER_ADDR_LEN
);
2414 if (ifp
->if_flags
& IFF_BROADCAST
)
2415 sc
->an_config
.an_rxmode
= AN_RXMODE_BC_ADDR
;
2417 sc
->an_config
.an_rxmode
= AN_RXMODE_ADDR
;
2419 if (ifp
->if_flags
& IFF_MULTICAST
)
2420 sc
->an_config
.an_rxmode
= AN_RXMODE_BC_MC_ADDR
;
2422 if (ifp
->if_flags
& IFF_PROMISC
) {
2423 if (sc
->an_monitor
& AN_MONITOR
) {
2424 if (sc
->an_monitor
& AN_MONITOR_ANY_BSS
) {
2425 sc
->an_config
.an_rxmode
|=
2426 AN_RXMODE_80211_MONITOR_ANYBSS
|
2427 AN_RXMODE_NO_8023_HEADER
;
2429 sc
->an_config
.an_rxmode
|=
2430 AN_RXMODE_80211_MONITOR_CURBSS
|
2431 AN_RXMODE_NO_8023_HEADER
;
2436 if (sc
->an_have_rssimap
)
2437 sc
->an_config
.an_rxmode
|= AN_RXMODE_NORMALIZED_RSSI
;
2439 /* Set the ssid list */
2440 sc
->an_ssidlist
.an_type
= AN_RID_SSIDLIST
;
2441 sc
->an_ssidlist
.an_len
= sizeof(struct an_ltv_ssidlist_new
);
2442 if (an_write_record(sc
, (struct an_ltv_gen
*)&sc
->an_ssidlist
)) {
2443 if_printf(ifp
, "failed to set ssid list\n");
2447 /* Set the AP list */
2448 sc
->an_aplist
.an_type
= AN_RID_APLIST
;
2449 sc
->an_aplist
.an_len
= sizeof(struct an_ltv_aplist
);
2450 if (an_write_record(sc
, (struct an_ltv_gen
*)&sc
->an_aplist
)) {
2451 if_printf(ifp
, "failed to set AP list\n");
2455 /* Set the configuration in the NIC */
2456 sc
->an_config
.an_len
= sizeof(struct an_ltv_genconfig
);
2457 sc
->an_config
.an_type
= AN_RID_GENCONFIG
;
2458 if (an_write_record(sc
, (struct an_ltv_gen
*)&sc
->an_config
)) {
2459 if_printf(ifp
, "failed to set configuration\n");
2463 /* Enable the MAC */
2464 if (an_cmd(sc
, AN_CMD_ENABLE
, 0)) {
2465 if_printf(ifp
, "failed to enable MAC\n");
2469 if (ifp
->if_flags
& IFF_PROMISC
)
2470 an_cmd(sc
, AN_CMD_SET_MODE
, 0xffff);
2472 /* enable interrupts */
2473 CSR_WRITE_2(sc
, AN_INT_EN(sc
->mpi350
), AN_INTRS(sc
->mpi350
));
2475 ifp
->if_flags
|= IFF_RUNNING
;
2476 ifp
->if_flags
&= ~IFF_OACTIVE
;
2478 callout_reset(&sc
->an_stat_timer
, hz
, an_stats_update
, sc
);
2482 an_start(struct ifnet
*ifp
)
2484 struct an_softc
*sc
;
2485 struct mbuf
*m0
= NULL
;
2486 struct an_txframe_802_3 tx_frame_802_3
;
2487 struct ether_header
*eh
;
2489 unsigned char txcontrol
;
2490 struct an_card_tx_desc an_tx_desc
;
2495 if (ifp
->if_flags
& IFF_OACTIVE
)
2498 if (!sc
->an_associated
)
2501 /* We can't send in monitor mode so toss any attempts. */
2502 if (sc
->an_monitor
&& (ifp
->if_flags
& IFF_PROMISC
)) {
2503 ifq_purge(&ifp
->if_snd
);
2507 idx
= sc
->an_rdata
.an_tx_prod
;
2510 bzero((char *)&tx_frame_802_3
, sizeof(tx_frame_802_3
));
2512 while (sc
->an_rdata
.an_tx_ring
[idx
] == 0) {
2513 m0
= ifq_dequeue(&ifp
->if_snd
, NULL
);
2517 id
= sc
->an_rdata
.an_tx_fids
[idx
];
2518 eh
= mtod(m0
, struct ether_header
*);
2520 bcopy((char *)&eh
->ether_dhost
,
2521 (char *)&tx_frame_802_3
.an_tx_dst_addr
,
2523 bcopy((char *)&eh
->ether_shost
,
2524 (char *)&tx_frame_802_3
.an_tx_src_addr
,
2527 /* minus src/dest mac & type */
2528 tx_frame_802_3
.an_tx_802_3_payload_len
=
2529 m0
->m_pkthdr
.len
- 12;
2531 m_copydata(m0
, sizeof(struct ether_header
) - 2 ,
2532 tx_frame_802_3
.an_tx_802_3_payload_len
,
2533 (caddr_t
)&sc
->an_txbuf
);
2535 txcontrol
= AN_TXCTL_8023
;
2536 /* write the txcontrol only */
2537 an_write_data(sc
, id
, 0x08, (caddr_t
)&txcontrol
,
2541 an_write_data(sc
, id
, 0x34, (caddr_t
)&tx_frame_802_3
,
2542 sizeof(struct an_txframe_802_3
));
2544 /* in mbuf header type is just before payload */
2545 an_write_data(sc
, id
, 0x44, (caddr_t
)&sc
->an_txbuf
,
2546 tx_frame_802_3
.an_tx_802_3_payload_len
);
2553 sc
->an_rdata
.an_tx_ring
[idx
] = id
;
2554 if (an_cmd(sc
, AN_CMD_TX
, id
))
2555 if_printf(ifp
, "xmit failed\n");
2557 AN_INC(idx
, AN_TX_RING_CNT
);
2560 * Set a timeout in case the chip goes out to lunch.
2564 } else { /* MPI-350 */
2565 /* Disable interrupts. */
2566 CSR_WRITE_2(sc
, AN_INT_EN(sc
->mpi350
), 0);
2568 while (sc
->an_rdata
.an_tx_empty
||
2569 idx
!= sc
->an_rdata
.an_tx_cons
) {
2570 m0
= ifq_dequeue(&ifp
->if_snd
, NULL
);
2574 buf
= sc
->an_tx_buffer
[idx
].an_dma_vaddr
;
2576 eh
= mtod(m0
, struct ether_header
*);
2578 /* DJA optimize this to limit bcopy */
2579 bcopy((char *)&eh
->ether_dhost
,
2580 (char *)&tx_frame_802_3
.an_tx_dst_addr
,
2582 bcopy((char *)&eh
->ether_shost
,
2583 (char *)&tx_frame_802_3
.an_tx_src_addr
,
2586 /* minus src/dest mac & type */
2587 tx_frame_802_3
.an_tx_802_3_payload_len
=
2588 m0
->m_pkthdr
.len
- 12;
2590 m_copydata(m0
, sizeof(struct ether_header
) - 2 ,
2591 tx_frame_802_3
.an_tx_802_3_payload_len
,
2592 (caddr_t
)&sc
->an_txbuf
);
2594 txcontrol
= AN_TXCTL_8023
;
2595 /* write the txcontrol only */
2596 bcopy((caddr_t
)&txcontrol
, &buf
[0x08],
2600 bcopy((caddr_t
)&tx_frame_802_3
, &buf
[0x34],
2601 sizeof(struct an_txframe_802_3
));
2603 /* in mbuf header type is just before payload */
2604 bcopy((caddr_t
)&sc
->an_txbuf
, &buf
[0x44],
2605 tx_frame_802_3
.an_tx_802_3_payload_len
);
2608 bzero(&an_tx_desc
, sizeof(an_tx_desc
));
2609 an_tx_desc
.an_offset
= 0;
2610 an_tx_desc
.an_eoc
= 1;
2611 an_tx_desc
.an_valid
= 1;
2612 an_tx_desc
.an_len
= 0x44 +
2613 tx_frame_802_3
.an_tx_802_3_payload_len
;
2614 an_tx_desc
.an_phys
= sc
->an_tx_buffer
[idx
].an_dma_paddr
;
2615 for (i
= 0; i
< sizeof(an_tx_desc
) / 4 ; i
++) {
2616 CSR_MEM_AUX_WRITE_4(sc
, AN_TX_DESC_OFFSET
2618 + (0 * sizeof(an_tx_desc
))
2620 ((u_int32_t
*)&an_tx_desc
)[i
]);
2628 AN_INC(idx
, AN_MAX_TX_DESC
);
2629 sc
->an_rdata
.an_tx_empty
= 0;
2631 CSR_WRITE_2(sc
, AN_EVENT_ACK(sc
->mpi350
), AN_EV_ALLOC
);
2634 * Set a timeout in case the chip goes out to lunch.
2639 /* Re-enable interrupts. */
2640 CSR_WRITE_2(sc
, AN_INT_EN(sc
->mpi350
), AN_INTRS(sc
->mpi350
));
2644 ifp
->if_flags
|= IFF_OACTIVE
;
2646 sc
->an_rdata
.an_tx_prod
= idx
;
2650 an_stop(struct an_softc
*sc
)
2655 ifp
= &sc
->arpcom
.ac_if
;
2657 an_cmd(sc
, AN_CMD_FORCE_SYNCLOSS
, 0);
2658 CSR_WRITE_2(sc
, AN_INT_EN(sc
->mpi350
), 0);
2659 an_cmd(sc
, AN_CMD_DISABLE
, 0);
2661 for (i
= 0; i
< AN_TX_RING_CNT
; i
++)
2662 an_cmd(sc
, AN_CMD_DEALLOC_MEM
, sc
->an_rdata
.an_tx_fids
[i
]);
2664 callout_stop(&sc
->an_stat_timer
);
2666 ifp
->if_flags
&= ~(IFF_RUNNING
|IFF_OACTIVE
);
2668 if (sc
->an_flash_buffer
) {
2669 kfree(sc
->an_flash_buffer
, M_DEVBUF
);
2670 sc
->an_flash_buffer
= NULL
;
2675 an_watchdog(struct ifnet
*ifp
)
2677 struct an_softc
*sc
;
2683 an_init_mpi350_desc(sc
);
2688 if_printf(ifp
, "device timeout\n");
2692 an_shutdown(device_t dev
)
2694 struct an_softc
*sc
;
2696 sc
= device_get_softc(dev
);
2703 an_resume(device_t dev
)
2705 struct an_softc
*sc
;
2709 sc
= device_get_softc(dev
);
2710 ifp
= &sc
->arpcom
.ac_if
;
2714 an_init_mpi350_desc(sc
);
2717 /* Recovery temporary keys */
2718 for (i
= 0; i
< 4; i
++) {
2719 sc
->areq
.an_type
= AN_RID_WEP_TEMP
;
2720 sc
->areq
.an_len
= sizeof(struct an_ltv_key
);
2721 bcopy(&sc
->an_temp_keys
[i
],
2722 &sc
->areq
, sizeof(struct an_ltv_key
));
2723 an_setdef(sc
, &sc
->areq
);
2726 if (ifp
->if_flags
& IFF_UP
)
2733 /* Aironet signal strength cache code.
2734 * store signal/noise/quality on per MAC src basis in
2735 * a small fixed cache. The cache wraps if > MAX slots
2736 * used. The cache may be zeroed out to start over.
2737 * Two simple filters exist to reduce computation:
2738 * 1. ip only (literally 0x800, ETHERTYPE_IP) which may be used
2739 * to ignore some packets. It defaults to ip only.
2740 * it could be used to focus on broadcast, non-IP 802.11 beacons.
2741 * 2. multicast/broadcast only. This may be used to
2742 * ignore unicast packets and only cache signal strength
2743 * for multicast/broadcast packets (beacons); e.g., Mobile-IP
2744 * beacons and not unicast traffic.
2746 * The cache stores (MAC src(index), IP src (major clue), signal,
2749 * No apologies for storing IP src here. It's easy and saves much
2750 * trouble elsewhere. The cache is assumed to be INET dependent,
2751 * although it need not be.
2753 * Note: the Aironet only has a single byte of signal strength value
2754 * in the rx frame header, and it's not scaled to anything sensible.
2755 * This is kind of lame, but it's all we've got.
2758 #ifdef documentation
2760 int an_sigitems
; /* number of cached entries */
2761 struct an_sigcache an_sigcache
[MAXANCACHE
]; /* array of cache entries */
2762 int an_nextitem
; /* index/# of entries */
2767 /* control variables for cache filtering. Basic idea is
2768 * to reduce cost (e.g., to only Mobile-IP agent beacons
2769 * which are broadcast or multicast). Still you might
2770 * want to measure signal strength anth unicast ping packets
2771 * on a pt. to pt. ant. setup.
2773 /* set true if you want to limit cache items to broadcast/mcast
2774 * only packets (not unicast). Useful for mobile-ip beacons which
2775 * are broadcast/multicast at network layer. Default is all packets
2776 * so ping/unicast anll work say anth pt. to pt. antennae setup.
2778 static int an_cache_mcastonly
= 0;
2779 SYSCTL_INT(_hw_an
, OID_AUTO
, an_cache_mcastonly
, CTLFLAG_RW
,
2780 &an_cache_mcastonly
, 0, "");
2782 /* set true if you want to limit cache items to IP packets only
2784 static int an_cache_iponly
= 1;
2785 SYSCTL_INT(_hw_an
, OID_AUTO
, an_cache_iponly
, CTLFLAG_RW
,
2786 &an_cache_iponly
, 0, "");
2789 * an_cache_store, per rx packet store signal
2790 * strength in MAC (src) indexed cache.
2793 an_cache_store (struct an_softc
*sc
, struct mbuf
*m
, u_int8_t rx_rssi
,
2794 u_int8_t rx_quality
)
2796 struct ether_header
*eh
= mtod(m
, struct ether_header
*);
2797 struct ip
*ip
= NULL
;
2799 static int cache_slot
= 0; /* use this cache entry */
2800 static int wrapindex
= 0; /* next "free" cache entry */
2804 * 2. configurable filter to throw out unicast packets,
2805 * keep multicast only.
2808 if ((ntohs(eh
->ether_type
) == ETHERTYPE_IP
))
2809 ip
= (struct ip
*)(mtod(m
, uint8_t *) + ETHER_HDR_LEN
);
2810 else if (an_cache_iponly
)
2813 /* filter for broadcast/multicast only
2815 if (an_cache_mcastonly
&& ((eh
->ether_dhost
[0] & 1) == 0)) {
2820 if_printf(&sc
->arpcom
.ac_if
, "q value %x (MSB=0x%x, LSB=0x%x)\n",
2821 rx_rssi
& 0xffff, rx_rssi
>> 8, rx_rssi
& 0xff);
2824 /* do a linear search for a matching MAC address
2825 * in the cache table
2826 * . MAC address is 6 bytes,
2827 * . var w_nextitem holds total number of entries already cached
2829 for (i
= 0; i
< sc
->an_nextitem
; i
++) {
2830 if (! bcmp(eh
->ether_shost
, sc
->an_sigcache
[i
].macsrc
, 6 )) {
2832 * so we already have this entry,
2839 /* did we find a matching mac address?
2840 * if yes, then overwrite a previously existing cache entry
2842 if (i
< sc
->an_nextitem
) {
2845 /* else, have a new address entry,so
2846 * add this new entry,
2847 * if table full, then we need to replace LRU entry
2851 /* check for space in cache table
2852 * note: an_nextitem also holds number of entries
2853 * added in the cache table
2855 if ( sc
->an_nextitem
< MAXANCACHE
) {
2856 cache_slot
= sc
->an_nextitem
;
2858 sc
->an_sigitems
= sc
->an_nextitem
;
2860 /* no space found, so simply wrap anth wrap index
2861 * and "zap" the next entry
2864 if (wrapindex
== MAXANCACHE
) {
2867 cache_slot
= wrapindex
++;
2871 /* invariant: cache_slot now points at some slot
2874 if (cache_slot
< 0 || cache_slot
>= MAXANCACHE
) {
2875 log(LOG_ERR
, "an_cache_store, bad index: %d of "
2876 "[0..%d], gross cache error\n",
2877 cache_slot
, MAXANCACHE
);
2881 /* store items in cache
2882 * .ip source address
2887 sc
->an_sigcache
[cache_slot
].ipsrc
= ip
->ip_src
.s_addr
;
2889 bcopy( eh
->ether_shost
, sc
->an_sigcache
[cache_slot
].macsrc
, 6);
2892 switch (an_cache_mode
) {
2894 if (sc
->an_have_rssimap
) {
2895 sc
->an_sigcache
[cache_slot
].signal
=
2896 - sc
->an_rssimap
.an_entries
[rx_rssi
].an_rss_dbm
;
2897 sc
->an_sigcache
[cache_slot
].quality
=
2898 - sc
->an_rssimap
.an_entries
[rx_quality
].an_rss_dbm
;
2900 sc
->an_sigcache
[cache_slot
].signal
= rx_rssi
- 100;
2901 sc
->an_sigcache
[cache_slot
].quality
= rx_quality
- 100;
2905 if (sc
->an_have_rssimap
) {
2906 sc
->an_sigcache
[cache_slot
].signal
=
2907 sc
->an_rssimap
.an_entries
[rx_rssi
].an_rss_pct
;
2908 sc
->an_sigcache
[cache_slot
].quality
=
2909 sc
->an_rssimap
.an_entries
[rx_quality
].an_rss_pct
;
2913 if (rx_quality
> 100)
2915 sc
->an_sigcache
[cache_slot
].signal
= rx_rssi
;
2916 sc
->an_sigcache
[cache_slot
].quality
= rx_quality
;
2920 sc
->an_sigcache
[cache_slot
].signal
= rx_rssi
;
2921 sc
->an_sigcache
[cache_slot
].quality
= rx_quality
;
2925 sc
->an_sigcache
[cache_slot
].noise
= 0;
2932 an_media_change(struct ifnet
*ifp
)
2934 struct an_softc
*sc
= ifp
->if_softc
;
2935 struct an_ltv_genconfig
*cfg
;
2936 int otype
= sc
->an_config
.an_opmode
;
2937 int orate
= sc
->an_tx_rate
;
2939 switch (IFM_SUBTYPE(sc
->an_ifmedia
.ifm_cur
->ifm_media
)) {
2940 case IFM_IEEE80211_DS1
:
2941 sc
->an_tx_rate
= AN_RATE_1MBPS
;
2943 case IFM_IEEE80211_DS2
:
2944 sc
->an_tx_rate
= AN_RATE_2MBPS
;
2946 case IFM_IEEE80211_DS5
:
2947 sc
->an_tx_rate
= AN_RATE_5_5MBPS
;
2949 case IFM_IEEE80211_DS11
:
2950 sc
->an_tx_rate
= AN_RATE_11MBPS
;
2957 if (orate
!= sc
->an_tx_rate
) {
2958 /* Read the current configuration */
2959 sc
->an_config
.an_type
= AN_RID_GENCONFIG
;
2960 sc
->an_config
.an_len
= sizeof(struct an_ltv_genconfig
);
2961 an_read_record(sc
, (struct an_ltv_gen
*)&sc
->an_config
);
2962 cfg
= &sc
->an_config
;
2964 /* clear other rates and set the only one we want */
2965 bzero(cfg
->an_rates
, sizeof(cfg
->an_rates
));
2966 cfg
->an_rates
[0] = sc
->an_tx_rate
;
2968 /* Save the new rate */
2969 sc
->an_config
.an_type
= AN_RID_GENCONFIG
;
2970 sc
->an_config
.an_len
= sizeof(struct an_ltv_genconfig
);
2973 if ((sc
->an_ifmedia
.ifm_cur
->ifm_media
& IFM_IEEE80211_ADHOC
) != 0)
2974 sc
->an_config
.an_opmode
&= ~AN_OPMODE_INFRASTRUCTURE_STATION
;
2976 sc
->an_config
.an_opmode
|= AN_OPMODE_INFRASTRUCTURE_STATION
;
2978 if (otype
!= sc
->an_config
.an_opmode
||
2979 orate
!= sc
->an_tx_rate
)
2986 an_media_status(struct ifnet
*ifp
, struct ifmediareq
*imr
)
2988 struct an_ltv_status status
;
2989 struct an_softc
*sc
= ifp
->if_softc
;
2991 status
.an_len
= sizeof(status
);
2992 status
.an_type
= AN_RID_STATUS
;
2993 if (an_read_record(sc
, (struct an_ltv_gen
*)&status
)) {
2994 /* If the status read fails, just lie. */
2995 imr
->ifm_active
= sc
->an_ifmedia
.ifm_cur
->ifm_media
;
2996 imr
->ifm_status
= IFM_AVALID
|IFM_ACTIVE
;
2999 if (sc
->an_tx_rate
== 0) {
3000 imr
->ifm_active
= IFM_IEEE80211
|IFM_AUTO
;
3001 if (sc
->an_config
.an_opmode
== AN_OPMODE_IBSS_ADHOC
)
3002 imr
->ifm_active
|= IFM_IEEE80211_ADHOC
;
3003 switch (status
.an_current_tx_rate
) {
3005 imr
->ifm_active
|= IFM_IEEE80211_DS1
;
3008 imr
->ifm_active
|= IFM_IEEE80211_DS2
;
3010 case AN_RATE_5_5MBPS
:
3011 imr
->ifm_active
|= IFM_IEEE80211_DS5
;
3013 case AN_RATE_11MBPS
:
3014 imr
->ifm_active
|= IFM_IEEE80211_DS11
;
3018 imr
->ifm_active
= sc
->an_ifmedia
.ifm_cur
->ifm_media
;
3021 imr
->ifm_status
= IFM_AVALID
;
3022 if (status
.an_opmode
& AN_STATUS_OPMODE_ASSOCIATED
)
3023 imr
->ifm_status
|= IFM_ACTIVE
;
3026 /********************** Cisco utility support routines *************/
3029 * ReadRids & WriteRids derived from Cisco driver additions to Ben Reed's
3034 readrids(struct ifnet
*ifp
, struct aironet_ioctl
*l_ioctl
)
3037 struct an_softc
*sc
;
3039 switch (l_ioctl
->command
) {
3041 rid
= AN_RID_CAPABILITIES
;
3044 rid
= AN_RID_GENCONFIG
;
3047 rid
= AN_RID_SSIDLIST
;
3050 rid
= AN_RID_APLIST
;
3053 rid
= AN_RID_DRVNAME
;
3056 rid
= AN_RID_ENCAPPROTO
;
3059 rid
= AN_RID_WEP_TEMP
;
3062 rid
= AN_RID_WEP_PERM
;
3065 rid
= AN_RID_STATUS
;
3068 rid
= AN_RID_32BITS_DELTA
;
3071 rid
= AN_RID_32BITS_CUM
;
3078 if (rid
== 999) /* Is bad command */
3082 sc
->areq
.an_len
= AN_MAX_DATALEN
;
3083 sc
->areq
.an_type
= rid
;
3085 an_read_record(sc
, (struct an_ltv_gen
*)&sc
->areq
);
3087 l_ioctl
->len
= sc
->areq
.an_len
- 4; /* just data */
3089 /* the data contains the length at first */
3090 if (copyout(&(sc
->areq
.an_len
), l_ioctl
->data
,
3091 sizeof(sc
->areq
.an_len
))) {
3094 /* Just copy the data back */
3095 if (copyout(&(sc
->areq
.an_val
), l_ioctl
->data
+ 2,
3103 writerids(struct ifnet
*ifp
, struct aironet_ioctl
*l_ioctl
)
3105 struct an_softc
*sc
;
3110 command
= l_ioctl
->command
;
3114 rid
= AN_RID_SSIDLIST
;
3117 rid
= AN_RID_CAPABILITIES
;
3120 rid
= AN_RID_APLIST
;
3123 rid
= AN_RID_GENCONFIG
;
3126 an_cmd(sc
, AN_CMD_ENABLE
, 0);
3130 an_cmd(sc
, AN_CMD_DISABLE
, 0);
3135 * This command merely clears the counts does not actually
3136 * store any data only reads rid. But as it changes the cards
3137 * state, I put it in the writerid routines.
3140 rid
= AN_RID_32BITS_DELTACLR
;
3142 sc
->areq
.an_len
= AN_MAX_DATALEN
;
3143 sc
->areq
.an_type
= rid
;
3145 an_read_record(sc
, (struct an_ltv_gen
*)&sc
->areq
);
3146 l_ioctl
->len
= sc
->areq
.an_len
- 4; /* just data */
3148 /* the data contains the length at first */
3149 if (copyout(&(sc
->areq
.an_len
), l_ioctl
->data
,
3150 sizeof(sc
->areq
.an_len
))) {
3153 /* Just copy the data */
3154 if (copyout(&(sc
->areq
.an_val
), l_ioctl
->data
+ 2,
3161 rid
= AN_RID_WEP_TEMP
;
3164 rid
= AN_RID_WEP_PERM
;
3167 rid
= AN_RID_LEAPUSERNAME
;
3170 rid
= AN_RID_LEAPPASSWORD
;
3177 if (l_ioctl
->len
> sizeof(sc
->areq
.an_val
) + 4)
3179 sc
->areq
.an_len
= l_ioctl
->len
+ 4; /* add type & length */
3180 sc
->areq
.an_type
= rid
;
3182 /* Just copy the data back */
3183 copyin((l_ioctl
->data
) + 2, &sc
->areq
.an_val
,
3186 an_cmd(sc
, AN_CMD_DISABLE
, 0);
3187 an_write_record(sc
, (struct an_ltv_gen
*)&sc
->areq
);
3188 an_cmd(sc
, AN_CMD_ENABLE
, 0);
3195 * General Flash utilities derived from Cisco driver additions to Ben Reed's
3199 #define FLASH_DELAY(x) tsleep(ifp, 0, "flash", ((x) / hz) + 1);
3200 #define FLASH_COMMAND 0x7e7e
3201 #define FLASH_SIZE 32 * 1024
3204 unstickbusy(struct ifnet
*ifp
)
3206 struct an_softc
*sc
= ifp
->if_softc
;
3208 if (CSR_READ_2(sc
, AN_COMMAND(sc
->mpi350
)) & AN_CMD_BUSY
) {
3209 CSR_WRITE_2(sc
, AN_EVENT_ACK(sc
->mpi350
),
3210 AN_EV_CLR_STUCK_BUSY
);
3217 * Wait for busy completion from card wait for delay uSec's Return true for
3218 * success meaning command reg is clear
3222 WaitBusy(struct ifnet
*ifp
, int uSec
)
3224 int statword
= 0xffff;
3226 struct an_softc
*sc
= ifp
->if_softc
;
3228 while ((statword
& AN_CMD_BUSY
) && delay
<= (1000 * 100)) {
3231 statword
= CSR_READ_2(sc
, AN_COMMAND(sc
->mpi350
));
3233 if ((AN_CMD_BUSY
& statword
) && (delay
% 200)) {
3238 return 0 == (AN_CMD_BUSY
& statword
);
3242 * STEP 1) Disable MAC and do soft reset on card.
3246 cmdreset(struct ifnet
*ifp
)
3249 struct an_softc
*sc
= ifp
->if_softc
;
3253 an_cmd(sc
, AN_CMD_DISABLE
, 0);
3255 if (!(status
= WaitBusy(ifp
, AN_TIMEOUT
))) {
3256 if_printf(ifp
, "Waitbusy hang b4 RESET =%d\n", status
);
3259 CSR_WRITE_2(sc
, AN_COMMAND(sc
->mpi350
), AN_CMD_FW_RESTART
);
3261 FLASH_DELAY(1000); /* WAS 600 12/7/00 */
3264 if (!(status
= WaitBusy(ifp
, 100))) {
3265 if_printf(ifp
, "Waitbusy hang AFTER RESET =%d\n", status
);
3272 * STEP 2) Put the card in legendary flash mode
3276 setflashmode(struct ifnet
*ifp
)
3279 struct an_softc
*sc
= ifp
->if_softc
;
3281 CSR_WRITE_2(sc
, AN_SW0(sc
->mpi350
), FLASH_COMMAND
);
3282 CSR_WRITE_2(sc
, AN_SW1(sc
->mpi350
), FLASH_COMMAND
);
3283 CSR_WRITE_2(sc
, AN_SW0(sc
->mpi350
), FLASH_COMMAND
);
3284 CSR_WRITE_2(sc
, AN_COMMAND(sc
->mpi350
), FLASH_COMMAND
);
3287 * mdelay(500); // 500ms delay
3292 if (!(status
= WaitBusy(ifp
, AN_TIMEOUT
))) {
3293 printf("Waitbusy hang after setflash mode\n");
3300 * Get a character from the card matching matchbyte Step 3)
3304 flashgchar(struct ifnet
*ifp
, int matchbyte
, int dwelltime
)
3307 unsigned char rbyte
= 0;
3309 struct an_softc
*sc
= ifp
->if_softc
;
3313 rchar
= CSR_READ_2(sc
, AN_SW1(sc
->mpi350
));
3315 if (dwelltime
&& !(0x8000 & rchar
)) {
3320 rbyte
= 0xff & rchar
;
3322 if ((rbyte
== matchbyte
) && (0x8000 & rchar
)) {
3323 CSR_WRITE_2(sc
, AN_SW1(sc
->mpi350
), 0);
3327 if (rbyte
== 0x81 || rbyte
== 0x82 || rbyte
== 0x83 || rbyte
== 0x1a || 0xffff == rchar
)
3329 CSR_WRITE_2(sc
, AN_SW1(sc
->mpi350
), 0);
3331 } while (dwelltime
> 0);
3336 * Put character to SWS0 wait for dwelltime x 50us for echo .
3340 flashpchar(struct ifnet
*ifp
, int byte
, int dwelltime
)
3343 int pollbusy
, waittime
;
3344 struct an_softc
*sc
= ifp
->if_softc
;
3351 waittime
= dwelltime
;
3354 * Wait for busy bit d15 to go false indicating buffer empty
3357 pollbusy
= CSR_READ_2(sc
, AN_SW0(sc
->mpi350
));
3359 if (pollbusy
& 0x8000) {
3366 while (waittime
>= 0);
3368 /* timeout for busy clear wait */
3370 if (waittime
<= 0) {
3371 if_printf(ifp
, "flash putchar busywait timeout!\n");
3375 * Port is clear now write byte and wait for it to echo back
3378 CSR_WRITE_2(sc
, AN_SW0(sc
->mpi350
), byte
);
3381 echo
= CSR_READ_2(sc
, AN_SW1(sc
->mpi350
));
3382 } while (dwelltime
>= 0 && echo
!= byte
);
3385 CSR_WRITE_2(sc
, AN_SW1(sc
->mpi350
), 0);
3387 return echo
== byte
;
3391 * Transfer 32k of firmware data from user buffer to our buffer and send to
3396 flashputbuf(struct ifnet
*ifp
)
3398 unsigned short *bufp
;
3400 struct an_softc
*sc
= ifp
->if_softc
;
3404 bufp
= sc
->an_flash_buffer
;
3407 CSR_WRITE_2(sc
, AN_AUX_PAGE
, 0x100);
3408 CSR_WRITE_2(sc
, AN_AUX_OFFSET
, 0);
3410 for (nwords
= 0; nwords
!= FLASH_SIZE
/ 2; nwords
++) {
3411 CSR_WRITE_2(sc
, AN_AUX_DATA
, bufp
[nwords
] & 0xffff);
3414 for (nwords
= 0; nwords
!= FLASH_SIZE
/ 4; nwords
++) {
3415 CSR_MEM_AUX_WRITE_4(sc
, 0x8000,
3416 ((u_int32_t
*)bufp
)[nwords
] & 0xffff);
3420 CSR_WRITE_2(sc
, AN_SW0(sc
->mpi350
), 0x8000);
3426 * After flashing restart the card.
3430 flashrestart(struct ifnet
*ifp
)
3433 struct an_softc
*sc
= ifp
->if_softc
;
3435 FLASH_DELAY(1024); /* Added 12/7/00 */
3439 FLASH_DELAY(1024); /* Added 12/7/00 */
3444 * Entry point for flash ioclt.
3448 flashcard(struct ifnet
*ifp
, struct aironet_ioctl
*l_ioctl
)
3451 struct an_softc
*sc
;
3455 if_printf(ifp
, "flashing not supported on MPI 350 yet\n");
3458 status
= l_ioctl
->command
;
3460 switch (l_ioctl
->command
) {
3462 return cmdreset(ifp
);
3465 if (sc
->an_flash_buffer
) {
3466 kfree(sc
->an_flash_buffer
, M_DEVBUF
);
3467 sc
->an_flash_buffer
= NULL
;
3469 sc
->an_flash_buffer
= kmalloc(FLASH_SIZE
, M_DEVBUF
, 0);
3470 if (sc
->an_flash_buffer
)
3471 return setflashmode(ifp
);
3475 case AIROFLSHGCHR
: /* Get char from aux */
3476 copyin(l_ioctl
->data
, &sc
->areq
, l_ioctl
->len
);
3477 z
= *(int *)&sc
->areq
;
3478 if ((status
= flashgchar(ifp
, z
, 8000)) == 1)
3483 case AIROFLSHPCHR
: /* Send char to card. */
3484 copyin(l_ioctl
->data
, &sc
->areq
, l_ioctl
->len
);
3485 z
= *(int *)&sc
->areq
;
3486 if ((status
= flashpchar(ifp
, z
, 8000)) == -1)
3491 case AIROFLPUTBUF
: /* Send 32k to card */
3492 if (l_ioctl
->len
> FLASH_SIZE
) {
3493 if_printf(ifp
, "Buffer to big, %x %x\n",
3494 l_ioctl
->len
, FLASH_SIZE
);
3497 copyin(l_ioctl
->data
, sc
->an_flash_buffer
, l_ioctl
->len
);
3499 if ((status
= flashputbuf(ifp
)) != 0)
3505 if ((status
= flashrestart(ifp
)) != 0) {
3506 if_printf(ifp
, "FLASHRESTART returned %d\n", status
);