summaryrefslogtreecommitdiff
path: root/sys/dev/pcmcia
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2000-08-17 16:16:32 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2000-08-17 16:16:32 +0000
commit9372b87e9b3753b4321c4fd1e64a830b6f7d6cfa (patch)
tree56a20bc794fdf2d7200ab90ebee5a81a03ad80fd /sys/dev/pcmcia
parenta5bdafd3e77273d8bbb56ae6eabd33da49eac255 (diff)
replace if_awi w/ semi-current netbsd driver; still has problems
Diffstat (limited to 'sys/dev/pcmcia')
-rw-r--r--sys/dev/pcmcia/files.pcmcia11
-rw-r--r--sys/dev/pcmcia/if_awi_pcmcia.c361
2 files changed, 192 insertions, 180 deletions
diff --git a/sys/dev/pcmcia/files.pcmcia b/sys/dev/pcmcia/files.pcmcia
index 1c07957361b..cea7d0a1b67 100644
--- a/sys/dev/pcmcia/files.pcmcia
+++ b/sys/dev/pcmcia/files.pcmcia
@@ -1,4 +1,4 @@
-# $OpenBSD: files.pcmcia,v 1.32 2000/06/19 08:58:54 fgsch Exp $
+# $OpenBSD: files.pcmcia,v 1.33 2000/08/17 16:16:31 mickey Exp $
# $NetBSD: files.pcmcia,v 1.9 1998/06/21 18:45:41 christos Exp $
#
# Config.new file and device description for machine-independent PCMCIA code.
@@ -77,10 +77,11 @@ file dev/pcmcia/if_wi.c wi
# AMD 79c930-based 802.11 cards (including BayStack 650 FH card).
device awi: ether, ifnet
attach awi at pcmcia with awi_pcmcia
-
-file dev/pcmcia/if_awi_pcmcia.c awi_pcmcia
-file dev/ic/awi.c awi
-file dev/ic/am79c930.c awi
+file dev/pcmcia/if_awi_pcmcia.c awi_pcmcia
+file dev/ic/awi.c awi
+file dev/ic/awi_wep.c awi
+#file dev/ic/awi_wicfg.c awi
+file dev/ic/am79c930.c awi
# Raytheon(Raylink)/WebGear IEEE 802.11 FH WLAN
device ray: ether, ifnet, ifmedia
diff --git a/sys/dev/pcmcia/if_awi_pcmcia.c b/sys/dev/pcmcia/if_awi_pcmcia.c
index 0119dced22e..7c9fb4b388d 100644
--- a/sys/dev/pcmcia/if_awi_pcmcia.c
+++ b/sys/dev/pcmcia/if_awi_pcmcia.c
@@ -1,5 +1,5 @@
-/* $NetBSD: if_awi_pcmcia.c,v 1.5 1999/11/06 16:43:54 sommerfeld Exp $ */
-/* $OpenBSD: if_awi_pcmcia.c,v 1.3 2000/04/24 19:43:35 niklas Exp $ */
+/* $NetBSD: if_awi_pcmcia.c,v 1.13 2000/03/22 11:22:20 onoe Exp $ */
+/* $OpenBSD: if_awi_pcmcia.c,v 1.4 2000/08/17 16:16:31 mickey Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -61,23 +61,13 @@
#include <net/if_dl.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>
-#endif
-
#include <netinet/if_ether.h>
-#ifdef NS
-#include <netns/ns.h>
-#include <netns/ns_if.h>
-#endif
+#include <net/if_ieee80211.h>
#if NBPFILTER > 0
#include <net/bpf.h>
-#include <net/bpfdesc.h>
#endif
#include <machine/cpu.h>
@@ -93,53 +83,102 @@
#include <dev/pcmcia/pcmciavar.h>
#include <dev/pcmcia/pcmciadevs.h>
-int awi_pcmcia_match __P((struct device *, void *, void *));
-void awi_pcmcia_attach __P((struct device *, struct device *, void *));
-int awi_pcmcia_detach __P((struct device *, int));
-
-int awi_pcmcia_get_enaddr __P((struct pcmcia_tuple *, void *));
-int awi_pcmcia_enable __P((struct awi_softc *));
-void awi_pcmcia_disable __P((struct awi_softc *));
-
struct awi_pcmcia_softc {
- struct awi_softc sc_awi; /* real "awi" softc */
+ struct awi_softc sc_awi; /* real "awi" softc */
/* PCMCIA-specific goo */
struct pcmcia_io_handle sc_pcioh; /* PCMCIA i/o space info */
+ struct pcmcia_mem_handle sc_memh; /* PCMCIA memory space info */
int sc_io_window; /* our i/o window */
+ int sc_mem_window; /* our memory window */
struct pcmcia_function *sc_pf; /* our PCMCIA function */
+ void *sc_powerhook; /* power hook descriptor */
};
-int awi_pcmcia_find __P((struct awi_pcmcia_softc *,
- struct pcmcia_attach_args *, struct pcmcia_config_entry *));
+static int awi_pcmcia_match __P((struct device *, void *, void *));
+static void awi_pcmcia_attach __P((struct device *, struct device *, void *));
+static int awi_pcmcia_detach __P((struct device *, int));
+static int awi_pcmcia_enable __P((struct awi_softc *));
+static void awi_pcmcia_disable __P((struct awi_softc *));
+static void awi_pcmcia_powerhook __P((int, void *));
-/* Autoconfig definition of driver back-end */
-struct cfdriver awi_cd = {
- NULL, "awi", DV_IFNET
-};
+static int awi_pcmcia_find __P((struct awi_pcmcia_softc *,
+ struct pcmcia_attach_args *, struct pcmcia_config_entry *));
struct cfattach awi_pcmcia_ca = {
sizeof(struct awi_pcmcia_softc), awi_pcmcia_match, awi_pcmcia_attach,
- awi_pcmcia_detach, /* awi_activate */ 0
+ awi_pcmcia_detach, awi_activate
};
-/*
- * XXX following is common to most PCMCIA NIC's and belongs
- * in common code
- */
+static struct awi_pcmcia_product {
+ u_int32_t app_vendor; /* vendor ID */
+ u_int32_t app_product; /* product ID */
+ const char *app_cisinfo[4]; /* CIS information */
+ const char *app_name; /* product name */
+} awi_pcmcia_products[] = {
+ { PCMCIA_VENDOR_BAY, PCMCIA_PRODUCT_BAY_STACK_650,
+ PCMCIA_CIS_BAY_STACK_650, "BayStack 650" },
+
+ { PCMCIA_VENDOR_BAY, PCMCIA_PRODUCT_BAY_STACK_660,
+ PCMCIA_CIS_BAY_STACK_660, "BayStack 660" },
-struct awi_pcmcia_get_enaddr_args {
- int got_enaddr;
- u_int8_t enaddr[ETHER_ADDR_LEN];
+ { PCMCIA_VENDOR_BAY, PCMCIA_PRODUCT_BAY_SURFER_PRO,
+ PCMCIA_CIS_BAY_SURFER_PRO, "AirSurfer Pro" },
+
+ { PCMCIA_VENDOR_AMD, PCMCIA_PRODUCT_AMD_AM79C930,
+ PCMCIA_CIS_AMD_AM79C930, "AMD AM79C930" },
+
+ { PCMCIA_VENDOR_ICOM, PCMCIA_PRODUCT_ICOM_SL200,
+ PCMCIA_CIS_ICOM_SL200, "Icom SL-200" },
+
+ { PCMCIA_VENDOR_NOKIA, PCMCIA_PRODUCT_NOKIA_C020_WLAN,
+ PCMCIA_CIS_NOKIA_C020_WLAN, "Nokia C020" },
+
+ { PCMCIA_VENDOR_FARALLON, PCMCIA_PRODUCT_FARALLON_SKYLINE,
+ PCMCIA_CIS_FARALLON_SKYLINE, "SkyLINE Wireless" },
+
+/* { PCMCIA_VENDOR_BREEZECOM, PCMCIA_PRODUCT_BREEZECOM_BREEZENET,
+ PCMCIA_CIS_BREEZECOM_BREEZENET, "BreezeNet SC-PX" },
+*/
+ { 0, 0,
+ { NULL, NULL, NULL, NULL }, NULL },
};
-int awi_pcmcia_get_enaddr __P((struct pcmcia_tuple *, void *));
+static struct awi_pcmcia_product *
+ awi_pcmcia_lookup __P((struct pcmcia_attach_args *));
+
+static struct awi_pcmcia_product *
+awi_pcmcia_lookup(pa)
+ struct pcmcia_attach_args *pa;
+{
+ struct awi_pcmcia_product *app;
+
+ for (app = awi_pcmcia_products; app->app_name != NULL; app++) {
+ /* match by vendor/product id */
+ if (pa->manufacturer != PCMCIA_VENDOR_INVALID &&
+ pa->manufacturer == app->app_vendor &&
+ pa->product != PCMCIA_PRODUCT_INVALID &&
+ pa->product == app->app_product)
+ return (app);
+
+ /* match by CIS information */
+ if (pa->card->cis1_info[0] != NULL &&
+ app->app_cisinfo[0] != NULL &&
+ strcmp(pa->card->cis1_info[0], app->app_cisinfo[0]) == 0 &&
+ pa->card->cis1_info[1] != NULL &&
+ app->app_cisinfo[1] != NULL &&
+ strcmp(pa->card->cis1_info[1], app->app_cisinfo[1]) == 0)
+ return (app);
+ }
+
+ return (NULL);
+}
-int
+static int
awi_pcmcia_enable(sc)
struct awi_softc *sc;
{
- struct awi_pcmcia_softc *psc = (struct awi_pcmcia_softc *) sc;
+ struct awi_pcmcia_softc *psc = (struct awi_pcmcia_softc *)sc;
struct pcmcia_function *pf = psc->sc_pf;
/* establish the interrupt. */
@@ -149,21 +188,28 @@ awi_pcmcia_enable(sc)
sc->sc_dev.dv_xname);
return (1);
}
- return (pcmcia_function_enable(pf));
+
+ if (pcmcia_function_enable(pf)) {
+ pcmcia_intr_disestablish(pf, sc->sc_ih);
+ return (1);
+ }
+ DELAY(1000);
+
+ return (0);
}
-void
+static void
awi_pcmcia_disable(sc)
struct awi_softc *sc;
{
- struct awi_pcmcia_softc *psc = (struct awi_pcmcia_softc *) sc;
+ struct awi_pcmcia_softc *psc = (struct awi_pcmcia_softc *)sc;
struct pcmcia_function *pf = psc->sc_pf;
pcmcia_intr_disestablish (pf, sc->sc_ih);
pcmcia_function_disable (pf);
}
-int
+static int
awi_pcmcia_match(parent, match, aux)
struct device *parent;
void *match;
@@ -171,17 +217,14 @@ awi_pcmcia_match(parent, match, aux)
{
struct pcmcia_attach_args *pa = aux;
- if (pa->manufacturer != PCMCIA_VENDOR_BAY)
- return (0);
-
- if (pa->product == PCMCIA_PRODUCT_BAY_STACK_650)
+ if (awi_pcmcia_lookup(pa) != NULL)
return (1);
return (0);
}
-int
-awi_pcmcia_find (psc, pa, cfe)
+static int
+awi_pcmcia_find(psc, pa, cfe)
struct awi_pcmcia_softc *psc;
struct pcmcia_attach_args *pa;
struct pcmcia_config_entry *cfe;
@@ -189,95 +232,69 @@ awi_pcmcia_find (psc, pa, cfe)
struct awi_softc *sc = &psc->sc_awi;
int fail = 0;
u_int8_t version[AWI_BANNER_LEN];
-
+
/*
* see if we can read the firmware version sanely
* through the i/o ports.
* if not, try a different CIS string..
*/
if (pcmcia_io_alloc(psc->sc_pf, cfe->iospace[0].start,
- cfe->iospace[0].length, 0, &psc->sc_pcioh) != 0)
+ cfe->iospace[0].length, AM79C930_IO_ALIGN,
+ &psc->sc_pcioh) != 0)
goto fail;
-
+
if (pcmcia_io_map(psc->sc_pf, PCMCIA_WIDTH_AUTO, 0, psc->sc_pcioh.size,
&psc->sc_pcioh, &psc->sc_io_window))
goto fail_io_free;
/* Enable the card. */
pcmcia_function_init(psc->sc_pf, cfe);
- if (pcmcia_function_enable(psc->sc_pf))
+ if (pcmcia_function_enable(psc->sc_pf))
goto fail_io_unmap;
-
+
+ sc->sc_chip.sc_bustype = AM79C930_BUS_PCMCIA;
sc->sc_chip.sc_iot = psc->sc_pcioh.iot;
sc->sc_chip.sc_ioh = psc->sc_pcioh.ioh;
am79c930_chip_init(&sc->sc_chip, 0);
DELAY(1000);
- awi_read_bytes (sc, AWI_BANNER, version, AWI_BANNER_LEN);
+ awi_read_bytes(sc, AWI_BANNER, version, AWI_BANNER_LEN);
if (memcmp(version, "PCnetMobile:", 12) == 0)
- return 0;
-
+ return (0);
+
fail++;
- pcmcia_function_disable (psc->sc_pf);
-
+ pcmcia_function_disable(psc->sc_pf);
+
fail_io_unmap:
fail++;
- pcmcia_io_unmap (psc->sc_pf, psc->sc_io_window);
-
+ pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
+
fail_io_free:
fail++;
- pcmcia_io_free (psc->sc_pf, &psc->sc_pcioh);
+ pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
fail:
fail++;
- return fail;
+ psc->sc_io_window = -1;
+ return (fail);
}
-
-
-void
+static void
awi_pcmcia_attach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
- struct awi_pcmcia_softc *psc = (void *) self;
+ struct awi_pcmcia_softc *psc = (void *)self;
struct awi_softc *sc = &psc->sc_awi;
+ struct awi_pcmcia_product *app;
struct pcmcia_attach_args *pa = aux;
struct pcmcia_config_entry *cfe;
- struct awi_pcmcia_get_enaddr_args pgea;
-#if 0
- struct pcmcia_mem_handle memh;
bus_addr_t memoff;
- int memwin;
-#endif
-#if 0
- int i, j;
-
- for (cfe = pa->pf->cfe_head.sqh_first, i=0;
- cfe != NULL;
- cfe = cfe->cfe_list.sqe_next, i++) {
- printf("%d: %d memspaces, %d iospaces\n",
- i, cfe->num_memspace, cfe->num_iospace);
- printf("%d: number %d flags %x iftype %d iomask %lx irqmask %x maxtwins %x\n",
- i, cfe->number, cfe->flags, cfe->iftype, cfe->iomask,
- cfe->irqmask, cfe->maxtwins);
- for (j=0; j<cfe->num_memspace; j++) {
- printf("%d: mem %d: len %lx card %lx host %lx\n",
- i, j,
- cfe->memspace[j].length,
- cfe->memspace[j].cardaddr,
- cfe->memspace[j].hostaddr);
- }
- for (j=0; j<cfe->num_iospace; j++) {
- printf("%d: io %d: len %lx start %lx\n",
- i, j,
- cfe->iospace[j].length,
- cfe->iospace[j].start);
- }
- }
-#endif
+ app = awi_pcmcia_lookup(pa);
+ if (app == NULL)
+ panic("awi_pcmcia_attach: impossible");
psc->sc_pf = pa->pf;
@@ -295,122 +312,116 @@ awi_pcmcia_attach(parent, self, aux)
}
if (cfe == NULL) {
printf(": no suitable CIS info found\n");
- return;
+ goto no_config_entry;
}
sc->sc_enabled = 1;
- sc->sc_state = AWI_ST_SELFTEST;
- printf(": BayStack 650 Wireless (802.11)\n");
+ printf(": %s\n", app->app_name);
-#if 0
- if (pcmcia_mem_alloc(psc->sc_pf, AM79C930_MEM_SIZE, &memh) != 0) {
+ psc->sc_mem_window = -1;
+ if (pcmcia_mem_alloc(psc->sc_pf, AM79C930_MEM_SIZE,
+ &psc->sc_memh) != 0) {
printf("%s: unable to allocate memory space; using i/o only\n",
sc->sc_dev.dv_xname);
- } else if (pcmcia_mem_map(psc->sc_pf, PCMCIA_MEM_COMMON,
- AM79C930_MEM_BASE, AM79C930_MEM_SIZE,
- &memh, &memoff, &memwin)) {
+ } else if (pcmcia_mem_map(psc->sc_pf,
+ PCMCIA_MEM_COMMON, AM79C930_MEM_BASE,
+ AM79C930_MEM_SIZE, &psc->sc_memh, &memoff, &psc->sc_mem_window)) {
printf("%s: unable to map memory space; using i/o only\n",
sc->sc_dev.dv_xname);
- pcmcia_mem_free(psc->sc_pf, &memh);
+ pcmcia_mem_free(psc->sc_pf, &psc->sc_memh);
} else {
- sc->sc_chip.sc_memt = memh.memt;
- sc->sc_chip.sc_memh = memh.memh;
+ sc->sc_chip.sc_memt = psc->sc_memh.memt;
+ sc->sc_chip.sc_memh = psc->sc_memh.memh;
am79c930_chip_init(&sc->sc_chip, 1);
}
-#endif
- sc->sc_chip.sc_bustype = AM79C930_BUS_PCMCIA;
-
sc->sc_enable = awi_pcmcia_enable;
sc->sc_disable = awi_pcmcia_disable;
- /* Read station address. */
- pgea.got_enaddr = 0;
- if (pcmcia_scan_cis(parent, awi_pcmcia_get_enaddr, &pgea) == -1) {
- printf("%s: Couldn't read CIS to get ethernet address\n",
- sc->sc_dev.dv_xname);
- return;
- } else if (!pgea.got_enaddr) {
- printf("%s: Couldn't get ethernet address from CIS\n",
+ /* establish the interrupt. */
+ sc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET, awi_intr, sc);
+ if (sc->sc_ih == NULL) {
+ printf("%s: couldn't establish interrupt\n",
sc->sc_dev.dv_xname);
- return;
- } else
-#ifdef DIAGNOSTIC
- printf("%s: Ethernet address from CIS: %s\n",
- sc->sc_dev.dv_xname, ether_sprintf(pgea.enaddr))
-#endif
- ;
+ goto no_interrupt;
+ }
+ sc->sc_ifp = &sc->sc_ec.ac_if;
+ sc->sc_cansleep = 1;
- awi_attach(sc, pgea.enaddr);
+ if (awi_attach(sc) != 0) {
+ printf("%s: failed to attach controller\n",
+ sc->sc_dev.dv_xname);
+ goto attach_failed;
+ }
+ psc->sc_powerhook = powerhook_establish(awi_pcmcia_powerhook, psc);
-#ifndef NETBSD_ORIGINAL
- awi_init(sc);
- awi_stop(sc);
-#endif
+ sc->sc_enabled = 0;
+ /* disable device and disestablish the interrupt */
+ awi_pcmcia_disable(sc);
+ return;
+
+ attach_failed:
+ pcmcia_intr_disestablish(psc->sc_pf, sc->sc_ih);
+
+ no_interrupt:
+ /* Unmap our memory window and space */
+ if (psc->sc_mem_window != -1) {
+ pcmcia_mem_unmap(psc->sc_pf, psc->sc_mem_window);
+ pcmcia_mem_free(psc->sc_pf, &psc->sc_memh);
+ }
-#ifdef notyet /* NETBSD_ORIGINAL */
- sc->sc_state = AWI_ST_OFF;
+ /* Unmap our i/o window and space */
+ pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
+ pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
- sc->sc_enabled = 0;
- /*
- * XXX This should be done once the framework has enable/disable hooks.
- */
+ /* Disable the function */
pcmcia_function_disable(psc->sc_pf);
-#endif /* notyet */
+
+ no_config_entry:
+ psc->sc_io_window = -1;
}
-int
+static int
awi_pcmcia_detach(self, flags)
struct device *self;
int flags;
{
struct awi_pcmcia_softc *psc = (struct awi_pcmcia_softc *)self;
+ int error;
+
+ if (psc->sc_io_window == -1)
+ /* Nothing to detach. */
+ return (0);
+
+ if (psc->sc_powerhook != NULL)
+ powerhook_disestablish(psc->sc_powerhook);
+
+ error = awi_detach(&psc->sc_awi);
+ if (error != 0)
+ return (error);
+
+ /* Unmap our memory window and free memory space */
+ if (psc->sc_mem_window != -1) {
+ pcmcia_mem_unmap(psc->sc_pf, psc->sc_mem_window);
+ pcmcia_mem_free(psc->sc_pf, &psc->sc_memh);
+ }
/* Unmap our i/o window. */
pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
/* Free our i/o space. */
pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
-
-#ifdef notyet
- /*
- * Our softc is about to go away, so drop our reference
- * to the ifnet.
- */
- if_delref(psc->sc_awi.sc_ethercom.ec_if);
return (0);
-#else
- return (EBUSY);
-#endif
}
-/*
- * XXX copied verbatim from if_mbe_pcmcia.c.
- * this function should be in common pcmcia code..
- */
-
-int
-awi_pcmcia_get_enaddr(tuple, arg)
- struct pcmcia_tuple *tuple;
+static void
+awi_pcmcia_powerhook(why, arg)
+ int why;
void *arg;
{
- struct awi_pcmcia_get_enaddr_args *p = arg;
- int i;
-
- if (tuple->code == PCMCIA_CISTPL_FUNCE) {
- if (tuple->length < 2) /* sub code and ether addr length */
- return (0);
-
- if ((pcmcia_tuple_read_1(tuple, 0) !=
- PCMCIA_TPLFE_TYPE_LAN_NID) ||
- (pcmcia_tuple_read_1(tuple, 1) != ETHER_ADDR_LEN))
- return (0);
+ struct awi_pcmcia_softc *psc = arg;
+ struct awi_softc *sc = &psc->sc_awi;
- for (i = 0; i < ETHER_ADDR_LEN; i++)
- p->enaddr[i] = pcmcia_tuple_read_1(tuple, i + 2);
- p->got_enaddr = 1;
- return (1);
- }
- return (0);
+ awi_power(sc, why);
}