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