diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2000-08-17 16:16:32 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2000-08-17 16:16:32 +0000 |
commit | 9372b87e9b3753b4321c4fd1e64a830b6f7d6cfa (patch) | |
tree | 56a20bc794fdf2d7200ab90ebee5a81a03ad80fd /sys/dev/pcmcia | |
parent | a5bdafd3e77273d8bbb56ae6eabd33da49eac255 (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.pcmcia | 11 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_awi_pcmcia.c | 361 |
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); } |