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