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