1 /* 2 * Copyright (c) 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)if_ec.c 7.3 (Berkeley) 11/21/91 8 */ 9 10 #include "ec.h" 11 #if NEC > 0 12 13 /* 14 * Intel 82586/3com Etherlink II controller. 15 */ 16 #include "param.h" 17 #include "systm.h" 18 #include "mbuf.h" 19 #include "buf.h" 20 #include "protosw.h" 21 #include "socket.h" 22 #include "syslog.h" 23 #include "ioctl.h" 24 #include "errno.h" 25 26 #include "net/if.h" 27 #include "net/netisr.h" 28 #include "net/route.h" 29 30 #ifdef INET 31 #include "netinet/in.h" 32 #include "netinet/in_systm.h" 33 #include "netinet/in_var.h" 34 #include "netinet/ip.h" 35 #include "netinet/if_ether.h" 36 #endif 37 38 #ifdef NS 39 #include "netns/ns.h" 40 #include "netns/ns_if.h" 41 #endif 42 43 #ifdef ISO 44 extern char all_es_snpa[], all_is_snpa[], all_l1is_snpa[], all_l2is_snpa[]; 45 #endif 46 47 #include "if_ecreg.h" 48 49 #if NBPFILTER > 0 50 #include "../net/bpf.h" 51 #include "../net/bpfdesc.h" 52 #endif 53 54 int ecdebug = 0; /* console error messages */ 55 56 int ecintr(), ecinit(), ecioctl(), ecstart(), ether_output(); 57 int ecattach(), ecprobe(), ecreset(), ecwatchdog(); 58 void ec_idpattern(), ec_reset_all(), ec_getnmdata(), ecread(); 59 60 struct mbuf *m_devget(); 61 extern struct ifnet loif; 62 struct ec_82586params ec_82586defaults = 63 { 11, 0xc8, ECMINSIZE, 0x2e, 0, 0x60, 0, 2, 0, 0, 0x40}; 64 /* 2e == no source insert */ 65 66 /* 67 * Ethernet software status per interface. 68 * 69 * Each interface is referenced by a network interface structure, 70 * sc_if, which the routing code uses to locate the interface. 71 * This structure contains the output queue for the interface, its address, ... 72 */ 73 struct ec_softc { 74 struct arpcom sc_ac; /* common Ethernet structures */ 75 #define sc_if sc_ac.ac_if /* network-visible interface */ 76 #define sc_addr sc_ac.ac_enaddr /* hardware Ethernet address */ 77 caddr_t sc_device; /* e.g. isa_device */ 78 caddr_t sc_bpf; /* for packet filter */ 79 struct ec_ports *sc_ports; /* control ports for this unit */ 80 struct ec_mem *sc_hmem; /* Host addr for shared memory */ 81 struct ec_mem *sc_dmem; /* Device (chip) addr for shared mem */ 82 int sc_msize; /* How much memory is mapped? */ 83 int sc_iflags; /* copy of sc_if.if_flags for state */ 84 int sc_rxnum; /* Last receiver dx we looked at */ 85 int sc_txnum; /* Last tranmistter dx we stomped on */ 86 int sc_txcnt; /* Number of packets queued for tx*/ 87 int sc_xint; 88 /* errors */ 89 int sc_txbusy; /* we're confused */ 90 int sc_uflo; /* DMA Late */ 91 int sc_runt; /* too short */ 92 int sc_txbad; 93 int sc_rxlen; 94 } ec_softc[NEC]; 95 96 #include "isa_device.h" 97 98 struct isa_driver ecdriver = { 99 ecprobe, ecattach, "ec", 100 }; 101 102 103 #define TIMO 10000 /* used in ec_uprim */ 104 105 ecprobe(id) 106 register struct isa_device *id; 107 { 108 int unit = id->id_unit, msize = id->id_msize; 109 struct ec_ports *reg = (struct ec_ports *)id->id_iobase; 110 register struct ec_softc *ec = ec_softc + unit; 111 u_char data[6]; 112 113 ec_reset_all(); 114 bzero((caddr_t)data, sizeof(data)); 115 ec_getnmdata(reg, R_ECID, data); 116 if (bcmp((caddr_t)data, "*3com*", sizeof(data)) != 0) { 117 if (ecdebug) 118 printf("ecprobe: ec%d not matched\n"); 119 return 0; 120 } 121 ec_getnmdata(reg, R_ETHER, ec->sc_addr); 122 ec_getnmdata(reg, R_REV, data); 123 ec->sc_hmem = (struct ec_mem *) (id->id_maddr); 124 ec->sc_dmem = (struct ec_mem *) (0x10000 - msize); 125 ec->sc_msize = msize; 126 ec->sc_device = (caddr_t) id; 127 ec->sc_ports = reg; 128 printf("ec%d: hardware address %s, rev info %4.4x%4.4x%4.4x\n", 129 unit, ether_sprintf(ec->sc_addr), 130 0[(u_short *)data], 1[(u_short *)data], 2[(u_short *)data]); 131 return 1; 132 } 133 134 void 135 ec_idpattern() 136 { 137 int i = 255, n; 138 register caddr_t p = (caddr_t)0x100; 139 for (n = 255; n > 0; n--) { 140 outb(p, i); 141 if ((i <<= 1) & 0x100) 142 i ^= 0xe7; 143 } 144 } 145 146 void 147 ec_reset_all() 148 { 149 register caddr_t p = (caddr_t)0x100; 150 outb(p, 0); 151 ec_idpattern(); 152 outb(p, 0); 153 } 154 extern int cpuspeed; 155 #define ECWR(p, e, d) outb(&(p->e), d) 156 #define ECRD(p, e) inb(&(p->e)) 157 #define SET_CA ECWR(ec->sc_ports, port_ca, 0) 158 #define UNLATCH_INT ECWR(ec->sc_ports, port_ic, 0); 159 160 void 161 ec_getnmdata(p, which, data) 162 register struct ec_ports *p; 163 int which; 164 register u_char *data; 165 { 166 register int i; 167 168 ECWR(p, creg, which); 169 DELAY(2); 170 for (i = 0; i < 6; i++) { 171 DELAY(2); 172 data[i] = ECRD(p, data[i]); 173 } 174 } 175 176 ecreset(unit) 177 register int unit; 178 { 179 register struct ec_softc *ec = &ec_softc[unit]; 180 struct ec_ports *p = ec->sc_ports; 181 struct ec_mem *hmem = ec->sc_hmem; 182 int timo; 183 184 ECWR(p, creg, R_LPB); DELAY(10); 185 if ((ec->sc_if.if_flags & IFF_RUNNING) == 0) 186 return 0; 187 ec_meminit(ec); 188 ECWR(p, creg, R_NORST); DELAY(10); 189 ECWR(p, port_ca, 0); DELAY(10); 190 hmem->iscp.busy = 1; 191 for (timo = TIMO; hmem->iscp.busy; ) 192 timo--; 193 if (timo == 0) { 194 printf("ec(%d)reset: iscp failed\n", unit); 195 return 0; 196 } 197 hmem->scb.command = CU_START; 198 ECWR(p, port_ca, 0); DELAY(10); 199 for (timo = TIMO; (hmem->scb.status & CU_STATE) == CUS_ACTIVE;) 200 timo--; 201 if (timo == 0 || hmem->scb.status == CUS_IDLE) { 202 printf("ec(%d)reset: setup failed\n"); 203 return 0; 204 } 205 hmem->scb.command = RU_START; 206 ECWR(p, port_ic, 0); DELAY(10); 207 ECWR(p, creg, R_NORST|R_IEN); 208 ECWR(p, port_ca, 0); DELAY(10); 209 ec->sc_if.if_timer = 5; 210 return 0; /* Keep GCC Happy! */ 211 } 212 213 /* 214 * Interface exists: make available by filling in network interface 215 * record. System will initialize the interface when it is ready 216 * to accept packets. 217 */ 218 219 ecattach(id) 220 register struct isa_device *id; 221 { 222 int unit = id->id_unit; 223 struct ec_softc *ec = &ec_softc[unit]; 224 struct ifnet *ifp = &ec->sc_if; 225 226 ifp->if_unit = unit; 227 ifp->if_name = "ec"; 228 ifp->if_mtu = ETHERMTU; 229 ifp->if_init = ecinit; 230 ifp->if_init = ecreset; 231 ifp->if_ioctl = ecioctl; 232 ifp->if_watchdog = ecwatchdog; 233 ifp->if_output = ether_output; 234 ifp->if_start = ecstart; 235 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; 236 #if NBPFILTER > 0 237 bpfattach(&ec->sc_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); 238 #endif 239 if_attach(ifp); 240 return (1); 241 } 242 #define OFF(e) ((u_short)&(((struct ec_mem *)0)->e)) 243 244 ec_meminit(ec) 245 register struct ec_softc *ec; 246 { 247 register struct ec_mem *hmem = ec->sc_hmem; 248 register int i; 249 struct ec_rfd *rc = hmem->rcom; 250 struct ec_transmit *tc = hmem->tcom; 251 caddr_t cp; 252 253 bzero((caddr_t)hmem, ec->sc_msize); 254 *(struct ec_mem **) 255 (ec->sc_msize - 4 + (caddr_t)ec->sc_hmem) = ec->sc_dmem; 256 257 hmem->iscp.scb_off = OFF(scb); 258 hmem->iscp.scb_base = (caddr_t)ec->sc_dmem; 259 260 hmem->scb.rfa_off = OFF(rcom[0]); 261 hmem->scb.cbl_off = OFF(config); 262 263 hmem->config.com1 = COM1_CONFIGURE; 264 bcopy((caddr_t)&ec_82586defaults, (caddr_t)&hmem->config.modes, 265 sizeof(hmem->config.modes)); 266 #if NBPFILTER > 0 267 if (ec->sc_if.if_flags & IFF_PROMISC) 268 hmem->config.modes.promisc |= M_PROMISC; 269 #endif 270 hmem->config.next_off = OFF(iasetup); 271 272 bcopy((caddr_t)ec->sc_addr, (caddr_t)hmem->iasetup.srcaddr, 6); 273 #ifndef ISO 274 hmem->iasetup.com1 = COM1_IASETUP | COM1_S | COM1_EL; 275 #else 276 hmem->iasetup.com1 = COM1_IASETUP; 277 hmem->iasetup.next_off = OFF(mcsetup); 278 279 hmem->mcsetup.com1 = COM1_MCSETUP | COM1_S | COM1_EL; 280 hmem->mcsetup.count = 24; 281 cp = (caddr_t)hmem->txbuf[0]; 282 bcopy((caddr_t)all_es_snpa, cp, 6); cp += 6; 283 bcopy((caddr_t)all_is_snpa, cp, 6); cp += 6; 284 bcopy((caddr_t)all_l1is_snpa, cp, 6); cp += 6; 285 bcopy((caddr_t)all_l2is_snpa, cp, 6); cp += 6; 286 #endif 287 for (i = 0; i < NTXBUF; i++) { 288 tc->tbd_off = OFF(tcom[i].count); 289 tc->buffer = ec->sc_dmem->txbuf[i]; 290 (tc++)->com1 = COM1_TRANSMIT | COM1_S | COM1_EL | COM1_I; 291 } 292 for (i = 0; i < NRXBUF; i++) { 293 rc->next_off = OFF(rcom[i + 1]); 294 rc->rbd_off = OFF(rcom[i].count); 295 rc->buffer = ec->sc_dmem->rxbuf[i]; 296 (rc++)->size = ECMTU | COM1_EL; 297 } 298 (--rc)->next_off = OFF(rcom[0]); 299 } 300 /* 301 * Initialization of interface 302 */ 303 ecinit(unit) 304 int unit; 305 { 306 register struct ifnet *ifp = &ec_softc[unit].sc_if; 307 register struct ifaddr *ifa; 308 int s; 309 310 /* not yet, if address still unknown */ 311 for (ifa = ifp->if_addrlist;; ifa = ifa->ifa_next) 312 if (ifa == 0) 313 return 0; 314 else if (ifa->ifa_addr && ifa->ifa_addr->sa_family != AF_LINK) 315 break; 316 if ((ifp->if_flags & IFF_RUNNING) == 0) { 317 s = splimp(); 318 ifp->if_flags |= IFF_RUNNING; 319 ecreset(unit); 320 (void) ecstart(ifp); 321 splx(s); 322 } 323 return 0; 324 } 325 326 /* 327 * Timeout: for now check for a transmit command taking more than 10 seconds. 328 */ 329 ecwatchdog(unit) 330 int unit; 331 { 332 register struct ec_softc *ec = ec_softc + unit; 333 if (ec->sc_iflags & IFF_OACTIVE) { 334 ec->sc_if.if_flags &= ~IFF_RUNNING; 335 ecinit(unit); 336 } else if (ec->sc_txcnt > 0) 337 ec->sc_iflags |= IFF_OACTIVE; 338 ec->sc_if.if_timer = 5; 339 } 340 341 342 343 ec_txstart(ec) 344 register struct ec_softc *ec; 345 { 346 struct ec_mem *hmem = ec->sc_hmem; 347 int i; 348 349 if ((i = ec->sc_txnum - ec->sc_txcnt) < 0) i += NTXBUF; 350 hmem->scb.cbl_off = OFF(tcom[i]); 351 hmem->scb.command = CU_START; 352 hmem->scb.status = 0; 353 SET_CA; 354 } 355 /* 356 * Start output on interface. Get another datagram to send 357 * off of the interface queue, and copy it to the interface 358 * before starting the output. 359 */ 360 ecstart(ifp) 361 struct ifnet *ifp; 362 { 363 register struct ec_softc *ec = &ec_softc[ifp->if_unit]; 364 register struct ec_transmit *tmd; 365 register struct mbuf *m; 366 int len; 367 368 again: 369 if ((ec->sc_if.if_flags & IFF_RUNNING) == 0 || ec->sc_txcnt >= NTXBUF) 370 return (0); 371 tmd = ec->sc_hmem->tcom + ec->sc_txnum; 372 if (tmd->com0 & (COM0_B | COM0_C)) 373 return (ec->sc_txbusy++, 0); 374 IF_DEQUEUE(&ec->sc_if.if_snd, m); 375 if (m == 0) 376 return (0); 377 len = ecput(ec->sc_hmem->txbuf[ec->sc_txnum], m); 378 #if NBPFILTER > 0 379 /* 380 * If bpf is listening on this interface, let it 381 * see the packet before we commit it to the wire. 382 */ 383 if (ec->sc_bpf) 384 bpf_tap(ec->sc_bpf, ec->sc_hmem->txbuf[ec->sc_txnum], len); 385 #endif 386 tmd->com0 = 0; 387 tmd->count = len | COM1_EL; 388 if (ec->sc_txcnt == 0) 389 ec_txstart(ec); 390 if (++ec->sc_txnum >= NTXBUF) 391 ec->sc_txnum = 0; 392 if (++ec->sc_txcnt >= NTXBUF) { 393 ec->sc_txcnt = NTXBUF; 394 ec->sc_if.if_flags |= IFF_OACTIVE; 395 } 396 goto again; 397 } 398 399 ecintr(unit) 400 register int unit; 401 { 402 struct ec_softc *ec = &ec_softc[unit]; 403 struct ec_mem *hmem = ec->sc_hmem; 404 register int stat = hmem->scb.status; 405 406 hmem->scb.command = stat & 0xf000; /* Ack interrupt cause */ 407 SET_CA; 408 if (stat & FR) 409 ecrint(unit); 410 if (stat & CX) 411 ecxint(unit); 412 UNLATCH_INT; 413 } 414 415 /* 416 * Ethernet interface transmitter interrupt. 417 * Start another output if more data to send. 418 */ 419 ecxint(unit) 420 register int unit; 421 { 422 register struct ec_softc *ec = &ec_softc[unit]; 423 register struct ec_transmit *tmd; 424 int i; 425 426 if (ec->sc_txcnt == 0) { 427 ec->sc_xint++; /* unexpected transmit interrupt */ 428 return; 429 } 430 ec->sc_iflags &= ~IFF_OACTIVE; /* clear deadman indication */ 431 if ((i = ec->sc_txnum - ec->sc_txcnt) < 0) i += NTXBUF; 432 tmd = ec->sc_hmem->tcom + i; 433 if (tmd->com0 & COM0_B) 434 return; 435 ec->sc_if.if_collisions += tmd->com0 & 0xf; 436 if ((tmd->com0 & EXCOL) && (tmd->com0 & 0xf) == 0) 437 ec->sc_if.if_collisions += 16; 438 if ((tmd->com0 & COM0_OK) == 0) { 439 ecxerror(unit); 440 ec->sc_if.if_oerrors++; 441 if (tmd->com0 & DMALATE) { 442 ec->sc_uflo++; 443 (void) ecreset(unit); 444 return; 445 } 446 } else 447 ec->sc_if.if_opackets++; 448 tmd->com0 = 0; 449 if (--ec->sc_txcnt > 0) 450 ec_txstart(ec); 451 if (ec->sc_txcnt < 0) { 452 ec->sc_txbad++; 453 ec->sc_txcnt = 0; 454 } 455 ec->sc_if.if_flags &= ~IFF_OACTIVE; 456 (void) ecstart(&ec->sc_if); 457 } 458 459 #define ECNEXTRCOM \ 460 if (++bix == NRXBUF) bix = 0, rmd = ec->sc_hmem->rcom; else ++rmd 461 462 /* 463 * Ethernet interface receiver interrupt. 464 * If input error just drop packet. 465 * Decapsulate packet based on type and pass to type specific 466 * higher-level input routine. 467 */ 468 ecrint(unit) 469 int unit; 470 { 471 register struct ec_softc *ec = &ec_softc[unit]; 472 register int bix = ec->sc_rxnum; 473 register struct ec_rfd *rmd = ec->sc_hmem->rcom + bix; 474 475 /* 476 * Out of sync with hardware, should never happen? 477 */ 478 if ((rmd->rfd0 & COM0_C) == 0 || (rmd->count & RBD_F) == 0) { 479 ecrerror(unit, "out of sync, resetting"); 480 return ecreset(unit); 481 } 482 /* 483 * Process all buffers with valid data 484 */ 485 while ((rmd->rfd0 & COM0_C) && (rmd->count & RBD_F)) { 486 if (rmd->rfd0 & (COM0_C|COM0_B|COM0_OK) != (COM0_C|COM0_OK)) { 487 ec->sc_rxnum = bix; 488 ecrerror(unit, "bad packet"); 489 ec->sc_if.if_ierrors++; 490 } 491 if ((rmd->count & (RBD_F|RBD_EOF)) != (RBD_F|RBD_EOF)) { 492 ecrerror(unit, "chained buffer"); 493 ec->sc_rxlen++; 494 ec->sc_if.if_ierrors++; 495 } else 496 ecread(ec, ec->sc_hmem->txbuf[bix], rmd->count & 0x2f); 497 rmd->count = 0; 498 rmd->rfd0 = 0; 499 ECNEXTRCOM; 500 ec->sc_rxnum = bix; 501 } 502 } 503 504 void 505 ecread(ec, buf, len) 506 register struct ec_softc *ec; 507 char *buf; 508 int len; 509 { 510 struct ether_header *et, eh; 511 struct mbuf *m; 512 int off, resid, unit = ec->sc_if.if_unit; 513 514 ec->sc_if.if_ipackets++; 515 et = (struct ether_header *)buf; 516 et->ether_type = ntohs((u_short)et->ether_type); 517 bcopy((caddr_t)et, &eh, sizeof(eh)); 518 /* adjust input length to account for header */ 519 len = len - sizeof(struct ether_header); 520 521 #define ecdataaddr(et, off, type) ((type)(((caddr_t)((et)+1)+(off)))) 522 if (et->ether_type >= ETHERTYPE_TRAIL && 523 et->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) { 524 off = (et->ether_type - ETHERTYPE_TRAIL) * 512; 525 if (off >= ETHERMTU) 526 return; /* sanity */ 527 et->ether_type = ntohs(*ecdataaddr(et, off, u_short *)); 528 resid = ntohs(*(ecdataaddr(et, off+2, u_short *))); 529 if (off + resid > len) 530 return; /* sanity */ 531 len = off + resid; 532 } else 533 off = 0; 534 535 if (len <= 0) { 536 if (ecdebug) 537 log(LOG_WARNING, 538 "ec%d: ierror(runt packet): from %s: len=%d\n", 539 unit, ether_sprintf(et->ether_shost), len); 540 ec->sc_runt++; 541 ec->sc_if.if_ierrors++; 542 return; 543 } 544 #if NBPFILTER > 0 545 /* 546 * Check if there's a bpf filter listening on this interface. 547 * If so, hand off the raw packet to bpf, which must deal with 548 * trailers in its own way. 549 */ 550 if (ec->sc_bpf) 551 bpf_tap(ec->sc_bpf, buf, len + sizeof(struct ether_header)); 552 #endif 553 #if defined(ISO) || NBPFILTER > 0 554 /* 555 * Note that the interface cannot be in promiscuous mode if 556 * there are no bpf listeners. If we are in promiscuous 557 * mode, we have to check if this packet is really ours. 558 * However, there may be appropriate multicate addresses involved 559 */ 560 #define NOT_TO(p) (bcmp(et->ether_dhost, p, sizeof(et->ether_dhost)) != 0) 561 if (et->ether_dhost[0] & 1) { 562 if (NOT_TO(etherbroadcastaddr) 563 #ifdef ISO 564 && NOT_TO(all_es_snpa) && NOT_TO(all_is_snpa) 565 && NOT_TO(all_l1is_snpa) && NOT_TO(all_l2is_snpa) 566 #endif 567 ) return; 568 } else if ((ec->sc_if.if_flags & IFF_PROMISC) && NOT_TO(ec->sc_addr)) 569 return; 570 #endif 571 /* 572 * Pull packet off interface. Off is nonzero if packet 573 * has trailing header; m_devget will then force this header 574 * information to be at the front, but we still have to drop 575 * the type and length which are at the front of any trailer data. 576 */ 577 m = m_devget((char *)(et + 1), len, off, &ec->sc_if, 0); 578 if (m == 0) 579 return; 580 ether_input(&ec->sc_if, &eh, m); 581 } 582 583 /* 584 * Routine to copy from mbuf chain to transmit 585 * buffer in board local memory. 586 */ 587 ecput(ecbuf, m) 588 register char *ecbuf; 589 register struct mbuf *m; 590 { 591 register struct mbuf *mp; 592 register int len, tlen = 0; 593 594 for (mp = m; mp; mp = mp->m_next) { 595 len = mp->m_len; 596 if (len == 0) 597 continue; 598 tlen += len; 599 bcopy(mtod(mp, char *), ecbuf, len); 600 ecbuf += len; 601 } 602 m_freem(m); 603 if (tlen < ECMINSIZE) { 604 bzero(ecbuf, ECMINSIZE - tlen); 605 tlen = ECMINSIZE; 606 } 607 return(tlen); 608 } 609 610 /* 611 * Process an ioctl request. 612 */ 613 ecioctl(ifp, cmd, data) 614 register struct ifnet *ifp; 615 int cmd; 616 caddr_t data; 617 { 618 register struct ifaddr *ifa = (struct ifaddr *)data; 619 struct ec_softc *ec = &ec_softc[ifp->if_unit]; 620 int s = splimp(), error = 0; 621 622 switch (cmd) { 623 624 case SIOCSIFADDR: 625 ifp->if_flags |= IFF_UP; 626 switch (ifa->ifa_addr->sa_family) { 627 #ifdef INET 628 case AF_INET: 629 ecinit(ifp->if_unit); /* before arpwhohas */ 630 ((struct arpcom *)ifp)->ac_ipaddr = 631 IA_SIN(ifa)->sin_addr; 632 arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr); 633 break; 634 #endif 635 #ifdef NS 636 case AF_NS: 637 { 638 register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); 639 640 if (ns_nullhost(*ina)) 641 ina->x_host = *(union ns_host *)(ec->sc_addr); 642 else { 643 ifp->if_flags &= ~IFF_RUNNING; 644 bcopy((caddr_t)ina->x_host.c_host, 645 (caddr_t)ec->sc_addr, sizeof(ec->sc_addr)); 646 } 647 ecinit(ifp->if_unit); 648 break; 649 } 650 #endif 651 default: 652 ecinit(ifp->if_unit); 653 break; 654 } 655 break; 656 657 case SIOCSIFFLAGS: 658 if ((ifp->if_flags & IFF_UP) == 0 && 659 ifp->if_flags & IFF_RUNNING) { 660 ifp->if_flags &= ~IFF_RUNNING; 661 ecreset(ifp->if_unit); 662 } else if (ifp->if_flags & IFF_UP && 663 (ifp->if_flags & IFF_RUNNING) == 0) 664 ecinit(ifp->if_unit); 665 /* 666 * If the state of the promiscuous bit changes, the interface 667 * must be reset to effect the change. 668 */ 669 if (((ifp->if_flags ^ ec->sc_iflags) & IFF_PROMISC) && 670 (ifp->if_flags & IFF_RUNNING)) { 671 ec->sc_iflags = ifp->if_flags & ~IFF_OACTIVE; 672 ecreset(ifp->if_unit); 673 ecstart(ifp); 674 } 675 break; 676 677 default: 678 error = EINVAL; 679 } 680 splx(s); 681 return (error); 682 } 683 684 ecrerror(unit, msg) 685 int unit; 686 char *msg; 687 { 688 register struct ec_softc *ec = &ec_softc[unit]; 689 register struct ec_rfd *rmd; 690 int len; 691 692 if (!ecdebug) 693 return; 694 695 rmd = &ec->sc_hmem->rcom[ec->sc_rxnum]; 696 len = rmd->count; 697 log(LOG_WARNING, 698 "ec%d: ierror(%s): from %s: buf=%d, len=%d, rmd1=%b\n", 699 unit, msg, 700 len > 11 ? ether_sprintf(&ec->sc_hmem->rxbuf[ec->sc_rxnum][6]) : "unknown", 701 ec->sc_rxnum, len, 702 rmd->rfd0, "\14\14LEN\13CRC\12ALGN\11NBUF\10DMAL\07SHRT"); 703 } 704 705 ecxerror(unit) 706 int unit; 707 { 708 register struct ec_softc *ec = &ec_softc[unit]; 709 register struct ec_transmit *tmd; 710 int len; 711 712 if (!ecdebug) 713 return; 714 715 tmd = &ec->sc_hmem->tcom[ec->sc_txnum]; 716 len = tmd->count; 717 log(LOG_WARNING, 718 "ec%d: oerror: to %s: buf=%d, len=%d, com0=%b\n", 719 unit, 720 len > 5 ? ether_sprintf(ec->sc_hmem->txbuf[ec->sc_txnum]) : "unknown", 721 ec->sc_txnum, len, 722 tmd->com0, 723 "\14\14ABRT\13LCOLL\12NCAR\11NCTS\10DMAL\07TDEF\06HRBT\05XCOL"); 724 } 725 #endif 726