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