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