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.12 1994/05/13 08:36:17 mycroft Exp $ 35 */ 36 37 #include "le.h" 38 #if NLE > 0 39 40 #include "bpfilter.h" 41 42 /* 43 * AMD 7990 LANCE 44 */ 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/kernel.h> 48 #include <sys/mbuf.h> 49 #include <sys/buf.h> 50 #include <sys/socket.h> 51 #include <sys/syslog.h> 52 #include <sys/ioctl.h> 53 #include <sys/malloc.h> 54 #include <sys/errno.h> 55 56 #include <net/if.h> 57 #include <net/netisr.h> 58 #include <net/route.h> 59 #if NBPFILTER > 0 60 #include <net/bpf.h> 61 #include <net/bpfdesc.h> 62 #endif 63 64 #ifdef INET 65 #include <netinet/in.h> 66 #include <netinet/in_systm.h> 67 #include <netinet/in_var.h> 68 #include <netinet/ip.h> 69 #include <netinet/if_ether.h> 70 #endif 71 72 #ifdef NS 73 #include <netns/ns.h> 74 #include <netns/ns_if.h> 75 #endif 76 77 #include <machine/cpu.h> 78 #include <hp300/hp300/isr.h> 79 #include <machine/mtpr.h> 80 81 #include <hp300/dev/device.h> 82 #include <hp300/dev/if_lereg.h> 83 84 /* offsets for: ID, REGS, MEM, NVRAM */ 85 int lestd[] = { 0, 0x4000, 0x8000, 0xC008 }; 86 87 struct isr le_isr[NLE]; 88 int ledebug = 0; /* console error messages */ 89 90 /* 91 * Ethernet software status per interface. 92 * 93 * Each interface is referenced by a network interface structure, 94 * le_if, which the routing code uses to locate the interface. 95 * This structure contains the output queue for the interface, its address, ... 96 */ 97 struct le_softc { 98 struct arpcom sc_ac; /* common Ethernet structures */ 99 #define sc_if sc_ac.ac_if /* network-visible interface */ 100 #define sc_addr sc_ac.ac_enaddr /* hardware Ethernet address */ 101 struct lereg0 *sc_r0; /* DIO registers */ 102 struct lereg1 *sc_r1; /* LANCE registers */ 103 struct lereg2 *sc_r2; /* dual-port RAM */ 104 int sc_rmd; /* predicted next rmd to process */ 105 int sc_tmd; /* next available tmd */ 106 int sc_txcnt; /* # of transmit buffers in use */ 107 /* stats */ 108 int sc_runt; 109 int sc_jab; 110 int sc_merr; 111 int sc_babl; 112 int sc_cerr; 113 int sc_miss; 114 int sc_rown; 115 int sc_xint; 116 int sc_xown; 117 int sc_xown2; 118 int sc_uflo; 119 int sc_rxlen; 120 int sc_rxoff; 121 int sc_txoff; 122 int sc_busy; 123 short sc_iflags; 124 } le_softc[NLE]; 125 126 /* access LANCE registers */ 127 #define LERDWR(cntl, src, dst) \ 128 do { \ 129 (dst) = (src); \ 130 } while (((cntl)->ler0_status & LE_ACK) == 0); 131 132 int leattach __P((struct hp_device *)); 133 void lesetladrf __P((struct arpcom *, u_long *)); 134 void ledrinit __P((struct lereg2 *)); 135 void lereset __P((struct le_softc *)); 136 void leinit __P((int)); 137 int lestart __P((struct ifnet *)); 138 int leintr __P((int)); 139 void lexint __P((struct le_softc *)); 140 void lerint __P((struct le_softc *)); 141 void leread __P((struct le_softc *, char *, int)); 142 int leput __P((char *, struct mbuf *)); 143 struct mbuf *leget __P((char *, int, int, struct ifnet *)); 144 int leioctl __P((struct ifnet *, int, caddr_t)); 145 void leerror __P((struct le_softc *, int)); 146 void lererror __P((struct le_softc *, char *)); 147 void lexerror __P((struct le_softc *)); 148 int ether_output(); 149 150 struct driver ledriver = { 151 leattach, "le", 152 }; 153 154 /* 155 * Interface exists: make available by filling in network interface 156 * record. System will initialize the interface when it is ready 157 * to accept packets. 158 */ 159 int 160 leattach(hd) 161 struct hp_device *hd; 162 { 163 register struct lereg0 *ler0; 164 register struct lereg2 *ler2; 165 struct lereg2 *lemem = 0; 166 struct le_softc *sc = &le_softc[hd->hp_unit]; 167 struct ifnet *ifp = &sc->sc_if; 168 char *cp; 169 int i; 170 171 ler0 = sc->sc_r0 = (struct lereg0 *)(lestd[0] + (int)hd->hp_addr); 172 sc->sc_r1 = (struct lereg1 *)(lestd[1] + (int)hd->hp_addr); 173 ler2 = sc->sc_r2 = (struct lereg2 *)(lestd[2] + (int)hd->hp_addr); 174 if (ler0->ler0_id != LEID) 175 return(0); 176 le_isr[hd->hp_unit].isr_intr = leintr; 177 hd->hp_ipl = le_isr[hd->hp_unit].isr_ipl = LE_IPL(ler0->ler0_status); 178 le_isr[hd->hp_unit].isr_arg = hd->hp_unit; 179 ler0->ler0_id = 0xFF; 180 DELAY(100); 181 182 /* 183 * Read the ethernet address off the board, one nibble at a time. 184 */ 185 cp = (char *)(lestd[3] + (int)hd->hp_addr); 186 for (i = 0; i < sizeof(sc->sc_addr); i++) { 187 sc->sc_addr[i] = (*++cp & 0xF) << 4; 188 cp++; 189 sc->sc_addr[i] |= *++cp & 0xF; 190 cp++; 191 } 192 printf("le%d: hardware address %s\n", hd->hp_unit, 193 ether_sprintf(sc->sc_addr)); 194 195 /* 196 * Setup for transmit/receive 197 */ 198 ler2->ler2_mode = LE_MODE; 199 ler2->ler2_rlen = LE_RLEN; 200 ler2->ler2_rdra = (int)lemem->ler2_rmd; 201 ler2->ler2_tlen = LE_TLEN; 202 ler2->ler2_tdra = (int)lemem->ler2_tmd; 203 isrlink(&le_isr[hd->hp_unit]); 204 ler0->ler0_status = LE_IE; 205 206 ifp->if_unit = hd->hp_unit; 207 ifp->if_name = "le"; 208 ifp->if_ioctl = leioctl; 209 ifp->if_output = ether_output; 210 ifp->if_start = lestart; 211 ifp->if_flags = 212 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; 213 if_attach(ifp); 214 ether_ifattach(ifp); 215 #if NBPFILTER > 0 216 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); 217 #endif 218 return (1); 219 } 220 221 /* 222 * Set up the logical address filter 223 */ 224 void 225 lesetladrf(ac, af) 226 struct arpcom *ac; 227 u_long *af; 228 { 229 struct ifnet *ifp = &ac->ac_if; 230 struct ether_multi *enm; 231 register u_char *cp, c; 232 register u_long crc; 233 register int i, len; 234 struct ether_multistep step; 235 236 /* 237 * Set up multicast address filter by passing all multicast addresses 238 * through a crc generator, and then using the high order 6 bits as an 239 * index into the 64 bit logical address filter. The high order bit 240 * selects the word, while the rest of the bits select the bit within 241 * the word. 242 */ 243 244 if (ifp->if_flags & IFF_PROMISC) { 245 ifp->if_flags |= IFF_ALLMULTI; 246 af[0] = af[1] = 0xffffffff; 247 return; 248 } 249 250 af[0] = af[1] = 0; 251 ETHER_FIRST_MULTI(step, ac, enm); 252 while (enm != NULL) { 253 if (bcmp(enm->enm_addrlo, enm->enm_addrhi, 254 sizeof(enm->enm_addrlo)) != 0) { 255 /* 256 * We must listen to a range of multicast addresses. 257 * For now, just accept all multicasts, rather than 258 * trying to set only those filter bits needed to match 259 * the range. (At this time, the only use of address 260 * ranges is for IP multicast routing, for which the 261 * range is big enough to require all bits set.) 262 */ 263 ifp->if_flags |= IFF_ALLMULTI; 264 af[0] = af[1] = 0xffffffff; 265 return; 266 } 267 268 cp = enm->enm_addrlo; 269 crc = 0xffffffff; 270 for (len = sizeof(enm->enm_addrlo); --len >= 0;) { 271 c = *cp++; 272 for (i = 8; --i >= 0;) { 273 if ((c & 0x01) ^ (crc & 0x01)) { 274 crc >>= 1; 275 crc ^= 0x6db88320 | 0x80000000; 276 } else 277 crc >>= 1; 278 c >>= 1; 279 } 280 } 281 /* Just want the 6 most significant bits. */ 282 crc >>= 26; 283 284 /* Turn on the corresponding bit in the filter. */ 285 af[crc >> 5] |= 1 << (crc & 0x1f); 286 287 ETHER_NEXT_MULTI(step, enm); 288 } 289 ifp->if_flags &= ~IFF_ALLMULTI; 290 } 291 292 void 293 ledrinit(ler2) 294 register struct lereg2 *ler2; 295 { 296 register struct lereg2 *lemem = 0; 297 register int i; 298 299 for (i = 0; i < LERBUF; i++) { 300 ler2->ler2_rmd[i].rmd0 = (int)lemem->ler2_rbuf[i]; 301 ler2->ler2_rmd[i].rmd1 = LE_OWN; 302 ler2->ler2_rmd[i].rmd2 = -LEMTU; 303 ler2->ler2_rmd[i].rmd3 = 0; 304 } 305 for (i = 0; i < LETBUF; i++) { 306 ler2->ler2_tmd[i].tmd0 = (int)lemem->ler2_tbuf[i]; 307 ler2->ler2_tmd[i].tmd1 = 0; 308 ler2->ler2_tmd[i].tmd2 = 0; 309 ler2->ler2_tmd[i].tmd3 = 0; 310 } 311 } 312 313 void 314 lereset(sc) 315 register struct le_softc *sc; 316 { 317 register struct lereg0 *ler0 = sc->sc_r0; 318 register struct lereg1 *ler1 = sc->sc_r1; 319 register struct lereg2 *ler2 = sc->sc_r2; 320 struct lereg2 *lemem = 0; 321 register int timo, stat; 322 323 #if NBPFILTER > 0 324 if (sc->sc_if.if_flags & IFF_PROMISC) 325 /* set the promiscuous bit */ 326 ler2->ler2_mode = LE_MODE|0x8000; 327 else 328 #endif 329 ler2->ler2_mode = LE_MODE; 330 LERDWR(ler0, LE_CSR0, ler1->ler1_rap); 331 LERDWR(ler0, LE_STOP, ler1->ler1_rdp); 332 333 ler2->ler2_padr[0] = sc->sc_addr[1]; 334 ler2->ler2_padr[1] = sc->sc_addr[0]; 335 ler2->ler2_padr[2] = sc->sc_addr[3]; 336 ler2->ler2_padr[3] = sc->sc_addr[2]; 337 ler2->ler2_padr[4] = sc->sc_addr[5]; 338 ler2->ler2_padr[5] = sc->sc_addr[4]; 339 lesetladrf(&sc->sc_ac, ler2->ler2_ladrf); 340 ledrinit(ler2); 341 sc->sc_rmd = sc->sc_tmd = sc->sc_txcnt = 0; 342 343 LERDWR(ler0, LE_CSR1, ler1->ler1_rap); 344 LERDWR(ler0, (int)&lemem->ler2_mode, ler1->ler1_rdp); 345 LERDWR(ler0, LE_CSR2, ler1->ler1_rap); 346 LERDWR(ler0, 0, ler1->ler1_rdp); 347 LERDWR(ler0, LE_CSR3, ler1->ler1_rap); 348 LERDWR(ler0, LE_BSWP, ler1->ler1_rdp); 349 LERDWR(ler0, LE_CSR0, ler1->ler1_rap); 350 LERDWR(ler0, LE_INIT, ler1->ler1_rdp); 351 timo = 100000; 352 do { 353 if (--timo == 0) { 354 printf("le%d: init timeout, stat=0x%x\n", 355 sc->sc_if.if_unit, stat); 356 break; 357 } 358 LERDWR(ler0, ler1->ler1_rdp, stat); 359 } while ((stat & (LE_IDON | LE_ERR)) == 0); 360 if (stat & LE_ERR) 361 printf("le%d: init failed, stat=0x%x\n", 362 sc->sc_if.if_unit, stat); 363 else 364 LERDWR(ler0, LE_IDON, ler1->ler1_rdp); 365 sc->sc_if.if_flags &= ~IFF_OACTIVE; 366 LERDWR(ler0, LE_STRT | LE_INEA, ler1->ler1_rdp); 367 } 368 369 /* 370 * Initialization of interface 371 */ 372 void 373 leinit(unit) 374 int unit; 375 { 376 struct le_softc *sc = &le_softc[unit]; 377 register struct ifnet *ifp = &sc->sc_if; 378 int s; 379 380 /* not yet, if address still unknown */ 381 if (ifp->if_addrlist == (struct ifaddr *)0) 382 return; 383 if ((ifp->if_flags & IFF_RUNNING) == 0) { 384 s = splimp(); 385 ifp->if_flags |= IFF_RUNNING; 386 lereset(sc); 387 (void) lestart(ifp); 388 splx(s); 389 } 390 } 391 392 #define LENEXTTMP \ 393 if (++bix == LETBUF) bix = 0, tmd = sc->sc_r2->ler2_tmd; else ++tmd 394 395 /* 396 * Start output on interface. Get another datagram to send 397 * off of the interface queue, and copy it to the interface 398 * before starting the output. 399 */ 400 int 401 lestart(ifp) 402 struct ifnet *ifp; 403 { 404 register struct le_softc *sc = &le_softc[ifp->if_unit]; 405 register int bix; 406 register struct letmd *tmd; 407 register struct mbuf *m; 408 int len, gotone = 0; 409 410 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) 411 return (0); 412 bix = sc->sc_tmd; 413 tmd = &sc->sc_r2->ler2_tmd[bix]; 414 do { 415 if (tmd->tmd1 & LE_OWN) { 416 if (gotone) 417 break; 418 sc->sc_xown2++; 419 return (0); 420 } 421 IF_DEQUEUE(&sc->sc_if.if_snd, m); 422 if (m == 0) { 423 if (gotone) 424 break; 425 return (0); 426 } 427 len = leput(sc->sc_r2->ler2_tbuf[bix], m); 428 #if NBPFILTER > 0 429 /* 430 * If bpf is listening on this interface, let it 431 * see the packet before we commit it to the wire. 432 */ 433 if (ifp->if_bpf) 434 bpf_tap(ifp->if_bpf, sc->sc_r2->ler2_tbuf[bix], len); 435 #endif 436 tmd->tmd3 = 0; 437 tmd->tmd2 = -len; 438 tmd->tmd1 = LE_OWN | LE_STP | LE_ENP; 439 LENEXTTMP; 440 gotone++; 441 } while (++sc->sc_txcnt < LETBUF); 442 sc->sc_tmd = bix; 443 sc->sc_if.if_flags |= IFF_OACTIVE; 444 /* transmit as soon as possible */ 445 LERDWR(sc->sc_r0, LE_INEA|LE_TDMD, sc->sc_r1->ler1_rdp); 446 return (0); 447 } 448 449 int 450 leintr(unit) 451 register int unit; 452 { 453 register struct le_softc *sc = &le_softc[unit]; 454 register struct lereg0 *ler0 = sc->sc_r0; 455 register struct lereg1 *ler1; 456 register int stat; 457 458 if ((ler0->ler0_status & LE_IR) == 0) 459 return(0); 460 if (ler0->ler0_status & LE_JAB) { 461 sc->sc_jab++; 462 lereset(sc); 463 return(1); 464 } 465 ler1 = sc->sc_r1; 466 LERDWR(ler0, ler1->ler1_rdp, stat); 467 if (stat & LE_SERR) { 468 leerror(sc, stat); 469 if (stat & LE_MERR) { 470 sc->sc_merr++; 471 lereset(sc); 472 return(1); 473 } 474 if (stat & LE_BABL) 475 sc->sc_babl++; 476 if (stat & LE_CERR) 477 sc->sc_cerr++; 478 if (stat & LE_MISS) 479 sc->sc_miss++; 480 LERDWR(ler0, LE_BABL|LE_CERR|LE_MISS|LE_INEA, ler1->ler1_rdp); 481 } 482 if ((stat & LE_RXON) == 0) { 483 sc->sc_rxoff++; 484 lereset(sc); 485 return(1); 486 } 487 if ((stat & LE_TXON) == 0) { 488 sc->sc_txoff++; 489 lereset(sc); 490 return(1); 491 } 492 if (stat & LE_RINT) 493 lerint(sc); 494 if (stat & LE_TINT) 495 lexint(sc); 496 return(1); 497 } 498 499 /* 500 * Ethernet interface transmitter interrupt. 501 * Start another output if more data to send. 502 */ 503 void 504 lexint(sc) 505 register struct le_softc *sc; 506 { 507 register struct letmd *tmd; 508 int bix, gotone = 0; 509 510 if ((sc->sc_if.if_flags & IFF_OACTIVE) == 0) { 511 sc->sc_xint++; 512 return; 513 } 514 if ((bix = sc->sc_tmd - sc->sc_txcnt) < 0) 515 bix += LETBUF; 516 tmd = &sc->sc_r2->ler2_tmd[bix]; 517 do { 518 if (tmd->tmd1 & LE_OWN) { 519 if (gotone) 520 break; 521 sc->sc_xown++; 522 return; 523 } 524 525 /* clear interrupt */ 526 LERDWR(sc->sc_r0, LE_TINT|LE_INEA, sc->sc_r1->ler1_rdp); 527 528 /* XXX documentation says BUFF not included in ERR */ 529 if ((tmd->tmd1 & LE_ERR) || (tmd->tmd3 & LE_TBUFF)) { 530 lexerror(sc); 531 sc->sc_if.if_oerrors++; 532 if (tmd->tmd3 & (LE_TBUFF|LE_UFLO)) { 533 sc->sc_uflo++; 534 lereset(sc); 535 } else if (tmd->tmd3 & LE_LCOL) 536 sc->sc_if.if_collisions++; 537 else if (tmd->tmd3 & LE_RTRY) 538 sc->sc_if.if_collisions += 16; 539 } 540 else if (tmd->tmd1 & LE_ONE) 541 sc->sc_if.if_collisions++; 542 else if (tmd->tmd1 & LE_MORE) 543 /* what is the real number? */ 544 sc->sc_if.if_collisions += 2; 545 else 546 sc->sc_if.if_opackets++; 547 LENEXTTMP; 548 gotone++; 549 } while (--sc->sc_txcnt > 0); 550 sc->sc_if.if_flags &= ~IFF_OACTIVE; 551 (void) lestart(&sc->sc_if); 552 } 553 554 #define LENEXTRMP \ 555 if (++bix == LERBUF) bix = 0, rmd = sc->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 void 564 lerint(sc) 565 register struct le_softc *sc; 566 { 567 register int bix = sc->sc_rmd; 568 register struct lermd *rmd = &sc->sc_r2->ler2_rmd[bix]; 569 570 /* 571 * Out of sync with hardware, should never happen? 572 */ 573 if (rmd->rmd1 & LE_OWN) { 574 sc->sc_rown++; 575 do { 576 LENEXTRMP; 577 } while ((rmd->rmd1 & LE_OWN) && bix != sc->sc_rmd); 578 if (bix == sc->sc_rmd) { 579 printf("le%d: rint with no buffer\n", 580 sc->sc_if.if_unit); 581 LERDWR(sc->sc_r0, LE_RINT|LE_INEA, sc->sc_r1->ler1_rdp); 582 return; 583 } 584 } 585 586 /* 587 * Process all buffers with valid data 588 */ 589 while ((rmd->rmd1 & LE_OWN) == 0) { 590 int len = rmd->rmd3; 591 592 /* Clear interrupt to avoid race condition */ 593 LERDWR(sc->sc_r0, LE_RINT|LE_INEA, sc->sc_r1->ler1_rdp); 594 595 if (rmd->rmd1 & LE_ERR) { 596 sc->sc_rmd = bix; 597 lererror(sc, "bad packet"); 598 sc->sc_if.if_ierrors++; 599 } else if ((rmd->rmd1 & (LE_STP|LE_ENP)) != (LE_STP|LE_ENP)) { 600 /* 601 * Find the end of the packet so we can see how long 602 * it was. We still throw it away. 603 */ 604 do { 605 LERDWR(sc->sc_r0, LE_RINT|LE_INEA, 606 sc->sc_r1->ler1_rdp); 607 rmd->rmd3 = 0; 608 rmd->rmd1 = LE_OWN; 609 LENEXTRMP; 610 } while (!(rmd->rmd1 & (LE_OWN|LE_ERR|LE_STP|LE_ENP))); 611 sc->sc_rmd = bix; 612 lererror(sc, "chained buffer"); 613 sc->sc_rxlen++; 614 /* 615 * If search terminated without successful completion 616 * we reset the hardware (conservative). 617 */ 618 if ((rmd->rmd1 & (LE_OWN|LE_ERR|LE_STP|LE_ENP)) != 619 LE_ENP) { 620 lereset(sc); 621 return; 622 } 623 } else 624 leread(sc, sc->sc_r2->ler2_rbuf[bix], len); 625 rmd->rmd3 = 0; 626 rmd->rmd1 = LE_OWN; 627 LENEXTRMP; 628 } 629 sc->sc_rmd = bix; 630 } 631 632 void 633 leread(sc, buf, len) 634 register struct le_softc *sc; 635 char *buf; 636 int len; 637 { 638 register struct ether_header *et; 639 register struct ifnet *ifp = &sc->sc_if; 640 struct mbuf *m; 641 642 ifp->if_ipackets++; 643 et = (struct ether_header *)buf; 644 /* adjust input length to account for header and CRC */ 645 len -= sizeof(struct ether_header) + 4; 646 647 if (len <= 0) { 648 if (ledebug) 649 log(LOG_WARNING, 650 "le%d: ierror(runt packet): from %s: len=%d\n", 651 sc->sc_if.if_unit, ether_sprintf(et->ether_shost), 652 len); 653 sc->sc_runt++; 654 ifp->if_ierrors++; 655 return; 656 } 657 658 #if NBPFILTER > 0 659 /* 660 * Check if there's a bpf filter listening on this interface. 661 * If so, hand off the raw packet to bpf, then discard things 662 * not destined for us (but be sure to keep broadcast/multicast). 663 */ 664 if (ifp->if_bpf) { 665 bpf_tap(ifp->if_bpf, buf, len + sizeof(struct ether_header)); 666 if ((ifp->if_flags & IFF_PROMISC) && 667 (et->ether_dhost[0] & 1) == 0 && 668 bcmp(et->ether_dhost, sc->sc_addr, 669 sizeof(et->ether_dhost)) != 0) 670 return; 671 } 672 #endif 673 674 m = leget(buf, len, 0, ifp); 675 if (m == 0) 676 return; 677 678 ether_input(ifp, et, m); 679 } 680 681 /* 682 * Routine to copy from mbuf chain to transmit 683 * buffer in board local memory. 684 */ 685 int 686 leput(lebuf, m) 687 register char *lebuf; 688 register struct mbuf *m; 689 { 690 register struct mbuf *mp; 691 register int len, tlen = 0; 692 693 for (mp = m; mp; mp = mp->m_next) { 694 len = mp->m_len; 695 if (len == 0) 696 continue; 697 tlen += len; 698 bcopy(mtod(mp, char *), lebuf, len); 699 lebuf += len; 700 } 701 m_freem(m); 702 if (tlen < LEMINSIZE) { 703 bzero(lebuf, LEMINSIZE - tlen); 704 tlen = LEMINSIZE; 705 } 706 return(tlen); 707 } 708 709 /* 710 * Routine to copy from board local memory into mbufs. 711 */ 712 struct mbuf * 713 leget(lebuf, totlen, off0, ifp) 714 char *lebuf; 715 int totlen, off0; 716 struct ifnet *ifp; 717 { 718 register struct mbuf *m; 719 struct mbuf *top = 0, **mp = ⊤ 720 register int off = off0, len; 721 register char *cp; 722 char *epkt; 723 724 lebuf += sizeof (struct ether_header); 725 cp = lebuf; 726 epkt = cp + totlen; 727 if (off) { 728 cp += off + 2 * sizeof(u_short); 729 totlen -= 2 * sizeof(u_short); 730 } 731 732 MGETHDR(m, M_DONTWAIT, MT_DATA); 733 if (m == 0) 734 return (0); 735 m->m_pkthdr.rcvif = ifp; 736 m->m_pkthdr.len = totlen; 737 m->m_len = MHLEN; 738 739 while (totlen > 0) { 740 if (top) { 741 MGET(m, M_DONTWAIT, MT_DATA); 742 if (m == 0) { 743 m_freem(top); 744 return (0); 745 } 746 m->m_len = MLEN; 747 } 748 len = min(totlen, epkt - cp); 749 if (len >= MINCLSIZE) { 750 MCLGET(m, M_DONTWAIT); 751 if (m->m_flags & M_EXT) 752 m->m_len = len = min(len, MCLBYTES); 753 else 754 len = m->m_len; 755 } else { 756 /* 757 * Place initial small packet/header at end of mbuf. 758 */ 759 if (len < m->m_len) { 760 if (top == 0 && len + max_linkhdr <= m->m_len) 761 m->m_data += max_linkhdr; 762 m->m_len = len; 763 } else 764 len = m->m_len; 765 } 766 bcopy(cp, mtod(m, caddr_t), (unsigned)len); 767 cp += len; 768 *mp = m; 769 mp = &m->m_next; 770 totlen -= len; 771 if (cp == epkt) 772 cp = lebuf; 773 } 774 return (top); 775 } 776 777 /* 778 * Process an ioctl request. 779 */ 780 int 781 leioctl(ifp, cmd, data) 782 register struct ifnet *ifp; 783 int cmd; 784 caddr_t data; 785 { 786 register struct ifaddr *ifa; 787 struct le_softc *sc = &le_softc[ifp->if_unit]; 788 int s = splimp(), error = 0; 789 790 switch (cmd) { 791 792 case SIOCSIFADDR: 793 ifa = (struct ifaddr *)data; 794 ifp->if_flags |= IFF_UP; 795 switch (ifa->ifa_addr->sa_family) { 796 #ifdef INET 797 case AF_INET: 798 leinit(ifp->if_unit); /* before arpwhohas */ 799 ((struct arpcom *)ifp)->ac_ipaddr = 800 IA_SIN(ifa)->sin_addr; 801 arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr); 802 break; 803 #endif 804 #ifdef NS 805 case AF_NS: 806 { 807 register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); 808 809 if (ns_nullhost(*ina)) 810 ina->x_host = *(union ns_host *)(sc->sc_addr); 811 else { 812 /* 813 * The manual says we can't change the address 814 * while the receiver is armed, 815 * so reset everything 816 */ 817 ifp->if_flags &= ~IFF_RUNNING; 818 LERDWR(sc->sc_r0, LE_STOP, sc->sc_r1->ler1_rdp); 819 bcopy((caddr_t)ina->x_host.c_host, 820 (caddr_t)sc->sc_addr, sizeof(sc->sc_addr)); 821 } 822 leinit(ifp->if_unit); /* does le_setaddr() */ 823 break; 824 } 825 #endif 826 default: 827 leinit(ifp->if_unit); 828 break; 829 } 830 break; 831 832 case SIOCSIFFLAGS: 833 if ((ifp->if_flags & IFF_UP) == 0 && 834 ifp->if_flags & IFF_RUNNING) { 835 ifp->if_flags &= ~IFF_RUNNING; 836 LERDWR(sc->sc_r0, LE_STOP, sc->sc_r1->ler1_rdp); 837 } else if (ifp->if_flags & IFF_UP && 838 (ifp->if_flags & IFF_RUNNING) == 0) 839 leinit(ifp->if_unit); 840 /* 841 * If the state of the promiscuous bit changes, the interface 842 * must be reset to effect the change. 843 */ 844 if (((ifp->if_flags ^ sc->sc_iflags) & IFF_PROMISC) && 845 (ifp->if_flags & IFF_RUNNING)) { 846 sc->sc_iflags = ifp->if_flags; 847 lereset(sc); 848 lestart(ifp); 849 } 850 break; 851 852 case SIOCADDMULTI: 853 error = ether_addmulti((struct ifreq *)data, &sc->sc_ac); 854 goto update_multicast; 855 856 case SIOCDELMULTI: 857 error = ether_delmulti((struct ifreq *)data, &sc->sc_ac); 858 update_multicast: 859 if (error == ENETRESET) { 860 /* 861 * Multicast list has changed; set the hardware 862 * filter accordingly. 863 */ 864 lereset(sc); 865 error = 0; 866 } 867 break; 868 869 default: 870 error = EINVAL; 871 } 872 splx(s); 873 return (error); 874 } 875 876 void 877 leerror(sc, stat) 878 register struct le_softc *sc; 879 int stat; 880 { 881 882 if (!ledebug) 883 return; 884 885 /* 886 * Not all transceivers implement heartbeat 887 * so we only log CERR once. 888 */ 889 if ((stat & LE_CERR) && sc->sc_cerr) 890 return; 891 log(LOG_WARNING, 892 "le%d: error: stat=%b\n", sc->sc_if.if_unit, stat, 893 "\20\20ERR\17BABL\16CERR\15MISS\14MERR\13RINT\12TINT\11IDON\10INTR\07INEA\06RXON\05TXON\04TDMD\03STOP\02STRT\01INIT"); 894 } 895 896 void 897 lererror(sc, msg) 898 register struct le_softc *sc; 899 char *msg; 900 { 901 register struct lermd *rmd; 902 int len; 903 904 if (!ledebug) 905 return; 906 907 rmd = &sc->sc_r2->ler2_rmd[sc->sc_rmd]; 908 len = rmd->rmd3; 909 log(LOG_WARNING, 910 "le%d: ierror(%s): from %s: buf=%d, len=%d, rmd1=%b\n", 911 sc->sc_if.if_unit, msg, 912 len > 11 ? ether_sprintf(&sc->sc_r2->ler2_rbuf[sc->sc_rmd][6]) : "unknown", 913 sc->sc_rmd, len, rmd->rmd1, 914 "\20\20OWN\17ERR\16FRAM\15OFLO\14CRC\13RBUF\12STP\11ENP"); 915 } 916 917 void 918 lexerror(sc) 919 register struct le_softc *sc; 920 { 921 register struct letmd *tmd; 922 register int len; 923 924 if (!ledebug) 925 return; 926 927 tmd = sc->sc_r2->ler2_tmd; 928 len = -tmd->tmd2; 929 log(LOG_WARNING, 930 "le%d: oerror: to %s: buf=%d, len=%d, tmd1=%b, tmd3=%b\n", 931 sc->sc_if.if_unit, 932 len > 5 ? ether_sprintf(&sc->sc_r2->ler2_tbuf[0][0]) : "unknown", 933 0, len, tmd->tmd1, 934 "\20\20OWN\17ERR\16RES\15MORE\14ONE\13DEF\12STP\11ENP", 935 tmd->tmd3, 936 "\20\20BUFF\17UFLO\16RES\15LCOL\14LCAR\13RTRY"); 937 } 938 #endif 939