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