diff options
| author | ichiro <ichiro@NetBSD.org> | 2001-10-13 15:00:23 +0000 |
|---|---|---|
| committer | ichiro <ichiro@NetBSD.org> | 2001-10-13 15:00:23 +0000 |
| commit | cbcfff63ec7b3663616433f2db8810e84d741055 (patch) | |
| tree | 715f9e1a6178faa93d341191bc6284355ae879f5 /sys/dev | |
| parent | 9202040b703bb7277d88328ff97f8f1046a9859d (diff) | |
Add Intersil Prism2.5 Mini-PCI wavelan.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/ic/wi.c | 20 | ||||
| -rw-r--r-- | sys/dev/ic/wireg.h | 59 | ||||
| -rw-r--r-- | sys/dev/ic/wivar.h | 4 | ||||
| -rw-r--r-- | sys/dev/pci/files.pci | 5 | ||||
| -rw-r--r-- | sys/dev/pci/if_wi_pci.c | 260 | ||||
| -rw-r--r-- | sys/dev/pcmcia/if_wi_pcmcia.c | 3 |
6 files changed, 333 insertions, 18 deletions
diff --git a/sys/dev/ic/wi.c b/sys/dev/ic/wi.c index 9e3c13bacf4..aab90fa0049 100644 --- a/sys/dev/ic/wi.c +++ b/sys/dev/ic/wi.c @@ -1,4 +1,4 @@ -/* $NetBSD: wi.c,v 1.25 2001/09/22 17:22:25 explorer Exp $ */ +/* $NetBSD: wi.c,v 1.26 2001/10/13 15:00:23 ichiro Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -707,6 +707,20 @@ wi_reset(sc) return; } +void +wi_pci_reset(sc) + struct wi_softc *sc; +{ + + bus_space_write_2(sc->sc_iot, sc->sc_ioh, WI_PCI_COR, 0x80); + DELAY(100*1000); /* 100 m sec */ + + bus_space_write_2(sc->sc_iot, sc->sc_ioh, WI_PCI_COR, 0x0); + DELAY(100*1000); /* 100 m sec */ + + return; +} + /* * Read an LTV record from the NIC. */ @@ -1891,6 +1905,10 @@ wi_get_id(sc) printf("RF:PRISM2.5 MAC:ISL3873"); sc->sc_prism2 = 1; break; + case WI_NIC_3874A: + printf("RF:PRISM2.5 MAC:ISL3874A(PCI)"); + sc->sc_prism2 = 1; + break; default: printf("Lucent chip or unknown chip\n"); sc->sc_prism2 = 0; diff --git a/sys/dev/ic/wireg.h b/sys/dev/ic/wireg.h index 2ff423be58e..f1a1eb214e5 100644 --- a/sys/dev/ic/wireg.h +++ b/sys/dev/ic/wireg.h @@ -1,4 +1,4 @@ -/* $NetBSD: wireg.h,v 1.10 2001/09/22 17:22:25 explorer Exp $ */ +/* $NetBSD: wireg.h,v 1.11 2001/10/13 15:00:23 ichiro Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -96,18 +96,24 @@ * register space access macros */ #define CSR_WRITE_4(sc, reg, val) \ - bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg, val) + bus_space_write_4(sc->sc_iot, sc->sc_ioh, \ + (sc->sc_pci? reg * 2: reg) , val) #define CSR_WRITE_2(sc, reg, val) \ - bus_space_write_2(sc->sc_iot, sc->sc_ioh, reg, val) + bus_space_write_2(sc->sc_iot, sc->sc_ioh, \ + (sc->sc_pci? reg * 2: reg), val) #define CSR_WRITE_1(sc, reg, val) \ - bus_space_write_1(sc->sc_iot, sc->sc_ioh, reg, val) + bus_space_write_1(sc->sc_iot, sc->sc_ioh, \ + (sc->sc_pci? reg * 2: reg), val) #define CSR_READ_4(sc, reg) \ - bus_space_read_4(sc->sc_iot, sc->sc_ioh, reg) + bus_space_read_4(sc->sc_iot, sc->sc_ioh, \ + (sc->sc_pci? reg * 2: reg)) #define CSR_READ_2(sc, reg) \ - bus_space_read_2(sc->sc_iot, sc->sc_ioh, reg) + bus_space_read_2(sc->sc_iot, sc->sc_ioh, \ + (sc->sc_pci? reg * 2: reg)) #define CSR_READ_1(sc, reg) \ - bus_space_read_1(sc->sc_iot, sc->sc_ioh, reg) + bus_space_read_1(sc->sc_iot, sc->sc_ioh, \ + (sc->sc_pci? reg * 2: reg)) #ifndef __BUS_SPACE_HAS_STREAM_METHODS #define bus_space_write_stream_2 bus_space_write_2 @@ -117,13 +123,17 @@ #endif #define CSR_WRITE_STREAM_2(sc, reg, val) \ - bus_space_write_stream_2(sc->sc_iot, sc->sc_ioh, reg, val) + bus_space_write_stream_2(sc->sc_iot, sc->sc_ioh, \ + (sc->sc_pci? reg * 2: reg), val) #define CSR_WRITE_MULTI_STREAM_2(sc, reg, val, count) \ - bus_space_write_multi_stream_2(sc->sc_iot, sc->sc_ioh, reg, val, count) + bus_space_write_multi_stream_2(sc->sc_iot, sc->sc_ioh, \ + (sc->sc_pci? reg * 2: reg), val, count) #define CSR_READ_STREAM_2(sc, reg) \ - bus_space_read_stream_2(sc->sc_iot, sc->sc_ioh, reg) + bus_space_read_stream_2(sc->sc_iot, sc->sc_ioh, \ + (sc->sc_pci? reg * 2: reg)) #define CSR_READ_MULTI_STREAM_2(sc, reg, buf, count) \ - bus_space_read_multi_stream_2(sc->sc_iot, sc->sc_ioh, reg, buf, count) + bus_space_read_multi_stream_2(sc->sc_iot, sc->sc_ioh, \ + (sc->sc_pci? reg * 2: reg), buf, count) /* * The WaveLAN/IEEE cards contain an 802.11 MAC controller which Lucent @@ -165,12 +175,13 @@ */ /* - * Size of Hermes I/O space. + * Size of Hermes & Prism2 I/O space. */ #define WI_IOSIZE 0x40 +#define WI_PCI_CBMA 0x10 /* Configuration Base Memory Address */ /* - * Hermes register definitions and what little I know about them. + * Hermes & Prism2 register definitions */ /* Hermes command/status registers. */ @@ -285,7 +296,7 @@ #define WI_SW0 0x28 #define WI_SW1 0x2A #define WI_SW2 0x2C -#define WI_SW3 0x2E +#define WI_SW3 0x2E /* does not appear in Prism2 */ #define WI_CNTL 0x14 @@ -300,6 +311,25 @@ #define WI_AUX_DATA 0x3E /* + * PCI Host Interface Registers (HFA3842 Specific) + * The value of all Register's Offset, such as WI_INFO_FID and WI_PARAM0, + * has doubled. + */ +#define WI_PCI_COR 0x4C +#define WI_PCI_HCR 0x5C +#define WI_PCI_MASTER0_ADDRH 0x80 +#define WI_PCI_MASTER0_ADDRL 0x84 +#define WI_PCI_MASTER0_LEN 0x88 +#define WI_PCI_MASTER0_CON 0x8C + +#define WI_PCI_STATUS 0x98 + +#define WI_PCI_MASTER1_ADDRH 0xA0 +#define WI_PCI_MASTER1_ADDRL 0xA4 +#define WI_PCI_MASTER1_LEN 0xA8 +#define WI_PCI_MASTER1_CON 0xAC + +/* * One form of communication with the Hermes is with what Lucent calls * LTV records, where LTV stands for Length, Type and Value. The length * and type are 16 bits and are in native byte order. The value is in @@ -381,6 +411,7 @@ struct wi_ltv_ver { #define WI_NIC_HWB1153 0x8007 #define WI_NIC_P2_SST 0x8008 /* Prism2 with SST flush */ #define WI_NIC_PRISM2_5 0x800C +#define WI_NIC_3874A 0x8013 /* Prism2.5 Mini-PCI */ }; /* diff --git a/sys/dev/ic/wivar.h b/sys/dev/ic/wivar.h index 5ee11613e62..c8e3f7c1e57 100644 --- a/sys/dev/ic/wivar.h +++ b/sys/dev/ic/wivar.h @@ -1,4 +1,4 @@ -/* $NetBSD: wivar.h,v 1.5 2001/09/22 17:22:25 explorer Exp $ */ +/* $NetBSD: wivar.h,v 1.6 2001/10/13 15:00:24 ichiro Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -50,6 +50,7 @@ struct wi_softc { int sc_enabled; int sc_prism2; int sc_prism2_ver; + int sc_pci; /* attach to PCI-Bus */ bus_space_tag_t sc_iot; /* bus cookie */ bus_space_handle_t sc_ioh; /* bus i/o handle */ @@ -96,3 +97,4 @@ int wi_activate __P((struct device *, enum devact)); int wi_intr __P((void *arg)); void wi_power __P((struct wi_softc *, int)); void wi_shutdown __P((struct wi_softc *)); +void wi_pci_reset __P((struct wi_softc *)); diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci index f5328c51c22..963dae47738 100644 --- a/sys/dev/pci/files.pci +++ b/sys/dev/pci/files.pci @@ -1,4 +1,4 @@ -# $NetBSD: files.pci,v 1.140 2001/09/16 00:11:42 eeh Exp $ +# $NetBSD: files.pci,v 1.141 2001/10/13 15:00:23 ichiro Exp $ # # Config file and device description for machine-independent PCI code. # Included by ports that need it. Requires that the SCSI files be @@ -448,6 +448,9 @@ file dev/pci/hifn7751.c hifn attach an at pci with an_pci file dev/pci/if_an_pci.c an_pci +# Intersil Prism2.5 Mini-PCI +attach wi at pci with wi_pci +file dev/pci/if_wi_pci.c wi_pci # ISDN devices attach isic at pci with isic_pci diff --git a/sys/dev/pci/if_wi_pci.c b/sys/dev/pci/if_wi_pci.c new file mode 100644 index 00000000000..bbe6e912426 --- /dev/null +++ b/sys/dev/pci/if_wi_pci.c @@ -0,0 +1,260 @@ +/* $NetBSD: if_wi_pci.c,v 1.1 2001/10/13 15:01:07 ichiro Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Hideaki Imaizumi <hiddy@sfc.wide.ad.jp> + * and Ichiro FUKUHARA (ichiro@ichiro.org). + * + * 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 the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 THE FOUNDATION OR CONTRIBUTORS + * 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. + */ + +/* + * PCI bus front-end for the Intersil PCI WaveLan. + * Works with Prism2.5 Mini-PCI wavelan. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/syslog.h> +#include <sys/socket.h> +#include <sys/device.h> +#include <sys/callout.h> + +#include <net/if.h> +#include <net/if_ether.h> +#include <net/if_media.h> +#include <net/if_ieee80211.h> + +#include <machine/bus.h> +#include <machine/intr.h> + +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pcidevs.h> + +#include <dev/ic/wi_ieee.h> +#include <dev/ic/wireg.h> +#include <dev/ic/wivar.h> + +struct wi_pci_softc { + struct wi_softc psc_wi; /* real "wi" softc */ + + /* PCI-specific goo */ + pci_intr_handle_t psc_ih; + struct pci_attach_args *psc_pa; + + void *sc_powerhook; /* power hook descriptor */ +}; + +static int wi_pci_match __P((struct device *, struct cfdata *, void *)); +static void wi_pci_attach __P((struct device *, struct device *, void *)); +static int wi_pci_enable __P((struct wi_softc *)); +static void wi_pci_disable __P((struct wi_softc *)); +static void wi_pci_powerhook __P((int, void *)); + +static const struct wi_pci_product + *wi_pci_lookup __P((struct pci_attach_args *)); + +struct cfattach wi_pci_ca = { + sizeof(struct wi_pci_softc), wi_pci_match, wi_pci_attach +}; + +const struct wi_pci_product { + pci_vendor_id_t wpp_vendor; /* vendor ID */ + pci_product_id_t wpp_product; /* product ID */ + const char *wpp_name; /* product name */ +} wi_pci_products[] = { + { PCI_VENDOR_INTERSIL, PCI_PRODUCT_INTERSIL_MINI_PCI_WLAN, + "Intersil Prism2.5" }, + { 0, 0, + NULL}, +}; + +static int +wi_pci_enable(sc) + struct wi_softc *sc; +{ + struct wi_pci_softc *psc = (struct wi_pci_softc *)sc; + + /* establish the interrupt. */ + sc->sc_ih = pci_intr_establish(psc->psc_pa->pa_pc, + psc->psc_ih, IPL_NET, wi_intr, sc); + if (sc->sc_ih == NULL) { + printf("%s: couldn't establish interrupt\n", + sc->sc_dev.dv_xname); + return (EIO); + } + sc->sc_pci = 1; + + /* reset HFA3842 MAC core */ + wi_pci_reset(sc); + + return (0); +} + +static void +wi_pci_disable(sc) + struct wi_softc *sc; +{ + struct wi_pci_softc *psc = (struct wi_pci_softc *)sc; + + pci_intr_disestablish(psc->psc_pa->pa_pc, sc->sc_ih); +} + +static const struct wi_pci_product * +wi_pci_lookup(pa) + struct pci_attach_args *pa; +{ + const struct wi_pci_product *wpp; + + for (wpp = wi_pci_products; wpp->wpp_name != NULL; wpp++) { + if (PCI_VENDOR(pa->pa_id) == wpp->wpp_vendor && + PCI_PRODUCT(pa->pa_id) == wpp->wpp_product) + return (wpp); + } + return (NULL); +} + +static int +wi_pci_match(parent, match, aux) + struct device *parent; + struct cfdata *match; + void *aux; +{ + struct pci_attach_args *pa = aux; + + if (wi_pci_lookup(pa) != NULL) + return (1); + return (0); +} + +static void +wi_pci_attach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + struct wi_pci_softc *psc = (struct wi_pci_softc *)self; + struct wi_softc *sc = &psc->psc_wi; + struct pci_attach_args *pa = aux; + pci_chipset_tag_t pc = pa->pa_pc; + const char *intrstr; + const struct wi_pci_product *wpp; + pci_intr_handle_t ih; + bus_space_tag_t memt; + bus_space_handle_t memh; + int memh_valid; + bus_addr_t busbase; + bus_size_t bussize; + + psc->psc_pa = pa; + + memh_valid = !pci_mapreg_map(pa, WI_PCI_CBMA, + PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, + &memt, &memh, &busbase, &bussize); + + if(memh_valid){ + sc->sc_iot = memt; + sc->sc_ioh = memh; + } + else { + printf(": unable to map device registers\n"); + return; + } + + wpp = wi_pci_lookup(pa); + if (wpp == NULL) { + printf("\n"); + panic("wi_pci_attach: impossible"); + } + + printf(": %s Wireless Lan\n", wpp->wpp_name); + + sc->sc_pci = 1; + sc->sc_enabled = 1; + sc->sc_enable = wi_pci_enable; + sc->sc_disable = wi_pci_disable; + + /* Enable the card. */ + pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, + pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) | + PCI_COMMAND_MASTER_ENABLE); + + + /* Map and establish the interrupt. */ + if (pci_intr_map(pa, &ih)) { + printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname); + return; + } + intrstr = pci_intr_string(pc, ih); + + psc->psc_ih = ih; + sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, wi_intr, sc); + if (sc->sc_ih == NULL) { + printf("%s: couldn't establish interrupt", + sc->sc_dev.dv_xname); + if (intrstr != NULL) + printf(" at %s", intrstr); + printf("\n"); + return; + } + + printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr); + + /* reset HFA3842 MAC core */ + wi_pci_reset(sc); + + sc->sc_ifp = &sc->sc_ethercom.ec_if; + if (wi_attach(sc) != 0) { + printf("%s: failed to attach controller\n", + sc->sc_dev.dv_xname); + pci_intr_disestablish(pa->pa_pc, sc->sc_ih); + return; + } + + /* Add a suspend hook to restore PCI config state */ + psc->sc_powerhook = powerhook_establish(wi_pci_powerhook, psc); + if (psc->sc_powerhook == NULL) + printf ("%s: WARNING: unable to establish pci power hook\n", + sc->sc_dev.dv_xname); +} + +static void +wi_pci_powerhook(why, arg) + int why; + void *arg; +{ + struct wi_pci_softc *psc = arg; + struct wi_softc *sc = &psc->psc_wi; + + wi_power(sc, why); +} diff --git a/sys/dev/pcmcia/if_wi_pcmcia.c b/sys/dev/pcmcia/if_wi_pcmcia.c index d4f98a4cb0e..fd5e9799bf4 100644 --- a/sys/dev/pcmcia/if_wi_pcmcia.c +++ b/sys/dev/pcmcia/if_wi_pcmcia.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_wi_pcmcia.c,v 1.7 2001/09/17 09:21:58 ichiro Exp $ */ +/* $NetBSD: if_wi_pcmcia.c,v 1.8 2001/10/13 15:00:24 ichiro Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -352,6 +352,7 @@ wi_pcmcia_attach(parent, self, aux) if (pp == NULL) panic("wi_pcmcia_attach: impossible"); + sc->sc_pci = 0; sc->sc_enabled = 1; sc->sc_enable = wi_pcmcia_enable; sc->sc_disable = wi_pcmcia_disable; |
