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