if_el.c revision 1.82 1 /* $NetBSD: if_el.c,v 1.82 2009/03/14 15:36:18 dsl Exp $ */
2
3 /*
4 * Copyright (c) 1994, Matthew E. Kimmel. Permission is hereby granted
5 * to use, copy, modify and distribute this software provided that both
6 * the copyright notice and this permission notice appear in all copies
7 * of the software, derivative works or modified versions, and any
8 * portions thereof.
9 */
10
11 /*
12 * 3COM Etherlink 3C501 device driver
13 */
14
15 /*
16 * Bugs/possible improvements:
17 * - Does not currently support DMA
18 * - Does not currently support multicasts
19 */
20
21 #include <sys/cdefs.h>
22 __KERNEL_RCSID(0, "$NetBSD: if_el.c,v 1.82 2009/03/14 15:36:18 dsl Exp $");
23
24 #include "opt_inet.h"
25 #include "bpfilter.h"
26 #include "rnd.h"
27
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/errno.h>
31 #include <sys/ioctl.h>
32 #include <sys/mbuf.h>
33 #include <sys/socket.h>
34 #include <sys/syslog.h>
35 #include <sys/device.h>
36 #if NRND > 0
37 #include <sys/rnd.h>
38 #endif
39
40 #include <net/if.h>
41 #include <net/if_dl.h>
42 #include <net/if_types.h>
43
44 #include <net/if_ether.h>
45
46 #ifdef INET
47 #include <netinet/in.h>
48 #include <netinet/in_systm.h>
49 #include <netinet/in_var.h>
50 #include <netinet/ip.h>
51 #include <netinet/if_inarp.h>
52 #endif
53
54
55 #if NBPFILTER > 0
56 #include <net/bpf.h>
57 #include <net/bpfdesc.h>
58 #endif
59
60 #include <sys/cpu.h>
61 #include <sys/intr.h>
62 #include <sys/bus.h>
63
64 #include <dev/isa/isavar.h>
65 #include <dev/isa/if_elreg.h>
66
67 /* for debugging convenience */
68 #ifdef EL_DEBUG
69 #define DPRINTF(x) printf x
70 #else
71 #define DPRINTF(x)
72 #endif
73
74 /*
75 * per-line info and status
76 */
77 struct el_softc {
78 struct device sc_dev;
79 void *sc_ih;
80
81 struct ethercom sc_ethercom; /* ethernet common */
82 bus_space_tag_t sc_iot; /* bus space identifier */
83 bus_space_handle_t sc_ioh; /* i/o handle */
84
85 #if NRND > 0
86 rndsource_element_t rnd_source;
87 #endif
88 };
89
90 /*
91 * prototypes
92 */
93 int elintr(void *);
94 void elinit(struct el_softc *);
95 int elioctl(struct ifnet *, u_long, void *);
96 void elstart(struct ifnet *);
97 void elwatchdog(struct ifnet *);
98 void elreset(struct el_softc *);
99 void elstop(struct el_softc *);
100 static int el_xmit(struct el_softc *);
101 void elread(struct el_softc *, int);
102 struct mbuf *elget(struct el_softc *sc, int);
103 static inline void el_hardreset(struct el_softc *);
104
105 int elprobe(struct device *, struct cfdata *, void *);
106 void elattach(struct device *, struct device *, void *);
107
108 CFATTACH_DECL(el, sizeof(struct el_softc),
109 elprobe, elattach, NULL, NULL);
110
111 /*
112 * Probe routine.
113 *
114 * See if the card is there and at the right place.
115 * (XXX - cgd -- needs help)
116 */
117 int
118 elprobe(struct device *parent, struct cfdata *match,
119 void *aux)
120 {
121 struct isa_attach_args *ia = aux;
122 bus_space_tag_t iot = ia->ia_iot;
123 bus_space_handle_t ioh;
124 int iobase;
125 u_int8_t station_addr[ETHER_ADDR_LEN];
126 u_int8_t i;
127 int rval;
128
129 rval = 0;
130
131 if (ia->ia_nio < 1)
132 return (0);
133 if (ia->ia_nirq < 1)
134 return (0);
135
136 if (ISA_DIRECT_CONFIG(ia))
137 return (0);
138
139 iobase = ia->ia_io[0].ir_addr;
140
141 if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT)
142 return (0);
143 if (ia->ia_irq[0].ir_irq == ISA_UNKNOWN_IRQ)
144 return (0);
145
146 /* First check the base. */
147 if (iobase < 0x200 || iobase > 0x3f0)
148 return 0;
149
150 /* Map i/o space. */
151 if (bus_space_map(iot, iobase, 16, 0, &ioh))
152 return 0;
153
154 /*
155 * Now attempt to grab the station address from the PROM and see if it
156 * contains the 3com vendor code.
157 */
158 DPRINTF(("Probing 3c501 at 0x%x...\n", iobase));
159
160 /* Reset the board. */
161 DPRINTF(("Resetting board...\n"));
162 bus_space_write_1(iot, ioh, EL_AC, EL_AC_RESET);
163 delay(5);
164 bus_space_write_1(iot, ioh, EL_AC, 0);
165
166 /* Now read the address. */
167 DPRINTF(("Reading station address...\n"));
168 for (i = 0; i < ETHER_ADDR_LEN; i++) {
169 bus_space_write_1(iot, ioh, EL_GPBL, i);
170 station_addr[i] = bus_space_read_1(iot, ioh, EL_EAW);
171 }
172 DPRINTF(("Address is %s\n", ether_sprintf(station_addr)));
173
174 /*
175 * If the vendor code is ok, return a 1. We'll assume that whoever
176 * configured this system is right about the IRQ.
177 */
178 if (station_addr[0] != 0x02 || station_addr[1] != 0x60 ||
179 station_addr[2] != 0x8c) {
180 DPRINTF(("Bad vendor code.\n"));
181 goto out;
182 }
183 DPRINTF(("Vendor code ok.\n"));
184
185 ia->ia_nio = 1;
186 ia->ia_io[0].ir_size = 16;
187
188 ia->ia_nirq = 1;
189
190 ia->ia_niomem = 0;
191 ia->ia_ndrq = 0;
192
193 rval = 1;
194
195 out:
196 bus_space_unmap(iot, ioh, 16);
197 return rval;
198 }
199
200 /*
201 * Attach the interface to the kernel data structures. By the time this is
202 * called, we know that the card exists at the given I/O address. We still
203 * assume that the IRQ given is correct.
204 */
205 void
206 elattach(struct device *parent, struct device *self, void *aux)
207 {
208 struct el_softc *sc = (void *)self;
209 struct isa_attach_args *ia = aux;
210 bus_space_tag_t iot = ia->ia_iot;
211 bus_space_handle_t ioh;
212 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
213 u_int8_t myaddr[ETHER_ADDR_LEN];
214 u_int8_t i;
215
216 printf("\n");
217
218 DPRINTF(("Attaching %s...\n", device_xname(&sc->sc_dev)));
219
220 /* Map i/o space. */
221 if (bus_space_map(iot, ia->ia_io[0].ir_addr, 16, 0, &ioh)) {
222 aprint_error_dev(self, "can't map i/o space\n");
223 return;
224 }
225
226 sc->sc_iot = iot;
227 sc->sc_ioh = ioh;
228
229 /* Reset the board. */
230 bus_space_write_1(iot, ioh, EL_AC, EL_AC_RESET);
231 delay(5);
232 bus_space_write_1(iot, ioh, EL_AC, 0);
233
234 /* Now read the address. */
235 for (i = 0; i < ETHER_ADDR_LEN; i++) {
236 bus_space_write_1(iot, ioh, EL_GPBL, i);
237 myaddr[i] = bus_space_read_1(iot, ioh, EL_EAW);
238 }
239
240 /* Stop the board. */
241 elstop(sc);
242
243 /* Initialize ifnet structure. */
244 strlcpy(ifp->if_xname, device_xname(&sc->sc_dev), IFNAMSIZ);
245 ifp->if_softc = sc;
246 ifp->if_start = elstart;
247 ifp->if_ioctl = elioctl;
248 ifp->if_watchdog = elwatchdog;
249 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
250 IFQ_SET_READY(&ifp->if_snd);
251
252 /* Now we can attach the interface. */
253 DPRINTF(("Attaching interface...\n"));
254 if_attach(ifp);
255 ether_ifattach(ifp, myaddr);
256
257 /* Print out some information for the user. */
258 printf("%s: address %s\n", device_xname(self), ether_sprintf(myaddr));
259
260 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
261 IST_EDGE, IPL_NET, elintr, sc);
262
263 #if NRND > 0
264 DPRINTF(("Attaching to random...\n"));
265 rnd_attach_source(&sc->rnd_source, device_xname(&sc->sc_dev),
266 RND_TYPE_NET, 0);
267 #endif
268
269 DPRINTF(("elattach() finished.\n"));
270 }
271
272 /*
273 * Reset interface.
274 */
275 void
276 elreset(struct el_softc *sc)
277 {
278 int s;
279
280 DPRINTF(("elreset()\n"));
281 s = splnet();
282 elstop(sc);
283 elinit(sc);
284 splx(s);
285 }
286
287 /*
288 * Stop interface.
289 */
290 void
291 elstop(struct el_softc *sc)
292 {
293
294 bus_space_write_1(sc->sc_iot, sc->sc_ioh, EL_AC, 0);
295 }
296
297 /*
298 * Do a hardware reset of the board, and upload the ethernet address again in
299 * case the board forgets.
300 */
301 static inline void
302 el_hardreset(struct el_softc *sc)
303 {
304 bus_space_tag_t iot = sc->sc_iot;
305 bus_space_handle_t ioh = sc->sc_ioh;
306 int i;
307
308 bus_space_write_1(iot, ioh, EL_AC, EL_AC_RESET);
309 delay(5);
310 bus_space_write_1(iot, ioh, EL_AC, 0);
311
312 for (i = 0; i < ETHER_ADDR_LEN; i++)
313 bus_space_write_1(iot, ioh, i,
314 CLLADDR(sc->sc_ethercom.ec_if.if_sadl)[i]);
315 }
316
317 /*
318 * Initialize interface.
319 */
320 void
321 elinit(struct el_softc *sc)
322 {
323 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
324 bus_space_tag_t iot = sc->sc_iot;
325 bus_space_handle_t ioh = sc->sc_ioh;
326
327 /* First, reset the board. */
328 el_hardreset(sc);
329
330 /* Configure rx. */
331 DPRINTF(("Configuring rx...\n"));
332 if (ifp->if_flags & IFF_PROMISC)
333 bus_space_write_1(iot, ioh, EL_RXC,
334 EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB |
335 EL_RXC_DOFLOW | EL_RXC_PROMISC);
336 else
337 bus_space_write_1(iot, ioh, EL_RXC,
338 EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB |
339 EL_RXC_DOFLOW | EL_RXC_ABROAD);
340 bus_space_write_1(iot, ioh, EL_RBC, 0);
341
342 /* Configure TX. */
343 DPRINTF(("Configuring tx...\n"));
344 bus_space_write_1(iot, ioh, EL_TXC, 0);
345
346 /* Start reception. */
347 DPRINTF(("Starting reception...\n"));
348 bus_space_write_1(iot, ioh, EL_AC, EL_AC_IRQE | EL_AC_RX);
349
350 /* Set flags appropriately. */
351 ifp->if_flags |= IFF_RUNNING;
352 ifp->if_flags &= ~IFF_OACTIVE;
353
354 /* And start output. */
355 elstart(ifp);
356 }
357
358 /*
359 * Start output on interface. Get datagrams from the queue and output them,
360 * giving the receiver a chance between datagrams. Call only from splnet or
361 * interrupt level!
362 */
363 void
364 elstart(struct ifnet *ifp)
365 {
366 struct el_softc *sc = ifp->if_softc;
367 bus_space_tag_t iot = sc->sc_iot;
368 bus_space_handle_t ioh = sc->sc_ioh;
369 struct mbuf *m, *m0;
370 int s, i, off, retries;
371
372 DPRINTF(("elstart()...\n"));
373 s = splnet();
374
375 /* Don't do anything if output is active. */
376 if ((ifp->if_flags & IFF_OACTIVE) != 0) {
377 splx(s);
378 return;
379 }
380
381 ifp->if_flags |= IFF_OACTIVE;
382
383 /*
384 * The main loop. They warned me against endless loops, but would I
385 * listen? NOOO....
386 */
387 for (;;) {
388 /* Dequeue the next datagram. */
389 IFQ_DEQUEUE(&ifp->if_snd, m0);
390
391 /* If there's nothing to send, return. */
392 if (m0 == 0)
393 break;
394
395 #if NBPFILTER > 0
396 /* Give the packet to the bpf, if any. */
397 if (ifp->if_bpf)
398 bpf_mtap(ifp->if_bpf, m0);
399 #endif
400
401 /* Disable the receiver. */
402 bus_space_write_1(iot, ioh, EL_AC, EL_AC_HOST);
403 bus_space_write_1(iot, ioh, EL_RBC, 0);
404
405 /* Transfer datagram to board. */
406 DPRINTF(("el: xfr pkt length=%d...\n", m0->m_pkthdr.len));
407 off = EL_BUFSIZ - max(m0->m_pkthdr.len,
408 ETHER_MIN_LEN - ETHER_CRC_LEN);
409 #ifdef DIAGNOSTIC
410 if ((off & 0xffff) != off)
411 printf("%s: bogus off 0x%x\n",
412 device_xname(&sc->sc_dev), off);
413 #endif
414 bus_space_write_1(iot, ioh, EL_GPBL, off & 0xff);
415 bus_space_write_1(iot, ioh, EL_GPBH, (off >> 8) & 0xff);
416
417 /* Copy the datagram to the buffer. */
418 for (m = m0; m != 0; m = m->m_next)
419 bus_space_write_multi_1(iot, ioh, EL_BUF,
420 mtod(m, u_int8_t *), m->m_len);
421 for (i = 0;
422 i < ETHER_MIN_LEN - ETHER_CRC_LEN - m0->m_pkthdr.len; i++)
423 bus_space_write_1(iot, ioh, EL_BUF, 0);
424
425 m_freem(m0);
426
427 /* Now transmit the datagram. */
428 retries = 0;
429 for (;;) {
430 bus_space_write_1(iot, ioh, EL_GPBL, off & 0xff);
431 bus_space_write_1(iot, ioh, EL_GPBH, (off >> 8) & 0xff);
432 if (el_xmit(sc)) {
433 ifp->if_oerrors++;
434 break;
435 }
436 /* Check out status. */
437 i = bus_space_read_1(iot, ioh, EL_TXS);
438 DPRINTF(("tx status=0x%x\n", i));
439 if ((i & EL_TXS_READY) == 0) {
440 DPRINTF(("el: err txs=%x\n", i));
441 if (i & (EL_TXS_COLL | EL_TXS_COLL16)) {
442 ifp->if_collisions++;
443 if ((i & EL_TXC_DCOLL16) == 0 &&
444 retries < 15) {
445 retries++;
446 bus_space_write_1(iot, ioh,
447 EL_AC, EL_AC_HOST);
448 }
449 } else {
450 ifp->if_oerrors++;
451 break;
452 }
453 } else {
454 ifp->if_opackets++;
455 break;
456 }
457 }
458
459 /*
460 * Now give the card a chance to receive.
461 * Gotta love 3c501s...
462 */
463 (void)bus_space_read_1(iot, ioh, EL_AS);
464 bus_space_write_1(iot, ioh, EL_AC, EL_AC_IRQE | EL_AC_RX);
465 splx(s);
466 /* Interrupt here. */
467 s = splnet();
468 }
469
470 (void)bus_space_read_1(iot, ioh, EL_AS);
471 bus_space_write_1(iot, ioh, EL_AC, EL_AC_IRQE | EL_AC_RX);
472 ifp->if_flags &= ~IFF_OACTIVE;
473 splx(s);
474 }
475
476 /*
477 * This function actually attempts to transmit a datagram downloaded to the
478 * board. Call at splnet or interrupt, after downloading data! Returns 0 on
479 * success, non-0 on failure.
480 */
481 static int
482 el_xmit(struct el_softc *sc)
483 {
484 bus_space_tag_t iot = sc->sc_iot;
485 bus_space_handle_t ioh = sc->sc_ioh;
486 int i;
487
488 /*
489 * XXX
490 * This busy-waits for the tx completion. Can we get an interrupt
491 * instead?
492 */
493
494 DPRINTF(("el: xmit..."));
495 bus_space_write_1(iot, ioh, EL_AC, EL_AC_TXFRX);
496 i = 20000;
497 while ((bus_space_read_1(iot, ioh, EL_AS) & EL_AS_TXBUSY) && (i > 0))
498 i--;
499 if (i == 0) {
500 DPRINTF(("tx not ready\n"));
501 return -1;
502 }
503 DPRINTF(("%d cycles.\n", 20000 - i));
504 return 0;
505 }
506
507 /*
508 * Controller interrupt.
509 */
510 int
511 elintr(void *arg)
512 {
513 struct el_softc *sc = arg;
514 bus_space_tag_t iot = sc->sc_iot;
515 bus_space_handle_t ioh = sc->sc_ioh;
516 u_int8_t rxstat;
517 int len;
518
519 DPRINTF(("elintr: "));
520
521 /* Check board status. */
522 if ((bus_space_read_1(iot, ioh, EL_AS) & EL_AS_RXBUSY) != 0) {
523 (void)bus_space_read_1(iot, ioh, EL_RXC);
524 bus_space_write_1(iot, ioh, EL_AC, EL_AC_IRQE | EL_AC_RX);
525 return 0;
526 }
527
528 for (;;) {
529 rxstat = bus_space_read_1(iot, ioh, EL_RXS);
530 if (rxstat & EL_RXS_STALE)
531 break;
532
533 /* If there's an overflow, reinit the board. */
534 if ((rxstat & EL_RXS_NOFLOW) == 0) {
535 DPRINTF(("overflow.\n"));
536 el_hardreset(sc);
537 /* Put board back into receive mode. */
538 if (sc->sc_ethercom.ec_if.if_flags & IFF_PROMISC)
539 bus_space_write_1(iot, ioh, EL_RXC,
540 EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB |
541 EL_RXC_DOFLOW | EL_RXC_PROMISC);
542 else
543 bus_space_write_1(iot, ioh, EL_RXC,
544 EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB |
545 EL_RXC_DOFLOW | EL_RXC_ABROAD);
546 (void)bus_space_read_1(iot, ioh, EL_AS);
547 bus_space_write_1(iot, ioh, EL_RBC, 0);
548 break;
549 }
550
551 /* Incoming packet. */
552 len = bus_space_read_1(iot, ioh, EL_RBL);
553 len |= bus_space_read_1(iot, ioh, EL_RBH) << 8;
554 DPRINTF(("receive len=%d rxstat=%x ", len, rxstat));
555 bus_space_write_1(iot, ioh, EL_AC, EL_AC_HOST);
556
557 /* Pass data up to upper levels. */
558 elread(sc, len);
559
560 /* Is there another packet? */
561 if ((bus_space_read_1(iot, ioh, EL_AS) & EL_AS_RXBUSY) != 0)
562 break;
563
564 #if NRND > 0
565 rnd_add_uint32(&sc->rnd_source, rxstat);
566 #endif
567
568 DPRINTF(("<rescan> "));
569 }
570
571 (void)bus_space_read_1(iot, ioh, EL_RXC);
572 bus_space_write_1(iot, ioh, EL_AC, EL_AC_IRQE | EL_AC_RX);
573 return 1;
574 }
575
576 /*
577 * Pass a packet to the higher levels.
578 */
579 void
580 elread(struct el_softc *sc, int len)
581 {
582 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
583 struct mbuf *m;
584
585 if (len <= sizeof(struct ether_header) ||
586 len > ETHER_MAX_LEN) {
587 printf("%s: invalid packet size %d; dropping\n",
588 device_xname(&sc->sc_dev), len);
589 ifp->if_ierrors++;
590 return;
591 }
592
593 /* Pull packet off interface. */
594 m = elget(sc, len);
595 if (m == 0) {
596 ifp->if_ierrors++;
597 return;
598 }
599
600 ifp->if_ipackets++;
601
602 #if NBPFILTER > 0
603 /*
604 * Check if there's a BPF listener on this interface.
605 * If so, hand off the raw packet to BPF.
606 */
607 if (ifp->if_bpf)
608 bpf_mtap(ifp->if_bpf, m);
609 #endif
610
611 (*ifp->if_input)(ifp, m);
612 }
613
614 /*
615 * Pull read data off a interface. Len is length of data, with local net
616 * header stripped. We copy the data into mbufs. When full cluster sized
617 * units are present we copy into clusters.
618 */
619 struct mbuf *
620 elget(struct el_softc *sc, int totlen)
621 {
622 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
623 bus_space_tag_t iot = sc->sc_iot;
624 bus_space_handle_t ioh = sc->sc_ioh;
625 struct mbuf *m, *m0, *newm;
626 int len;
627
628 MGETHDR(m0, M_DONTWAIT, MT_DATA);
629 if (m0 == 0)
630 return (0);
631 m0->m_pkthdr.rcvif = ifp;
632 m0->m_pkthdr.len = totlen;
633 len = MHLEN;
634 m = m0;
635
636 bus_space_write_1(iot, ioh, EL_GPBL, 0);
637 bus_space_write_1(iot, ioh, EL_GPBH, 0);
638
639 while (totlen > 0) {
640 if (totlen >= MINCLSIZE) {
641 MCLGET(m, M_DONTWAIT);
642 if ((m->m_flags & M_EXT) == 0)
643 goto bad;
644 len = MCLBYTES;
645 }
646
647 m->m_len = len = min(totlen, len);
648 bus_space_read_multi_1(iot, ioh, EL_BUF, mtod(m, u_int8_t *), len);
649
650 totlen -= len;
651 if (totlen > 0) {
652 MGET(newm, M_DONTWAIT, MT_DATA);
653 if (newm == 0)
654 goto bad;
655 len = MLEN;
656 m = m->m_next = newm;
657 }
658 }
659
660 bus_space_write_1(iot, ioh, EL_RBC, 0);
661 bus_space_write_1(iot, ioh, EL_AC, EL_AC_RX);
662
663 return (m0);
664
665 bad:
666 m_freem(m0);
667 return (0);
668 }
669
670 /*
671 * Process an ioctl request. This code needs some work - it looks pretty ugly.
672 */
673 int
674 elioctl(struct ifnet *ifp, u_long cmd, void *data)
675 {
676 struct el_softc *sc = ifp->if_softc;
677 struct ifaddr *ifa = (struct ifaddr *)data;
678 int s, error = 0;
679
680 s = splnet();
681
682 switch (cmd) {
683
684 case SIOCINITIFADDR:
685 ifp->if_flags |= IFF_UP;
686
687 elinit(sc);
688 switch (ifa->ifa_addr->sa_family) {
689 #ifdef INET
690 case AF_INET:
691 arp_ifinit(ifp, ifa);
692 break;
693 #endif
694 default:
695 break;
696 }
697 break;
698
699 case SIOCSIFFLAGS:
700 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
701 break;
702 /* XXX re-use ether_ioctl() */
703 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
704 case IFF_RUNNING:
705 /*
706 * If interface is marked down and it is running, then
707 * stop it.
708 */
709 elstop(sc);
710 ifp->if_flags &= ~IFF_RUNNING;
711 break;
712 case IFF_UP:
713 /*
714 * If interface is marked up and it is stopped, then
715 * start it.
716 */
717 elinit(sc);
718 break;
719 default:
720 /*
721 * Some other important flag might have changed, so
722 * reset.
723 */
724 elreset(sc);
725 break;
726 }
727 break;
728
729 default:
730 error = ether_ioctl(ifp, cmd, data);
731 break;
732 }
733
734 splx(s);
735 return error;
736 }
737
738 /*
739 * Device timeout routine.
740 */
741 void
742 elwatchdog(struct ifnet *ifp)
743 {
744 struct el_softc *sc = ifp->if_softc;
745
746 log(LOG_ERR, "%s: device timeout\n", device_xname(&sc->sc_dev));
747 sc->sc_ethercom.ec_if.if_oerrors++;
748
749 elreset(sc);
750 }
751