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