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