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.
This commit is contained in:
Warner Losh 2002-04-02 02:38:35 +00:00
parent 2da08e795e
commit dbab04ca39
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=93611
7 changed files with 614 additions and 479 deletions

View File

@ -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 {

View File

@ -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),
devclass_t wi_devclass;
/* 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
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;
{

186
sys/dev/wi/if_wi_pccard.c Normal file
View File

@ -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));
}

235
sys/dev/wi/if_wi_pci.c Normal file
View File

@ -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);
}

View File

@ -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 */

183
sys/dev/wi/if_wivar.h Normal file
View File

@ -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;

View File

@ -3,11 +3,7 @@
.PATH: ${.CURDIR}/../../dev/wi
KMOD= if_wi
SRCS= if_wi.c card_if.h device_if.h bus_if.h pci_if.h pci.h
CLEANFILES += pci.h
pci.h:
echo "#define NPCI 1" > $@
SRCS= if_wi.c if_wi_pccard.c if_wi_pci.c \
card_if.h device_if.h bus_if.h pci_if.h
.include <bsd.kmod.mk>