1 /* $NetBSD: if_le.c,v 1.12 1995/04/13 11:59:21 chopps Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1990 The Regents of the University of California. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)if_le.c 7.6 (Berkeley) 5/8/91 36 */ 37 38 #include "le.h" 39 #if NLE > 0 40 41 #include "bpfilter.h" 42 43 /* 44 * AMD 7990 LANCE 45 * 46 * This driver will generate and accept tailer encapsulated packets even 47 * though it buys us nothing. The motivation was to avoid incompatibilities 48 * with VAXen, SUNs, and others that handle and benefit from them. 49 * This reasoning is dubious. 50 */ 51 #include <sys/param.h> 52 #include <sys/systm.h> 53 #include <sys/mbuf.h> 54 #include <sys/buf.h> 55 #include <sys/protosw.h> 56 #include <sys/socket.h> 57 #include <sys/syslog.h> 58 #include <sys/ioctl.h> 59 #include <sys/errno.h> 60 #include <sys/device.h> 61 62 #include <net/if.h> 63 #include <net/netisr.h> 64 #include <net/route.h> 65 66 #ifdef INET 67 #include <netinet/in.h> 68 #include <netinet/in_systm.h> 69 #include <netinet/in_var.h> 70 #include <netinet/ip.h> 71 #include <netinet/if_ether.h> 72 #endif 73 74 #ifdef NS 75 #include <netns/ns.h> 76 #include <netns/ns_if.h> 77 #endif 78 79 #include <machine/cpu.h> 80 #include <machine/mtpr.h> 81 #include <amiga/amiga/device.h> 82 #include <amiga/amiga/isr.h> 83 #include <amiga/dev/zbusvar.h> 84 #include <amiga/dev/if_lereg.h> 85 86 /* 87 * Ethernet software status per interface. 88 * 89 * Each interface is referenced by a network interface structure, 90 * le_if, which the routing code uses to locate the interface. 91 * This structure contains the output queue for the interface, its address, ... 92 */ 93 struct le_softc { 94 struct isr sc_isr; 95 struct arpcom sc_ac; /* common Ethernet structures */ 96 #define sc_if sc_ac.ac_if /* network-visible interface */ 97 #define sc_addr sc_ac.ac_enaddr /* hardware Ethernet address */ 98 void *sc_base; /* base address of board */ 99 struct lereg1 *sc_r1; /* LANCE registers */ 100 struct lereg2 *sc_r2; /* dual-port RAM */ 101 int sc_rmd; /* predicted next rmd to process */ 102 int sc_tmd; /* next tmd to use */ 103 int sc_no_td; /* number of tmds in use */ 104 int sc_runt; 105 int sc_jab; 106 int sc_merr; 107 int sc_babl; 108 int sc_cerr; 109 int sc_miss; 110 int sc_xint; 111 int sc_xown; 112 int sc_uflo; 113 int sc_rxlen; 114 int sc_rxoff; 115 int sc_txoff; 116 int sc_busy; 117 short sc_iflags; 118 #if NBPFILTER > 0 119 caddr_t sc_bpf; 120 #endif 121 } le_softc[NLE]; 122 123 #if NBPFILTER > 0 124 #include <net/bpf.h> 125 #include <net/bpfdesc.h> 126 #endif 127 128 /* offsets for: ID, REGS, MEM */ 129 int lestd[] = { 0, 0x4000, 0x8000 }; 130 131 /* console error messages */ 132 int ledebug = 0; 133 134 int leioctl __P((struct ifnet *, u_long, caddr_t)); 135 int leintr __P((struct le_softc *)); 136 void lestart __P((struct ifnet *)); 137 void leinit __P((int)); 138 139 struct mbuf *leget(); 140 extern struct ifnet loif; 141 142 void leattach __P((struct device *, struct device *, void *)); 143 int lematch __P((struct device *, struct cfdata *, void *args)); 144 145 struct cfdriver lecd = { 146 NULL, "le", (cfmatch_t)lematch, leattach, DV_IFNET, 147 sizeof(struct le_softc), NULL, 0}; 148 149 int 150 lematch(pdp, cfp, auxp) 151 struct device *pdp; 152 struct cfdata *cfp; 153 void *auxp; 154 { 155 156 struct zbus_args *zap; 157 158 zap = (struct zbus_args *)auxp; 159 160 /* Commodore ethernet card */ 161 if ( zap->manid == 514 && zap->prodid == 112) 162 return(1); 163 164 /* Ameristar ethernet card */ 165 if ( zap->manid == 1053 && zap->prodid == 1) 166 return(1); 167 168 return (0); 169 } 170 171 /* 172 * Interface exists: make available by filling in network interface 173 * record. System will initialize the interface when it is ready 174 * to accept packets. 175 */ 176 void 177 leattach(pdp, dp, auxp) 178 struct device *pdp, *dp; 179 void *auxp; 180 { 181 register struct lereg0 *ler0; 182 register struct lereg2 *ler2; 183 struct zbus_args *zap; 184 struct lereg2 *lemem = (struct lereg2 *) 0x8000; 185 struct le_softc *le = &le_softc[dp->dv_unit]; 186 struct ifnet *ifp = &le->sc_if; 187 char *cp; 188 int i; 189 unsigned long ser; 190 int s = splhigh (); 191 192 zap =(struct zbus_args *)auxp; 193 194 /* 195 * Make config msgs look nicer. 196 */ 197 printf("\n"); 198 199 ler0 = le->sc_base = zap->va; 200 le->sc_r1 = (struct lereg1 *)(lestd[1] + (int)zap->va); 201 ler2 = le->sc_r2 = (struct lereg2 *)(lestd[2] + (int)zap->va); 202 203 /* 204 * Manufacturer decides the 3 first bytes, i.e. ethernet vendor ID. 205 */ 206 if ( zap->manid == 514 && zap->prodid == 112) { 207 /* Commodore 2065 */ 208 le->sc_addr[0] = 0x00; 209 le->sc_addr[1] = 0x80; 210 le->sc_addr[2] = 0x10; 211 } 212 if ( zap->manid == 1053 && zap->prodid == 1) { 213 le->sc_addr[0] = 0x00; 214 le->sc_addr[1] = 0x00; 215 le->sc_addr[2] = 0x9f; 216 } 217 218 /* 219 * Serial number for board is used as host ID. 220 */ 221 ser = (unsigned long) zap->serno; 222 223 le->sc_addr[3] = (ser >> 16) & 0xff; 224 le->sc_addr[4] = (ser >> 8) & 0xff; 225 le->sc_addr[5] = (ser ) & 0xff; 226 227 #ifdef LE_USE_16K 228 printf("le%d: hardware address %s 16K\n", 229 #else 230 printf("le%d: hardware address %s 32K\n", 231 #endif 232 dp->dv_unit, ether_sprintf(le->sc_addr)); 233 234 /* 235 * Setup for transmit/receive 236 */ 237 ler2->ler2_mode = LE_MODE; 238 ler2->ler2_padr[0] = le->sc_addr[1]; 239 ler2->ler2_padr[1] = le->sc_addr[0]; 240 ler2->ler2_padr[2] = le->sc_addr[3]; 241 ler2->ler2_padr[3] = le->sc_addr[2]; 242 ler2->ler2_padr[4] = le->sc_addr[5]; 243 ler2->ler2_padr[5] = le->sc_addr[4]; 244 ler2->ler2_ladrf0 = 0; 245 ler2->ler2_ladrf1 = 0; 246 ler2->ler2_rlen = LE_RLEN; 247 ler2->ler2_rdra = (int)lemem->ler2_rmd; 248 ler2->ler2_tlen = LE_TLEN; 249 ler2->ler2_tdra = (int)lemem->ler2_tmd; 250 251 splx (s); 252 253 ifp->if_unit = dp->dv_unit; 254 ifp->if_name = "le"; 255 ifp->if_mtu = ETHERMTU; 256 ifp->if_ioctl = leioctl; 257 ifp->if_output = ether_output; 258 ifp->if_start = lestart; 259 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; 260 261 #if NBPFILTER > 0 262 bpfattach(&le->sc_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); 263 #endif 264 if_attach(ifp); 265 ether_ifattach(ifp); 266 267 le->sc_isr.isr_intr = leintr; 268 le->sc_isr.isr_arg = le; 269 le->sc_isr.isr_ipl = 2; 270 add_isr (&le->sc_isr); 271 272 return; 273 } 274 275 ledrinit(ler2) 276 register struct lereg2 *ler2; 277 { 278 register struct lereg2 *lemem = (struct lereg2 *) 0x8000; 279 register int i; 280 281 for (i = 0; i < LERBUF; i++) { 282 ler2->ler2_rmd[i].rmd0 = (int)lemem->ler2_rbuf[i]; 283 ler2->ler2_rmd[i].rmd1 = LE_OWN; 284 ler2->ler2_rmd[i].rmd2 = -LEMTU; 285 ler2->ler2_rmd[i].rmd3 = 0; 286 } 287 288 for (i = 0; i < LETBUF; i++) { 289 ler2->ler2_tmd[i].tmd0 = (int)lemem->ler2_tbuf[i]; 290 ler2->ler2_tmd[i].tmd1 = 0; 291 ler2->ler2_tmd[i].tmd2 = 0; 292 ler2->ler2_tmd[i].tmd3 = 0; 293 } 294 } 295 296 void 297 lereset(unit) 298 register int unit; 299 { 300 register struct le_softc *le = &le_softc[unit]; 301 register struct lereg1 *ler1 = le->sc_r1; 302 /* 303 * This structure is referenced from the CARDS/LANCE point of 304 * view, thus the 0x8000 address which is the buffer RAM area of 305 * the Commodore and Ameristar cards. This pointer is manipulated 306 * with the LANCE's view of memory and NOT the Amiga's. FYI. 307 */ 308 register struct lereg2 *lemem = (struct lereg2 *) 0x8000; 309 310 register int timo = 100000; 311 register int stat; 312 313 #ifdef lint 314 stat = unit; 315 #endif 316 #if NBPFILTER > 0 317 if (le->sc_if.if_flags & IFF_PROMISC) 318 /* set the promiscuous bit */ 319 le->sc_r2->ler2_mode = LE_MODE|0x8000; 320 else 321 le->sc_r2->ler2_mode = LE_MODE; 322 #endif 323 ler1->ler1_rap = LE_CSR0; 324 ler1->ler1_rdp = LE_STOP; 325 326 ledrinit(le->sc_r2); 327 328 le->sc_rmd = le->sc_tmd = le->sc_no_td = 0; 329 ler1->ler1_rap = LE_CSR1; 330 ler1->ler1_rdp = (int)&lemem->ler2_mode; 331 ler1->ler1_rap = LE_CSR2; 332 ler1->ler1_rdp = 0; 333 ler1->ler1_rap = LE_CSR0; 334 ler1->ler1_rdp = LE_INIT; 335 336 do { 337 if (--timo == 0) { 338 printf("le%d: init timeout, stat = 0x%x\n", 339 unit, stat); 340 break; 341 } 342 stat = ler1->ler1_rdp; 343 } while ((stat & LE_IDON) == 0); 344 345 ler1->ler1_rdp = LE_STOP; 346 ler1->ler1_rap = LE_CSR3; 347 ler1->ler1_rdp = LE_BSWP; 348 ler1->ler1_rap = LE_CSR0; 349 ler1->ler1_rdp = LE_STRT | LE_INEA; 350 le->sc_if.if_flags &= ~IFF_OACTIVE; 351 352 return; 353 } 354 355 /* 356 * Initialization of interface 357 */ 358 void 359 leinit(unit) 360 int unit; 361 { 362 struct le_softc *le = &le_softc[unit]; 363 register struct ifnet *ifp = &le->sc_if; 364 int s; 365 366 /* not yet, if address still unknown */ 367 if (ifp->if_addrlist == (struct ifaddr *)0) 368 return; 369 370 if ((ifp->if_flags & IFF_RUNNING) == 0) { 371 s = splimp(); 372 ifp->if_flags |= IFF_RUNNING; 373 lereset(unit); 374 (void) lestart(ifp); 375 splx(s); 376 } 377 378 return; 379 } 380 381 #define LENEXTTMP \ 382 if (++bix == LETBUF) bix = 0, tmd = le->sc_r2->ler2_tmd; else ++tmd 383 384 /* 385 * Start output on interface. Get another datagram to send 386 * off of the interface queue, and copy it to the interface 387 * before starting the output. 388 */ 389 void 390 lestart(ifp) 391 struct ifnet *ifp; 392 { 393 register struct le_softc *le = &le_softc[ifp->if_unit]; 394 register int bix; 395 register struct letmd *tmd; 396 register struct mbuf *m; 397 int len; 398 399 if ((le->sc_if.if_flags & IFF_RUNNING) == 0) 400 return; 401 402 bix = le->sc_tmd; 403 tmd = &le->sc_r2->ler2_tmd[bix]; 404 405 for (;;) { 406 if (le->sc_no_td >= LETBUF) { 407 le->sc_if.if_flags |= IFF_OACTIVE; 408 break; 409 } 410 411 IF_DEQUEUE(&le->sc_if.if_snd, m); 412 if (m == 0) 413 break; 414 415 ++le->sc_no_td; 416 417 len = leput(le->sc_r2->ler2_tbuf[bix], m); 418 419 #if NBPFILTER > 0 420 /* 421 * If bpf is listening on this interface, let it 422 * see the packet before we commit it to the wire. 423 */ 424 if (le->sc_bpf) 425 bpf_tap(le->sc_bpf, le->sc_r2->ler2_tbuf[bix], len); 426 #endif 427 428 tmd->tmd3 = 0; 429 tmd->tmd2 = -len; 430 tmd->tmd1 = LE_OWN | LE_STP | LE_ENP; 431 432 LENEXTTMP; 433 } 434 435 le->sc_tmd = bix; 436 } 437 438 int 439 leintr(le) 440 struct le_softc *le; 441 { 442 #if 0 443 register struct le_softc *le = &le_softc[unit]; 444 #else 445 int unit = le->sc_if.if_unit; 446 #endif 447 register struct lereg1 *ler1; 448 register int stat; 449 450 /* if not even initialized, don't do anything further.. */ 451 if (! le->sc_base) 452 return 0; 453 454 ler1 = le->sc_r1; 455 stat = ler1->ler1_rdp; 456 457 if (! (stat & LE_INTR)) 458 return 0; 459 460 if (stat & LE_SERR) { 461 leerror(unit, stat); 462 if (stat & LE_MERR) { 463 le->sc_merr++; 464 lereset(unit); 465 return(1); 466 } 467 if (stat & LE_BABL) 468 le->sc_babl++; 469 if (stat & LE_CERR) 470 le->sc_cerr++; 471 if (stat & LE_MISS) 472 le->sc_miss++; 473 ler1->ler1_rdp = LE_BABL|LE_CERR|LE_MISS|LE_INEA; 474 } 475 if ((stat & LE_RXON) == 0) { 476 le->sc_rxoff++; 477 lereset(unit); 478 return(1); 479 } 480 if ((stat & LE_TXON) == 0) { 481 le->sc_txoff++; 482 lereset(unit); 483 return(1); 484 } 485 if (stat & LE_RINT) { 486 /* interrupt is cleared in lerint */ 487 lerint(unit); 488 } 489 if (stat & LE_TINT) { 490 ler1->ler1_rdp = LE_TINT|LE_INEA; 491 lexint(unit); 492 } 493 return(1); 494 } 495 496 /* 497 * Ethernet interface transmitter interrupt. 498 * Start another output if more data to send. 499 */ 500 lexint(unit) 501 register int unit; 502 { 503 register struct le_softc *le = &le_softc[unit]; 504 register int bix = (le->sc_tmd - le->sc_no_td + LETBUF) % LETBUF; 505 register struct letmd *tmd = &le->sc_r2->ler2_tmd[bix]; 506 507 if ((le->sc_if.if_flags & IFF_OACTIVE) == 0) { 508 le->sc_xint++; 509 return; 510 } 511 if (tmd->tmd1 & LE_OWN) { 512 printf("le%d: extra xint\n", unit); 513 le->sc_xown++; 514 return; 515 } 516 le->sc_if.if_flags &= ~IFF_OACTIVE; 517 518 do { 519 if (le->sc_no_td <= 0) 520 break; 521 --le->sc_no_td; 522 523 if (tmd->tmd1 & LE_ERR) { 524 err: 525 printf("le%d: xint error\n", unit); 526 lexerror(unit); 527 le->sc_if.if_oerrors++; 528 if (tmd->tmd3 & (LE_TBUFF|LE_UFLO)) { 529 le->sc_uflo++; 530 lereset(unit); 531 return; 532 } 533 else if (tmd->tmd3 & LE_LCOL) 534 le->sc_if.if_collisions++; 535 else if (tmd->tmd3 & LE_RTRY) 536 le->sc_if.if_collisions += 16; 537 } 538 else if (tmd->tmd3 & LE_TBUFF) 539 /* XXX documentation says BUFF not included in ERR */ 540 goto err; 541 else if (tmd->tmd1 & LE_ONE) 542 le->sc_if.if_collisions++; 543 else if (tmd->tmd1 & LE_MORE) 544 /* what is the real number? */ 545 le->sc_if.if_collisions += 2; 546 else 547 le->sc_if.if_opackets++; 548 LENEXTTMP; 549 } while ((tmd->tmd1 & LE_OWN) == 0); 550 551 (void) lestart(&le->sc_if); 552 } 553 554 #define LENEXTRMP \ 555 if (++bix == LERBUF) bix = 0, rmd = le->sc_r2->ler2_rmd; else ++rmd 556 557 /* 558 * Ethernet interface receiver interrupt. 559 * If input error just drop packet. 560 * Decapsulate packet based on type and pass to type specific 561 * higher-level input routine. 562 */ 563 lerint(unit) 564 int unit; 565 { 566 register struct le_softc *le = &le_softc[unit]; 567 register int bix = le->sc_rmd; 568 register struct lermd *rmd = &le->sc_r2->ler2_rmd[bix]; 569 570 /* 571 * Out of sync with hardware, should never happen? 572 */ 573 if (rmd->rmd1 & LE_OWN) { 574 le->sc_r1->ler1_rdp = LE_RINT|LE_INEA; 575 return; 576 } 577 578 /* 579 * Process all buffers with valid data 580 */ 581 while ((rmd->rmd1 & LE_OWN) == 0) { 582 int len = rmd->rmd3; 583 584 /* Clear interrupt to avoid race condition */ 585 le->sc_r1->ler1_rdp = LE_RINT|LE_INEA; 586 587 if (rmd->rmd1 & LE_ERR) { 588 le->sc_rmd = bix; 589 lererror(unit, "bad packet"); 590 le->sc_if.if_ierrors++; 591 } else if ((rmd->rmd1 & (LE_STP|LE_ENP)) != (LE_STP|LE_ENP)) { 592 /* 593 * Find the end of the packet so we can see how long 594 * it was. We still throw it away. 595 */ 596 do { 597 le->sc_r1->ler1_rdp = LE_RINT|LE_INEA; 598 rmd->rmd3 = 0; 599 rmd->rmd1 = LE_OWN; 600 LENEXTRMP; 601 } while (!(rmd->rmd1 & (LE_OWN|LE_ERR|LE_STP|LE_ENP))); 602 603 le->sc_rmd = bix; 604 lererror(unit, "chained buffer"); 605 le->sc_rxlen++; 606 607 /* 608 * If search terminated without successful completion 609 * we reset the hardware (conservative). 610 */ 611 if ((rmd->rmd1 & (LE_OWN|LE_ERR|LE_STP|LE_ENP)) != LE_ENP) { 612 lereset(unit); 613 return; 614 } 615 } else 616 leread(unit, le->sc_r2->ler2_rbuf[bix], len); 617 618 rmd->rmd3 = 0; 619 rmd->rmd1 = LE_OWN; 620 LENEXTRMP; 621 622 } 623 624 le->sc_rmd = bix; 625 } 626 627 leread(unit, buf, len) 628 int unit; 629 char *buf; 630 int len; 631 { 632 register struct le_softc *le = &le_softc[unit]; 633 register struct ether_header *et; 634 struct mbuf *m; 635 int off, resid; 636 637 le->sc_if.if_ipackets++; 638 639 et = (struct ether_header *)buf; 640 et->ether_type = ntohs((u_short)et->ether_type); 641 642 /* adjust input length to account for header and CRC */ 643 len = len - sizeof(struct ether_header) - 4; 644 645 #define ledataaddr(et, off, type) ((type)(((caddr_t)((et)+1)+(off)))) 646 if (et->ether_type >= ETHERTYPE_TRAIL && 647 et->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) { 648 off = (et->ether_type - ETHERTYPE_TRAIL) * 512; 649 if (off >= ETHERMTU) 650 return; /* sanity */ 651 et->ether_type = ntohs(*ledataaddr(et, off, u_short *)); 652 resid = ntohs(*(ledataaddr(et, off+2, u_short *))); 653 if (off + resid > len) 654 return; /* sanity */ 655 len = off + resid; 656 } else 657 off = 0; 658 659 if (len <= 0) { 660 if (ledebug) 661 log(LOG_WARNING, 662 "le%d: ierror(runt packet): from %s: len=%d\n", 663 unit, ether_sprintf(et->ether_shost), len); 664 le->sc_runt++; 665 le->sc_if.if_ierrors++; 666 return; 667 } 668 #if NBPFILTER > 0 669 /* 670 * Check if there's a bpf filter listening on this interface. 671 * If so, hand off the raw packet to bpf, which must deal with 672 * trailers in its own way. 673 */ 674 if (le->sc_bpf) { 675 bpf_tap(le->sc_bpf, buf, len + sizeof(struct ether_header)); 676 677 /* 678 * Note that the interface cannot be in promiscuous mode if 679 * there are no bpf listeners. And if we are in promiscuous 680 * mode, we have to check if this packet is really ours. 681 * 682 * XXX This test does not support multicasts. 683 */ 684 if ((le->sc_if.if_flags & IFF_PROMISC) 685 && bcmp(et->ether_dhost, le->sc_addr, 686 sizeof(et->ether_dhost)) != 0 687 && bcmp(et->ether_dhost, etherbroadcastaddr, 688 sizeof(et->ether_dhost)) != 0) 689 return; 690 } 691 #endif 692 /* 693 * Pull packet off interface. Off is nonzero if packet 694 * has trailing header; leget will then force this header 695 * information to be at the front, but we still have to drop 696 * the type and length which are at the front of any trailer data. 697 */ 698 m = leget(buf, len, off, &le->sc_if); 699 if (m == 0) 700 return; 701 702 ether_input(&le->sc_if, et, m); 703 } 704 705 /* 706 * Routine to copy from mbuf chain to transmit 707 * buffer in board local memory. 708 */ 709 leput(lebuf, m) 710 register char *lebuf; 711 register struct mbuf *m; 712 { 713 register struct mbuf *mp; 714 register int len, tlen = 0; 715 716 for (mp = m; mp; mp = mp->m_next) { 717 len = mp->m_len; 718 if (len == 0) 719 continue; 720 tlen += len; 721 bcopy(mtod(mp, char *), lebuf, len); 722 lebuf += len; 723 } 724 725 m_freem(m); 726 727 if (tlen < LEMINSIZE) { 728 bzero(lebuf, LEMINSIZE - tlen); 729 tlen = LEMINSIZE; 730 } 731 732 return(tlen); 733 } 734 735 /* 736 * Routine to copy from board local memory into mbufs. 737 */ 738 struct mbuf * 739 leget(lebuf, totlen, off0, ifp) 740 char *lebuf; 741 int totlen, off0; 742 struct ifnet *ifp; 743 { 744 register struct mbuf *m; 745 struct mbuf *top = 0, **mp = ⊤ 746 register int off = off0, len; 747 register char *cp; 748 char *epkt; 749 750 lebuf += sizeof (struct ether_header); 751 cp = lebuf; 752 epkt = cp + totlen; 753 if (off) { 754 cp += off + 2 * sizeof(u_short); 755 totlen -= 2 * sizeof(u_short); 756 } 757 758 MGETHDR(m, M_DONTWAIT, MT_DATA); 759 760 if (m == 0) 761 return (0); 762 763 m->m_pkthdr.rcvif = ifp; 764 m->m_pkthdr.len = totlen; 765 m->m_len = MHLEN; 766 767 while (totlen > 0) { 768 769 if (top) { 770 MGET(m, M_DONTWAIT, MT_DATA); 771 if (m == 0) { 772 m_freem(top); 773 return (0); 774 } 775 m->m_len = MLEN; 776 } 777 778 len = min(totlen, epkt - cp); 779 if (len >= MINCLSIZE) { 780 MCLGET(m, M_DONTWAIT); 781 if (m->m_flags & M_EXT) 782 m->m_len = len = min(len, MCLBYTES); 783 else 784 len = m->m_len; 785 } else { 786 /* 787 * Place initial small packet/header at end of mbuf. 788 */ 789 if (len < m->m_len) { 790 if (top == 0 && len + max_linkhdr <= m->m_len) 791 m->m_data += max_linkhdr; 792 m->m_len = len; 793 } else 794 len = m->m_len; 795 } 796 797 bcopy(cp, mtod(m, caddr_t), (unsigned)len); 798 cp += len; 799 *mp = m; 800 mp = &m->m_next; 801 totlen -= len; 802 803 if (cp == epkt) 804 cp = lebuf; 805 806 } 807 808 return (top); 809 } 810 811 /* 812 * Process an ioctl request. 813 */ 814 int 815 leioctl(ifp, cmd, data) 816 register struct ifnet *ifp; 817 u_long cmd; 818 caddr_t data; 819 { 820 register struct ifaddr *ifa = (struct ifaddr *)data; 821 struct le_softc *le = &le_softc[ifp->if_unit]; 822 struct lereg1 *ler1 = le->sc_r1; 823 int s = splimp(), error = 0; 824 825 switch (cmd) { 826 827 case SIOCSIFADDR: 828 ifp->if_flags |= IFF_UP; 829 switch (ifa->ifa_addr->sa_family) { 830 #ifdef INET 831 case AF_INET: 832 leinit(ifp->if_unit); 833 arp_ifinit(&le->sc_ac, ifa); 834 break; 835 #endif 836 #ifdef NS 837 case AF_NS: 838 { 839 register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); 840 841 if (ns_nullhost(*ina)) 842 ina->x_host = *(union ns_host *)(le->sc_addr); 843 else { 844 /* 845 * The manual says we can't change the address 846 * while the receiver is armed, 847 * so reset everything 848 */ 849 ifp->if_flags &= ~IFF_RUNNING; 850 bcopy((caddr_t)ina->x_host.c_host, 851 (caddr_t)le->sc_addr, sizeof(le->sc_addr)); 852 } 853 leinit(ifp->if_unit); /* does le_setaddr() */ 854 break; 855 } 856 #endif 857 default: 858 leinit(ifp->if_unit); 859 break; 860 } 861 break; 862 863 case SIOCSIFFLAGS: 864 if ((ifp->if_flags & IFF_UP) == 0 && 865 ifp->if_flags & IFF_RUNNING) { 866 ler1->ler1_rdp = LE_STOP; 867 ifp->if_flags &= ~IFF_RUNNING; 868 } else if (ifp->if_flags & IFF_UP && (ifp->if_flags & IFF_RUNNING) == 0) 869 leinit(ifp->if_unit); 870 871 /* 872 * If the state of the promiscuous bit changes, the interface 873 * must be reset to effect the change. 874 */ 875 if (((ifp->if_flags ^ le->sc_iflags) & IFF_PROMISC) && (ifp->if_flags & IFF_RUNNING)) { 876 le->sc_iflags = ifp->if_flags; 877 lereset(ifp->if_unit); 878 lestart(ifp); 879 } 880 break; 881 882 default: 883 error = EINVAL; 884 } 885 886 splx(s); 887 return (error); 888 } 889 890 leerror(unit, stat) 891 int unit; 892 int stat; 893 { 894 if (!ledebug) 895 return; 896 897 /* 898 * Not all transceivers implement heartbeat 899 * so we only log CERR once. 900 */ 901 if ((stat & LE_CERR) && le_softc[unit].sc_cerr) 902 return; 903 904 log(LOG_WARNING, 905 "le%d: error: stat=%b\n", unit, 906 stat, 907 "\20\20ERR\17BABL\16CERR\15MISS\14MERR\13RINT\12TINT\11IDON\10INTR\07INEA\06RXON\05TXON\04TDMD\03STOP\02STRT\01INIT"); 908 } 909 910 lererror(unit, msg) 911 int unit; 912 char *msg; 913 { 914 register struct le_softc *le = &le_softc[unit]; 915 register struct lermd *rmd; 916 int len; 917 918 if (!ledebug) 919 return; 920 921 rmd = &le->sc_r2->ler2_rmd[le->sc_rmd]; 922 len = rmd->rmd3; 923 924 log(LOG_WARNING, 925 "le%d: ierror(%s): from %s: buf=%d, len=%d, rmd1=%b\n", 926 unit, msg, 927 len > 11 ? ether_sprintf(&le->sc_r2->ler2_rbuf[le->sc_rmd][6]) : "unknown", 928 le->sc_rmd, len, 929 rmd->rmd1, 930 "\20\20OWN\17ERR\16FRAM\15OFLO\14CRC\13RBUF\12STP\11ENP"); 931 } 932 933 lexerror(unit) 934 int unit; 935 { 936 register struct le_softc *le = &le_softc[unit]; 937 int bix; 938 register struct letmd *tmd; 939 int len; 940 941 if (!ledebug) 942 return; 943 944 bix = (le->sc_tmd - le->sc_no_td + LETBUF) % LETBUF; 945 tmd = &le->sc_r2->ler2_tmd[bix]; 946 len = -tmd->tmd2; 947 948 log(LOG_WARNING, 949 "le%d: oerror: to %s: buf=%d, len=%d, tmd1=%b, tmd3=%b\n", 950 unit, 951 len > 5 ? ether_sprintf(&le->sc_r2->ler2_tbuf[0][0]) : "unknown", 952 0, len, 953 tmd->tmd1, 954 "\20\20OWN\17ERR\16RES\15MORE\14ONE\13DEF\12STP\11ENP", 955 tmd->tmd3, 956 "\20\20BUFF\17UFLO\16RES\15LCOL\14LCAR\13RTRY"); 957 } 958 959 #endif 960 961 962