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