1 /* $NetBSD: if_el.c,v 1.82 2009/03/14 15:36:18 dsl 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.82 2009/03/14 15:36:18 dsl 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(struct el_softc *sc) 277 { 278 int s; 279 280 DPRINTF(("elreset()\n")); 281 s = splnet(); 282 elstop(sc); 283 elinit(sc); 284 splx(s); 285 } 286 287 /* 288 * Stop interface. 289 */ 290 void 291 elstop(struct el_softc *sc) 292 { 293 294 bus_space_write_1(sc->sc_iot, sc->sc_ioh, EL_AC, 0); 295 } 296 297 /* 298 * Do a hardware reset of the board, and upload the ethernet address again in 299 * case the board forgets. 300 */ 301 static inline void 302 el_hardreset(struct el_softc *sc) 303 { 304 bus_space_tag_t iot = sc->sc_iot; 305 bus_space_handle_t ioh = sc->sc_ioh; 306 int i; 307 308 bus_space_write_1(iot, ioh, EL_AC, EL_AC_RESET); 309 delay(5); 310 bus_space_write_1(iot, ioh, EL_AC, 0); 311 312 for (i = 0; i < ETHER_ADDR_LEN; i++) 313 bus_space_write_1(iot, ioh, i, 314 CLLADDR(sc->sc_ethercom.ec_if.if_sadl)[i]); 315 } 316 317 /* 318 * Initialize interface. 319 */ 320 void 321 elinit(struct el_softc *sc) 322 { 323 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 324 bus_space_tag_t iot = sc->sc_iot; 325 bus_space_handle_t ioh = sc->sc_ioh; 326 327 /* First, reset the board. */ 328 el_hardreset(sc); 329 330 /* Configure rx. */ 331 DPRINTF(("Configuring rx...\n")); 332 if (ifp->if_flags & IFF_PROMISC) 333 bus_space_write_1(iot, ioh, EL_RXC, 334 EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | 335 EL_RXC_DOFLOW | EL_RXC_PROMISC); 336 else 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_ABROAD); 340 bus_space_write_1(iot, ioh, EL_RBC, 0); 341 342 /* Configure TX. */ 343 DPRINTF(("Configuring tx...\n")); 344 bus_space_write_1(iot, ioh, EL_TXC, 0); 345 346 /* Start reception. */ 347 DPRINTF(("Starting reception...\n")); 348 bus_space_write_1(iot, ioh, EL_AC, EL_AC_IRQE | EL_AC_RX); 349 350 /* Set flags appropriately. */ 351 ifp->if_flags |= IFF_RUNNING; 352 ifp->if_flags &= ~IFF_OACTIVE; 353 354 /* And start output. */ 355 elstart(ifp); 356 } 357 358 /* 359 * Start output on interface. Get datagrams from the queue and output them, 360 * giving the receiver a chance between datagrams. Call only from splnet or 361 * interrupt level! 362 */ 363 void 364 elstart(struct ifnet *ifp) 365 { 366 struct el_softc *sc = ifp->if_softc; 367 bus_space_tag_t iot = sc->sc_iot; 368 bus_space_handle_t ioh = sc->sc_ioh; 369 struct mbuf *m, *m0; 370 int s, i, off, retries; 371 372 DPRINTF(("elstart()...\n")); 373 s = splnet(); 374 375 /* Don't do anything if output is active. */ 376 if ((ifp->if_flags & IFF_OACTIVE) != 0) { 377 splx(s); 378 return; 379 } 380 381 ifp->if_flags |= IFF_OACTIVE; 382 383 /* 384 * The main loop. They warned me against endless loops, but would I 385 * listen? NOOO.... 386 */ 387 for (;;) { 388 /* Dequeue the next datagram. */ 389 IFQ_DEQUEUE(&ifp->if_snd, m0); 390 391 /* If there's nothing to send, return. */ 392 if (m0 == 0) 393 break; 394 395 #if NBPFILTER > 0 396 /* Give the packet to the bpf, if any. */ 397 if (ifp->if_bpf) 398 bpf_mtap(ifp->if_bpf, m0); 399 #endif 400 401 /* Disable the receiver. */ 402 bus_space_write_1(iot, ioh, EL_AC, EL_AC_HOST); 403 bus_space_write_1(iot, ioh, EL_RBC, 0); 404 405 /* Transfer datagram to board. */ 406 DPRINTF(("el: xfr pkt length=%d...\n", m0->m_pkthdr.len)); 407 off = EL_BUFSIZ - max(m0->m_pkthdr.len, 408 ETHER_MIN_LEN - ETHER_CRC_LEN); 409 #ifdef DIAGNOSTIC 410 if ((off & 0xffff) != off) 411 printf("%s: bogus off 0x%x\n", 412 device_xname(&sc->sc_dev), off); 413 #endif 414 bus_space_write_1(iot, ioh, EL_GPBL, off & 0xff); 415 bus_space_write_1(iot, ioh, EL_GPBH, (off >> 8) & 0xff); 416 417 /* Copy the datagram to the buffer. */ 418 for (m = m0; m != 0; m = m->m_next) 419 bus_space_write_multi_1(iot, ioh, EL_BUF, 420 mtod(m, u_int8_t *), m->m_len); 421 for (i = 0; 422 i < ETHER_MIN_LEN - ETHER_CRC_LEN - m0->m_pkthdr.len; i++) 423 bus_space_write_1(iot, ioh, EL_BUF, 0); 424 425 m_freem(m0); 426 427 /* Now transmit the datagram. */ 428 retries = 0; 429 for (;;) { 430 bus_space_write_1(iot, ioh, EL_GPBL, off & 0xff); 431 bus_space_write_1(iot, ioh, EL_GPBH, (off >> 8) & 0xff); 432 if (el_xmit(sc)) { 433 ifp->if_oerrors++; 434 break; 435 } 436 /* Check out status. */ 437 i = bus_space_read_1(iot, ioh, EL_TXS); 438 DPRINTF(("tx status=0x%x\n", i)); 439 if ((i & EL_TXS_READY) == 0) { 440 DPRINTF(("el: err txs=%x\n", i)); 441 if (i & (EL_TXS_COLL | EL_TXS_COLL16)) { 442 ifp->if_collisions++; 443 if ((i & EL_TXC_DCOLL16) == 0 && 444 retries < 15) { 445 retries++; 446 bus_space_write_1(iot, ioh, 447 EL_AC, EL_AC_HOST); 448 } 449 } else { 450 ifp->if_oerrors++; 451 break; 452 } 453 } else { 454 ifp->if_opackets++; 455 break; 456 } 457 } 458 459 /* 460 * Now give the card a chance to receive. 461 * Gotta love 3c501s... 462 */ 463 (void)bus_space_read_1(iot, ioh, EL_AS); 464 bus_space_write_1(iot, ioh, EL_AC, EL_AC_IRQE | EL_AC_RX); 465 splx(s); 466 /* Interrupt here. */ 467 s = splnet(); 468 } 469 470 (void)bus_space_read_1(iot, ioh, EL_AS); 471 bus_space_write_1(iot, ioh, EL_AC, EL_AC_IRQE | EL_AC_RX); 472 ifp->if_flags &= ~IFF_OACTIVE; 473 splx(s); 474 } 475 476 /* 477 * This function actually attempts to transmit a datagram downloaded to the 478 * board. Call at splnet or interrupt, after downloading data! Returns 0 on 479 * success, non-0 on failure. 480 */ 481 static int 482 el_xmit(struct el_softc *sc) 483 { 484 bus_space_tag_t iot = sc->sc_iot; 485 bus_space_handle_t ioh = sc->sc_ioh; 486 int i; 487 488 /* 489 * XXX 490 * This busy-waits for the tx completion. Can we get an interrupt 491 * instead? 492 */ 493 494 DPRINTF(("el: xmit...")); 495 bus_space_write_1(iot, ioh, EL_AC, EL_AC_TXFRX); 496 i = 20000; 497 while ((bus_space_read_1(iot, ioh, EL_AS) & EL_AS_TXBUSY) && (i > 0)) 498 i--; 499 if (i == 0) { 500 DPRINTF(("tx not ready\n")); 501 return -1; 502 } 503 DPRINTF(("%d cycles.\n", 20000 - i)); 504 return 0; 505 } 506 507 /* 508 * Controller interrupt. 509 */ 510 int 511 elintr(void *arg) 512 { 513 struct el_softc *sc = arg; 514 bus_space_tag_t iot = sc->sc_iot; 515 bus_space_handle_t ioh = sc->sc_ioh; 516 u_int8_t rxstat; 517 int len; 518 519 DPRINTF(("elintr: ")); 520 521 /* Check board status. */ 522 if ((bus_space_read_1(iot, ioh, EL_AS) & EL_AS_RXBUSY) != 0) { 523 (void)bus_space_read_1(iot, ioh, EL_RXC); 524 bus_space_write_1(iot, ioh, EL_AC, EL_AC_IRQE | EL_AC_RX); 525 return 0; 526 } 527 528 for (;;) { 529 rxstat = bus_space_read_1(iot, ioh, EL_RXS); 530 if (rxstat & EL_RXS_STALE) 531 break; 532 533 /* If there's an overflow, reinit the board. */ 534 if ((rxstat & EL_RXS_NOFLOW) == 0) { 535 DPRINTF(("overflow.\n")); 536 el_hardreset(sc); 537 /* Put board back into receive mode. */ 538 if (sc->sc_ethercom.ec_if.if_flags & IFF_PROMISC) 539 bus_space_write_1(iot, ioh, EL_RXC, 540 EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | 541 EL_RXC_DOFLOW | EL_RXC_PROMISC); 542 else 543 bus_space_write_1(iot, ioh, EL_RXC, 544 EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | 545 EL_RXC_DOFLOW | EL_RXC_ABROAD); 546 (void)bus_space_read_1(iot, ioh, EL_AS); 547 bus_space_write_1(iot, ioh, EL_RBC, 0); 548 break; 549 } 550 551 /* Incoming packet. */ 552 len = bus_space_read_1(iot, ioh, EL_RBL); 553 len |= bus_space_read_1(iot, ioh, EL_RBH) << 8; 554 DPRINTF(("receive len=%d rxstat=%x ", len, rxstat)); 555 bus_space_write_1(iot, ioh, EL_AC, EL_AC_HOST); 556 557 /* Pass data up to upper levels. */ 558 elread(sc, len); 559 560 /* Is there another packet? */ 561 if ((bus_space_read_1(iot, ioh, EL_AS) & EL_AS_RXBUSY) != 0) 562 break; 563 564 #if NRND > 0 565 rnd_add_uint32(&sc->rnd_source, rxstat); 566 #endif 567 568 DPRINTF(("<rescan> ")); 569 } 570 571 (void)bus_space_read_1(iot, ioh, EL_RXC); 572 bus_space_write_1(iot, ioh, EL_AC, EL_AC_IRQE | EL_AC_RX); 573 return 1; 574 } 575 576 /* 577 * Pass a packet to the higher levels. 578 */ 579 void 580 elread(struct el_softc *sc, int len) 581 { 582 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 583 struct mbuf *m; 584 585 if (len <= sizeof(struct ether_header) || 586 len > ETHER_MAX_LEN) { 587 printf("%s: invalid packet size %d; dropping\n", 588 device_xname(&sc->sc_dev), len); 589 ifp->if_ierrors++; 590 return; 591 } 592 593 /* Pull packet off interface. */ 594 m = elget(sc, len); 595 if (m == 0) { 596 ifp->if_ierrors++; 597 return; 598 } 599 600 ifp->if_ipackets++; 601 602 #if NBPFILTER > 0 603 /* 604 * Check if there's a BPF listener on this interface. 605 * If so, hand off the raw packet to BPF. 606 */ 607 if (ifp->if_bpf) 608 bpf_mtap(ifp->if_bpf, m); 609 #endif 610 611 (*ifp->if_input)(ifp, 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(struct el_softc *sc, int totlen) 621 { 622 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 623 bus_space_tag_t iot = sc->sc_iot; 624 bus_space_handle_t ioh = sc->sc_ioh; 625 struct mbuf *m, *m0, *newm; 626 int len; 627 628 MGETHDR(m0, M_DONTWAIT, MT_DATA); 629 if (m0 == 0) 630 return (0); 631 m0->m_pkthdr.rcvif = ifp; 632 m0->m_pkthdr.len = totlen; 633 len = MHLEN; 634 m = m0; 635 636 bus_space_write_1(iot, ioh, EL_GPBL, 0); 637 bus_space_write_1(iot, ioh, EL_GPBH, 0); 638 639 while (totlen > 0) { 640 if (totlen >= MINCLSIZE) { 641 MCLGET(m, M_DONTWAIT); 642 if ((m->m_flags & M_EXT) == 0) 643 goto bad; 644 len = MCLBYTES; 645 } 646 647 m->m_len = len = min(totlen, len); 648 bus_space_read_multi_1(iot, ioh, EL_BUF, mtod(m, u_int8_t *), len); 649 650 totlen -= len; 651 if (totlen > 0) { 652 MGET(newm, M_DONTWAIT, MT_DATA); 653 if (newm == 0) 654 goto bad; 655 len = MLEN; 656 m = m->m_next = newm; 657 } 658 } 659 660 bus_space_write_1(iot, ioh, EL_RBC, 0); 661 bus_space_write_1(iot, ioh, EL_AC, EL_AC_RX); 662 663 return (m0); 664 665 bad: 666 m_freem(m0); 667 return (0); 668 } 669 670 /* 671 * Process an ioctl request. This code needs some work - it looks pretty ugly. 672 */ 673 int 674 elioctl(struct ifnet *ifp, u_long cmd, void *data) 675 { 676 struct el_softc *sc = ifp->if_softc; 677 struct ifaddr *ifa = (struct ifaddr *)data; 678 int s, error = 0; 679 680 s = splnet(); 681 682 switch (cmd) { 683 684 case SIOCINITIFADDR: 685 ifp->if_flags |= IFF_UP; 686 687 elinit(sc); 688 switch (ifa->ifa_addr->sa_family) { 689 #ifdef INET 690 case AF_INET: 691 arp_ifinit(ifp, ifa); 692 break; 693 #endif 694 default: 695 break; 696 } 697 break; 698 699 case SIOCSIFFLAGS: 700 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 701 break; 702 /* XXX re-use ether_ioctl() */ 703 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) { 704 case IFF_RUNNING: 705 /* 706 * If interface is marked down and it is running, then 707 * stop it. 708 */ 709 elstop(sc); 710 ifp->if_flags &= ~IFF_RUNNING; 711 break; 712 case IFF_UP: 713 /* 714 * If interface is marked up and it is stopped, then 715 * start it. 716 */ 717 elinit(sc); 718 break; 719 default: 720 /* 721 * Some other important flag might have changed, so 722 * reset. 723 */ 724 elreset(sc); 725 break; 726 } 727 break; 728 729 default: 730 error = ether_ioctl(ifp, cmd, data); 731 break; 732 } 733 734 splx(s); 735 return error; 736 } 737 738 /* 739 * Device timeout routine. 740 */ 741 void 742 elwatchdog(struct ifnet *ifp) 743 { 744 struct el_softc *sc = ifp->if_softc; 745 746 log(LOG_ERR, "%s: device timeout\n", device_xname(&sc->sc_dev)); 747 sc->sc_ethercom.ec_if.if_oerrors++; 748 749 elreset(sc); 750 } 751