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