if_re_cardbus.c revision 1.4 1 /* $NetBSD: if_re_cardbus.c,v 1.4 2005/01/15 12:32:09 kanaoka Exp $ */
2
3 /*
4 * Copyright (c) 2004 Jonathan Stone
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 /*
31 * if_re_cardbus.c:
32 * Cardbus specific routines for Realtek 8169 ethernet adapter.
33 * Tested for :
34 * Netgear GA-511 (8169S)
35 * Buffalo LPC-CB-CLGT
36 */
37
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: if_re_cardbus.c,v 1.4 2005/01/15 12:32:09 kanaoka Exp $");
40
41 #include "opt_inet.h"
42 #include "opt_ns.h"
43 #include "bpfilter.h"
44 #include "rnd.h"
45
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/callout.h>
49 #include <sys/device.h>
50 #include <sys/sockio.h>
51 #include <sys/mbuf.h>
52 #include <sys/malloc.h>
53 #include <sys/kernel.h>
54 #include <sys/socket.h>
55
56 #include <net/if.h>
57 #include <net/if_arp.h>
58 #include <net/if_ether.h>
59 #include <net/if_dl.h>
60 #include <net/if_media.h>
61 #ifdef INET
62 #include <netinet/in.h>
63 #include <netinet/if_inarp.h>
64 #endif
65 #ifdef NS
66 #include <netns/ns.h>
67 #include <netns/ns_if.h>
68 #endif
69
70 #if NBPFILTER > 0
71 #include <net/bpf.h>
72 #endif
73 #if NRND > 0
74 #include <sys/rnd.h>
75 #endif
76
77 #include <machine/bus.h>
78
79 #include <dev/pci/pcireg.h>
80 #include <dev/pci/pcivar.h>
81 #include <dev/pci/pcidevs.h>
82
83 #include <dev/cardbus/cardbusvar.h>
84 #include <dev/pci/pcidevs.h>
85
86 #include <dev/mii/mii.h>
87 #include <dev/mii/miivar.h>
88
89 /*
90 * Default to using PIO access for this driver. On SMP systems,
91 * there appear to be problems with memory mapped mode: it looks like
92 * doing too many memory mapped access back to back in rapid succession
93 * can hang the bus. I'm inclined to blame this on crummy design/construction
94 * on the part of Realtek. Memory mapped mode does appear to work on
95 * uniprocessor systems though.
96 */
97 #define RTK_USEIOSPACE
98
99 #include <dev/ic/rtl81x9reg.h>
100 #include <dev/ic/rtl81x9var.h>
101
102 #include <dev/ic/rtl8169var.h>
103
104 /*
105 * Various supported device vendors/types and their names.
106 */
107 static const struct rtk_type re_cardbus_devs[] = {
108 { PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8169,
109 RTK_8169, "Realtek 10/100/1000baseT" },
110 { 0, 0, 0, NULL }
111 };
112
113 static int re_cardbus_match(struct device *, struct cfdata *, void *);
114 static void re_cardbus_attach(struct device *, struct device *, void *);
115 static int re_cardbus_detach(struct device *, int);
116
117 struct re_cardbus_softc {
118 struct rtk_softc sc_rtk; /* real rtk softc */
119
120 /* CardBus-specific goo. */
121 void *sc_ih;
122 cardbus_devfunc_t sc_ct;
123 cardbustag_t sc_tag;
124 int sc_csr;
125 int sc_cben;
126 int sc_bar_reg;
127 pcireg_t sc_bar_val;
128 bus_size_t sc_mapsize;
129 int sc_intrline;
130 };
131
132 CFATTACH_DECL(re_cardbus, sizeof(struct re_cardbus_softc),
133 re_cardbus_match, re_cardbus_attach, re_cardbus_detach, re_activate);
134
135 const struct rtk_type *re_cardbus_lookup(const struct cardbus_attach_args *);
136
137 void re_cardbus_setup(struct re_cardbus_softc *);
138
139 int re_cardbus_enable(struct rtk_softc *);
140 void re_cardbus_disable(struct rtk_softc *);
141 void re_cardbus_power(struct rtk_softc *, int);
142
143 const struct rtk_type *
144 re_cardbus_lookup(const struct cardbus_attach_args *ca)
145 {
146 const struct rtk_type *t;
147
148 for (t = re_cardbus_devs; t->rtk_name != NULL; t++) {
149 if (CARDBUS_VENDOR(ca->ca_id) == t->rtk_vid &&
150 CARDBUS_PRODUCT(ca->ca_id) == t->rtk_did) {
151 return t;
152 }
153 }
154 return NULL;
155 }
156
157 int
158 re_cardbus_match(struct device *parent, struct cfdata *match, void *aux)
159 {
160 struct cardbus_attach_args *ca = aux;
161
162 if (re_cardbus_lookup(ca) != NULL)
163 return 1;
164
165 return 0;
166 }
167
168
169 void
170 re_cardbus_attach(struct device *parent, struct device *self, void *aux)
171 {
172 struct re_cardbus_softc *csc = (struct re_cardbus_softc *)self;
173 struct rtk_softc *sc = &csc->sc_rtk;
174 struct cardbus_attach_args *ca = aux;
175 cardbus_devfunc_t ct = ca->ca_ct;
176 const struct rtk_type *t;
177 bus_addr_t adr;
178
179 sc->sc_dmat = ca->ca_dmat;
180 csc->sc_ct = ct;
181 csc->sc_tag = ca->ca_tag;
182 csc->sc_intrline = ca->ca_intrline;
183
184 t = re_cardbus_lookup(ca);
185 if (t == NULL) {
186 aprint_error("\n");
187 panic("re_cardbus_attach: impossible");
188 }
189 aprint_normal(": %s\n", t->rtk_name);
190
191 /*
192 * Power management hooks.
193 */
194 sc->sc_enable = re_cardbus_enable;
195 sc->sc_disable = re_cardbus_disable;
196 sc->sc_power = re_cardbus_power;
197
198 /*
199 * Map control/status registers.
200 */
201 csc->sc_csr = CARDBUS_COMMAND_MASTER_ENABLE;
202 #ifdef RTK_USEIOSPACE
203 if (Cardbus_mapreg_map(ct, RTK_PCI_LOIO, CARDBUS_MAPREG_TYPE_IO, 0,
204 &sc->rtk_btag, &sc->rtk_bhandle, &adr, &csc->sc_mapsize) == 0) {
205 #if rbus
206 #else
207 (*ct->ct_cf->cardbus_io_open)(cc, 0, adr, adr+csc->sc_mapsize);
208 #endif
209 csc->sc_cben = CARDBUS_IO_ENABLE;
210 csc->sc_csr |= CARDBUS_COMMAND_IO_ENABLE;
211 csc->sc_bar_reg = RTK_PCI_LOIO;
212 csc->sc_bar_val = adr | CARDBUS_MAPREG_TYPE_IO;
213 }
214 #else
215 if (Cardbus_mapreg_map(ct, RTK_PCI_LOMEM, CARDBUS_MAPREG_TYPE_MEM, 0,
216 &sc->rtk_btag, &sc->rtk_bhandle, &adr, &csc->sc_mapsize) == 0) {
217 #if rbus
218 #else
219 (*ct->ct_cf->cardbus_mem_open)(cc, 0, adr, adr+csc->sc_mapsize);
220 #endif
221 csc->sc_cben = CARDBUS_MEM_ENABLE;
222 csc->sc_csr |= CARDBUS_COMMAND_MEM_ENABLE;
223 csc->sc_bar_reg = RTK_PCI_LOMEM;
224 csc->sc_bar_val = adr | CARDBUS_MAPREG_TYPE_MEM;
225 }
226 #endif
227 else {
228 aprint_error("%s: unable to map deviceregisters\n",
229 sc->sc_dev.dv_xname);
230 return;
231 }
232 /*
233 * Handle power management nonsense and initialize the
234 * configuration registers.
235 */
236 re_cardbus_setup(csc);
237
238 sc->rtk_type = t->rtk_basetype;
239 sc->sc_dmat = ca->ca_dmat;
240 re_attach(sc);
241
242 /*
243 * Power down the socket.
244 */
245 Cardbus_function_disable(csc->sc_ct);
246 }
247
248 int
249 re_cardbus_detach(struct device *self, int flags)
250 {
251 struct re_cardbus_softc *csc = (void *) self;
252 struct rtk_softc *sc = &csc->sc_rtk;
253 struct cardbus_devfunc *ct = csc->sc_ct;
254 int rv;
255
256 #ifdef DIAGNOSTIC
257 if (ct == NULL)
258 panic("%s: cardbus softc, cardbus_devfunc NULL",
259 sc->sc_dev.dv_xname);
260 #endif
261 rv = re_detach(sc);
262 if (rv)
263 return rv;
264 /*
265 * Unhook the interrupt handler.
266 */
267 if (csc->sc_ih != NULL)
268 cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, csc->sc_ih);
269
270 /*
271 * Release bus space and close window.
272 */
273 if (csc->sc_bar_reg != 0)
274 Cardbus_mapreg_unmap(ct, csc->sc_bar_reg,
275 sc->rtk_btag, sc->rtk_bhandle, csc->sc_mapsize);
276
277 return 0;
278 }
279
280 void
281 re_cardbus_setup(struct re_cardbus_softc *csc)
282 {
283 struct rtk_softc *sc = &csc->sc_rtk;
284 cardbus_devfunc_t ct = csc->sc_ct;
285 cardbus_chipset_tag_t cc = ct->ct_cc;
286 cardbus_function_tag_t cf = ct->ct_cf;
287 pcireg_t reg,command;
288 int pmreg;
289
290 /*
291 * Handle power management nonsense.
292 */
293 if (cardbus_get_capability(cc, cf, csc->sc_tag,
294 PCI_CAP_PWRMGMT, &pmreg, 0)) {
295 command = cardbus_conf_read(cc, cf, csc->sc_tag,
296 pmreg + PCI_PMCSR);
297 if (command & RTK_PSTATE_MASK) {
298 pcireg_t iobase, membase, irq;
299
300 /* Save important PCI config data. */
301 iobase = cardbus_conf_read(cc, cf, csc->sc_tag,
302 RTK_PCI_LOIO);
303 membase = cardbus_conf_read(cc, cf,csc->sc_tag,
304 RTK_PCI_LOMEM);
305 irq = cardbus_conf_read(cc, cf,csc->sc_tag,
306 CARDBUS_INTERRUPT_REG);
307
308 /* Reset the power state. */
309 aprint_normal("%s: chip is in D%d power mode "
310 "-- setting to D0\n", sc->sc_dev.dv_xname,
311 command & RTK_PSTATE_MASK);
312 command &= ~RTK_PSTATE_MASK;
313 cardbus_conf_write(cc, cf, csc->sc_tag,
314 pmreg + PCI_PMCSR, command);
315
316 /* Restore PCI config data. */
317 cardbus_conf_write(cc, cf, csc->sc_tag,
318 RTK_PCI_LOIO, iobase);
319 cardbus_conf_write(cc, cf, csc->sc_tag,
320 RTK_PCI_LOMEM, membase);
321 cardbus_conf_write(cc, cf, csc->sc_tag,
322 CARDBUS_INTERRUPT_REG, irq);
323 }
324 }
325
326 /* Program the BAR */
327 cardbus_conf_write(cc, cf, csc->sc_tag,
328 csc->sc_bar_reg, csc->sc_bar_val);
329
330 /* Make sure the right access type is on the CardBus bridge. */
331 (*ct->ct_cf->cardbus_ctrl)(cc, csc->sc_cben);
332 (*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
333
334 /* Enable the appropriate bits in the CARDBUS CSR. */
335 reg = cardbus_conf_read(cc, cf, csc->sc_tag,
336 CARDBUS_COMMAND_STATUS_REG);
337 reg &= ~(CARDBUS_COMMAND_IO_ENABLE|CARDBUS_COMMAND_MEM_ENABLE);
338 reg |= csc->sc_csr;
339 cardbus_conf_write(cc, cf, csc->sc_tag,
340 CARDBUS_COMMAND_STATUS_REG, reg);
341
342 /*
343 * Make sure the latency timer is set to some reasonable
344 * value.
345 */
346 reg = cardbus_conf_read(cc, cf, csc->sc_tag, CARDBUS_BHLC_REG);
347 if (CARDBUS_LATTIMER(reg) < 0x40) {
348 reg &= ~(CARDBUS_LATTIMER_MASK << CARDBUS_LATTIMER_SHIFT);
349 reg |= (0x40 << CARDBUS_LATTIMER_SHIFT);
350 cardbus_conf_write(cc, cf, csc->sc_tag, CARDBUS_BHLC_REG, reg);
351 }
352 }
353
354 int
355 re_cardbus_enable(struct rtk_softc *sc)
356 {
357 struct re_cardbus_softc *csc = (void *) sc;
358 cardbus_devfunc_t ct = csc->sc_ct;
359 cardbus_chipset_tag_t cc = ct->ct_cc;
360 cardbus_function_tag_t cf = ct->ct_cf;
361
362 /*
363 * Power on the socket.
364 */
365 Cardbus_function_enable(ct);
366
367 /*
368 * Set up the PCI configuration registers.
369 */
370 re_cardbus_setup(csc);
371
372 /*
373 * Map and establish the interrupt.
374 */
375 csc->sc_ih = cardbus_intr_establish(cc, cf, csc->sc_intrline,
376 IPL_NET, re_intr, sc);
377 if (csc->sc_ih == NULL) {
378 aprint_error("%s: unable to establish interrupt at %d\n",
379 sc->sc_dev.dv_xname, csc->sc_intrline);
380 Cardbus_function_disable(csc->sc_ct);
381 return 1;
382 }
383 aprint_normal("%s: interrupting at %d\n", sc->sc_dev.dv_xname,
384 csc->sc_intrline);
385 return 0;
386 }
387
388 void
389 re_cardbus_disable(struct rtk_softc *sc)
390 {
391 struct re_cardbus_softc *csc = (void *) sc;
392 cardbus_devfunc_t ct = csc->sc_ct;
393 cardbus_chipset_tag_t cc = ct->ct_cc;
394 cardbus_function_tag_t cf = ct->ct_cf;
395
396 /* Unhook the interrupt handler. */
397 cardbus_intr_disestablish(cc, cf, csc->sc_ih);
398 csc->sc_ih = NULL;
399
400 /* Power down the socket. */
401 Cardbus_function_disable(ct);
402 }
403
404 void
405 re_cardbus_power(struct rtk_softc *sc, int why)
406 {
407 struct re_cardbus_softc *csc = (void *) sc;
408
409 if (why == PWR_RESUME) {
410 /*
411 * Give the PCI configuration registers a kick
412 * in the head.
413 */
414 #ifdef DIAGNOSTIC
415 if (RTK_IS_ENABLED(sc) == 0)
416 panic("re_cardbus_power");
417 #endif
418 re_cardbus_setup(csc);
419 }
420 }
421