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