Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pcmcia Blitz port of the FreeBSD wi* driver for the ...



details:   https://anonhg.NetBSD.org/src/rev/bc69241e72c3
branches:  trunk
changeset: 474662:bc69241e72c3
user:      sommerfeld <sommerfeld%NetBSD.org@localhost>
date:      Wed Jul 14 22:24:07 1999 +0000

description:
Blitz port of the FreeBSD wi* driver for the Lucent WaveLan IEEE
PCMCIA wireless LAN.
Original driver written by Bill Paul <wpaul%ctr.columbia.edu@localhost>

diffstat:

 sys/dev/pcmcia/files.pcmcia      |     8 +-
 sys/dev/pcmcia/if_wi.c           |  1345 ++++++++++++++++++++++++++++++++++++++
 sys/dev/pcmcia/if_wi_ieee.h      |   296 ++++++++
 sys/dev/pcmcia/if_wireg.h        |   554 +++++++++++++++
 sys/dev/pcmcia/if_wivar.h        |   101 ++
 sys/dev/pcmcia/pcmciadevs.h      |    15 +-
 sys/dev/pcmcia/pcmciadevs_data.h |    25 +-
 7 files changed, 2339 insertions(+), 5 deletions(-)

diffs (truncated from 2437 to 300 lines):

diff -r b7232a153348 -r bc69241e72c3 sys/dev/pcmcia/files.pcmcia
--- a/sys/dev/pcmcia/files.pcmcia       Wed Jul 14 22:13:27 1999 +0000
+++ b/sys/dev/pcmcia/files.pcmcia       Wed Jul 14 22:24:07 1999 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.pcmcia,v 1.14 1999/01/01 19:30:03 christos Exp $
+#      $NetBSD: files.pcmcia,v 1.15 1999/07/14 22:24:12 sommerfeld Exp $
 #
 # Config.new file and device description for machine-independent PCMCIA code.
 # Included by ports that need it.
@@ -63,3 +63,9 @@
 device cnw: arp, ether, ifnet
 attach cnw at pcmcia
 file   dev/pcmcia/if_cnw.c                     cnw
