if_re_pci.c revision 1.1 1 /*
2 * RealTek 8139C+/8169/8169S/8110S PCI NIC driver
3 *
4 * Written by Bill Paul <wpaul (at) windriver.com>
5 * Senior Networking Software Engineer
6 * Wind River Systems
7 *
8 * NetBSD bus-specific frontends for written by
9 * Jonathan Stone <jonathan (at) netbsd.org>
10 */
11
12 #include "bpfilter.h"
13 #include "vlan.h"
14
15 #include <sys/types.h>
16
17 #include <machine/bus.h>
18
19 #include <dev/pci/pcireg.h>
20 #include <dev/pci/pcivar.h>
21 #include <dev/pci/pcidevs.h>
22
23 #include <sys/param.h>
24 #include <sys/endian.h>
25 #include <sys/systm.h>
26 #include <sys/sockio.h>
27 #include <sys/mbuf.h>
28 #include <sys/malloc.h>
29 #include <sys/kernel.h>
30 #include <sys/socket.h>
31 #include <sys/device.h>
32
33 #include <net/if.h>
34 #include <net/if_arp.h>
35 #include <net/if_dl.h>
36 #include <net/if_ether.h>
37 #include <net/if_media.h>
38 #include <net/if_vlanvar.h>
39
40 #include <dev/mii/mii.h>
41 #include <dev/mii/miivar.h>
42
43 /*
44 * Default to using PIO access for this driver.
45 */
46 #define RE_USEIOSPACE
47
48 #include <dev/ic/rtl81x9reg.h>
49 #include <dev/ic/rtl81x9var.h>
50 #include <dev/ic/rtl8169var.h>
51
52 struct re_pci_softc {
53 struct rtk_softc sc_rtk;
54
55 void *sc_ih;
56 pci_chipset_tag_t sc_pc;
57 pcitag_t sc_pcitag;
58 };
59
60 static int re_pci_probe(struct device *, struct cfdata *, void *);
61 static void re_pci_attach(struct device *, struct device *, void *);
62
63 /*
64 * Various supported device vendors/types and their names.
65 */
66 static struct rtk_type re_devs[] = {
67 { PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8139, RTK_HWREV_8139CPLUS,
68 "RealTek 8139C+ 10/100BaseTX" },
69 { PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8169, RTK_HWREV_8169,
70 "RealTek 8169 Gigabit Ethernet" },
71 { PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8169, RTK_HWREV_8169S,
72 "RealTek 8169S Single-chip Gigabit Ethernet" },
73 { PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8169, RTK_HWREV_8110S,
74 "RealTek 8110S Single-chip Gigabit Ethernet" },
75 { 0, 0, 0, NULL }
76 };
77
78 static struct rtk_hwrev re_hwrevs[] = {
79 { RTK_HWREV_8139, RTK_8139, "" },
80 { RTK_HWREV_8139A, RTK_8139, "A" },
81 { RTK_HWREV_8139AG, RTK_8139, "A-G" },
82 { RTK_HWREV_8139B, RTK_8139, "B" },
83 { RTK_HWREV_8130, RTK_8139, "8130" },
84 { RTK_HWREV_8139C, RTK_8139, "C" },
85 { RTK_HWREV_8139D, RTK_8139, "8139D/8100B/8100C" },
86 { RTK_HWREV_8139CPLUS, RTK_8139CPLUS, "C+"},
87 { RTK_HWREV_8169, RTK_8169, "8169"},
88 { RTK_HWREV_8169S, RTK_8169, "8169S"},
89 { RTK_HWREV_8110S, RTK_8169, "8110S"},
90 { RTK_HWREV_8100, RTK_8139, "8100"},
91 { RTK_HWREV_8101, RTK_8139, "8101"},
92 { 0, 0, NULL }
93 };
94
95 CFATTACH_DECL(re_pci, sizeof(struct re_pci_softc), re_pci_probe, re_pci_attach,
96 NULL, NULL);
97
98 /*
99 * Probe for a RealTek 8139C+/8169/8110 chip. Check the PCI vendor and device
100 * IDs against our list and return a device name if we find a match.
101 */
102 static int
103 re_pci_probe(struct device *parent, struct cfdata *match, void *aux)
104 {
105 struct rtk_type *t;
106 struct pci_attach_args *pa = aux;
107 bus_space_tag_t rtk_btag;
108 bus_space_handle_t rtk_bhandle;
109 bus_size_t bsize;
110 u_int32_t hwrev;
111
112 t = re_devs;
113
114 while(t->rtk_name != NULL) {
115 if ((PCI_VENDOR(pa->pa_id) == t->rtk_vid) &&
116 (PCI_PRODUCT(pa->pa_id) == t->rtk_did)) {
117
118 /*
119 * Temporarily map the I/O space
120 * so we can read the chip ID register.
121 */
122 if (pci_mapreg_map(pa, RTK_PCI_LOIO,
123 PCI_MAPREG_TYPE_IO, 0, &rtk_btag,
124 &rtk_bhandle, NULL, &bsize)) {
125 printf("can't map i/o space\n");
126 return 0;
127 }
128 hwrev = bus_space_read_4(rtk_btag, rtk_bhandle,
129 RTK_TXCFG) & RTK_TXCFG_HWREV;
130 bus_space_unmap(rtk_btag, rtk_bhandle, bsize);
131 if (t->rtk_basetype == hwrev)
132 return 2; /* defeat rtk(4) */
133 }
134 t++;
135 }
136
137 return 0;
138 }
139
140 static void
141 re_pci_attach(struct device *parent, struct device *self, void *aux)
142 {
143 #if 0
144 u_char eaddr[ETHER_ADDR_LEN];
145 u_int16_t val;
146 struct rtk_hwrev *hw_rev;
147 int i, addr_len;
148 #endif
149 struct re_pci_softc *psc = (void *)self;
150 struct rtk_softc *sc = &psc->sc_rtk;
151 struct pci_attach_args *pa = aux;
152 pci_chipset_tag_t pc = pa->pa_pc;
153 pci_intr_handle_t ih;
154 const char *intrstr = NULL;
155 struct ifnet *ifp;
156 struct rtk_type *t;
157 struct rtk_hwrev *hw_rev;
158 int hwrev;
159 int error = 0;
160 pcireg_t command;
161
162
163 #if 0 /*ndef BURN_BRIDGES*/
164 /*
165 * Handle power management nonsense.
166 */
167
168 if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
169 u_int32_t iobase, membase, irq;
170
171 /* Save important PCI config data. */
172 iobase = pci_read_config(dev, RTK_PCI_LOIO, 4);
173 membase = pci_read_config(dev, RTK_PCI_LOMEM, 4);
174 irq = pci_read_config(dev, RTK_PCI_INTLINE, 4);
175
176 /* Reset the power state. */
177 printf("%s: chip is is in D%d power mode "
178 "-- setting to D0\n", unit,
179 pci_get_powerstate(dev));
180
181 pci_set_powerstate(dev, PCI_POWERSTATE_D0);
182
183 /* Restore PCI config data. */
184 pci_write_config(dev, RTK_PCI_LOIO, iobase, 4);
185 pci_write_config(dev, RTK_PCI_LOMEM, membase, 4);
186 pci_write_config(dev, RTK_PCI_INTLINE, irq, 4);
187 }
188 #endif
189 /*
190 * Map control/status registers.
191 */
192 command = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
193 command |= PCI_COMMAND_MASTER_ENABLE;
194 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, command);
195
196 #ifdef RE_USEIOSPACE
197 if (pci_mapreg_map(pa, RTK_PCI_LOIO, PCI_MAPREG_TYPE_IO, 0,
198 &sc->rtk_btag, &sc->rtk_bhandle, NULL, NULL)) {
199 printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname);
200 error = ENXIO;
201 goto fail;
202 }
203 #else
204 if (pci_mapreg_map(pa, RTK_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0,
205 &sc->rtk_btag, &sc->rtk_bhandle, NULL, NULL)) {
206 printf("%s: can't map mem space\n", sc->sc_dev.dv_xname);
207 error = ENXIO;
208 goto fail;
209 }
210 #endif
211 t = re_devs;
212 hwrev = CSR_READ_4(sc, RTK_TXCFG) & RTK_TXCFG_HWREV;
213
214 while(t->rtk_name != NULL) {
215 if ((PCI_VENDOR(pa->pa_id) == t->rtk_vid) &&
216 (PCI_PRODUCT(pa->pa_id) == t->rtk_did)) {
217
218 if (t->rtk_basetype == hwrev)
219 break;
220 }
221 t++;
222 }
223
224 hw_rev = re_hwrevs;
225 hwrev = CSR_READ_4(sc, RTK_TXCFG) & RTK_TXCFG_HWREV;
226 while (hw_rev->rtk_desc != NULL) {
227 if (hw_rev->rtk_rev == hwrev) {
228 sc->rtk_type = hw_rev->rtk_type;
229 break;
230 }
231 hw_rev++;
232 }
233
234 sc->sc_dmat = pa->pa_dmat;
235
236 /*
237 * No power/enable/disable machinery for PCI attac;
238 * mark the card enabled now.
239 */
240 sc->sc_flags |= RTK_ENABLED;
241
242 re_attach(sc);
243
244 ifp = &sc->ethercom.ec_if;
245
246 /* Hook interrupt last to avoid having to lock softc */
247 /* Allocate interrupt */
248 if (pci_intr_map(pa, &ih)) {
249 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
250 error = ENXIO;
251 ether_ifdetach(ifp);
252 if_detach(ifp);
253 goto fail;
254 }
255 intrstr = pci_intr_string(pc, ih);
256 psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, re_intr, sc);
257 if (psc->sc_ih == NULL) {
258 printf("%s: couldn't establish interrupt",
259 sc->sc_dev.dv_xname);
260 if (intrstr != NULL)
261 printf(" at %s", intrstr);
262 printf("\n");
263 ether_ifdetach(ifp);
264 if_detach(ifp);
265 return;
266 }
267 aprint_normal("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
268
269 fail:
270 #if 0
271 if (error)
272 re_detach(sc);
273 #endif
274 return;
275 }
276