Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-1-5]: src/sys/dev/ic Pull up revisions 1.1-1.3 (plus patch, new, ...



details:   https://anonhg.NetBSD.org/src/rev/ec030cb7928e
branches:  netbsd-1-5
changeset: 490286:ec030cb7928e
user:      he <he%NetBSD.org@localhost>
date:      Tue Dec 12 21:25:42 2000 +0000

description:
Pull up revisions 1.1-1.3 (plus patch, new, requested by he):
  Add a driver for an(4), Aironet and Cisco wireless pcmcia cards.

diffstat:

 sys/dev/ic/an.c |  1608 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 1608 insertions(+), 0 deletions(-)

diffs (truncated from 1612 to 300 lines):

diff -r 8c508d0b673c -r ec030cb7928e sys/dev/ic/an.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/ic/an.c   Tue Dec 12 21:25:42 2000 +0000
@@ -0,0 +1,1608 @@
+/*     $NetBSD: an.c,v 1.5.2.2 2000/12/12 21:25:42 he Exp $    */
+/*
+ * Copyright (c) 1997, 1998, 1999
+ *     Bill Paul <wpaul%ctr.columbia.edu@localhost>.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD: src/sys/dev/an/if_an.c,v 1.12 2000/11/13 23:04:12 wpaul Exp $
+ */
+
+/*
+ * Aironet 4500/4800 802.11 PCMCIA/ISA/PCI driver for FreeBSD.
+ *
+ * Written by Bill Paul <wpaul%ctr.columbia.edu@localhost>
+ * Electrical Engineering Department
+ * Columbia University, New York City
+ */
+
+/*
+ * The Aironet 4500/4800 series cards some in PCMCIA, ISA and PCI form.
+ * This driver supports all three device types (PCI devices are supported
+ * through an extra PCI shim: /sys/pci/if_an_p.c). ISA devices can be
+ * supported either using hard-coded IO port/IRQ settings or via Plug
+ * and Play. The 4500 series devices support 1Mbps and 2Mbps data rates.
+ * The 4800 devices support 1, 2, 5.5 and 11Mbps rates.
+ *
+ * Like the WaveLAN/IEEE cards, the Aironet NICs are all essentially
+ * PCMCIA devices. The ISA and PCI cards are a combination of a PCMCIA
+ * device and a PCMCIA to ISA or PCMCIA to PCI adapter card. There are
+ * a couple of important differences though:
+ *
+ * - Lucent doesn't currently offer a PCI card, however Aironet does
+ * - Lucent ISA card looks to the host like a PCMCIA controller with
+ *   a PCMCIA WaveLAN card inserted. This means that even desktop
+ *   machines need to be configured with PCMCIA support in order to
+ *   use WaveLAN/IEEE ISA cards. The Aironet cards on the other hand
+ *   actually look like normal ISA and PCI devices to the host, so
+ *   no PCMCIA controller support is needed
+ *
+ * The latter point results in a small gotcha. The Aironet PCMCIA
+ * cards can be configured for one of two operating modes depending
+ * on how the Vpp1 and Vpp2 programming voltages are set when the
+ * card is activated. In order to put the card in proper PCMCIA
+ * operation (where the CIS table is visible and the interface is
+ * programmed for PCMCIA operation), both Vpp1 and Vpp2 have to be
+ * set to 5 volts. FreeBSD by default doesn't set the Vpp voltages,
+ * which leaves the card in ISA/PCI mode, which prevents it from
+ * being activated as an PCMCIA device. Consequently, /sys/pccard/pccard.c
+ * has to be patched slightly in order to enable the Vpp voltages in
+ * order to make the Aironet PCMCIA cards work.
+ *
+ * Note that some PCMCIA controller software packages for Windows NT
+ * fail to set the voltages as well.
+ * 
+ * The Aironet devices can operate in both station mode and access point
+ * mode. Typically, when programmed for station mode, the card can be set
+ * to automatically perform encapsulation/decapsulation of Ethernet II
+ * and 802.3 frames within 802.11 frames so that the host doesn't have
+ * to do it itself. This driver doesn't program the card that way: the
+ * driver handles all of the encapsulation/decapsulation itself.
+ */
+
+/*
+ * Ported to NetBSD from FreeBSD by Atsushi Onoe at the San Diego
+ * IETF meeting.
+ */
+
+#include "opt_inet.h"
+#include "bpfilter.h"
+
+#ifdef INET
+#define ANCACHE                        /* enable signal strength cache */
+#endif
+
+#include <sys/param.h>
+#include <sys/callout.h>
+#include <sys/systm.h>
+#include <sys/sockio.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/ucred.h>
+#include <sys/socket.h>
+#include <sys/device.h>
+#ifdef ANCACHE
+#include <sys/syslog.h>
+#include <sys/sysctl.h>
+#endif
+
+#include <machine/bus.h>
+
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_dl.h>
+#include <net/if_ether.h>
+#include <net/if_ieee80211.h>
+#include <net/if_types.h>
+#include <net/if_media.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/if_inarp.h>
+#endif
+
+#include <net/if_sppp.h>       /* for SIOCGIFGENERIC */
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+
+#include <dev/ic/anvar.h>
+#include <dev/ic/anreg.h>
+
+#if !defined(lint)
+static const char rcsid[] =
+  "$FreeBSD: src/sys/dev/an/if_an.c,v 1.12 2000/11/13 23:04:12 wpaul Exp $";
+#endif
+
+/* These are global because we need them in sys/pci/if_an_p.c. */
+static void an_reset           __P((struct an_softc *));
+static int an_ioctl            __P((struct ifnet *, u_long, caddr_t));
+static int an_init             __P((struct ifnet *));
+static void an_stop            __P((struct ifnet *, int));
+static int an_init_tx_ring     __P((struct an_softc *));
+static void an_start           __P((struct ifnet *));
+static void an_watchdog                __P((struct ifnet *));
+static void an_rxeof           __P((struct an_softc *));
+static void an_txeof           __P((struct an_softc *, int));
+
+static void an_promisc         __P((struct an_softc *, int));
+static int an_cmd              __P((struct an_softc *, int, int));
+static int an_read_record      __P((struct an_softc *, struct an_ltv_gen *));
+static int an_write_record     __P((struct an_softc *, struct an_ltv_gen *));
+static int an_read_data                __P((struct an_softc *, int,
+                                       int, caddr_t, int));
+static int an_write_data       __P((struct an_softc *, int,
+                                       int, caddr_t, int));
+static int an_seek             __P((struct an_softc *, int, int, int));
+static int an_alloc_nicmem     __P((struct an_softc *, int, int *));
+static void an_stats_update    __P((void *));
+static void an_setdef          __P((struct an_softc *, struct an_req *));
+#ifdef ANCACHE
+static void an_cache_store     __P((struct an_softc *, struct ether_header *,
+                                       struct mbuf *, unsigned short));
+#endif
+#ifdef IFM_IEEE80211
+static int an_media_change __P((struct ifnet *ifp));
+static void an_media_status __P((struct ifnet *ifp, struct ifmediareq *imr));
+#endif
+
+/* 
+ * We probe for an Aironet 4500/4800 card by attempting to
+ * read the default SSID list. On reset, the first entry in
+ * the SSID list will contain the name "tsunami." If we don't
+ * find this, then there's no card present.
+ */
+int an_probe(sc)
+       struct an_softc *sc;
+{
+       struct an_ltv_ssidlist  ssid;
+
+       bzero((char *)&ssid, sizeof(ssid));
+
+       ssid.an_len = sizeof(ssid);
+       ssid.an_type = AN_RID_SSIDLIST;
+
+        /* Make sure interrupts are disabled. */
+        CSR_WRITE_2(sc, AN_INT_EN, 0);
+        CSR_WRITE_2(sc, AN_EVENT_ACK, 0xFFFF);
+
+       an_reset(sc);
+
+       if (an_cmd(sc, AN_CMD_READCFG, 0))
+               return(0);
+
+       if (an_read_record(sc, (struct an_ltv_gen *)&ssid))
+               return(0);
+
+       /* See if the ssid matches what we expect ... but doesn't have to */
+       if (strcmp(ssid.an_ssid1, AN_DEF_SSID))
+               return(0);
+       
+       return(AN_IOSIZ);
+}
+
+int an_attach(sc)
+       struct an_softc *sc;
+{
+       struct ifnet            *ifp = &sc->arpcom.ec_if;
+#ifdef IFM_IEEE80211
+       struct ifmediareq imr;
+#endif
+
+       sc->an_associated = 0;
+
+       /* Reset the NIC. */
+       an_reset(sc);
+
+       /* Load factory config */
+       if (an_cmd(sc, AN_CMD_READCFG, 0)) {
+               printf("%s: failed to load config data\n", sc->an_dev.dv_xname);
+               return(EIO);
+       }
+
+       /* Read the current configuration */
+       sc->an_config.an_type = AN_RID_GENCONFIG;
+       sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
+       if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_config)) {
+               printf("%s: read record failed\n", sc->an_dev.dv_xname);
+               return(EIO);
+       }
+
+       /* Read the card capabilities */
+       sc->an_caps.an_type = AN_RID_CAPABILITIES;
+       sc->an_caps.an_len = sizeof(struct an_ltv_caps);
+       if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_caps)) {
+               printf("%s: read record failed\n", sc->an_dev.dv_xname);
+               return(EIO);
+       }
+
+       /* Read ssid list */
+       sc->an_ssidlist.an_type = AN_RID_SSIDLIST;
+       sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist);
+       if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) {
+               printf("%s: read record failed\n", sc->an_dev.dv_xname);
+               return(EIO);
+       }
+
+       /* Read AP list */
+       sc->an_aplist.an_type = AN_RID_APLIST;
+       sc->an_aplist.an_len = sizeof(struct an_ltv_aplist);
+       if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) {
+               printf("%s: read record failed\n", sc->an_dev.dv_xname);
+               return(EIO);
+       }
+
+       printf("%s: 802.11 address: %s\n", sc->an_dev.dv_xname,
+           ether_sprintf(sc->an_caps.an_oemaddr));
+
+       ifp->if_softc = sc;
+       ifp->if_flags =
+           IFF_BROADCAST | IFF_NOTRAILERS | IFF_SIMPLEX | IFF_MULTICAST;
+       ifp->if_ioctl = an_ioctl;
+       ifp->if_start = an_start;
+       ifp->if_watchdog = an_watchdog;
+
+       memcpy(ifp->if_xname, sc->an_dev.dv_xname, IFNAMSIZ);
+
+       bzero(sc->an_config.an_nodename, sizeof(sc->an_config.an_nodename));
+       bcopy(AN_DEFAULT_NODENAME, sc->an_config.an_nodename,
+           sizeof(AN_DEFAULT_NODENAME) - 1);
+
+       bzero(sc->an_ssidlist.an_ssid1, sizeof(sc->an_ssidlist.an_ssid1));
+       bcopy(AN_DEFAULT_NETNAME, sc->an_ssidlist.an_ssid1,
+           sizeof(AN_DEFAULT_NETNAME) - 1);
+       sc->an_ssidlist.an_ssid1_len = strlen(AN_DEFAULT_NETNAME);
+
+       sc->an_config.an_opmode = AN_OPMODE_INFRASTRUCTURE_STATION;
+
+       sc->an_tx_rate = 0;
+       bzero((char *)&sc->an_stats, sizeof(sc->an_stats));
+
+       /*
+        * Call MI attach routine.
+        */
+       if_attach(ifp);
+       ether_ifattach(ifp, sc->an_caps.an_oemaddr);
+#if NBPFILTER > 0
+       bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));



Home | Main Index | Thread Index | Old Index