xref: /freebsd/sys/dev/ral/if_ral_pci.c (revision 3642298923e528d795e3a30ec165d2b469e28b40)
1 /*	$FreeBSD$	*/
2 
3 /*-
4  * Copyright (c) 2005
5  *	Damien Bergamini <damien.bergamini@free.fr>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/cdefs.h>
21 __FBSDID("$FreeBSD$");
22 
23 /*
24  * PCI front-end for the Ralink RT2500 driver.
25  */
26 
27 #include <sys/param.h>
28 #include <sys/sysctl.h>
29 #include <sys/sockio.h>
30 #include <sys/mbuf.h>
31 #include <sys/kernel.h>
32 #include <sys/socket.h>
33 #include <sys/systm.h>
34 #include <sys/malloc.h>
35 #include <sys/module.h>
36 #include <sys/bus.h>
37 #include <sys/endian.h>
38 
39 #include <machine/bus.h>
40 #include <machine/resource.h>
41 #include <machine/clock.h>
42 #include <sys/rman.h>
43 
44 #include <net/bpf.h>
45 #include <net/if.h>
46 #include <net/if_arp.h>
47 #include <net/ethernet.h>
48 #include <net/if_dl.h>
49 #include <net/if_media.h>
50 #include <net/if_types.h>
51 
52 #include <net80211/ieee80211_var.h>
53 #include <net80211/ieee80211_radiotap.h>
54 
55 #include <dev/pci/pcireg.h>
56 #include <dev/pci/pcivar.h>
57 
58 #include <dev/ral/if_ralrate.h>
59 #include <dev/ral/if_ralreg.h>
60 #include <dev/ral/if_ralvar.h>
61 
62 MODULE_DEPEND(ral, pci, 1, 1, 1);
63 MODULE_DEPEND(ral, wlan, 1, 1, 1);
64 
65 struct ral_pci_ident {
66 	uint16_t	vendor;
67 	uint16_t	device;
68 	const char	*name;
69 };
70 
71 static const struct ral_pci_ident ral_pci_ids[] = {
72 	{ 0x1814, 0x0201, "Ralink Technology RT2500" },
73 
74 	{ 0, 0, NULL }
75 };
76 
77 static int ral_pci_probe(device_t);
78 static int ral_pci_attach(device_t);
79 static int ral_pci_suspend(device_t);
80 static int ral_pci_resume(device_t);
81 
82 static 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 
93 static driver_t ral_pci_driver = {
94 	"ral",
95 	ral_pci_methods,
96 	sizeof (struct ral_softc)
97 };
98 
99 DRIVER_MODULE(ral, pci, ral_pci_driver, ral_devclass, 0, 0);
100 DRIVER_MODULE(ral, cardbus, ral_pci_driver, ral_devclass, 0, 0);
101 
102 static int
103 ral_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 
120 static int
121 ral_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 
145 static int
146 ral_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 
155 static int
156 ral_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_drv_flags & IFF_DRV_RUNNING)
164 			ifp->if_start(ifp);
165 	}
166 
167 	return 0;
168 }
169