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