diff options
author | imp <imp@FreeBSD.org> | 2002-04-02 02:38:35 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2002-04-02 02:38:35 +0000 |
commit | 6503ac6382f452943f43a23d7f762a41446b9fde (patch) | |
tree | 5ecd72ef70990280cf10f0f5f174874ad7b4c4ef /sys/dev | |
parent | 6f01a2296f0fcd6e8dd625aa2b6ee0d2da57686a (diff) | |
download | FreeBSD-src-6503ac6382f452943f43a23d7f762a41446b9fde.zip FreeBSD-src-6503ac6382f452943f43a23d7f762a41446b9fde.tar.gz |
First cut at breaking out the bus attachment from the bus independent
part of the driver. Also, move the softc and some other stuff to
if_wivar.h from if_wireg.h to make future merging activities easier.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/wi/if_wavelan_ieee.h | 6 | ||||
-rw-r--r-- | sys/dev/wi/if_wi.c | 333 | ||||
-rw-r--r-- | sys/dev/wi/if_wi_pccard.c | 186 | ||||
-rw-r--r-- | sys/dev/wi/if_wi_pci.c | 235 | ||||
-rw-r--r-- | sys/dev/wi/if_wireg.h | 142 | ||||
-rw-r--r-- | sys/dev/wi/if_wivar.h | 183 |
6 files changed, 612 insertions, 473 deletions
diff --git a/sys/dev/wi/if_wavelan_ieee.h b/sys/dev/wi/if_wavelan_ieee.h index ac3bb25..c50f9f6 100644 --- a/sys/dev/wi/if_wavelan_ieee.h +++ b/sys/dev/wi/if_wavelan_ieee.h @@ -72,10 +72,8 @@ struct wi_req { */ #define WI_RID_IFACE_STATS 0x0100 #define WI_RID_MGMT_XMIT 0x0200 -#ifdef WICACHE #define WI_RID_ZERO_CACHE 0x0300 #define WI_RID_READ_CACHE 0x0400 -#endif struct wi_80211_hdr { u_int16_t frame_ctl; @@ -133,9 +131,6 @@ struct wi_mgmt_hdr { * * Each entry in the wi_sigcache has a unique macsrc. */ -#ifdef WICACHE -#define MAXWICACHE 10 - struct wi_sigcache { char macsrc[6]; /* unique MAC address for entry */ int ipsrc; /* ip address associated with packet */ @@ -143,7 +138,6 @@ struct wi_sigcache { int noise; /* noise value */ int quality; /* quality of the packet */ }; -#endif #ifndef _KERNEL struct wi_counters { diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c index 71a66ee..aa6a787 100644 --- a/sys/dev/wi/if_wi.c +++ b/sys/dev/wi/if_wi.c @@ -62,12 +62,6 @@ * both the ISA and PCMCIA adapters. */ -#define WI_HERMES_AUTOINC_WAR /* Work around data write autoinc bug. */ -#define WI_HERMES_STATS_WAR /* Work around stats counter bug. */ -#define WICACHE /* turn on signal strength cache code */ - -#include "pci.h" - #include <sys/param.h> #include <sys/systm.h> #include <sys/sockio.h> @@ -82,15 +76,8 @@ #include <machine/bus.h> #include <machine/resource.h> -#include <machine/md_var.h> -#include <machine/bus_pio.h> #include <sys/rman.h> -#if NPCI > 0 -#include <pci/pcireg.h> -#include <pci/pcivar.h> -#endif - #include <net/if.h> #include <net/if_arp.h> #include <net/ethernet.h> @@ -107,23 +94,15 @@ #include <net/bpf.h> -#include <dev/pccard/pccardvar.h> -#include <dev/pccard/pccarddevs.h> - #include <dev/wi/if_wavelan_ieee.h> +#include <dev/wi/if_wivar.h> #include <dev/wi/if_wireg.h> -#include "card_if.h" - #if !defined(lint) static const char rcsid[] = "$FreeBSD$"; #endif -#ifdef foo -static u_int8_t wi_mcast_addr[6] = { 0x01, 0x60, 0x1D, 0x00, 0x01, 0x00 }; -#endif - static void wi_intr(void *); static void wi_reset(struct wi_softc *); static int wi_ioctl(struct ifnet *, u_long, caddr_t); @@ -153,20 +132,6 @@ void wi_cache_store(struct wi_softc *, struct ether_header *, struct mbuf *, unsigned short); #endif -static int wi_generic_attach(device_t); -static int wi_pccard_match(device_t); -static int wi_pccard_probe(device_t); -static int wi_pccard_attach(device_t); -#if NPCI > 0 -static int wi_pci_probe(device_t); -static int wi_pci_attach(device_t); -#endif -static int wi_pccard_detach(device_t); -static void wi_shutdown(device_t); - -static int wi_alloc(device_t, int); -static void wi_free(device_t); - static int wi_get_cur_ssid(struct wi_softc *, char *, int *); static void wi_get_id(struct wi_softc *, device_t); static int wi_media_change(struct ifnet *); @@ -175,164 +140,10 @@ static void wi_media_status(struct ifnet *, struct ifmediareq *); static int wi_get_debug(struct wi_softc *, struct wi_req *); static int wi_set_debug(struct wi_softc *, struct wi_req *); -static device_method_t wi_pccard_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, pccard_compat_probe), - DEVMETHOD(device_attach, pccard_compat_attach), - DEVMETHOD(device_detach, wi_pccard_detach), - DEVMETHOD(device_shutdown, wi_shutdown), - - /* Card interface */ - DEVMETHOD(card_compat_match, wi_pccard_match), - DEVMETHOD(card_compat_probe, wi_pccard_probe), - DEVMETHOD(card_compat_attach, wi_pccard_attach), - - { 0, 0 } -}; - -#if NPCI > 0 -static device_method_t wi_pci_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, wi_pci_probe), - DEVMETHOD(device_attach, wi_pci_attach), - DEVMETHOD(device_detach, wi_pccard_detach), - DEVMETHOD(device_shutdown, wi_shutdown), - - { 0, 0 } -}; -#endif - -static driver_t wi_pccard_driver = { - "wi", - wi_pccard_methods, - sizeof(struct wi_softc) -}; - -#if NPCI > 0 -static driver_t wi_pci_driver = { - "wi", - wi_pci_methods, - sizeof(struct wi_softc) -}; - -static struct { - unsigned int vendor,device; - int bus_type; - char *desc; -} pci_ids[] = { - {0x1638, 0x1100, WI_BUS_PCI_PLX, "PRISM2STA PCI WaveLAN/IEEE 802.11"}, - {0x1385, 0x4100, WI_BUS_PCI_PLX, "Netgear MA301 PCI IEEE 802.11b"}, - {0x16ab, 0x1101, WI_BUS_PCI_PLX, "GLPRISM2 PCI WaveLAN/IEEE 802.11"}, - {0x16ab, 0x1102, WI_BUS_PCI_PLX, "Linksys WDT11 PCI IEEE 802.11b"}, - {0x1260, 0x3873, WI_BUS_PCI_NATIVE, "Linksys WMP11 PCI Prism2.5"}, - {0x10b7, 0x7770, WI_BUS_PCI_PLX, "3Com Airconnect IEEE 802.11b"}, - {0, 0, 0, NULL} -}; -#endif +devclass_t wi_devclass; -static devclass_t wi_devclass; - -DRIVER_MODULE(if_wi, pccard, wi_pccard_driver, wi_devclass, 0, 0); -#if NPCI > 0 -DRIVER_MODULE(if_wi, pci, wi_pci_driver, wi_devclass, 0, 0); -#endif - -static const struct pccard_product wi_pccard_products[] = { - PCMCIA_CARD(3COM, 3CRWE737A, 0), - PCMCIA_CARD(BUFFALO, WLI_PCM_S11, 0), - PCMCIA_CARD(BUFFALO, WLI_CF_S11G, 0), - PCMCIA_CARD(COMPAQ, NC5004, 0), - PCMCIA_CARD(CONTEC, FX_DS110_PCC, 0), - PCMCIA_CARD(COREGA, WIRELESS_LAN_PCC_11, 0), - PCMCIA_CARD(COREGA, WIRELESS_LAN_PCCA_11, 0), - PCMCIA_CARD(COREGA, WIRELESS_LAN_PCCB_11, 0), - PCMCIA_CARD(ELSA, XI300_IEEE, 0), - PCMCIA_CARD(ELSA, XI800_IEEE, 0), - PCMCIA_CARD(EMTAC, WLAN, 0), - PCMCIA_CARD(ERICSSON, WIRELESSLAN, 0), - PCMCIA_CARD(GEMTEK, WLAN, 0), - PCMCIA_CARD(HWN, AIRWAY80211, 0), - PCMCIA_CARD(INTEL, PRO_WLAN_2011, 0), - PCMCIA_CARD(INTERSIL, PRISM2, 0), - PCMCIA_CARD(IODATA2, WNB11PCM, 0), - /* Now that we do PRISM detection, I don't think we need these - imp */ - PCMCIA_CARD2(LUCENT, WAVELAN_IEEE, NANOSPEED_PRISM2, 0), - PCMCIA_CARD2(LUCENT, WAVELAN_IEEE, NEC_CMZ_RT_WP, 0), - PCMCIA_CARD2(LUCENT, WAVELAN_IEEE, NTT_ME_WLAN, 0), - PCMCIA_CARD2(LUCENT, WAVELAN_IEEE, SMC_2632W, 0), - /* Must be after other LUCENT ones because it is less specific */ - PCMCIA_CARD(LUCENT, WAVELAN_IEEE, 0), - PCMCIA_CARD(LINKSYS2, IWN, 0), - PCMCIA_CARD(SAMSUNG, SWL_2000N, 0), - PCMCIA_CARD(SIMPLETECH, SPECTRUM24_ALT, 0), - PCMCIA_CARD(SOCKET, LP_WLAN_CF, 0), - PCMCIA_CARD(SYMBOL, LA4100, 0), - PCMCIA_CARD(TDK, LAK_CD011WL, 0), - { NULL } -}; - -static int -wi_pccard_match(dev) - device_t dev; -{ - const struct pccard_product *pp; - - if ((pp = pccard_product_lookup(dev, wi_pccard_products, - sizeof(wi_pccard_products[0]), NULL)) != NULL) { - device_set_desc(dev, pp->pp_name); - return 0; - } - return ENXIO; -} - -static int -wi_pccard_probe(dev) - device_t dev; -{ - struct wi_softc *sc; - int error; - - sc = device_get_softc(dev); - sc->wi_gone = 0; - sc->wi_bus_type = WI_BUS_PCCARD; - - error = wi_alloc(dev, 0); - if (error) - return (error); - - wi_free(dev); - - /* Make sure interrupts are disabled. */ - CSR_WRITE_2(sc, WI_INT_EN, 0); - CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); - - return (0); -} - -#if NPCI > 0 -static int -wi_pci_probe(dev) - device_t dev; -{ - struct wi_softc *sc; - int i; - - sc = device_get_softc(dev); - for(i=0; pci_ids[i].vendor != 0; i++) { - if ((pci_get_vendor(dev) == pci_ids[i].vendor) && - (pci_get_device(dev) == pci_ids[i].device)) { - sc->wi_prism2 = 1; - sc->wi_bus_type = pci_ids[i].bus_type; - device_set_desc(dev, pci_ids[i].desc); - return (0); - } - } - return(ENXIO); -} -#endif - -static int -wi_pccard_detach(dev) +int +wi_generic_detach(dev) device_t dev; { struct wi_softc *sc; @@ -364,135 +175,7 @@ wi_pccard_detach(dev) return(0); } -static int -wi_pccard_attach(device_t dev) -{ - struct wi_softc *sc; - int error; - - sc = device_get_softc(dev); - - error = wi_alloc(dev, 0); - if (error) { - device_printf(dev, "wi_alloc() failed! (%d)\n", error); - return (error); - } - return (wi_generic_attach(dev)); -} - -#if NPCI > 0 -static int -wi_pci_attach(device_t dev) -{ - struct wi_softc *sc; - u_int32_t command, wanted; - u_int16_t reg; - int error; - int timeout; - - sc = device_get_softc(dev); - - command = pci_read_config(dev, PCIR_COMMAND, 4); - wanted = PCIM_CMD_PORTEN|PCIM_CMD_MEMEN; - command |= wanted; - pci_write_config(dev, PCIR_COMMAND, command, 4); - command = pci_read_config(dev, PCIR_COMMAND, 4); - if ((command & wanted) != wanted) { - device_printf(dev, "wi_pci_attach() failed to enable pci!\n"); - return (ENXIO); - } - - if (sc->wi_bus_type != WI_BUS_PCI_NATIVE) { - error = wi_alloc(dev, WI_PCI_IORES); - if (error) - return (error); - - /* Make sure interrupts are disabled. */ - CSR_WRITE_2(sc, WI_INT_EN, 0); - CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); - - /* We have to do a magic PLX poke to enable interrupts */ - sc->local_rid = WI_PCI_LOCALRES; - sc->local = bus_alloc_resource(dev, SYS_RES_IOPORT, - &sc->local_rid, 0, ~0, 1, RF_ACTIVE); - sc->wi_localtag = rman_get_bustag(sc->local); - sc->wi_localhandle = rman_get_bushandle(sc->local); - command = bus_space_read_4(sc->wi_localtag, sc->wi_localhandle, - WI_LOCAL_INTCSR); - command |= WI_LOCAL_INTEN; - bus_space_write_4(sc->wi_localtag, sc->wi_localhandle, - WI_LOCAL_INTCSR, command); - bus_release_resource(dev, SYS_RES_IOPORT, sc->local_rid, - sc->local); - sc->local = NULL; - - sc->mem_rid = WI_PCI_MEMRES; - sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->mem_rid, - 0, ~0, 1, RF_ACTIVE); - if (sc->mem == NULL) { - device_printf(dev, "couldn't allocate memory\n"); - wi_free(dev); - return (ENXIO); - } - sc->wi_bmemtag = rman_get_bustag(sc->mem); - sc->wi_bmemhandle = rman_get_bushandle(sc->mem); - - /* - * From Linux driver: - * Write COR to enable PC card - * This is a subset of the protocol that the pccard bus code - * would do. - */ - CSM_WRITE_1(sc, WI_COR_OFFSET, WI_COR_VALUE); - reg = CSM_READ_1(sc, WI_COR_OFFSET); - if (reg != WI_COR_VALUE) { - device_printf(dev, "CSM_READ_1(WI_COR_OFFSET) " - "wanted %d, got %d\n", WI_COR_VALUE, reg); - wi_free(dev); - return (ENXIO); - } - } else { - error = wi_alloc(dev, WI_PCI_LMEMRES); - if (error) - return (error); - - CSR_WRITE_2(sc, WI_HFA384X_PCICOR_OFF, 0x0080); - DELAY(250000); - - CSR_WRITE_2(sc, WI_HFA384X_PCICOR_OFF, 0x0000); - DELAY(500000); - - timeout=2000000; - while ((--timeout > 0) && - (CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY)) - DELAY(10); - - if (timeout == 0) { - device_printf(dev, "couldn't reset prism2.5 core.\n"); - wi_free(dev); - return(ENXIO); - } - } - - CSR_WRITE_2(sc, WI_HFA384X_SWSUPPORT0_OFF, WI_PRISM2STA_MAGIC); - reg = CSR_READ_2(sc, WI_HFA384X_SWSUPPORT0_OFF); - if (reg != WI_PRISM2STA_MAGIC) { - device_printf(dev, - "CSR_READ_2(WI_HFA384X_SWSUPPORT0_OFF) " - "wanted %d, got %d\n", WI_PRISM2STA_MAGIC, reg); - wi_free(dev); - return (ENXIO); - } - - error = wi_generic_attach(dev); - if (error != 0) - return (error); - - return (0); -} -#endif - -static int +int wi_generic_attach(device_t dev) { struct wi_softc *sc; @@ -2334,7 +2017,7 @@ wi_watchdog(ifp) return; } -static int +int wi_alloc(dev, rid) device_t dev; int rid; @@ -2386,7 +2069,7 @@ wi_alloc(dev, rid) return (0); } -static void +void wi_free(dev) device_t dev; { @@ -2408,7 +2091,7 @@ wi_free(dev) return; } -static void +void wi_shutdown(dev) device_t dev; { diff --git a/sys/dev/wi/if_wi_pccard.c b/sys/dev/wi/if_wi_pccard.c new file mode 100644 index 0000000..3ef8a2e --- /dev/null +++ b/sys/dev/wi/if_wi_pccard.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 1997, 1998, 1999 + * Bill Paul <wpaul@ctr.columbia.edu>. 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. + */ + +/* + * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for FreeBSD. + * + * Written by Bill Paul <wpaul@ctr.columbia.edu> + * Electrical Engineering Department + * Columbia University, New York City + */ + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/socket.h> +#include <sys/module.h> +#include <sys/bus.h> + +#include <machine/bus.h> +#include <machine/resource.h> +#include <sys/rman.h> + +#include <net/if.h> +#include <net/if_arp.h> +#include <net/ethernet.h> +#include <net/if_dl.h> +#include <net/if_media.h> +#include <net/if_types.h> +#include <net/if_ieee80211.h> + +#include <dev/pccard/pccardvar.h> +#include <dev/pccard/pccarddevs.h> + +#include <dev/wi/if_wavelan_ieee.h> +#include <dev/wi/if_wivar.h> +#include <dev/wi/if_wireg.h> + +#include "card_if.h" + +#if !defined(lint) +static const char rcsid[] = + "$FreeBSD$"; +#endif + +static int wi_pccard_match(device_t); +static int wi_pccard_probe(device_t); +static int wi_pccard_attach(device_t); + +static device_method_t wi_pccard_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, pccard_compat_probe), + DEVMETHOD(device_attach, pccard_compat_attach), + DEVMETHOD(device_detach, wi_generic_detach), + DEVMETHOD(device_shutdown, wi_shutdown), + + /* Card interface */ + DEVMETHOD(card_compat_match, wi_pccard_match), + DEVMETHOD(card_compat_probe, wi_pccard_probe), + DEVMETHOD(card_compat_attach, wi_pccard_attach), + + { 0, 0 } +}; + +static driver_t wi_pccard_driver = { + "wi", + wi_pccard_methods, + sizeof(struct wi_softc) +}; + +DRIVER_MODULE(if_wi, pccard, wi_pccard_driver, wi_devclass, 0, 0); + +static const struct pccard_product wi_pccard_products[] = { + PCMCIA_CARD(3COM, 3CRWE737A, 0), + PCMCIA_CARD(BUFFALO, WLI_PCM_S11, 0), + PCMCIA_CARD(BUFFALO, WLI_CF_S11G, 0), + PCMCIA_CARD(COMPAQ, NC5004, 0), + PCMCIA_CARD(CONTEC, FX_DS110_PCC, 0), + PCMCIA_CARD(COREGA, WIRELESS_LAN_PCC_11, 0), + PCMCIA_CARD(COREGA, WIRELESS_LAN_PCCA_11, 0), + PCMCIA_CARD(COREGA, WIRELESS_LAN_PCCB_11, 0), + PCMCIA_CARD(ELSA, XI300_IEEE, 0), + PCMCIA_CARD(ELSA, XI800_IEEE, 0), + PCMCIA_CARD(EMTAC, WLAN, 0), + PCMCIA_CARD(ERICSSON, WIRELESSLAN, 0), + PCMCIA_CARD(GEMTEK, WLAN, 0), + PCMCIA_CARD(HWN, AIRWAY80211, 0), + PCMCIA_CARD(INTEL, PRO_WLAN_2011, 0), + PCMCIA_CARD(INTERSIL, PRISM2, 0), + PCMCIA_CARD(IODATA2, WNB11PCM, 0), + /* Now that we do PRISM detection, I don't think we need these - imp */ + PCMCIA_CARD2(LUCENT, WAVELAN_IEEE, NANOSPEED_PRISM2, 0), + PCMCIA_CARD2(LUCENT, WAVELAN_IEEE, NEC_CMZ_RT_WP, 0), + PCMCIA_CARD2(LUCENT, WAVELAN_IEEE, NTT_ME_WLAN, 0), + PCMCIA_CARD2(LUCENT, WAVELAN_IEEE, SMC_2632W, 0), + /* Must be after other LUCENT ones because it is less specific */ + PCMCIA_CARD(LUCENT, WAVELAN_IEEE, 0), + PCMCIA_CARD(LINKSYS2, IWN, 0), + PCMCIA_CARD(SAMSUNG, SWL_2000N, 0), + PCMCIA_CARD(SIMPLETECH, SPECTRUM24_ALT, 0), + PCMCIA_CARD(SOCKET, LP_WLAN_CF, 0), + PCMCIA_CARD(SYMBOL, LA4100, 0), + PCMCIA_CARD(TDK, LAK_CD011WL, 0), + { NULL } +}; + +static int +wi_pccard_match(dev) + device_t dev; +{ + const struct pccard_product *pp; + + if ((pp = pccard_product_lookup(dev, wi_pccard_products, + sizeof(wi_pccard_products[0]), NULL)) != NULL) { + device_set_desc(dev, pp->pp_name); + return 0; + } + return ENXIO; +} + +static int +wi_pccard_probe(dev) + device_t dev; +{ + struct wi_softc *sc; + int error; + + sc = device_get_softc(dev); + sc->wi_gone = 0; + sc->wi_bus_type = WI_BUS_PCCARD; + + error = wi_alloc(dev, 0); + if (error) + return (error); + + wi_free(dev); + + /* Make sure interrupts are disabled. */ + CSR_WRITE_2(sc, WI_INT_EN, 0); + CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); + + return (0); +} + +static int +wi_pccard_attach(device_t dev) +{ + struct wi_softc *sc; + int error; + + sc = device_get_softc(dev); + + error = wi_alloc(dev, 0); + if (error) { + device_printf(dev, "wi_alloc() failed! (%d)\n", error); + return (error); + } + return (wi_generic_attach(dev)); +} diff --git a/sys/dev/wi/if_wi_pci.c b/sys/dev/wi/if_wi_pci.c new file mode 100644 index 0000000..e9c1c9f --- /dev/null +++ b/sys/dev/wi/if_wi_pci.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) 1997, 1998, 1999 + * Bill Paul <wpaul@ctr.columbia.edu>. 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. + */ + +/* + * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for FreeBSD. + * + * Written by Bill Paul <wpaul@ctr.columbia.edu> + * Electrical Engineering Department + * Columbia University, New York City + */ + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/socket.h> +#include <sys/module.h> +#include <sys/bus.h> + +#include <machine/bus.h> +#include <machine/resource.h> +#include <sys/rman.h> + +#include <pci/pcireg.h> +#include <pci/pcivar.h> + +#include <net/if.h> +#include <net/if_arp.h> +#include <net/ethernet.h> +#include <net/if_media.h> +#include <net/if_types.h> +#include <net/if_ieee80211.h> + +#include <dev/wi/if_wavelan_ieee.h> +#include <dev/wi/if_wivar.h> +#include <dev/wi/if_wireg.h> + +#include "card_if.h" + +#if !defined(lint) +static const char rcsid[] = + "$FreeBSD$"; +#endif + +static int wi_pci_probe(device_t); +static int wi_pci_attach(device_t); + +static device_method_t wi_pci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, wi_pci_probe), + DEVMETHOD(device_attach, wi_pci_attach), + DEVMETHOD(device_detach, wi_generic_detach), + DEVMETHOD(device_shutdown, wi_shutdown), + + { 0, 0 } +}; + +static driver_t wi_pci_driver = { + "wi", + wi_pci_methods, + sizeof(struct wi_softc) +}; + +static struct { + unsigned int vendor,device; + int bus_type; + char *desc; +} pci_ids[] = { + {0x1638, 0x1100, WI_BUS_PCI_PLX, "PRISM2STA PCI WaveLAN/IEEE 802.11"}, + {0x1385, 0x4100, WI_BUS_PCI_PLX, "Netgear MA301 PCI IEEE 802.11b"}, + {0x16ab, 0x1101, WI_BUS_PCI_PLX, "GLPRISM2 PCI WaveLAN/IEEE 802.11"}, + {0x16ab, 0x1102, WI_BUS_PCI_PLX, "Linksys WDT11 PCI IEEE 802.11b"}, + {0x1260, 0x3873, WI_BUS_PCI_NATIVE, "Linksys WMP11 PCI Prism2.5"}, + {0x10b7, 0x7770, WI_BUS_PCI_PLX, "3Com Airconnect IEEE 802.11b"}, + {0, 0, 0, NULL} +}; + +DRIVER_MODULE(if_wi, pci, wi_pci_driver, wi_devclass, 0, 0); + +static int +wi_pci_probe(dev) + device_t dev; +{ + struct wi_softc *sc; + int i; + + sc = device_get_softc(dev); + for(i=0; pci_ids[i].vendor != 0; i++) { + if ((pci_get_vendor(dev) == pci_ids[i].vendor) && + (pci_get_device(dev) == pci_ids[i].device)) { + sc->wi_prism2 = 1; + sc->wi_bus_type = pci_ids[i].bus_type; + device_set_desc(dev, pci_ids[i].desc); + return (0); + } + } + return(ENXIO); +} + +static int +wi_pci_attach(device_t dev) +{ + struct wi_softc *sc; + u_int32_t command, wanted; + u_int16_t reg; + int error; + int timeout; + + sc = device_get_softc(dev); + + command = pci_read_config(dev, PCIR_COMMAND, 4); + wanted = PCIM_CMD_PORTEN|PCIM_CMD_MEMEN; + command |= wanted; + pci_write_config(dev, PCIR_COMMAND, command, 4); + command = pci_read_config(dev, PCIR_COMMAND, 4); + if ((command & wanted) != wanted) { + device_printf(dev, "wi_pci_attach() failed to enable pci!\n"); + return (ENXIO); + } + + if (sc->wi_bus_type != WI_BUS_PCI_NATIVE) { + error = wi_alloc(dev, WI_PCI_IORES); + if (error) + return (error); + + /* Make sure interrupts are disabled. */ + CSR_WRITE_2(sc, WI_INT_EN, 0); + CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); + + /* We have to do a magic PLX poke to enable interrupts */ + sc->local_rid = WI_PCI_LOCALRES; + sc->local = bus_alloc_resource(dev, SYS_RES_IOPORT, + &sc->local_rid, 0, ~0, 1, RF_ACTIVE); + sc->wi_localtag = rman_get_bustag(sc->local); + sc->wi_localhandle = rman_get_bushandle(sc->local); + command = bus_space_read_4(sc->wi_localtag, sc->wi_localhandle, + WI_LOCAL_INTCSR); + command |= WI_LOCAL_INTEN; + bus_space_write_4(sc->wi_localtag, sc->wi_localhandle, + WI_LOCAL_INTCSR, command); + bus_release_resource(dev, SYS_RES_IOPORT, sc->local_rid, + sc->local); + sc->local = NULL; + + sc->mem_rid = WI_PCI_MEMRES; + sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->mem_rid, + 0, ~0, 1, RF_ACTIVE); + if (sc->mem == NULL) { + device_printf(dev, "couldn't allocate memory\n"); + wi_free(dev); + return (ENXIO); + } + sc->wi_bmemtag = rman_get_bustag(sc->mem); + sc->wi_bmemhandle = rman_get_bushandle(sc->mem); + + /* + * From Linux driver: + * Write COR to enable PC card + * This is a subset of the protocol that the pccard bus code + * would do. + */ + CSM_WRITE_1(sc, WI_COR_OFFSET, WI_COR_VALUE); + reg = CSM_READ_1(sc, WI_COR_OFFSET); + if (reg != WI_COR_VALUE) { + device_printf(dev, "CSM_READ_1(WI_COR_OFFSET) " + "wanted %d, got %d\n", WI_COR_VALUE, reg); + wi_free(dev); + return (ENXIO); + } + } else { + error = wi_alloc(dev, WI_PCI_LMEMRES); + if (error) + return (error); + + CSR_WRITE_2(sc, WI_HFA384X_PCICOR_OFF, 0x0080); + DELAY(250000); + + CSR_WRITE_2(sc, WI_HFA384X_PCICOR_OFF, 0x0000); + DELAY(500000); + + timeout=2000000; + while ((--timeout > 0) && + (CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY)) + DELAY(10); + + if (timeout == 0) { + device_printf(dev, "couldn't reset prism2.5 core.\n"); + wi_free(dev); + return(ENXIO); + } + } + + CSR_WRITE_2(sc, WI_HFA384X_SWSUPPORT0_OFF, WI_PRISM2STA_MAGIC); + reg = CSR_READ_2(sc, WI_HFA384X_SWSUPPORT0_OFF); + if (reg != WI_PRISM2STA_MAGIC) { + device_printf(dev, + "CSR_READ_2(WI_HFA384X_SWSUPPORT0_OFF) " + "wanted %d, got %d\n", WI_PRISM2STA_MAGIC, reg); + wi_free(dev); + return (ENXIO); + } + + error = wi_generic_attach(dev); + if (error != 0) + return (error); + + return (0); +} diff --git a/sys/dev/wi/if_wireg.h b/sys/dev/wi/if_wireg.h index 3df0ea1..bf28e64 100644 --- a/sys/dev/wi/if_wireg.h +++ b/sys/dev/wi/if_wireg.h @@ -32,148 +32,6 @@ * $FreeBSD$ */ -#include <netinet/if_ether.h> -#include <dev/wi/if_wavelan_ieee.h> -#include <sys/bus.h> - -struct wi_counters { - u_int32_t wi_tx_unicast_frames; - u_int32_t wi_tx_multicast_frames; - u_int32_t wi_tx_fragments; - u_int32_t wi_tx_unicast_octets; - u_int32_t wi_tx_multicast_octets; - u_int32_t wi_tx_deferred_xmits; - u_int32_t wi_tx_single_retries; - u_int32_t wi_tx_multi_retries; - u_int32_t wi_tx_retry_limit; - u_int32_t wi_tx_discards; - u_int32_t wi_rx_unicast_frames; - u_int32_t wi_rx_multicast_frames; - u_int32_t wi_rx_fragments; - u_int32_t wi_rx_unicast_octets; - u_int32_t wi_rx_multicast_octets; - u_int32_t wi_rx_fcs_errors; - u_int32_t wi_rx_discards_nobuf; - u_int32_t wi_tx_discards_wrong_sa; - u_int32_t wi_rx_WEP_cant_decrypt; - u_int32_t wi_rx_msg_in_msg_frags; - u_int32_t wi_rx_msg_in_bad_msg_frags; -}; - -/* - * Encryption controls. We can enable or disable encryption as - * well as specify up to 4 encryption keys. We can also specify - * which of the four keys will be used for transmit encryption. - */ -#define WI_RID_ENCRYPTION 0xFC20 -#define WI_RID_AUTHTYPE 0xFC21 -#define WI_RID_DEFLT_CRYPT_KEYS 0xFCB0 -#define WI_RID_TX_CRYPT_KEY 0xFCB1 -#define WI_RID_WEP_AVAIL 0xFD4F -#define WI_RID_P2_TX_CRYPT_KEY 0xFC23 -#define WI_RID_P2_CRYPT_KEY0 0xFC24 -#define WI_RID_P2_CRYPT_KEY1 0xFC25 -#define WI_RID_MICROWAVE_OVEN 0xFC25 -#define WI_RID_P2_CRYPT_KEY2 0xFC26 -#define WI_RID_P2_CRYPT_KEY3 0xFC27 -#define WI_RID_P2_ENCRYPTION 0xFC28 -#define WI_RID_ROAMING_MODE 0xFC2D -#define WI_RID_CUR_TX_RATE 0xFD44 /* current TX rate */ -struct wi_key { - u_int16_t wi_keylen; - u_int8_t wi_keydat[14]; -}; - -struct wi_ltv_keys { - u_int16_t wi_len; - u_int16_t wi_type; - struct wi_key wi_keys[4]; -}; - -struct wi_softc { - struct arpcom arpcom; - struct ifmedia ifmedia; - device_t dev; - int wi_unit; - struct resource * local; - int local_rid; - struct resource * iobase; - int iobase_rid; - struct resource * irq; - int irq_rid; - struct resource * mem; - int mem_rid; - bus_space_handle_t wi_localhandle; - bus_space_tag_t wi_localtag; - bus_space_handle_t wi_bhandle; - bus_space_tag_t wi_btag; - bus_space_handle_t wi_bmemhandle; - bus_space_tag_t wi_bmemtag; - void * wi_intrhand; - int wi_io_addr; - int wi_tx_data_id; - int wi_tx_mgmt_id; - int wi_gone; - int wi_if_flags; - u_int16_t wi_procframe; - u_int16_t wi_ptype; - u_int16_t wi_portnum; - u_int16_t wi_max_data_len; - u_int16_t wi_rts_thresh; - u_int16_t wi_ap_density; - u_int16_t wi_tx_rate; - u_int16_t wi_create_ibss; - u_int16_t wi_channel; - u_int16_t wi_pm_enabled; - u_int16_t wi_mor_enabled; - u_int16_t wi_max_sleep; - u_int16_t wi_authtype; - u_int16_t wi_roaming; - - char wi_node_name[32]; - char wi_net_name[32]; - char wi_ibss_name[32]; - u_int8_t wi_txbuf[1596]; - u_int8_t wi_scanbuf[1596]; - int wi_scanbuf_len; - struct wi_counters wi_stats; - int wi_has_wep; - int wi_use_wep; - int wi_tx_key; - struct wi_ltv_keys wi_keys; -#ifdef WICACHE - int wi_sigitems; - struct wi_sigcache wi_sigcache[MAXWICACHE]; - int wi_nextitem; -#endif - struct callout_handle wi_stat_ch; - struct mtx wi_mtx; - int wi_prism2; - int wi_firmware_ver; - int wi_nic_type; - int wi_bus_type; /* Bus attachment type */ - struct { - u_int16_t wi_sleep; - u_int16_t wi_delaysupp; - u_int16_t wi_txsupp; - u_int16_t wi_monitor; - u_int16_t wi_ledtest; - u_int16_t wi_ledtest_param0; - u_int16_t wi_ledtest_param1; - u_int16_t wi_conttx; - u_int16_t wi_conttx_param0; - u_int16_t wi_contrx; - u_int16_t wi_sigstate; - u_int16_t wi_sigstate_param0; - u_int16_t wi_confbits; - u_int16_t wi_confbits_param0; - } wi_debug; - -}; - -#define WI_LOCK(_sc) -#define WI_UNLOCK(_sc) - #define WI_DELAY 5 #define WI_TIMEOUT (500000/WI_DELAY) /* 500 ms */ diff --git a/sys/dev/wi/if_wivar.h b/sys/dev/wi/if_wivar.h new file mode 100644 index 0000000..655b623 --- /dev/null +++ b/sys/dev/wi/if_wivar.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2002 + * M Warner Losh <imp@freebsd.org>. All rights reserved. + * Copyright (c) 1997, 1998, 1999 + * Bill Paul <wpaul@ctr.columbia.edu>. 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. + * + * $FreeBSD$ + */ + +#define WICACHE /* turn on signal strength cache code */ +#define MAXWICACHE 10 + +struct wi_counters { + u_int32_t wi_tx_unicast_frames; + u_int32_t wi_tx_multicast_frames; + u_int32_t wi_tx_fragments; + u_int32_t wi_tx_unicast_octets; + u_int32_t wi_tx_multicast_octets; + u_int32_t wi_tx_deferred_xmits; + u_int32_t wi_tx_single_retries; + u_int32_t wi_tx_multi_retries; + u_int32_t wi_tx_retry_limit; + u_int32_t wi_tx_discards; + u_int32_t wi_rx_unicast_frames; + u_int32_t wi_rx_multicast_frames; + u_int32_t wi_rx_fragments; + u_int32_t wi_rx_unicast_octets; + u_int32_t wi_rx_multicast_octets; + u_int32_t wi_rx_fcs_errors; + u_int32_t wi_rx_discards_nobuf; + u_int32_t wi_tx_discards_wrong_sa; + u_int32_t wi_rx_WEP_cant_decrypt; + u_int32_t wi_rx_msg_in_msg_frags; + u_int32_t wi_rx_msg_in_bad_msg_frags; +}; + +/* + * Encryption controls. We can enable or disable encryption as + * well as specify up to 4 encryption keys. We can also specify + * which of the four keys will be used for transmit encryption. + */ +#define WI_RID_ENCRYPTION 0xFC20 +#define WI_RID_AUTHTYPE 0xFC21 +#define WI_RID_DEFLT_CRYPT_KEYS 0xFCB0 +#define WI_RID_TX_CRYPT_KEY 0xFCB1 +#define WI_RID_WEP_AVAIL 0xFD4F +#define WI_RID_P2_TX_CRYPT_KEY 0xFC23 +#define WI_RID_P2_CRYPT_KEY0 0xFC24 +#define WI_RID_P2_CRYPT_KEY1 0xFC25 +#define WI_RID_MICROWAVE_OVEN 0xFC25 +#define WI_RID_P2_CRYPT_KEY2 0xFC26 +#define WI_RID_P2_CRYPT_KEY3 0xFC27 +#define WI_RID_P2_ENCRYPTION 0xFC28 +#define WI_RID_ROAMING_MODE 0xFC2D +#define WI_RID_CUR_TX_RATE 0xFD44 /* current TX rate */ +struct wi_key { + u_int16_t wi_keylen; + u_int8_t wi_keydat[14]; +}; + +struct wi_ltv_keys { + u_int16_t wi_len; + u_int16_t wi_type; + struct wi_key wi_keys[4]; +}; + +struct wi_softc { + struct arpcom arpcom; + struct ifmedia ifmedia; + device_t dev; + int wi_unit; + struct resource * local; + int local_rid; + struct resource * iobase; + int iobase_rid; + struct resource * irq; + int irq_rid; + struct resource * mem; + int mem_rid; + bus_space_handle_t wi_localhandle; + bus_space_tag_t wi_localtag; + bus_space_handle_t wi_bhandle; + bus_space_tag_t wi_btag; + bus_space_handle_t wi_bmemhandle; + bus_space_tag_t wi_bmemtag; + void * wi_intrhand; + int wi_io_addr; + int wi_tx_data_id; + int wi_tx_mgmt_id; + int wi_gone; + int wi_if_flags; + u_int16_t wi_procframe; + u_int16_t wi_ptype; + u_int16_t wi_portnum; + u_int16_t wi_max_data_len; + u_int16_t wi_rts_thresh; + u_int16_t wi_ap_density; + u_int16_t wi_tx_rate; + u_int16_t wi_create_ibss; + u_int16_t wi_channel; + u_int16_t wi_pm_enabled; + u_int16_t wi_mor_enabled; + u_int16_t wi_max_sleep; + u_int16_t wi_authtype; + u_int16_t wi_roaming; + + char wi_node_name[32]; + char wi_net_name[32]; + char wi_ibss_name[32]; + u_int8_t wi_txbuf[1596]; + u_int8_t wi_scanbuf[1596]; + int wi_scanbuf_len; + struct wi_counters wi_stats; + int wi_has_wep; + int wi_use_wep; + int wi_tx_key; + struct wi_ltv_keys wi_keys; +#ifdef WICACHE + int wi_sigitems; + struct wi_sigcache wi_sigcache[MAXWICACHE]; + int wi_nextitem; +#endif + struct callout_handle wi_stat_ch; + struct mtx wi_mtx; + int wi_prism2; + int wi_firmware_ver; + int wi_nic_type; + int wi_bus_type; /* Bus attachment type */ + struct { + u_int16_t wi_sleep; + u_int16_t wi_delaysupp; + u_int16_t wi_txsupp; + u_int16_t wi_monitor; + u_int16_t wi_ledtest; + u_int16_t wi_ledtest_param0; + u_int16_t wi_ledtest_param1; + u_int16_t wi_conttx; + u_int16_t wi_conttx_param0; + u_int16_t wi_contrx; + u_int16_t wi_sigstate; + u_int16_t wi_sigstate_param0; + u_int16_t wi_confbits; + u_int16_t wi_confbits_param0; + } wi_debug; + +}; + +#define WI_LOCK(_sc) +#define WI_UNLOCK(_sc) + +int wi_generic_attach(device_t); +int wi_generic_detach(device_t); +void wi_shutdown(device_t); +int wi_alloc(device_t, int); +void wi_free(device_t); +extern devclass_t wi_devclass; |