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