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