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