summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorichiro <ichiro@NetBSD.org>2001-10-13 15:00:23 +0000
committerichiro <ichiro@NetBSD.org>2001-10-13 15:00:23 +0000
commitcbcfff63ec7b3663616433f2db8810e84d741055 (patch)
tree715f9e1a6178faa93d341191bc6284355ae879f5 /sys/dev
parent9202040b703bb7277d88328ff97f8f1046a9859d (diff)
Add Intersil Prism2.5 Mini-PCI wavelan.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/wi.c20
-rw-r--r--sys/dev/ic/wireg.h59
-rw-r--r--sys/dev/ic/wivar.h4
-rw-r--r--sys/dev/pci/files.pci5
-rw-r--r--sys/dev/pci/if_wi_pci.c260
-rw-r--r--sys/dev/pcmcia/if_wi_pcmcia.c3
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;