1 /* $NetBSD: if_le.c,v 1.19 1995/04/16 01:52:07 gwr Exp $ */ 2 3 /* 4 * LANCE Ethernet driver 5 * 6 * Copyright (c) 1995 Gordon W. Ross 7 * Copyright (c) 1994 Charles Hannum. 8 * 9 * Copyright (C) 1993, Paul Richards. This software may be used, modified, 10 * copied, distributed, and sold, in both source and binary form provided 11 * that the above copyright and these terms are retained. Under no 12 * circumstances is the author responsible for the proper functioning 13 * of this software, nor does the author assume any responsibility 14 * for damages incurred with its use. 15 */ 16 17 #include "bpfilter.h" 18 19 #include <sys/param.h> 20 #include <sys/systm.h> 21 #include <sys/errno.h> 22 #include <sys/ioctl.h> 23 #include <sys/mbuf.h> 24 #include <sys/socket.h> 25 #include <sys/syslog.h> 26 #include <sys/device.h> 27 28 #include <net/if.h> 29 #include <net/if_dl.h> 30 #include <net/if_types.h> 31 #include <net/netisr.h> 32 33 #ifdef INET 34 #include <netinet/in.h> 35 #include <netinet/in_systm.h> 36 #include <netinet/in_var.h> 37 #include <netinet/ip.h> 38 #include <netinet/if_ether.h> 39 #endif 40 41 #ifdef NS 42 #include <netns/ns.h> 43 #include <netns/ns_if.h> 44 #endif 45 46 #if NBPFILTER > 0 47 #include <net/bpf.h> 48 #include <net/bpfdesc.h> 49 #endif 50 51 #include <machine/autoconf.h> 52 #include <machine/cpu.h> 53 54 /* #define LEDEBUG 1 */ 55 56 #include "if_lereg.h" 57 #include "if_le.h" 58 #include "if_le_subr.h" 59 60 #define RMD_BITS "\20\20own\17err\16fram\15oflo\14crc\13rbuf\12stp\11enp" 61 62 #define ETHER_MIN_LEN 64 63 #define ETHER_MAX_LEN 1518 64 65 /* 66 * The lance has only 24 address lines. When it accesses memory, 67 * the high address lines are hard-wired to 0xFF, so we must: 68 * (1) put what we want the LANCE to see above 0xFF000000, and 69 * (2) mask our CPU addresses down to 24 bits for the LANCE. 70 */ 71 #define LANCE_ADDR(sc,x) ((u_int)(x) & 0xFFffff) 72 73 #ifdef PACKETSTATS 74 long lexpacketsizes[LEMTU+1]; 75 long lerpacketsizes[LEMTU+1]; 76 #endif 77 78 /* autoconfiguration driver */ 79 void le_attach(struct device *, struct device *, void *); 80 81 struct cfdriver lecd = { 82 NULL, "le", le_md_match, le_attach, 83 DV_IFNET, sizeof(struct le_softc), 84 }; 85 86 int leioctl __P((struct ifnet *, u_long, caddr_t)); 87 void lestart __P((struct ifnet *)); 88 void lewatchdog __P((/* short */)); 89 static inline void lewrcsr __P((/* struct le_softc *, u_short, u_short */)); 90 static inline u_short lerdcsr __P((/* struct le_softc *, u_short */)); 91 void leinit __P((struct le_softc *)); 92 void lememinit __P((struct le_softc *)); 93 void lereset __P((struct le_softc *)); 94 void lestop __P((struct le_softc *)); 95 void letint __P((struct le_softc *)); 96 void lerint __P((struct le_softc *)); 97 void leread __P((struct le_softc *, u_char *, int)); 98 struct mbuf *leget __P((u_char *, int, struct ifnet *)); 99 void lesetladrf __P((struct arpcom *, u_long *)); 100 #ifdef LEDEBUG 101 void recv_print __P((struct le_softc *, int)); 102 void xmit_print __P((struct le_softc *, int)); 103 #endif 104 105 /* 106 * Inline routines to read and write the LANCE registers. 107 */ 108 109 static inline void 110 lewrcsr(sc, regnum, value) 111 struct le_softc *sc; 112 u_short regnum; 113 u_short value; 114 { 115 volatile struct le_regs *regs = sc->sc_regs; 116 117 regs->lereg_addr = regnum; 118 regs->lereg_data = value; 119 } 120 121 static inline u_short 122 lerdcsr(sc, regnum) 123 struct le_softc *sc; 124 u_short regnum; 125 { 126 volatile struct le_regs *regs = sc->sc_regs; 127 u_short value; 128 129 regs->lereg_addr = regnum; 130 value = regs->lereg_data; 131 132 return (value); 133 } 134 135 /* 136 * The probe is done in if_le_subr.c:if_md_match() 137 */ 138 139 /* 140 * Interface exists: make available by filling in network interface 141 * record. System will initialize the interface when it is ready 142 * to accept packets. We get the ethernet address here. 143 */ 144 void 145 le_attach(parent, self, aux) 146 struct device *parent, *self; 147 void *aux; 148 { 149 struct le_softc *sc = (void *)self; 150 struct confargs *ca = aux; 151 struct ifnet *ifp = &sc->sc_if; 152 int pri; 153 u_int a; 154 155 le_md_attach(parent, self, aux); 156 printf(" hwaddr %s\n", ether_sprintf(sc->sc_enaddr)); 157 158 /* 159 * Initialize and attach S/W interface 160 */ 161 ifp->if_unit = sc->sc_dev.dv_unit; 162 ifp->if_name = lecd.cd_name; 163 ifp->if_start = lestart; 164 ifp->if_ioctl = leioctl; 165 ifp->if_watchdog = lewatchdog; 166 ifp->if_flags = 167 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; 168 169 /* Attach the interface. */ 170 if_attach(ifp); 171 ether_ifattach(ifp); 172 #if NBPFILTER > 0 173 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); 174 #endif 175 } 176 177 void 178 lereset(sc) 179 struct le_softc *sc; 180 { 181 182 leinit(sc); 183 } 184 185 void 186 lewatchdog(unit) 187 short unit; 188 { 189 struct le_softc *sc = lecd.cd_devs[unit]; 190 191 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname); 192 ++sc->sc_if.if_oerrors; 193 lereset(sc); 194 } 195 196 /* LANCE initialization block set up. */ 197 void 198 lememinit(sc) 199 register struct le_softc *sc; 200 { 201 struct ifnet *ifp = &sc->sc_if; 202 int i; 203 void *mem; 204 u_long a; 205 206 /* 207 * At this point we assume that the memory allocated to the Lance is 208 * quadword aligned. If it isn't then the initialisation is going 209 * fail later on. 210 */ 211 mem = sc->sc_mem; 212 213 sc->sc_init = mem; 214 #if NBPFILTER > 0 215 if (ifp->if_flags & IFF_PROMISC) 216 sc->sc_init->mode = LE_NORMAL | LE_PROM; 217 else 218 #endif 219 sc->sc_init->mode = LE_NORMAL; 220 221 /* Set the Ethernet address (have to byte-swap) */ 222 for (i = 0; i < 6; i += 2) { 223 sc->sc_init->padr[i] = sc->sc_enaddr[i+1]; 224 sc->sc_init->padr[i+1] = sc->sc_enaddr[i]; 225 } 226 lesetladrf(&sc->sc_ac, sc->sc_init->ladrf); 227 mem += sizeof(struct init_block); 228 229 sc->sc_rd = mem; 230 a = LANCE_ADDR(sc, mem); 231 sc->sc_init->rdra = a; 232 sc->sc_init->rlen = ((a >> 16) & 0xff) | (RLEN << 13); 233 mem += NRBUF * sizeof(struct mds); 234 235 sc->sc_td = mem; 236 a = LANCE_ADDR(sc, mem); 237 sc->sc_init->tdra = a; 238 sc->sc_init->tlen = ((a >> 16) & 0xff) | (TLEN << 13); 239 mem += NTBUF * sizeof(struct mds); 240 241 /* 242 * Set up receive ring descriptors. 243 */ 244 sc->sc_rbuf = mem; 245 for (i = 0; i < NRBUF; i++) { 246 a = LANCE_ADDR(sc, mem); 247 sc->sc_rd[i].addr = a; 248 sc->sc_rd[i].flags = ((a >> 16) & 0xff) | LE_OWN; 249 sc->sc_rd[i].bcnt = -BUFSIZE; 250 sc->sc_rd[i].mcnt = 0; 251 mem += BUFSIZE; 252 } 253 254 /* 255 * Set up transmit ring descriptors. 256 */ 257 sc->sc_tbuf = mem; 258 for (i = 0; i < NTBUF; i++) { 259 a = LANCE_ADDR(sc, mem); 260 sc->sc_td[i].addr = a; 261 sc->sc_td[i].flags= ((a >> 16) & 0xff); 262 sc->sc_td[i].bcnt = 0xf000; 263 sc->sc_td[i].mcnt = 0; 264 mem += BUFSIZE; 265 } 266 267 #ifdef DIAGNOSTIC 268 if (mem > (sc->sc_mem + MEMSIZE)) 269 panic("lememinit: used 0x%x\n", mem - sc->sc_mem); 270 #endif 271 } 272 273 void 274 lestop(sc) 275 struct le_softc *sc; 276 { 277 278 lewrcsr(sc, 0, LE_STOP); 279 } 280 281 /* 282 * Initialization of interface; set up initialization block 283 * and transmit/receive descriptor rings. 284 */ 285 void 286 leinit(sc) 287 register struct le_softc *sc; 288 { 289 struct ifnet *ifp = &sc->sc_if; 290 int s; 291 register int timo; 292 u_long a; 293 294 /* Address not known. */ 295 if (!ifp->if_addrlist) 296 return; 297 298 s = splimp(); 299 300 /* Don't want to get in a weird state. */ 301 lewrcsr(sc, 0, LE_STOP); 302 delay(100); 303 304 sc->sc_last_rd = sc->sc_last_td = sc->sc_no_td = 0; 305 306 /* Set up LANCE init block. */ 307 lememinit(sc); 308 309 /* Set byte swapping etc. */ 310 lewrcsr(sc, 3, LE_CONF3); 311 312 /* Give LANCE the physical address of its init block. */ 313 a = LANCE_ADDR(sc, sc->sc_init); 314 lewrcsr(sc, 1, a); 315 lewrcsr(sc, 2, (a >> 16) & 0xff); 316 317 /* Try to initialize the LANCE. */ 318 delay(100); 319 lewrcsr(sc, 0, LE_INIT); 320 321 /* Wait for initialization to finish. */ 322 for (timo = 1000; timo; timo--) 323 if (lerdcsr(sc, 0) & LE_IDON) 324 break; 325 326 if (lerdcsr(sc, 0) & LE_IDON) { 327 /* Start the LANCE. */ 328 lewrcsr(sc, 0, LE_INEA | LE_STRT | LE_IDON); 329 ifp->if_flags |= IFF_RUNNING; 330 ifp->if_flags &= ~IFF_OACTIVE; 331 lestart(ifp); 332 } else 333 printf("%s: card failed to initialize\n", sc->sc_dev.dv_xname); 334 335 (void) splx(s); 336 } 337 338 /* 339 * Controller interrupt. 340 */ 341 int 342 leintr(vsc) 343 void *vsc; 344 { 345 register struct le_softc *sc = vsc; 346 register u_short isr; 347 348 isr = lerdcsr(sc, 0); 349 #ifdef LEDEBUG 350 if (sc->sc_debug) 351 printf("%s: leintr entering with isr=%04x\n", 352 sc->sc_dev.dv_xname, isr); 353 #endif 354 if ((isr & LE_INTR) == 0) 355 return 0; 356 357 do { 358 lewrcsr(sc, 0, 359 isr & (LE_INEA | LE_BABL | LE_MISS | LE_MERR | 360 LE_RINT | LE_TINT | LE_IDON)); 361 if (isr & (LE_BABL | LE_CERR | LE_MISS | LE_MERR)) { 362 if (isr & LE_BABL) { 363 printf("%s: babble\n", sc->sc_dev.dv_xname); 364 sc->sc_if.if_oerrors++; 365 } 366 #if 0 367 if (isr & LE_CERR) { 368 printf("%s: collision error\n", sc->sc_dev.dv_xname); 369 sc->sc_if.if_collisions++; 370 } 371 #endif 372 if (isr & LE_MISS) { 373 #if 0 374 printf("%s: missed packet\n", sc->sc_dev.dv_xname); 375 #endif 376 sc->sc_if.if_ierrors++; 377 } 378 if (isr & LE_MERR) { 379 printf("%s: memory error\n", sc->sc_dev.dv_xname); 380 lereset(sc); 381 goto out; 382 } 383 } 384 385 if ((isr & LE_RXON) == 0) { 386 printf("%s: receiver disabled\n", sc->sc_dev.dv_xname); 387 sc->sc_if.if_ierrors++; 388 lereset(sc); 389 goto out; 390 } 391 if ((isr & LE_TXON) == 0) { 392 printf("%s: transmitter disabled\n", sc->sc_dev.dv_xname); 393 sc->sc_if.if_oerrors++; 394 lereset(sc); 395 goto out; 396 } 397 398 if (isr & LE_RINT) { 399 /* Reset watchdog timer. */ 400 sc->sc_if.if_timer = 0; 401 lerint(sc); 402 } 403 if (isr & LE_TINT) { 404 /* Reset watchdog timer. */ 405 sc->sc_if.if_timer = 0; 406 letint(sc); 407 } 408 409 isr = lerdcsr(sc, 0); 410 } while ((isr & LE_INTR) != 0); 411 412 #ifdef LEDEBUG 413 if (sc->sc_debug) 414 printf("%s: leintr returning with isr=%04x\n", 415 sc->sc_dev.dv_xname, isr); 416 #endif 417 418 out: 419 return 1; 420 } 421 422 #define NEXTTDS \ 423 if (++tmd == NTBUF) tmd=0, cdm=sc->sc_td; else ++cdm 424 425 /* 426 * Setup output on interface. 427 * Get another datagram to send off of the interface queue, and map it to the 428 * interface before starting the output. 429 * Called only at splimp or interrupt level. 430 */ 431 void 432 lestart(ifp) 433 struct ifnet *ifp; 434 { 435 register struct le_softc *sc = lecd.cd_devs[ifp->if_unit]; 436 register int tmd; 437 volatile struct mds *cdm; 438 struct mbuf *m0, *m; 439 u_char *buffer; 440 int len; 441 442 if ((sc->sc_if.if_flags & (IFF_RUNNING | IFF_OACTIVE)) != 443 IFF_RUNNING) 444 return; 445 446 tmd = sc->sc_last_td; 447 cdm = &sc->sc_td[tmd]; 448 449 for (;;) { 450 if (sc->sc_no_td >= NTBUF) { 451 sc->sc_if.if_flags |= IFF_OACTIVE; 452 #ifdef LEDEBUG 453 if (sc->sc_debug) 454 printf("no_td = %d, last_td = %d\n", sc->sc_no_td, 455 sc->sc_last_td); 456 #endif 457 break; 458 } 459 460 #ifdef LEDEBUG 461 if (cdm->flags & LE_OWN) { 462 sc->sc_if.if_flags |= IFF_OACTIVE; 463 printf("missing buffer, no_td = %d, last_td = %d\n", 464 sc->sc_no_td, sc->sc_last_td); 465 } 466 #endif 467 468 IF_DEQUEUE(&sc->sc_if.if_snd, m); 469 if (!m) 470 break; 471 472 ++sc->sc_no_td; 473 474 /* 475 * Copy the mbuf chain into the transmit buffer. 476 */ 477 buffer = sc->sc_tbuf + (BUFSIZE * sc->sc_last_td); 478 len = 0; 479 for (m0 = m; m; m = m->m_next) { 480 bcopy(mtod(m, caddr_t), buffer, m->m_len); 481 buffer += m->m_len; 482 len += m->m_len; 483 } 484 485 #ifdef LEDEBUG 486 if (len > ETHER_MAX_LEN) 487 printf("packet length %d\n", len); 488 #endif 489 490 #if NBPFILTER > 0 491 if (sc->sc_if.if_bpf) 492 bpf_mtap(sc->sc_if.if_bpf, m0); 493 #endif 494 495 m_freem(m0); 496 len = max(len, ETHER_MIN_LEN); 497 498 /* 499 * Init transmit registers, and set transmit start flag. 500 */ 501 cdm->bcnt = -len; 502 cdm->mcnt = 0; 503 cdm->flags |= LE_OWN | LE_STP | LE_ENP; 504 505 #ifdef LEDEBUG 506 if (sc->sc_debug) 507 xmit_print(sc, sc->sc_last_td); 508 #endif 509 510 lewrcsr(sc, 0, LE_INEA | LE_TDMD); 511 512 NEXTTDS; 513 } 514 515 sc->sc_last_td = tmd; 516 } 517 518 void 519 letint(sc) 520 struct le_softc *sc; 521 { 522 register int tmd = (sc->sc_last_td - sc->sc_no_td + NTBUF) % NTBUF; 523 volatile struct mds *cdm; 524 525 cdm = &sc->sc_td[tmd]; 526 if (cdm->flags & LE_OWN) { 527 /* Race condition with loop below. */ 528 #ifdef LEDEBUG 529 if (sc->sc_debug) 530 printf("%s: extra tint\n", sc->sc_dev.dv_xname); 531 #endif 532 return; 533 } 534 535 sc->sc_if.if_flags &= ~IFF_OACTIVE; 536 537 do { 538 if (sc->sc_no_td <= 0) 539 break; 540 #ifdef LEDEBUG 541 if (sc->sc_debug) 542 printf("trans cdm = %x\n", cdm); 543 #endif 544 sc->sc_if.if_opackets++; 545 --sc->sc_no_td; 546 if (cdm->mcnt & (LE_TBUFF | LE_UFLO | LE_LCOL | LE_LCAR | LE_RTRY)) { 547 if (cdm->mcnt & LE_TBUFF) 548 printf("%s: transmit buffer error\n", sc->sc_dev.dv_xname); 549 if ((cdm->mcnt & (LE_TBUFF | LE_UFLO)) == LE_UFLO) 550 printf("%s: underflow\n", sc->sc_dev.dv_xname); 551 if (cdm->mcnt & LE_UFLO) { 552 lereset(sc); 553 return; 554 } 555 #if 0 556 if (cdm->mcnt & LE_LCOL) { 557 printf("%s: late collision\n", sc->sc_dev.dv_xname); 558 sc->sc_if.if_collisions++; 559 } 560 if (cdm->mcnt & LE_LCAR) 561 printf("%s: lost carrier\n", sc->sc_dev.dv_xname); 562 if (cdm->mcnt & LE_RTRY) { 563 printf("%s: excessive collisions, tdr %d\n", 564 sc->sc_dev.dv_xname, cdm->flags & 0x1ff); 565 sc->sc_if.if_collisions += 16; 566 } 567 #endif 568 } else if (cdm->flags & LE_ONE) 569 sc->sc_if.if_collisions++; 570 else if (cdm->flags & LE_MORE) 571 /* Real number is unknown. */ 572 sc->sc_if.if_collisions += 2; 573 NEXTTDS; 574 } while ((cdm->flags & LE_OWN) == 0); 575 576 lestart(&sc->sc_if); 577 } 578 579 #define NEXTRDS \ 580 if (++rmd == NRBUF) rmd=0, cdm=sc->sc_rd; else ++cdm 581 582 /* only called from one place, so may as well integrate */ 583 void 584 lerint(sc) 585 struct le_softc *sc; 586 { 587 register int rmd = sc->sc_last_rd; 588 volatile struct mds *cdm; 589 590 cdm = &sc->sc_rd[rmd]; 591 if (cdm->flags & LE_OWN) { 592 /* Race condition with loop below. */ 593 #ifdef LEDEBUG 594 if (sc->sc_debug) 595 printf("%s: extra rint\n", sc->sc_dev.dv_xname); 596 #endif 597 return; 598 } 599 600 /* Process all buffers with valid data. */ 601 do { 602 if (cdm->flags & LE_ERR) { 603 #ifdef LEDEBUG 604 /* 605 * XXX - These happen a LOT on the Sun3/50 so 606 * it is really NOT appropriate to print them. 607 */ 608 printf("%s: error, cdm->flags=%b\n", 609 sc->sc_dev.dv_xname, cdm->flags, RMD_BITS); 610 #endif 611 sc->sc_if.if_ierrors++; 612 } else if (cdm->flags & (LE_STP | LE_ENP) != (LE_STP | LE_ENP)) { 613 do { 614 cdm->mcnt = 0; 615 cdm->flags |= LE_OWN; 616 NEXTRDS; 617 } while ((cdm->flags & (LE_OWN | LE_ERR | LE_STP | LE_ENP)) == 0); 618 sc->sc_last_rd = rmd; 619 printf("%s: chained buffer\n", sc->sc_dev.dv_xname); 620 if ((cdm->flags & (LE_OWN | LE_ERR | LE_STP | LE_ENP)) != LE_ENP) { 621 lereset(sc); 622 return; 623 } 624 } else { 625 #ifdef LEDEBUG 626 if (sc->sc_debug) 627 recv_print(sc, sc->sc_last_rd); 628 #endif 629 leread(sc, sc->sc_rbuf + (BUFSIZE * rmd), 630 (int)cdm->mcnt); 631 sc->sc_if.if_ipackets++; 632 } 633 634 cdm->bcnt = -BUFSIZE; 635 cdm->mcnt = 0; 636 cdm->flags |= LE_OWN; 637 NEXTRDS; 638 #ifdef LEDEBUG 639 if (sc->sc_debug) 640 printf("sc->sc_last_rd = %x, cdm = %x\n", 641 sc->sc_last_rd, cdm); 642 #endif 643 } while ((cdm->flags & LE_OWN) == 0); 644 645 sc->sc_last_rd = rmd; 646 } 647 648 /* 649 * Pass a packet to the higher levels. 650 */ 651 void 652 leread(sc, buf, len) 653 register struct le_softc *sc; 654 u_char *buf; 655 int len; 656 { 657 struct ifnet *ifp; 658 struct mbuf *m; 659 struct ether_header *eh; 660 661 len -= 4; 662 if (len <= 0) 663 return; 664 665 /* Pull packet off interface. */ 666 ifp = &sc->sc_if; 667 m = leget(buf, len, ifp); 668 if (m == 0) 669 return; 670 671 /* We assume that the header fit entirely in one mbuf. */ 672 eh = mtod(m, struct ether_header *); 673 674 #if NBPFILTER > 0 675 /* 676 * Check if there's a BPF listener on this interface. 677 * If so, hand off the raw packet to BPF. 678 */ 679 if (ifp->if_bpf) { 680 bpf_mtap(ifp->if_bpf, m); 681 682 /* 683 * Note that the interface cannot be in promiscuous mode if 684 * there are no BPF listeners. And if we are in promiscuous 685 * mode, we have to check if this packet is really ours. 686 */ 687 if ((ifp->if_flags & IFF_PROMISC) && 688 (eh->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */ 689 bcmp(eh->ether_dhost, sc->sc_enaddr, 690 sizeof(eh->ether_dhost)) != 0) { 691 m_freem(m); 692 return; 693 } 694 } 695 #endif 696 697 /* We assume that the header fit entirely in one mbuf. */ 698 m->m_pkthdr.len -= sizeof(*eh); 699 m->m_len -= sizeof(*eh); 700 m->m_data += sizeof(*eh); 701 702 ether_input(ifp, eh, m); 703 } 704 705 /* 706 * Supporting routines 707 */ 708 709 /* 710 * Pull data off an interface. 711 * Len is length of data, with local net header stripped. 712 * We copy the data into mbufs. When full cluster sized units are present 713 * we copy into clusters. 714 */ 715 struct mbuf * 716 leget(buf, totlen, ifp) 717 u_char *buf; 718 int totlen; 719 struct ifnet *ifp; 720 { 721 struct mbuf *top, **mp, *m; 722 int len; 723 724 MGETHDR(m, M_DONTWAIT, MT_DATA); 725 if (m == 0) 726 return 0; 727 m->m_pkthdr.rcvif = ifp; 728 m->m_pkthdr.len = totlen; 729 len = MHLEN; 730 top = 0; 731 mp = ⊤ 732 733 while (totlen > 0) { 734 if (top) { 735 MGET(m, M_DONTWAIT, MT_DATA); 736 if (m == 0) { 737 m_freem(top); 738 return 0; 739 } 740 len = MLEN; 741 } 742 if (totlen >= MINCLSIZE) { 743 MCLGET(m, M_DONTWAIT); 744 if (m->m_flags & M_EXT) 745 len = MCLBYTES; 746 } 747 m->m_len = len = min(totlen, len); 748 bcopy((caddr_t)buf, mtod(m, caddr_t), len); 749 buf += len; 750 totlen -= len; 751 *mp = m; 752 mp = &m->m_next; 753 } 754 755 return top; 756 } 757 758 /* 759 * Process an ioctl request. 760 */ 761 int 762 leioctl(ifp, cmd, data) 763 register struct ifnet *ifp; 764 u_long cmd; 765 caddr_t data; 766 { 767 struct le_softc *sc = lecd.cd_devs[ifp->if_unit]; 768 struct ifaddr *ifa = (struct ifaddr *)data; 769 struct ifreq *ifr = (struct ifreq *)data; 770 int s, error = 0; 771 772 s = splimp(); 773 774 switch (cmd) { 775 776 case SIOCSIFADDR: 777 ifp->if_flags |= IFF_UP; 778 779 switch (ifa->ifa_addr->sa_family) { 780 #ifdef INET 781 case AF_INET: 782 leinit(sc); 783 arp_ifinit(&sc->sc_ac, ifa); 784 break; 785 #endif 786 #ifdef NS 787 /* XXX - This code is probably wrong. */ 788 case AF_NS: 789 { 790 register struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; 791 792 if (ns_nullhost(*ina)) 793 ina->x_host = 794 *(union ns_host *)(sc->sc_enaddr); 795 else 796 bcopy(ina->x_host.c_host, 797 sc->sc_enaddr, 798 sizeof(sc->sc_enaddr)); 799 /* Set new address. */ 800 leinit(sc); 801 break; 802 } 803 #endif 804 default: 805 leinit(sc); 806 break; 807 } 808 break; 809 810 case SIOCSIFFLAGS: 811 /* 812 * If interface is marked down and it is running, then stop it 813 */ 814 if ((ifp->if_flags & IFF_UP) == 0 && 815 (ifp->if_flags & IFF_RUNNING) != 0) { 816 /* 817 * If interface is marked down and it is running, then 818 * stop it. 819 */ 820 lestop(sc); 821 ifp->if_flags &= ~IFF_RUNNING; 822 } else if ((ifp->if_flags & IFF_UP) != 0 && 823 (ifp->if_flags & IFF_RUNNING) == 0) { 824 /* 825 * If interface is marked up and it is stopped, then 826 * start it. 827 */ 828 leinit(sc); 829 } else { 830 /* 831 * Reset the interface to pick up changes in any other 832 * flags that affect hardware registers. 833 */ 834 /*lestop(sc);*/ 835 leinit(sc); 836 } 837 #ifdef LEDEBUG 838 if (ifp->if_flags & IFF_DEBUG) 839 sc->sc_debug = 1; 840 else 841 sc->sc_debug = 0; 842 #endif 843 break; 844 845 case SIOCADDMULTI: 846 case SIOCDELMULTI: 847 error = (cmd == SIOCADDMULTI) ? 848 ether_addmulti(ifr, &sc->sc_ac): 849 ether_delmulti(ifr, &sc->sc_ac); 850 851 if (error == ENETRESET) { 852 /* 853 * Multicast list has changed; set the hardware filter 854 * accordingly. 855 */ 856 leinit(sc); 857 error = 0; 858 } 859 break; 860 861 default: 862 error = EINVAL; 863 } 864 (void) splx(s); 865 return error; 866 } 867 868 #ifdef LEDEBUG 869 void 870 recv_print(sc, no) 871 struct le_softc *sc; 872 int no; 873 { 874 struct mds *rmd; 875 int i, printed = 0; 876 u_short len; 877 878 rmd = &sc->sc_rd[no]; 879 len = rmd->mcnt; 880 printf("%s: receive buffer %d, len = %d\n", sc->sc_dev.dv_xname, no, 881 len); 882 printf("%s: status %x\n", sc->sc_dev.dv_xname, lerdcsr(sc, 0)); 883 for (i = 0; i < len; i++) { 884 if (!printed) { 885 printed = 1; 886 printf("%s: data: ", sc->sc_dev.dv_xname); 887 } 888 printf("%x ", *(sc->sc_rbuf + (BUFSIZE*no) + i)); 889 } 890 if (printed) 891 printf("\n"); 892 } 893 894 void 895 xmit_print(sc, no) 896 struct le_softc *sc; 897 int no; 898 { 899 struct mds *rmd; 900 int i, printed=0; 901 u_short len; 902 903 rmd = &sc->sc_td[no]; 904 len = -rmd->bcnt; 905 printf("%s: transmit buffer %d, len = %d\n", sc->sc_dev.dv_xname, no, 906 len); 907 printf("%s: status %x\n", sc->sc_dev.dv_xname, lerdcsr(sc, 0)); 908 printf("%s: addr %x, flags %x, bcnt %x, mcnt %x\n", 909 sc->sc_dev.dv_xname, rmd->addr, rmd->flags, rmd->bcnt, rmd->mcnt); 910 for (i = 0; i < len; i++) { 911 if (!printed) { 912 printed = 1; 913 printf("%s: data: ", sc->sc_dev.dv_xname); 914 } 915 printf("%x ", *(sc->sc_tbuf + (BUFSIZE*no) + i)); 916 } 917 if (printed) 918 printf("\n"); 919 } 920 #endif /* LEDEBUG */ 921 922 /* 923 * Set up the logical address filter. 924 */ 925 void 926 lesetladrf(ac, af) 927 struct arpcom *ac; 928 u_long *af; 929 { 930 struct ifnet *ifp = &ac->ac_if; 931 struct ether_multi *enm; 932 register u_char *cp, c; 933 register u_long crc; 934 register int i, len; 935 struct ether_multistep step; 936 937 /* 938 * Set up multicast address filter by passing all multicast addresses 939 * through a crc generator, and then using the high order 6 bits as an 940 * index into the 64 bit logical address filter. The high order bit 941 * selects the word, while the rest of the bits select the bit within 942 * the word. 943 */ 944 945 if (ifp->if_flags & IFF_PROMISC) { 946 ifp->if_flags |= IFF_ALLMULTI; 947 af[0] = af[1] = 0xffffffff; 948 return; 949 } 950 951 af[0] = af[1] = 0; 952 ETHER_FIRST_MULTI(step, ac, enm); 953 while (enm != NULL) { 954 if (bcmp(enm->enm_addrlo, enm->enm_addrhi, 955 sizeof(enm->enm_addrlo)) != 0) { 956 /* 957 * We must listen to a range of multicast addresses. 958 * For now, just accept all multicasts, rather than 959 * trying to set only those filter bits needed to match 960 * the range. (At this time, the only use of address 961 * ranges is for IP multicast routing, for which the 962 * range is big enough to require all bits set.) 963 */ 964 ifp->if_flags |= IFF_ALLMULTI; 965 af[0] = af[1] = 0xffffffff; 966 return; 967 } 968 969 cp = enm->enm_addrlo; 970 crc = 0xffffffff; 971 for (len = sizeof(enm->enm_addrlo); --len >= 0;) { 972 c = *cp++; 973 for (i = 8; --i >= 0;) { 974 if ((crc & 0x01) ^ (c & 0x01)) { 975 crc >>= 1; 976 crc ^= 0x6db88320 | 0x80000000; 977 } else 978 crc >>= 1; 979 c >>= 1; 980 } 981 } 982 /* Just want the 6 most significant bits. */ 983 crc >>= 26; 984 985 /* Turn on the corresponding bit in the filter. */ 986 af[crc >> 5] |= 1 << ((crc & 0x1f) ^ 0); 987 988 ETHER_NEXT_MULTI(step, enm); 989 } 990 ifp->if_flags &= ~IFF_ALLMULTI; 991 } 992