1 /* $NetBSD: if_le.c,v 1.16 1995/01/03 15:43:36 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 ETHER_MIN_LEN 64 61 #define ETHER_MAX_LEN 1518 62 63 /* 64 * The lance has only 24 address lines. When it accesses memory, 65 * the high address lines are hard-wired to 0xFF, so we must: 66 * (1) put what we want the LANCE to see above 0xFF000000, and 67 * (2) mask our CPU addresses down to 24 bits for the LANCE. 68 */ 69 #define LANCE_ADDR(sc,x) ((u_int)(x) & 0xFFffff) 70 71 #ifdef PACKETSTATS 72 long lexpacketsizes[LEMTU+1]; 73 long lerpacketsizes[LEMTU+1]; 74 #endif 75 76 /* autoconfiguration driver */ 77 void le_attach(struct device *, struct device *, void *); 78 79 struct cfdriver lecd = { 80 NULL, "le", le_md_match, le_attach, 81 DV_IFNET, sizeof(struct le_softc), 82 }; 83 84 int leioctl __P((struct ifnet *, u_long, caddr_t)); 85 int lestart __P((struct ifnet *)); 86 int lewatchdog __P((/* short */)); 87 static inline void lewrcsr __P((/* struct le_softc *, u_short, u_short */)); 88 static inline u_short lerdcsr __P((/* struct le_softc *, u_short */)); 89 void leinit __P((struct le_softc *)); 90 void lememinit __P((struct le_softc *)); 91 void lereset __P((struct le_softc *)); 92 void lestop __P((struct le_softc *)); 93 void letint __P((struct le_softc *)); 94 void lerint __P((struct le_softc *)); 95 void leread __P((struct le_softc *, u_char *, int)); 96 struct mbuf *leget __P((u_char *, int, struct ifnet *)); 97 void lesetladrf __P((struct arpcom *, u_long *)); 98 #ifdef LEDEBUG 99 void recv_print __P((struct le_softc *, int)); 100 void xmit_print __P((struct le_softc *, int)); 101 #endif 102 103 /* 104 * Inline routines to read and write the LANCE registers. 105 */ 106 107 static inline void 108 lewrcsr(sc, regnum, value) 109 struct le_softc *sc; 110 u_short regnum; 111 u_short value; 112 { 113 volatile struct le_regs *regs = sc->sc_regs; 114 115 regs->lereg_addr = regnum; 116 regs->lereg_data = value; 117 } 118 119 static inline u_short 120 lerdcsr(sc, regnum) 121 struct le_softc *sc; 122 u_short regnum; 123 { 124 volatile struct le_regs *regs = sc->sc_regs; 125 u_short value; 126 127 regs->lereg_addr = regnum; 128 value = regs->lereg_data; 129 130 return (value); 131 } 132 133 /* 134 * The probe is done in if_le_subr.c:if_md_match() 135 */ 136 137 /* 138 * Interface exists: make available by filling in network interface 139 * record. System will initialize the interface when it is ready 140 * to accept packets. We get the ethernet address here. 141 */ 142 void 143 le_attach(parent, self, aux) 144 struct device *parent, *self; 145 void *aux; 146 { 147 struct le_softc *sc = (void *)self; 148 struct confargs *ca = aux; 149 struct ifnet *ifp = &sc->sc_if; 150 int pri; 151 u_int a; 152 153 le_md_attach(parent, self, aux); 154 printf(" hwaddr %s\n", ether_sprintf(sc->sc_enaddr)); 155 156 /* 157 * Initialize and attach S/W interface 158 */ 159 ifp->if_unit = sc->sc_dev.dv_unit; 160 ifp->if_name = lecd.cd_name; 161 ifp->if_output = ether_output; 162 ifp->if_start = lestart; 163 ifp->if_ioctl = leioctl; 164 ifp->if_watchdog = lewatchdog; 165 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 166 #ifdef IFF_NOTRAILERS 167 /* XXX still compile when the blasted things are gone... */ 168 ifp->if_flags |= IFF_NOTRAILERS; 169 #endif 170 if_attach(ifp); 171 ether_ifattach(ifp); 172 #if NBPFILTER > 0 173 bpfattach(&sc->sc_if.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 int 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 int 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_FRAM | LE_OFLO | LE_CRC | LE_RBUFF)) { 603 if ((cdm->flags & (LE_FRAM | LE_OFLO | LE_ENP)) == (LE_FRAM | LE_ENP)) 604 printf("%s: framing error\n", sc->sc_dev.dv_xname); 605 if ((cdm->flags & (LE_OFLO | LE_ENP)) == LE_OFLO) 606 printf("%s: overflow\n", sc->sc_dev.dv_xname); 607 if ((cdm->flags & (LE_CRC | LE_OFLO | LE_ENP)) == (LE_CRC | LE_ENP)) 608 printf("%s: crc mismatch\n", sc->sc_dev.dv_xname); 609 if (cdm->flags & LE_RBUFF) 610 printf("%s: receive buffer error\n", sc->sc_dev.dv_xname); 611 } else if (cdm->flags & (LE_STP | LE_ENP) != (LE_STP | LE_ENP)) { 612 do { 613 cdm->mcnt = 0; 614 cdm->flags |= LE_OWN; 615 NEXTRDS; 616 } while ((cdm->flags & (LE_OWN | LE_ERR | LE_STP | LE_ENP)) == 0); 617 sc->sc_last_rd = rmd; 618 printf("%s: chained buffer\n", sc->sc_dev.dv_xname); 619 if ((cdm->flags & (LE_OWN | LE_ERR | LE_STP | LE_ENP)) != LE_ENP) { 620 lereset(sc); 621 return; 622 } 623 } else { 624 #ifdef LEDEBUG 625 if (sc->sc_debug) 626 recv_print(sc, sc->sc_last_rd); 627 #endif 628 leread(sc, sc->sc_rbuf + (BUFSIZE * rmd), 629 (int)cdm->mcnt); 630 sc->sc_if.if_ipackets++; 631 } 632 633 cdm->bcnt = -BUFSIZE; 634 cdm->mcnt = 0; 635 cdm->flags |= LE_OWN; 636 NEXTRDS; 637 #ifdef LEDEBUG 638 if (sc->sc_debug) 639 printf("sc->sc_last_rd = %x, cdm = %x\n", 640 sc->sc_last_rd, cdm); 641 #endif 642 } while ((cdm->flags & LE_OWN) == 0); 643 644 sc->sc_last_rd = rmd; 645 } 646 647 /* 648 * Pass a packet to the higher levels. 649 */ 650 void 651 leread(sc, buf, len) 652 register struct le_softc *sc; 653 u_char *buf; 654 int len; 655 { 656 struct ifnet *ifp; 657 struct mbuf *m; 658 struct ether_header *eh; 659 660 len -= 4; 661 if (len <= 0) 662 return; 663 664 /* Pull packet off interface. */ 665 ifp = &sc->sc_if; 666 m = leget(buf, len, ifp); 667 if (m == 0) 668 return; 669 670 /* We assume that the header fit entirely in one mbuf. */ 671 eh = mtod(m, struct ether_header *); 672 673 #if NBPFILTER > 0 674 /* 675 * Check if there's a BPF listener on this interface. 676 * If so, hand off the raw packet to BPF. 677 */ 678 if (ifp->if_bpf) { 679 bpf_mtap(ifp->if_bpf, m); 680 681 /* 682 * Note that the interface cannot be in promiscuous mode if 683 * there are no BPF listeners. And if we are in promiscuous 684 * mode, we have to check if this packet is really ours. 685 */ 686 if ((ifp->if_flags & IFF_PROMISC) && 687 (eh->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */ 688 bcmp(eh->ether_dhost, sc->sc_enaddr, 689 sizeof(eh->ether_dhost)) != 0) { 690 m_freem(m); 691 return; 692 } 693 } 694 #endif 695 696 /* We assume that the header fit entirely in one mbuf. */ 697 m->m_pkthdr.len -= sizeof(*eh); 698 m->m_len -= sizeof(*eh); 699 m->m_data += sizeof(*eh); 700 701 ether_input(ifp, eh, m); 702 } 703 704 /* 705 * Supporting routines 706 */ 707 708 /* 709 * Pull data off an interface. 710 * Len is length of data, with local net header stripped. 711 * We copy the data into mbufs. When full cluster sized units are present 712 * we copy into clusters. 713 */ 714 struct mbuf * 715 leget(buf, totlen, ifp) 716 u_char *buf; 717 int totlen; 718 struct ifnet *ifp; 719 { 720 struct mbuf *top, **mp, *m; 721 int len; 722 723 MGETHDR(m, M_DONTWAIT, MT_DATA); 724 if (m == 0) 725 return 0; 726 m->m_pkthdr.rcvif = ifp; 727 m->m_pkthdr.len = totlen; 728 len = MHLEN; 729 top = 0; 730 mp = ⊤ 731 732 while (totlen > 0) { 733 if (top) { 734 MGET(m, M_DONTWAIT, MT_DATA); 735 if (m == 0) { 736 m_freem(top); 737 return 0; 738 } 739 len = MLEN; 740 } 741 if (totlen >= MINCLSIZE) { 742 MCLGET(m, M_DONTWAIT); 743 if (m->m_flags & M_EXT) 744 len = MCLBYTES; 745 } 746 m->m_len = len = min(totlen, len); 747 bcopy((caddr_t)buf, mtod(m, caddr_t), len); 748 buf += len; 749 totlen -= len; 750 *mp = m; 751 mp = &m->m_next; 752 } 753 754 return top; 755 } 756 757 /* 758 * Process an ioctl request. 759 */ 760 int 761 leioctl(ifp, cmd, data) 762 register struct ifnet *ifp; 763 u_long cmd; 764 caddr_t data; 765 { 766 struct le_softc *sc = lecd.cd_devs[ifp->if_unit]; 767 struct ifaddr *ifa = (struct ifaddr *)data; 768 struct ifreq *ifr = (struct ifreq *)data; 769 int s, error = 0; 770 771 s = splimp(); 772 773 switch (cmd) { 774 775 case SIOCSIFADDR: 776 ifp->if_flags |= IFF_UP; 777 778 switch (ifa->ifa_addr->sa_family) { 779 #ifdef INET 780 case AF_INET: 781 leinit(sc); /* before arpwhohas */ 782 /* 783 * See if another station has *our* IP address. 784 * i.e.: There is an address conflict! If a 785 * conflict exists, a message is sent to the 786 * console. 787 */ 788 sc->sc_ac.ac_ipaddr = IA_SIN(ifa)->sin_addr; 789 arpwhohas(&sc->sc_ac, &IA_SIN(ifa)->sin_addr); 790 break; 791 #endif 792 #ifdef NS 793 /* XXX - This code is probably wrong. */ 794 case AF_NS: 795 { 796 register struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; 797 798 if (ns_nullhost(*ina)) 799 ina->x_host = 800 *(union ns_host *)(sc->sc_enaddr); 801 else 802 bcopy(ina->x_host.c_host, 803 sc->sc_enaddr, 804 sizeof(sc->sc_enaddr)); 805 /* Set new address. */ 806 leinit(sc); 807 break; 808 } 809 #endif 810 default: 811 leinit(sc); 812 break; 813 } 814 break; 815 816 case SIOCSIFFLAGS: 817 /* 818 * If interface is marked down and it is running, then stop it 819 */ 820 if ((ifp->if_flags & IFF_UP) == 0 && 821 (ifp->if_flags & IFF_RUNNING) != 0) { 822 /* 823 * If interface is marked down and it is running, then 824 * stop it. 825 */ 826 lestop(sc); 827 ifp->if_flags &= ~IFF_RUNNING; 828 } else if ((ifp->if_flags & IFF_UP) != 0 && 829 (ifp->if_flags & IFF_RUNNING) == 0) { 830 /* 831 * If interface is marked up and it is stopped, then 832 * start it. 833 */ 834 leinit(sc); 835 } else { 836 /* 837 * Reset the interface to pick up changes in any other 838 * flags that affect hardware registers. 839 */ 840 /*lestop(sc);*/ 841 leinit(sc); 842 } 843 #ifdef LEDEBUG 844 if (ifp->if_flags & IFF_DEBUG) 845 sc->sc_debug = 1; 846 else 847 sc->sc_debug = 0; 848 #endif 849 break; 850 851 case SIOCADDMULTI: 852 case SIOCDELMULTI: 853 error = (cmd == SIOCADDMULTI) ? 854 ether_addmulti(ifr, &sc->sc_ac): 855 ether_delmulti(ifr, &sc->sc_ac); 856 857 if (error == ENETRESET) { 858 /* 859 * Multicast list has changed; set the hardware filter 860 * accordingly. 861 */ 862 leinit(sc); 863 error = 0; 864 } 865 break; 866 867 default: 868 error = EINVAL; 869 } 870 (void) splx(s); 871 return error; 872 } 873 874 #ifdef LEDEBUG 875 void 876 recv_print(sc, no) 877 struct le_softc *sc; 878 int no; 879 { 880 struct mds *rmd; 881 int i, printed = 0; 882 u_short len; 883 884 rmd = &sc->sc_rd[no]; 885 len = rmd->mcnt; 886 printf("%s: receive buffer %d, len = %d\n", sc->sc_dev.dv_xname, no, 887 len); 888 printf("%s: status %x\n", sc->sc_dev.dv_xname, lerdcsr(sc, 0)); 889 for (i = 0; i < len; i++) { 890 if (!printed) { 891 printed = 1; 892 printf("%s: data: ", sc->sc_dev.dv_xname); 893 } 894 printf("%x ", *(sc->sc_rbuf + (BUFSIZE*no) + i)); 895 } 896 if (printed) 897 printf("\n"); 898 } 899 900 void 901 xmit_print(sc, no) 902 struct le_softc *sc; 903 int no; 904 { 905 struct mds *rmd; 906 int i, printed=0; 907 u_short len; 908 909 rmd = &sc->sc_td[no]; 910 len = -rmd->bcnt; 911 printf("%s: transmit buffer %d, len = %d\n", sc->sc_dev.dv_xname, no, 912 len); 913 printf("%s: status %x\n", sc->sc_dev.dv_xname, lerdcsr(sc, 0)); 914 printf("%s: addr %x, flags %x, bcnt %x, mcnt %x\n", 915 sc->sc_dev.dv_xname, rmd->addr, rmd->flags, rmd->bcnt, rmd->mcnt); 916 for (i = 0; i < len; i++) { 917 if (!printed) { 918 printed = 1; 919 printf("%s: data: ", sc->sc_dev.dv_xname); 920 } 921 printf("%x ", *(sc->sc_tbuf + (BUFSIZE*no) + i)); 922 } 923 if (printed) 924 printf("\n"); 925 } 926 #endif /* LEDEBUG */ 927 928 /* 929 * Set up the logical address filter. 930 */ 931 void 932 lesetladrf(ac, af) 933 struct arpcom *ac; 934 u_long *af; 935 { 936 struct ifnet *ifp = &ac->ac_if; 937 struct ether_multi *enm; 938 register u_char *cp, c; 939 register u_long crc; 940 register int i, len; 941 struct ether_multistep step; 942 943 /* 944 * Set up multicast address filter by passing all multicast addresses 945 * through a crc generator, and then using the high order 6 bits as an 946 * index into the 64 bit logical address filter. The high order bit 947 * selects the word, while the rest of the bits select the bit within 948 * the word. 949 */ 950 951 if (ifp->if_flags & IFF_PROMISC) { 952 ifp->if_flags |= IFF_ALLMULTI; 953 af[0] = af[1] = 0xffffffff; 954 return; 955 } 956 957 af[0] = af[1] = 0; 958 ETHER_FIRST_MULTI(step, ac, enm); 959 while (enm != NULL) { 960 if (bcmp(enm->enm_addrlo, enm->enm_addrhi, 961 sizeof(enm->enm_addrlo)) != 0) { 962 /* 963 * We must listen to a range of multicast addresses. 964 * For now, just accept all multicasts, rather than 965 * trying to set only those filter bits needed to match 966 * the range. (At this time, the only use of address 967 * ranges is for IP multicast routing, for which the 968 * range is big enough to require all bits set.) 969 */ 970 ifp->if_flags |= IFF_ALLMULTI; 971 af[0] = af[1] = 0xffffffff; 972 return; 973 } 974 975 cp = enm->enm_addrlo; 976 crc = 0xffffffff; 977 for (len = sizeof(enm->enm_addrlo); --len >= 0;) { 978 c = *cp++; 979 for (i = 8; --i >= 0;) { 980 if ((crc & 0x01) ^ (c & 0x01)) { 981 crc >>= 1; 982 crc ^= 0x6db88320 | 0x80000000; 983 } else 984 crc >>= 1; 985 c >>= 1; 986 } 987 } 988 /* Just want the 6 most significant bits. */ 989 crc >>= 26; 990 991 /* Turn on the corresponding bit in the filter. */ 992 af[crc >> 5] |= 1 << ((crc & 0x1f) ^ 0); 993 994 ETHER_NEXT_MULTI(step, enm); 995 } 996 ifp->if_flags &= ~IFF_ALLMULTI; 997 } 998