1 /* 2 * Copyright (c) 1994, Matthew E. Kimmel. Permission is hereby granted 3 * to use, copy, modify and distribute this software provided that both 4 * the copyright notice and this permission notice appear in all copies 5 * of the software, derivative works or modified versions, and any 6 * portions thereof. 7 */ 8 9 /* 10 * 3COM Etherlink 3C501 device driver 11 * 12 * $Id: if_el.c,v 1.13 1994/05/13 06:13:48 mycroft Exp $ 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 *, int, 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(); 99 void elattach(); 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, self, aux) 114 struct device *parent, *self; 115 void *aux; 116 { 117 struct el_softc *sc = (void *)self; 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 int 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