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