+
+# Lucent WaveLan IEEE (802.11)
+device wi: arp, ether, ifnet
+attach wi at pcmcia
+file   dev/pcmcia/if_wi.c                      wi
+
diff -r b7232a153348 -r bc69241e72c3 sys/dev/pcmcia/if_wi.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/pcmcia/if_wi.c    Wed Jul 14 22:24:07 1999 +0000
@@ -0,0 +1,1345 @@
+/*     $NetBSD: if_wi.c,v 1.1 1999/07/14 22:24:08 sommerfeld 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.
+ *
+ *     $Id: if_wi.c,v 1.1 1999/07/14 22:24:08 sommerfeld Exp $
+ */
+
+/*
+ * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for NetBSD.
+ *
+ * Original FreeBSD driver written by Bill Paul <wpaul%ctr.columbia.edu@localhost>
+ * Electrical Engineering Department
+ * Columbia University, New York City
+ */
+
+/*
+ * The WaveLAN/IEEE adapter is the second generation of the WaveLAN
+ * from Lucent. Unlike the older cards, the new ones are programmed
+ * entirely via a firmware-driven controller called the Hermes.
+ * Unfortunately, Lucent will not release the Hermes programming manual
+ * without an NDA (if at all). What they do release is an API library
+ * called the HCF (Hardware Control Functions) which is supposed to
+ * do the device-specific operations of a device driver for you. The
+ * publically available version of the HCF library (the 'HCF Light') is 
+ * a) extremely gross, b) lacks certain features, particularly support
+ * for 802.11 frames, and c) is contaminated by the GNU Public License.
+ *
+ * This driver does not use the HCF or HCF Light at all. Instead, it
+ * programs the Hermes controller directly, using information gleaned
+ * from the HCF Light code and corresponding documentation.
+ *
+ * This driver supports both the PCMCIA and ISA versions of the
+ * WaveLAN/IEEE cards. Note however that the ISA card isn't really
+ * anything of the sort: it's actually a PCMCIA bridge adapter
+ * that fits into an ISA slot, into which a PCMCIA WaveLAN card is
+ * inserted. Consequently, you need to use the pccard support for
+ * both the ISA and PCMCIA adapters.
+ */
+
+/*
+ * FreeBSD driver ported to NetBSD by Bill Sommerfeld in the back of the
+ * Oslo IETF plenary meeting.
+ */
+
+#define WI_HERMES_AUTOINC_WAR  /* Work around data write autoinc bug. */
+#define WI_HERMES_STATS_WAR    /* Work around stats counter bug. */
+
+#include "opt_inet.h"
+#include "bpfilter.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/socket.h>
+#include <sys/mbuf.h>
+#include <sys/ioctl.h>
+#include <sys/kernel.h>                /* for hz */
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_ether.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
+
+#if NBPF > 0
+#include <net/bpf.h>
+#include <net/bpfdesc.h>
+#endif
+
+#include <dev/pcmcia/if_wireg.h>
+
+#include <dev/pcmcia/pcmciareg.h>
+#include <dev/pcmcia/pcmciavar.h>
+#include <dev/pcmcia/pcmciadevs.h>
+
+#include <dev/pcmcia/if_wivar.h>
+
+#include <dev/pcmcia/if_wi_ieee.h>
+
+#if !defined(lint)
+static const char rcsid[] =
+       "$Id: if_wi.c,v 1.1 1999/07/14 22:24:08 sommerfeld Exp $";
+#endif
+
+#ifdef foo
+static u_int8_t        wi_mcast_addr[6] = { 0x01, 0x60, 0x1D, 0x00, 0x01, 0x00 };
+#endif
+
+static int wi_match            __P((struct device *, struct cfdata *, void *));
+static void wi_attach          __P((struct device *, struct device *, void *));
+
+
+static int wi_intr __P((void *arg));
+
+static void wi_reset           __P((struct wi_softc *));
+static int wi_ioctl            __P((struct ifnet *, u_long, caddr_t));
+static void wi_init            __P((void *));
+static void wi_start           __P((struct ifnet *));
+static void wi_stop            __P((struct wi_softc *));
+static void wi_watchdog                __P((struct ifnet *));
+static void wi_rxeof           __P((struct wi_softc *));
+static void wi_txeof           __P((struct wi_softc *, int));
+static void wi_update_stats    __P((struct wi_softc *));
+static void wi_setmulti                __P((struct wi_softc *));
+
+static int wi_cmd              __P((struct wi_softc *, int, int));
+static int wi_read_record      __P((struct wi_softc *, struct wi_ltv_gen *));
+static int wi_write_record     __P((struct wi_softc *, struct wi_ltv_gen *));
+static int wi_read_data                __P((struct wi_softc *, int,
+                                       int, caddr_t, int));
+static int wi_write_data       __P((struct wi_softc *, int,
+                                       int, caddr_t, int));
+static int wi_seek             __P((struct wi_softc *, int, int, int));
+static int wi_alloc_nicmem     __P((struct wi_softc *, int, int *));
+static void wi_inquire         __P((void *));
+static void wi_setdef          __P((struct wi_softc *, struct wi_req *));
+static int wi_mgmt_xmit                __P((struct wi_softc *, caddr_t, int));
+
+static int wi_enable __P((struct wi_softc *));
+static int wi_disable __P((struct wi_softc *));
+
+
+struct cfattach wi_ca =
+{
+       sizeof(struct wi_softc), wi_match, wi_attach
+};
+
+static int
+wi_match(parent, match, aux)
+       struct device *parent;
+       struct cfdata *match;
+       void *aux;
+{
+       struct pcmcia_attach_args *pa = aux;
+
+       return (pa->manufacturer == PCMCIA_VENDOR_LUCENT &&
+           pa->product == PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE);
+}
+
+int
+wi_enable(sc)
+       struct wi_softc *sc;
+{
+       struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+
+       sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_NET, wi_intr, sc);
+       if (sc->sc_ih == NULL) {
+               printf("%s: couldn't establish interrupt handler\n",
+                   sc->sc_dev.dv_xname);
+               return (EIO);
+       }
+       if (pcmcia_function_enable(sc->sc_pf) != 0) {
+               printf("%s: couldn't enable card\n", sc->sc_dev.dv_xname);
+               return (EIO);
+       }
+
+       wi_init(sc);
+       ifp->if_flags |= IFF_RUNNING;
+       return 0;
+}
+
+int
+wi_disable(sc)
+       struct wi_softc *sc;
+{
+       struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+
+       if (ifp->if_flags & IFF_RUNNING) {
+               wi_stop(sc);
+               pcmcia_function_disable(sc->sc_pf);
+               pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
+       }
+       ifp->if_flags &= ~IFF_RUNNING;
+       ifp->if_timer = 0;
+
+       /* XXX */;
+       return 0;
+}
+
+
+/*
+ * Attach the card.
+ */
+void
+wi_attach(parent, self, aux)
+       struct device  *parent, *self;
+       void           *aux;
+{
+       struct wi_softc *sc = (void *) self;
+       struct pcmcia_attach_args *pa = aux;
+       struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+       struct wi_ltv_macaddr   mac;
+       struct wi_ltv_gen       gen;
+
+       ifp = &sc->sc_ethercom.ec_if;
+
+       /* Enable the card */
+       sc->sc_pf = pa->pf;
+       pcmcia_function_init(sc->sc_pf, sc->sc_pf->cfe_head.sqh_first);
+       if (pcmcia_function_enable(sc->sc_pf)) {
+               printf(": function enable failed\n");
+               return;
+       }
+
+       /* allocate/map ISA I/O space */
+
+       if (pcmcia_io_alloc(sc->sc_pf, 0, WI_IOSIZ, WI_IOSIZ,
+           &sc->sc_pcioh) != 0) {
+               printf(": can't allocate i/o space\n");
+               return;
+       }
+       if (pcmcia_io_map(sc->sc_pf, PCMCIA_WIDTH_IO16, 0,
+           WI_IOSIZ, &sc->sc_pcioh, &sc->sc_iowin) != 0) {
+               printf(": can't map i/o space\n");
+               return;
+       }
+       sc->wi_btag = sc->sc_pcioh.iot;
+       sc->wi_bhandle = sc->sc_pcioh.ioh;
+
+       /* Make sure interrupts are disabled. */
+       CSR_WRITE_2(sc, WI_INT_EN, 0);
+       CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
+
+       /* Reset the NIC. */
+       wi_reset(sc);
+
+       memset(&mac, 0, sizeof(mac));
+       /* Read the station address. */
+       mac.wi_type = WI_RID_MAC_NODE;
+       mac.wi_len = 4;
+       wi_read_record(sc, (struct wi_ltv_gen *)&mac);
+       memcpy(sc->sc_macaddr, mac.wi_mac_addr, ETHER_ADDR_LEN);
+
+       printf("\n%s: address %s\n", sc->sc_dev.dv_xname,
+           ether_sprintf(sc->sc_macaddr));
+
+       memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
+       ifp->if_softc = sc;
+       ifp->if_start = wi_start;
+       ifp->if_ioctl = wi_ioctl;
+       ifp->if_watchdog = wi_watchdog;



Home | Main Index | Thread Index | Old Index