if_el.c revision 1.16 1 /* $NetBSD: if_el.c,v 1.16 1994/11/03 23:14:53 mycroft 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 "bpfilter.h"
22
23 #include <sys/param.h>
24 #include <sys/errno.h>
25 #include <sys/ioctl.h>
26 #include <sys/mbuf.h>
27 #include <sys/socket.h>
28 #include <sys/syslog.h>
29 #include <sys/device.h>
30
31 #include <net/if.h>
32 #include <net/if_dl.h>
33 #include <net/if_types.h>
34
35 #ifdef INET
36 #include <netinet/in.h>
37 #include <netinet/in_systm.h>
38 #include <netinet/in_var.h>
39 #include <netinet/ip.h>
40 #include <netinet/if_ether.h>
41 #endif
42
43 #ifdef NS
44 #include <netns/ns.h>
45 #include <netns/ns_if.h>
46 #endif
47
48 #if NBPFILTER > 0
49 #include <net/bpf.h>
50 #include <net/bpfdesc.h>
51 #endif
52
53 #include <machine/cpu.h>
54 #include <machine/pio.h>
55
56 #include <i386/isa/isavar.h>
57 #include <i386/isa/icu.h>
58 #include <i386/isa/if_elreg.h>
59
60 #define ETHER_MIN_LEN 64
61 #define ETHER_MAX_LEN 1518
62 #define ETHER_ADDR_LEN 6
63
64 /* for debugging convenience */
65 #ifdef EL_DEBUG
66 #define dprintf(x) printf x
67 #else
68 #define dprintf(x)
69 #endif
70
71 /*
72 * per-line info and status
73 */
74 struct el_softc {
75 struct device sc_dev;
76 struct intrhand sc_ih;
77
78 struct arpcom sc_arpcom; /* ethernet common */
79 u_short sc_iobase; /* base I/O addr */
80 char sc_pktbuf[EL_BUFSIZ]; /* frame buffer */
81 };
82
83 /*
84 * prototypes
85 */
86 int elintr __P((struct el_softc *));
87 static int el_init __P((struct el_softc *));
88 static int el_ioctl __P((struct ifnet *, u_long, caddr_t));
89 static int el_start __P((struct ifnet *));
90 static int el_watchdog __P((int));
91 static void el_reset __P((struct el_softc *));
92 static void el_stop __P((struct el_softc *));
93 static int el_xmit __P((struct el_softc *, int));
94 static inline void elread __P((struct el_softc *, caddr_t, int));
95 static struct mbuf *elget __P((caddr_t, int, struct ifnet *));
96 static inline void el_hardreset __P((struct el_softc *));
97
98 int elprobe __P((struct device *, void *, void *));
99 void elattach __P((struct device *, struct device *, void *));
100
101 /* isa_driver structure for autoconf */
102 struct cfdriver elcd = {
103 NULL, "el", elprobe, elattach, DV_IFNET, sizeof(struct el_softc)
104 };
105
106 /*
107 * Probe routine.
108 *
109 * See if the card is there and at the right place.
110 * (XXX - cgd -- needs help)
111 */
112 int
113 elprobe(parent, match, aux)
114 struct device *parent;
115 void *match, *aux;
116 {
117 struct el_softc *sc = match;
118 struct isa_attach_args *ia = aux;
119 u_short iobase = ia->ia_iobase;
120 u_char station_addr[ETHER_ADDR_LEN];
121 int i;
122
123 /* First check the base. */
124 if (iobase < 0x280 || iobase > 0x3f0)
125 return 0;
126
127 /* Grab some info for our structure. */
128 sc->sc_iobase = iobase;
129
130 /*
131 * Now attempt to grab the station address from the PROM and see if it
132 * contains the 3com vendor code.
133 */
134 dprintf(("Probing 3c501 at 0x%x...\n", iobase));
135
136 /* Reset the board. */
137 dprintf(("Resetting board...\n"));
138 outb(iobase+EL_AC, EL_AC_RESET);
139 delay(5);
140 outb(iobase+EL_AC, 0);
141
142 /* Now read the address. */
143 dprintf(("Reading station address...\n"));
144 for (i = 0; i < ETHER_ADDR_LEN; i++) {
145 outb(iobase+EL_GPBL, i);
146 station_addr[i] = inb(iobase+EL_EAW);
147 }
148 dprintf(("Address is %s\n", ether_sprintf(station_addr)));
149
150 /*
151 * If the vendor code is ok, return a 1. We'll assume that whoever
152 * configured this system is right about the IRQ.
153 */
154 if (station_addr[0] != 0x02 || station_addr[1] != 0x60 ||
155 station_addr[2] != 0x8c) {
156 dprintf(("Bad vendor code.\n"));
157 return 0;
158 }
159
160 dprintf(("Vendor code ok.\n"));
161 /* Copy the station address into the arpcom structure. */
162 bcopy(station_addr, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
163
164 ia->ia_iosize = 4; /* XXX */
165 ia->ia_msize = 0;
166 return 1;
167 }
168
169 /*
170 * Attach the interface to the kernel data structures. By the time this is
171 * called, we know that the card exists at the given I/O address. We still
172 * assume that the IRQ given is correct.
173 */
174 void
175 elattach(parent, self, aux)
176 struct device *parent, *self;
177 void *aux;
178 {
179 struct el_softc *sc = (void *)self;
180 struct isa_attach_args *ia = aux;
181 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
182
183 dprintf(("Attaching %s...\n", sc->sc_dev.dv_xname));
184
185 /* Stop the board. */
186 el_stop(sc);
187
188 /* Initialize ifnet structure. */
189 ifp->if_unit = sc->sc_dev.dv_unit;
190 ifp->if_name = elcd.cd_name;
191 ifp->if_output = ether_output;
192 ifp->if_start = el_start;
193 ifp->if_ioctl = el_ioctl;
194 ifp->if_watchdog = el_watchdog;
195 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
196
197 /* Now we can attach the interface. */
198 dprintf(("Attaching interface...\n"));
199 if_attach(ifp);
200 ether_ifattach(ifp);
201
202 /* Print out some information for the user. */
203 printf("%s: address %s\n", sc->sc_dev.dv_xname,
204 ether_sprintf(sc->sc_arpcom.ac_enaddr));
205
206 /* Finally, attach to bpf filter if it is present. */
207 #if NBPFILTER > 0
208 dprintf(("Attaching to BPF...\n"));
209 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
210 #endif
211
212 sc->sc_ih.ih_fun = elintr;
213 sc->sc_ih.ih_arg = sc;
214 sc->sc_ih.ih_level = IPL_NET;
215 intr_establish(ia->ia_irq, &sc->sc_ih);
216
217 dprintf(("elattach() finished.\n"));
218 }
219
220 /*
221 * Reset interface.
222 */
223 static void
224 el_reset(sc)
225 struct el_softc *sc;
226 {
227 int s;
228
229 dprintf(("elreset()\n"));
230 s = splimp();
231 el_stop(sc);
232 el_init(sc);
233 splx(s);
234 }
235
236 /*
237 * Stop interface.
238 */
239 static void
240 el_stop(sc)
241 struct el_softc *sc;
242 {
243
244 outb(sc->sc_iobase+EL_AC, 0);
245 }
246
247 /*
248 * Do a hardware reset of the board, and upload the ethernet address again in
249 * case the board forgets.
250 */
251 static inline void
252 el_hardreset(sc)
253 struct el_softc *sc;
254 {
255 u_short iobase = sc->sc_iobase;
256 int i;
257
258 outb(iobase+EL_AC, EL_AC_RESET);
259 delay(5);
260 outb(iobase+EL_AC, 0);
261
262 for (i = 0; i < ETHER_ADDR_LEN; i++)
263 outb(iobase+i, sc->sc_arpcom.ac_enaddr[i]);
264 }
265
266 /*
267 * Initialize interface.
268 */
269 static int
270 el_init(sc)
271 struct el_softc *sc;
272 {
273 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
274 u_short iobase = sc->sc_iobase;
275 int s;
276
277 /* If address not known, do nothing. */
278 if (ifp->if_addrlist == 0)
279 return;
280
281 s = splimp();
282
283 /* First, reset the board. */
284 el_hardreset(sc);
285
286 /* Configure rx. */
287 dprintf(("Configuring rx...\n"));
288 if (ifp->if_flags & IFF_PROMISC)
289 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_PROMISC);
290 else
291 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_ABROAD);
292 outb(iobase+EL_RBC, 0);
293
294 /* Configure TX. */
295 dprintf(("Configuring tx...\n"));
296 outb(iobase+EL_TXC, 0);
297
298 /* Start reception. */
299 dprintf(("Starting reception...\n"));
300 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX);
301
302 /* Set flags appropriately. */
303 ifp->if_flags |= IFF_RUNNING;
304 ifp->if_flags &= ~IFF_OACTIVE;
305
306 /* And start output. */
307 el_start(ifp);
308
309 splx(s);
310 }
311
312 /*
313 * Start output on interface. Get datagrams from the queue and output them,
314 * giving the receiver a chance between datagrams. Call only from splimp or
315 * interrupt level!
316 */
317 static int
318 el_start(ifp)
319 struct ifnet *ifp;
320 {
321 struct el_softc *sc = elcd.cd_devs[ifp->if_unit];
322 u_short iobase = sc->sc_iobase;
323 struct mbuf *m, *m0;
324 int s, i, len, retries, done;
325
326 dprintf(("el_start()...\n"));
327 s = splimp();
328
329 /* Don't do anything if output is active. */
330 if (sc->sc_arpcom.ac_if.if_flags & IFF_OACTIVE)
331 return;
332 sc->sc_arpcom.ac_if.if_flags |= IFF_OACTIVE;
333
334 /*
335 * The main loop. They warned me against endless loops, but would I
336 * listen? NOOO....
337 */
338 for (;;) {
339 /* Dequeue the next datagram. */
340 IF_DEQUEUE(&sc->sc_arpcom.ac_if.if_snd, m0);
341
342 /* If there's nothing to send, return. */
343 if (!m0) {
344 sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
345 splx(s);
346 return;
347 }
348
349 /* Disable the receiver. */
350 outb(iobase+EL_AC, EL_AC_HOST);
351 outb(iobase+EL_RBC, 0);
352
353 /* Copy the datagram to the buffer. */
354 len = 0;
355 for (m = m0; m; m = m->m_next) {
356 if (m->m_len == 0)
357 continue;
358 bcopy(mtod(m, caddr_t), sc->sc_pktbuf + len, m->m_len);
359 len += m->m_len;
360 }
361 m_freem(m0);
362
363 len = max(len, ETHER_MIN_LEN);
364
365 /* Give the packet to the bpf, if any. */
366 #if NBPFILTER > 0
367 if (sc->sc_arpcom.ac_if.if_bpf)
368 bpf_tap(sc->sc_arpcom.ac_if.if_bpf, sc->sc_pktbuf, len);
369 #endif
370
371 /* Transfer datagram to board. */
372 dprintf(("el: xfr pkt length=%d...\n", len));
373 i = EL_BUFSIZ - len;
374 outb(iobase+EL_GPBL, i);
375 outb(iobase+EL_GPBH, i >> 8);
376 outsb(iobase+EL_BUF, sc->sc_pktbuf, len);
377
378 /* Now transmit the datagram. */
379 retries = 0;
380 done = 0;
381 while (!done) {
382 if (el_xmit(sc, len)) {
383 /* Something went wrong. */
384 done = -1;
385 break;
386 }
387 /* Check out status. */
388 i = inb(iobase+EL_TXS);
389 dprintf(("tx status=0x%x\n", i));
390 if ((i & EL_TXS_READY) == 0) {
391 dprintf(("el: err txs=%x\n", i));
392 sc->sc_arpcom.ac_if.if_oerrors++;
393 if (i & (EL_TXS_COLL | EL_TXS_COLL16)) {
394 if ((i & EL_TXC_DCOLL16) == 0 &&
395 retries < 15) {
396 retries++;
397 outb(iobase+EL_AC, EL_AC_HOST);
398 }
399 } else
400 done = 1;
401 } else {
402 sc->sc_arpcom.ac_if.if_opackets++;
403 done = 1;
404 }
405 }
406 if (done == -1)
407 /* Packet not transmitted. */
408 continue;
409
410 /*
411 * Now give the card a chance to receive.
412 * Gotta love 3c501s...
413 */
414 (void)inb(iobase+EL_AS);
415 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX);
416 splx(s);
417 /* Interrupt here. */
418 s = splimp();
419 }
420 }
421
422 /*
423 * This function actually attempts to transmit a datagram downloaded to the
424 * board. Call at splimp or interrupt, after downloading data! Returns 0 on
425 * success, non-0 on failure.
426 */
427 static int
428 el_xmit(sc, len)
429 struct el_softc *sc;
430 int len;
431 {
432 u_short iobase = sc->sc_iobase;
433 int gpl;
434 int i;
435
436 gpl = EL_BUFSIZ - len;
437 dprintf(("el: xmit..."));
438 outb(iobase+EL_GPBL, gpl);
439 outb(iobase+EL_GPBH, gpl >> 8);
440 outb(iobase+EL_AC, EL_AC_TXFRX);
441 i = 20000;
442 while ((inb(iobase+EL_AS) & EL_AS_TXBUSY) && (i > 0))
443 i--;
444 if (i == 0) {
445 dprintf(("tx not ready\n"));
446 sc->sc_arpcom.ac_if.if_oerrors++;
447 return -1;
448 }
449 dprintf(("%d cycles.\n", 20000 - i));
450 return 0;
451 }
452
453 /*
454 * Controller interrupt.
455 */
456 int
457 elintr(sc)
458 register struct el_softc *sc;
459 {
460 u_short iobase = sc->sc_iobase;
461 int stat, rxstat, len, done;
462
463 dprintf(("elintr: "));
464
465 /* Check board status. */
466 stat = inb(iobase+EL_AS);
467 if (stat & EL_AS_RXBUSY) {
468 (void)inb(iobase+EL_RXC);
469 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX);
470 return 0;
471 }
472
473 done = 0;
474 while (!done) {
475 rxstat = inb(iobase+EL_RXS);
476 if (rxstat & EL_RXS_STALE) {
477 (void)inb(iobase+EL_RXC);
478 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX);
479 return 1;
480 }
481
482 /* If there's an overflow, reinit the board. */
483 if ((rxstat & EL_RXS_NOFLOW) == 0) {
484 dprintf(("overflow.\n"));
485 el_hardreset(sc);
486 /* Put board back into receive mode. */
487 if (sc->sc_arpcom.ac_if.if_flags & IFF_PROMISC)
488 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_PROMISC);
489 else
490 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_ABROAD);
491 (void)inb(iobase+EL_AS);
492 outb(iobase+EL_RBC, 0);
493 (void)inb(iobase+EL_RXC);
494 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX);
495 return 1;
496 }
497
498 /* Incoming packet. */
499 len = inb(iobase+EL_RBL);
500 len |= inb(iobase+EL_RBH) << 8;
501 dprintf(("receive len=%d rxstat=%x ", len, rxstat));
502 outb(iobase+EL_AC, EL_AC_HOST);
503
504 /*
505 * If packet too short or too long, restore rx mode and return.
506 */
507 if (len <= sizeof(struct ether_header) ||
508 len > ETHER_MAX_LEN) {
509 if (sc->sc_arpcom.ac_if.if_flags & IFF_PROMISC)
510 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_PROMISC);
511 else
512 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_ABROAD);
513 (void)inb(iobase+EL_AS);
514 outb(iobase+EL_RBC, 0);
515 (void)inb(iobase+EL_RXC);
516 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX);
517 return 1;
518 }
519
520 sc->sc_arpcom.ac_if.if_ipackets++;
521
522 /* Copy the data into our buffer. */
523 outb(iobase+EL_GPBL, 0);
524 outb(iobase+EL_GPBH, 0);
525 insb(iobase+EL_BUF, sc->sc_pktbuf, len);
526 outb(iobase+EL_RBC, 0);
527 outb(iobase+EL_AC, EL_AC_RX);
528 dprintf(("%s-->", ether_sprintf(sc->sc_pktbuf+6)));
529 dprintf(("%s\n", ether_sprintf(sc->sc_pktbuf)));
530
531 /* Pass data up to upper levels. */
532 elread(sc, (caddr_t)sc->sc_pktbuf, len);
533
534 /* Is there another packet? */
535 stat = inb(iobase+EL_AS);
536
537 /* If so, do it all again (i.e. don't set done to 1). */
538 if ((stat & EL_AS_RXBUSY) == 0)
539 dprintf(("<rescan> "));
540 else
541 done = 1;
542 }
543
544 (void)inb(iobase+EL_RXC);
545 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX);
546 return 1;
547 }
548
549 /*
550 * Pass a packet up to the higher levels.
551 */
552 static inline void
553 elread(sc, buf, len)
554 struct el_softc *sc;
555 caddr_t buf;
556 int len;
557 {
558 register struct ether_header *eh;
559 struct mbuf *m;
560
561 eh = (struct ether_header *)buf;
562 len -= sizeof(struct ether_header);
563 if (len <= 0)
564 return;
565
566 /* Pull packet off interface. */
567 m = elget(buf, len, &sc->sc_arpcom.ac_if);
568 if (m == 0)
569 return;
570
571 #if NBPFILTER > 0
572 /*
573 * Check if there's a BPF listener on this interface.
574 * If so, hand off the raw packet to bpf.
575 */
576 if (sc->sc_arpcom.ac_if.if_bpf) {
577 bpf_mtap(sc->sc_arpcom.ac_if.if_bpf, m);
578
579 /*
580 * Note that the interface cannot be in promiscuous mode if
581 * there are no BPF listeners. And if we are in promiscuous
582 * mode, we have to check if this packet is really ours.
583 */
584 if ((sc->sc_arpcom.ac_if.if_flags & IFF_PROMISC) &&
585 (eh->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */
586 bcmp(eh->ether_dhost, sc->sc_arpcom.ac_enaddr,
587 sizeof(eh->ether_dhost)) != 0) {
588 m_freem(m);
589 return;
590 }
591 }
592 #endif
593
594 ether_input(&sc->sc_arpcom.ac_if, eh, m);
595 }
596
597 /*
598 * Pull read data off a interface. Len is length of data, with local net
599 * header stripped. We copy the data into mbufs. When full cluster sized
600 * units are present we copy into clusters.
601 */
602 struct mbuf *
603 elget(buf, totlen, ifp)
604 caddr_t buf;
605 int totlen;
606 struct ifnet *ifp;
607 {
608 struct mbuf *top, **mp, *m, *p;
609 int len;
610 register caddr_t cp = buf;
611 char *epkt;
612
613 buf += sizeof(struct ether_header);
614 cp = buf;
615 epkt = cp + totlen;
616
617 MGETHDR(m, M_DONTWAIT, MT_DATA);
618 if (m == 0)
619 return 0;
620 m->m_pkthdr.rcvif = ifp;
621 m->m_pkthdr.len = totlen;
622 m->m_len = MHLEN;
623 top = 0;
624 mp = ⊤
625
626 while (totlen > 0) {
627 if (top) {
628 MGET(m, M_DONTWAIT, MT_DATA);
629 if (m == 0) {
630 m_freem(top);
631 return 0;
632 }
633 m->m_len = MLEN;
634 }
635 len = min(totlen, epkt - cp);
636 if (len >= MINCLSIZE) {
637 MCLGET(m, M_DONTWAIT);
638 if (m->m_flags & M_EXT)
639 m->m_len = len = min(len, MCLBYTES);
640 else
641 len = m->m_len;
642 } else {
643 /*
644 * Place initial small packet/header at end of mbuf.
645 */
646 if (len < m->m_len) {
647 if (top == 0 && len + max_linkhdr <= m->m_len)
648 m->m_data += max_linkhdr;
649 m->m_len = len;
650 } else
651 len = m->m_len;
652 }
653 bcopy(cp, mtod(m, caddr_t), (unsigned)len);
654 cp += len;
655 *mp = m;
656 mp = &m->m_next;
657 totlen -= len;
658 if (cp == epkt)
659 cp = buf;
660 }
661
662 return top;
663 }
664
665 /*
666 * Process an ioctl request. This code needs some work - it looks pretty ugly.
667 */
668 static int
669 el_ioctl(ifp, cmd, data)
670 register struct ifnet *ifp;
671 u_long cmd;
672 caddr_t data;
673 {
674 struct el_softc *sc = elcd.cd_devs[ifp->if_unit];
675 struct ifaddr *ifa = (struct ifaddr *)data;
676 struct ifreq *ifr = (struct ifreq *)data;
677 int s, error = 0;
678
679 s = splimp();
680
681 switch (cmd) {
682
683 case SIOCSIFADDR:
684 ifp->if_flags |= IFF_UP;
685
686 switch (ifa->ifa_addr->sa_family) {
687 #ifdef INET
688 case AF_INET:
689 el_init(sc); /* before arpwhohas */
690 /*
691 * See if another station has *our* IP address.
692 * i.e.: There is an address conflict! If a
693 * conflict exists, a message is sent to the
694 * console.
695 */
696 sc->sc_arpcom.ac_ipaddr = IA_SIN(ifa)->sin_addr;
697 arpwhohas(&sc->sc_arpcom, &IA_SIN(ifa)->sin_addr);
698 break;
699 #endif
700 #ifdef NS
701 /*
702 * XXX - This code is probably wrong.
703 */
704 case AF_NS:
705 {
706 register struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
707
708 if (ns_nullhost(*ina))
709 ina->x_host =
710 *(union ns_host *)(sc->sc_arpcom.ac_enaddr);
711 else {
712 /*
713 *
714 */
715 bcopy((caddr_t)ina->x_host.c_host,
716 (caddr_t)sc->sc_arpcom.ac_enaddr,
717 sizeof(sc->sc_arpcom.ac_enaddr));
718 }
719 /* Set new address. */
720 el_init(sc);
721 break;
722 }
723 #endif
724 default:
725 el_init(sc);
726 break;
727 }
728 break;
729
730 case SIOCSIFFLAGS:
731 if ((ifp->if_flags & IFF_UP) == 0 &&
732 (ifp->if_flags & IFF_RUNNING) != 0) {
733 /*
734 * If interface is marked down and it is running, then
735 * stop it.
736 */
737 el_stop(sc);
738 ifp->if_flags &= ~IFF_RUNNING;
739 } else if ((ifp->if_flags & IFF_UP) != 0 &&
740 (ifp->if_flags & IFF_RUNNING) == 0) {
741 /*
742 * If interface is marked up and it is stopped, then
743 * start it.
744 */
745 el_init(sc);
746 } else {
747 /*
748 * Some other important flag might have changed, so
749 * reset.
750 */
751 el_reset(sc);
752 }
753
754 default:
755 error = EINVAL;
756 }
757 (void) splx(s);
758 return error;
759 }
760
761 /*
762 * Device timeout routine.
763 */
764 static int
765 el_watchdog(unit)
766 int unit;
767 {
768 struct el_softc *sc = elcd.cd_devs[unit];
769
770 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
771 sc->sc_arpcom.ac_if.if_oerrors++;
772
773 el_reset(sc);
774 }
775