1 /* $NetBSD: if_el.c,v 1.23 1995/04/17 12:08:56 cgd 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 <dev/isa/isavar.h> 57 #include <dev/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 void *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((void *)); 86 static int el_init __P((struct el_softc *)); 87 static int el_ioctl __P((struct ifnet *, u_long, caddr_t)); 88 static void el_start __P((struct ifnet *)); 89 static void 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_start = el_start; 191 ifp->if_ioctl = el_ioctl; 192 ifp->if_watchdog = el_watchdog; 193 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS; 194 195 /* Now we can attach the interface. */ 196 dprintf(("Attaching interface...\n")); 197 if_attach(ifp); 198 ether_ifattach(ifp); 199 200 /* Print out some information for the user. */ 201 printf(": address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr)); 202 203 /* Finally, attach to bpf filter if it is present. */ 204 #if NBPFILTER > 0 205 dprintf(("Attaching to BPF...\n")); 206 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); 207 #endif 208 209 sc->sc_ih = isa_intr_establish(ia->ia_irq, ISA_IST_EDGE, ISA_IPL_NET, 210 elintr, sc); 211 212 dprintf(("elattach() finished.\n")); 213 } 214 215 /* 216 * Reset interface. 217 */ 218 static void 219 el_reset(sc) 220 struct el_softc *sc; 221 { 222 int s; 223 224 dprintf(("elreset()\n")); 225 s = splimp(); 226 el_stop(sc); 227 el_init(sc); 228 splx(s); 229 } 230 231 /* 232 * Stop interface. 233 */ 234 static void 235 el_stop(sc) 236 struct el_softc *sc; 237 { 238 239 outb(sc->sc_iobase+EL_AC, 0); 240 } 241 242 /* 243 * Do a hardware reset of the board, and upload the ethernet address again in 244 * case the board forgets. 245 */ 246 static inline void 247 el_hardreset(sc) 248 struct el_softc *sc; 249 { 250 int iobase = sc->sc_iobase; 251 int i; 252 253 outb(iobase+EL_AC, EL_AC_RESET); 254 delay(5); 255 outb(iobase+EL_AC, 0); 256 257 for (i = 0; i < ETHER_ADDR_LEN; i++) 258 outb(iobase+i, sc->sc_arpcom.ac_enaddr[i]); 259 } 260 261 /* 262 * Initialize interface. 263 */ 264 static int 265 el_init(sc) 266 struct el_softc *sc; 267 { 268 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 269 int iobase = sc->sc_iobase; 270 int s; 271 272 /* If address not known, do nothing. */ 273 if (ifp->if_addrlist == 0) 274 return; 275 276 s = splimp(); 277 278 /* First, reset the board. */ 279 el_hardreset(sc); 280 281 /* Configure rx. */ 282 dprintf(("Configuring rx...\n")); 283 if (ifp->if_flags & IFF_PROMISC) 284 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_PROMISC); 285 else 286 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_ABROAD); 287 outb(iobase+EL_RBC, 0); 288 289 /* Configure TX. */ 290 dprintf(("Configuring tx...\n")); 291 outb(iobase+EL_TXC, 0); 292 293 /* Start reception. */ 294 dprintf(("Starting reception...\n")); 295 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX); 296 297 /* Set flags appropriately. */ 298 ifp->if_flags |= IFF_RUNNING; 299 ifp->if_flags &= ~IFF_OACTIVE; 300 301 /* And start output. */ 302 el_start(ifp); 303 304 splx(s); 305 } 306 307 /* 308 * Start output on interface. Get datagrams from the queue and output them, 309 * giving the receiver a chance between datagrams. Call only from splimp or 310 * interrupt level! 311 */ 312 static void 313 el_start(ifp) 314 struct ifnet *ifp; 315 { 316 struct el_softc *sc = elcd.cd_devs[ifp->if_unit]; 317 int iobase = sc->sc_iobase; 318 struct mbuf *m, *m0; 319 int s, i, len, retries, done; 320 321 dprintf(("el_start()...\n")); 322 s = splimp(); 323 324 /* Don't do anything if output is active. */ 325 if (sc->sc_arpcom.ac_if.if_flags & IFF_OACTIVE) 326 return; 327 sc->sc_arpcom.ac_if.if_flags |= IFF_OACTIVE; 328 329 /* 330 * The main loop. They warned me against endless loops, but would I 331 * listen? NOOO.... 332 */ 333 for (;;) { 334 /* Dequeue the next datagram. */ 335 IF_DEQUEUE(&sc->sc_arpcom.ac_if.if_snd, m0); 336 337 /* If there's nothing to send, return. */ 338 if (!m0) { 339 sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE; 340 splx(s); 341 return; 342 } 343 344 /* Disable the receiver. */ 345 outb(iobase+EL_AC, EL_AC_HOST); 346 outb(iobase+EL_RBC, 0); 347 348 /* Copy the datagram to the buffer. */ 349 len = 0; 350 for (m = m0; m; m = m->m_next) { 351 if (m->m_len == 0) 352 continue; 353 bcopy(mtod(m, caddr_t), sc->sc_pktbuf + len, m->m_len); 354 len += m->m_len; 355 } 356 m_freem(m0); 357 358 len = max(len, ETHER_MIN_LEN); 359 360 /* Give the packet to the bpf, if any. */ 361 #if NBPFILTER > 0 362 if (sc->sc_arpcom.ac_if.if_bpf) 363 bpf_tap(sc->sc_arpcom.ac_if.if_bpf, sc->sc_pktbuf, len); 364 #endif 365 366 /* Transfer datagram to board. */ 367 dprintf(("el: xfr pkt length=%d...\n", len)); 368 i = EL_BUFSIZ - len; 369 outb(iobase+EL_GPBL, i); 370 outb(iobase+EL_GPBH, i >> 8); 371 outsb(iobase+EL_BUF, sc->sc_pktbuf, len); 372 373 /* Now transmit the datagram. */ 374 retries = 0; 375 done = 0; 376 while (!done) { 377 if (el_xmit(sc, len)) { 378 /* Something went wrong. */ 379 done = -1; 380 break; 381 } 382 /* Check out status. */ 383 i = inb(iobase+EL_TXS); 384 dprintf(("tx status=0x%x\n", i)); 385 if ((i & EL_TXS_READY) == 0) { 386 dprintf(("el: err txs=%x\n", i)); 387 sc->sc_arpcom.ac_if.if_oerrors++; 388 if (i & (EL_TXS_COLL | EL_TXS_COLL16)) { 389 if ((i & EL_TXC_DCOLL16) == 0 && 390 retries < 15) { 391 retries++; 392 outb(iobase+EL_AC, EL_AC_HOST); 393 } 394 } else 395 done = 1; 396 } else { 397 sc->sc_arpcom.ac_if.if_opackets++; 398 done = 1; 399 } 400 } 401 if (done == -1) 402 /* Packet not transmitted. */ 403 continue; 404 405 /* 406 * Now give the card a chance to receive. 407 * Gotta love 3c501s... 408 */ 409 (void)inb(iobase+EL_AS); 410 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX); 411 splx(s); 412 /* Interrupt here. */ 413 s = splimp(); 414 } 415 } 416 417 /* 418 * This function actually attempts to transmit a datagram downloaded to the 419 * board. Call at splimp or interrupt, after downloading data! Returns 0 on 420 * success, non-0 on failure. 421 */ 422 static int 423 el_xmit(sc, len) 424 struct el_softc *sc; 425 int len; 426 { 427 int iobase = sc->sc_iobase; 428 int gpl; 429 int i; 430 431 gpl = EL_BUFSIZ - len; 432 dprintf(("el: xmit...")); 433 outb(iobase+EL_GPBL, gpl); 434 outb(iobase+EL_GPBH, gpl >> 8); 435 outb(iobase+EL_AC, EL_AC_TXFRX); 436 i = 20000; 437 while ((inb(iobase+EL_AS) & EL_AS_TXBUSY) && (i > 0)) 438 i--; 439 if (i == 0) { 440 dprintf(("tx not ready\n")); 441 sc->sc_arpcom.ac_if.if_oerrors++; 442 return -1; 443 } 444 dprintf(("%d cycles.\n", 20000 - i)); 445 return 0; 446 } 447 448 /* 449 * Controller interrupt. 450 */ 451 int 452 elintr(arg) 453 void *arg; 454 { 455 register struct el_softc *sc = arg; 456 int iobase = sc->sc_iobase; 457 int stat, rxstat, len, done; 458 459 dprintf(("elintr: ")); 460 461 /* Check board status. */ 462 stat = inb(iobase+EL_AS); 463 if (stat & EL_AS_RXBUSY) { 464 (void)inb(iobase+EL_RXC); 465 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX); 466 return 0; 467 } 468 469 done = 0; 470 while (!done) { 471 rxstat = inb(iobase+EL_RXS); 472 if (rxstat & EL_RXS_STALE) { 473 (void)inb(iobase+EL_RXC); 474 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX); 475 return 1; 476 } 477 478 /* If there's an overflow, reinit the board. */ 479 if ((rxstat & EL_RXS_NOFLOW) == 0) { 480 dprintf(("overflow.\n")); 481 el_hardreset(sc); 482 /* Put board back into receive mode. */ 483 if (sc->sc_arpcom.ac_if.if_flags & IFF_PROMISC) 484 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_PROMISC); 485 else 486 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_ABROAD); 487 (void)inb(iobase+EL_AS); 488 outb(iobase+EL_RBC, 0); 489 (void)inb(iobase+EL_RXC); 490 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX); 491 return 1; 492 } 493 494 /* Incoming packet. */ 495 len = inb(iobase+EL_RBL); 496 len |= inb(iobase+EL_RBH) << 8; 497 dprintf(("receive len=%d rxstat=%x ", len, rxstat)); 498 outb(iobase+EL_AC, EL_AC_HOST); 499 500 /* 501 * If packet too short or too long, restore rx mode and return. 502 */ 503 if (len <= sizeof(struct ether_header) || 504 len > ETHER_MAX_LEN) { 505 if (sc->sc_arpcom.ac_if.if_flags & IFF_PROMISC) 506 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_PROMISC); 507 else 508 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_ABROAD); 509 (void)inb(iobase+EL_AS); 510 outb(iobase+EL_RBC, 0); 511 (void)inb(iobase+EL_RXC); 512 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX); 513 return 1; 514 } 515 516 sc->sc_arpcom.ac_if.if_ipackets++; 517 518 /* Copy the data into our buffer. */ 519 outb(iobase+EL_GPBL, 0); 520 outb(iobase+EL_GPBH, 0); 521 insb(iobase+EL_BUF, sc->sc_pktbuf, len); 522 outb(iobase+EL_RBC, 0); 523 outb(iobase+EL_AC, EL_AC_RX); 524 dprintf(("%s-->", ether_sprintf(sc->sc_pktbuf+6))); 525 dprintf(("%s\n", ether_sprintf(sc->sc_pktbuf))); 526 527 /* Pass data up to upper levels. */ 528 elread(sc, (caddr_t)sc->sc_pktbuf, len); 529 530 /* Is there another packet? */ 531 stat = inb(iobase+EL_AS); 532 533 /* If so, do it all again (i.e. don't set done to 1). */ 534 if ((stat & EL_AS_RXBUSY) == 0) 535 dprintf(("<rescan> ")); 536 else 537 done = 1; 538 } 539 540 (void)inb(iobase+EL_RXC); 541 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX); 542 return 1; 543 } 544 545 /* 546 * Pass a packet up to the higher levels. 547 */ 548 static inline void 549 elread(sc, buf, len) 550 struct el_softc *sc; 551 caddr_t buf; 552 int len; 553 { 554 register struct ether_header *eh; 555 struct mbuf *m; 556 557 eh = (struct ether_header *)buf; 558 len -= sizeof(struct ether_header); 559 if (len <= 0) 560 return; 561 562 /* Pull packet off interface. */ 563 m = elget(buf, len, &sc->sc_arpcom.ac_if); 564 if (m == 0) 565 return; 566 567 #if NBPFILTER > 0 568 /* 569 * Check if there's a BPF listener on this interface. 570 * If so, hand off the raw packet to bpf. 571 */ 572 if (sc->sc_arpcom.ac_if.if_bpf) { 573 bpf_mtap(sc->sc_arpcom.ac_if.if_bpf, m); 574 575 /* 576 * Note that the interface cannot be in promiscuous mode if 577 * there are no BPF listeners. And if we are in promiscuous 578 * mode, we have to check if this packet is really ours. 579 */ 580 if ((sc->sc_arpcom.ac_if.if_flags & IFF_PROMISC) && 581 (eh->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */ 582 bcmp(eh->ether_dhost, sc->sc_arpcom.ac_enaddr, 583 sizeof(eh->ether_dhost)) != 0) { 584 m_freem(m); 585 return; 586 } 587 } 588 #endif 589 590 ether_input(&sc->sc_arpcom.ac_if, eh, m); 591 } 592 593 /* 594 * Pull read data off a interface. Len is length of data, with local net 595 * header stripped. We copy the data into mbufs. When full cluster sized 596 * units are present we copy into clusters. 597 */ 598 struct mbuf * 599 elget(buf, totlen, ifp) 600 caddr_t buf; 601 int totlen; 602 struct ifnet *ifp; 603 { 604 struct mbuf *top, **mp, *m, *p; 605 int len; 606 register caddr_t cp = buf; 607 char *epkt; 608 609 buf += sizeof(struct ether_header); 610 cp = buf; 611 epkt = cp + totlen; 612 613 MGETHDR(m, M_DONTWAIT, MT_DATA); 614 if (m == 0) 615 return 0; 616 m->m_pkthdr.rcvif = ifp; 617 m->m_pkthdr.len = totlen; 618 m->m_len = MHLEN; 619 top = 0; 620 mp = ⊤ 621 622 while (totlen > 0) { 623 if (top) { 624 MGET(m, M_DONTWAIT, MT_DATA); 625 if (m == 0) { 626 m_freem(top); 627 return 0; 628 } 629 m->m_len = MLEN; 630 } 631 len = min(totlen, epkt - cp); 632 if (len >= MINCLSIZE) { 633 MCLGET(m, M_DONTWAIT); 634 if (m->m_flags & M_EXT) 635 m->m_len = len = min(len, MCLBYTES); 636 else 637 len = m->m_len; 638 } else { 639 /* 640 * Place initial small packet/header at end of mbuf. 641 */ 642 if (len < m->m_len) { 643 if (top == 0 && len + max_linkhdr <= m->m_len) 644 m->m_data += max_linkhdr; 645 m->m_len = len; 646 } else 647 len = m->m_len; 648 } 649 bcopy(cp, mtod(m, caddr_t), (unsigned)len); 650 cp += len; 651 *mp = m; 652 mp = &m->m_next; 653 totlen -= len; 654 if (cp == epkt) 655 cp = buf; 656 } 657 658 return top; 659 } 660 661 /* 662 * Process an ioctl request. This code needs some work - it looks pretty ugly. 663 */ 664 static int 665 el_ioctl(ifp, cmd, data) 666 register struct ifnet *ifp; 667 u_long cmd; 668 caddr_t data; 669 { 670 struct el_softc *sc = elcd.cd_devs[ifp->if_unit]; 671 struct ifaddr *ifa = (struct ifaddr *)data; 672 struct ifreq *ifr = (struct ifreq *)data; 673 int s, error = 0; 674 675 s = splimp(); 676 677 switch (cmd) { 678 679 case SIOCSIFADDR: 680 ifp->if_flags |= IFF_UP; 681 682 switch (ifa->ifa_addr->sa_family) { 683 #ifdef INET 684 case AF_INET: 685 el_init(sc); 686 arp_ifinit(&sc->sc_arpcom, ifa); 687 break; 688 #endif 689 #ifdef NS 690 /* 691 * XXX - This code is probably wrong. 692 */ 693 case AF_NS: 694 { 695 register struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; 696 697 if (ns_nullhost(*ina)) 698 ina->x_host = 699 *(union ns_host *)(sc->sc_arpcom.ac_enaddr); 700 else { 701 /* 702 * 703 */ 704 bcopy((caddr_t)ina->x_host.c_host, 705 (caddr_t)sc->sc_arpcom.ac_enaddr, 706 sizeof(sc->sc_arpcom.ac_enaddr)); 707 } 708 /* Set new address. */ 709 el_init(sc); 710 break; 711 } 712 #endif 713 default: 714 el_init(sc); 715 break; 716 } 717 break; 718 719 case SIOCSIFFLAGS: 720 if ((ifp->if_flags & IFF_UP) == 0 && 721 (ifp->if_flags & IFF_RUNNING) != 0) { 722 /* 723 * If interface is marked down and it is running, then 724 * stop it. 725 */ 726 el_stop(sc); 727 ifp->if_flags &= ~IFF_RUNNING; 728 } else if ((ifp->if_flags & IFF_UP) != 0 && 729 (ifp->if_flags & IFF_RUNNING) == 0) { 730 /* 731 * If interface is marked up and it is stopped, then 732 * start it. 733 */ 734 el_init(sc); 735 } else { 736 /* 737 * Some other important flag might have changed, so 738 * reset. 739 */ 740 el_reset(sc); 741 } 742 743 default: 744 error = EINVAL; 745 } 746 splx(s); 747 return error; 748 } 749 750 /* 751 * Device timeout routine. 752 */ 753 static void 754 el_watchdog(unit) 755 int unit; 756 { 757 struct el_softc *sc = elcd.cd_devs[unit]; 758 759 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname); 760 sc->sc_arpcom.ac_if.if_oerrors++; 761 762 el_reset(sc); 763 } 764