freebsd-skq/sys/dev/ral/if_ral_pci.c
rwatson 5d770a09e8 Propagate rename of IFF_OACTIVE and IFF_RUNNING to IFF_DRV_OACTIVE and
IFF_DRV_RUNNING, as well as the move from ifnet.if_flags to
ifnet.if_drv_flags.  Device drivers are now responsible for
synchronizing access to these flags, as they are in if_drv_flags.  This
helps prevent races between the network stack and device driver in
maintaining the interface flags field.

Many __FreeBSD__ and __FreeBSD_version checks maintained and continued;
some less so.

Reviewed by:	pjd, bz
MFC after:	7 days
2005-08-09 10:20:02 +00:00

169 lines
3.8 KiB
C

/* $FreeBSD$ */
/*-
* Copyright (c) 2005
* Damien Bergamini <damien.bergamini@free.fr>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* PCI front-end for the Ralink RT2500 driver.
*/
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/sockio.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/endian.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <machine/clock.h>
#include <sys/rman.h>
#include <net/bpf.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 <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/ral/if_ralrate.h>
#include <dev/ral/if_ralreg.h>
#include <dev/ral/if_ralvar.h>
MODULE_DEPEND(ral, pci, 1, 1, 1);
MODULE_DEPEND(ral, wlan, 1, 1, 1);
struct ral_pci_ident {
uint16_t vendor;
uint16_t device;
const char *name;
};
static const struct ral_pci_ident ral_pci_ids[] = {
{ 0x1814, 0x0201, "Ralink Technology RT2500" },
{ 0, 0, NULL }
};
static int ral_pci_probe(device_t);
static int ral_pci_attach(device_t);
static int ral_pci_suspend(device_t);
static int ral_pci_resume(device_t);
static device_method_t ral_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ral_pci_probe),
DEVMETHOD(device_attach, ral_pci_attach),
DEVMETHOD(device_detach, ral_detach),
DEVMETHOD(device_suspend, ral_pci_suspend),
DEVMETHOD(device_resume, ral_pci_resume),
{ 0, 0 }
};
static driver_t ral_pci_driver = {
"ral",
ral_pci_methods,
sizeof (struct ral_softc)
};
DRIVER_MODULE(ral, pci, ral_pci_driver, ral_devclass, 0, 0);
DRIVER_MODULE(ral, cardbus, ral_pci_driver, ral_devclass, 0, 0);
static int
ral_pci_probe(device_t dev)
{
const struct ral_pci_ident *ident;
for (ident = ral_pci_ids; ident->name != NULL; ident++) {
if (pci_get_vendor(dev) == ident->vendor &&
pci_get_device(dev) == ident->device) {
device_set_desc(dev, ident->name);
return 0;
}
}
return ENXIO;
}
/* Base Address Register */
#define RAL_PCI_BAR0 0x10
static int
ral_pci_attach(device_t dev)
{
int error;
if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
device_printf(dev, "chip is in D%d power mode "
"-- setting to D0\n", pci_get_powerstate(dev));
pci_set_powerstate(dev, PCI_POWERSTATE_D0);
}
/* enable bus-mastering */
pci_enable_busmaster(dev);
error = ral_alloc(dev, RAL_PCI_BAR0);
if (error != 0)
return error;
error = ral_attach(dev);
if (error != 0)
ral_free(dev);
return error;
}
static int
ral_pci_suspend(device_t dev)
{
struct ral_softc *sc = device_get_softc(dev);
ral_stop(sc);
return 0;
}
static int
ral_pci_resume(device_t dev)
{
struct ral_softc *sc = device_get_softc(dev);
struct ifnet *ifp = sc->sc_ic.ic_ifp;
if (ifp->if_flags & IFF_UP) {
ifp->if_init(ifp->if_softc);
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
ifp->if_start(ifp);
}
return 0;
}