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