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