if_ral_pci.c revision 145247
1285809Sscottl/*	$FreeBSD: head/sys/dev/ral/if_ral_pci.c 145247 2005-04-18 18:47:38Z damien $	*/
2285809Sscottl
3285809Sscottl/*-
4285809Sscottl * Copyright (c) 2005
5285809Sscottl *	Damien Bergamini <damien.bergamini@free.fr>
6285809Sscottl *
7285809Sscottl * Permission to use, copy, modify, and distribute this software for any
8285809Sscottl * purpose with or without fee is hereby granted, provided that the above
9285809Sscottl * copyright notice and this permission notice appear in all copies.
10285809Sscottl *
11285809Sscottl * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12285809Sscottl * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13285809Sscottl * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14285809Sscottl * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15285809Sscottl * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16285809Sscottl * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17285809Sscottl * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18285809Sscottl */
19285809Sscottl
20285809Sscottl#include <sys/cdefs.h>
21285809Sscottl__FBSDID("$FreeBSD: head/sys/dev/ral/if_ral_pci.c 145247 2005-04-18 18:47:38Z damien $");
22285809Sscottl
23285809Sscottl/*
24285809Sscottl * PCI front-end for the Ralink RT2500 driver.
25285809Sscottl */
26285809Sscottl
27285809Sscottl#include <sys/param.h>
28285809Sscottl#include <sys/sysctl.h>
29285809Sscottl#include <sys/sockio.h>
30285809Sscottl#include <sys/mbuf.h>
31285809Sscottl#include <sys/kernel.h>
32285809Sscottl#include <sys/socket.h>
33285809Sscottl#include <sys/systm.h>
34285809Sscottl#include <sys/malloc.h>
35285809Sscottl#include <sys/module.h>
36285809Sscottl#include <sys/bus.h>
37285809Sscottl#include <sys/endian.h>
38285809Sscottl
39285809Sscottl#include <machine/bus.h>
40285809Sscottl#include <machine/resource.h>
41285809Sscottl#include <machine/clock.h>
42285809Sscottl#include <sys/rman.h>
43285809Sscottl
44285809Sscottl#include <net/bpf.h>
45285809Sscottl#include <net/if.h>
46285809Sscottl#include <net/if_arp.h>
47285809Sscottl#include <net/ethernet.h>
48285809Sscottl#include <net/if_dl.h>
49285809Sscottl#include <net/if_media.h>
50285809Sscottl#include <net/if_types.h>
51285809Sscottl
52285809Sscottl#include <net80211/ieee80211_var.h>
53285809Sscottl#include <net80211/ieee80211_radiotap.h>
54285809Sscottl
55285809Sscottl#include <dev/pci/pcireg.h>
56285809Sscottl#include <dev/pci/pcivar.h>
57285809Sscottl
58285809Sscottl#include <dev/ral/if_ralrate.h>
59285809Sscottl#include <dev/ral/if_ralreg.h>
60285809Sscottl#include <dev/ral/if_ralvar.h>
61285809Sscottl
62285809SscottlMODULE_DEPEND(ral, pci, 1, 1, 1);
63285809SscottlMODULE_DEPEND(ral, wlan, 1, 1, 1);
64285809Sscottl
65285809Sscottlstruct ral_pci_ident {
66285809Sscottl	uint16_t	vendor;
67	uint16_t	device;
68	const char	*name;
69};
70
71static const struct ral_pci_ident ral_pci_ids[] = {
72	{ 0x1814, 0x0201, "Ralink Technology RT2500" },
73
74	{ 0, 0, NULL }
75};
76
77static int ral_pci_probe(device_t);
78static int ral_pci_attach(device_t);
79static int ral_pci_suspend(device_t);
80static int ral_pci_resume(device_t);
81
82static device_method_t ral_pci_methods[] = {
83	/* Device interface */
84	DEVMETHOD(device_probe,		ral_pci_probe),
85	DEVMETHOD(device_attach,	ral_pci_attach),
86	DEVMETHOD(device_detach,	ral_detach),
87	DEVMETHOD(device_suspend,	ral_pci_suspend),
88	DEVMETHOD(device_resume,	ral_pci_resume),
89
90	{ 0, 0 }
91};
92
93static driver_t ral_pci_driver = {
94	"ral",
95	ral_pci_methods,
96	sizeof (struct ral_softc)
97};
98
99DRIVER_MODULE(ral, pci, ral_pci_driver, ral_devclass, 0, 0);
100DRIVER_MODULE(ral, cardbus, ral_pci_driver, ral_devclass, 0, 0);
101
102static int
103ral_pci_probe(device_t dev)
104{
105	const struct ral_pci_ident *ident;
106
107	for (ident = ral_pci_ids; ident->name != NULL; ident++) {
108		if (pci_get_vendor(dev) == ident->vendor &&
109		    pci_get_device(dev) == ident->device) {
110			device_set_desc(dev, ident->name);
111			return 0;
112		}
113	}
114	return ENXIO;
115}
116
117/* Base Address Register */
118#define RAL_PCI_BAR0	0x10
119
120static int
121ral_pci_attach(device_t dev)
122{
123	int error;
124
125	if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
126		device_printf(dev, "chip is in D%d power mode "
127		    "-- setting to D0\n", pci_get_powerstate(dev));
128		pci_set_powerstate(dev, PCI_POWERSTATE_D0);
129	}
130
131	/* enable bus-mastering */
132	pci_enable_busmaster(dev);
133
134	error = ral_alloc(dev, RAL_PCI_BAR0);
135	if (error != 0)
136		return error;
137
138	error = ral_attach(dev);
139	if (error != 0)
140		ral_free(dev);
141
142	return error;
143}
144
145static int
146ral_pci_suspend(device_t dev)
147{
148	struct ral_softc *sc = device_get_softc(dev);
149
150	ral_stop(sc);
151
152	return 0;
153}
154
155static int
156ral_pci_resume(device_t dev)
157{
158	struct ral_softc *sc = device_get_softc(dev);
159	struct ifnet *ifp = sc->sc_ic.ic_ifp;
160
161	if (ifp->if_flags & IFF_UP) {
162		ifp->if_init(ifp->if_softc);
163		if (ifp->if_flags & IFF_RUNNING)
164			ifp->if_start(ifp);
165	}
166
167	return 0;
168}
169