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.2 (Berkeley) 09/17/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 return ec_rxstart(ec); 480 /* 481 * Process all buffers with valid data 482 */ 483 while ((rmd->rfd0 & COM0_C) && (rmd->count & RBD_F)) { 484 if (rmd->rfd0 & (COM0_C|COM0_B|COM0_OK) != (COM0_C|COM0_OK)) { 485 ec->sc_rxnum = bix; 486 ecrerror(unit, "bad packet"); 487 ec->sc_if.if_ierrors++; 488 } 489 if ((rmd->count & (RBD_F|RBD_EOF)) != (RBD_F|RBD_EOF)) { 490 ecrerror(unit, "chained buffer"); 491 ec->sc_rxlen++; 492 ec->sc_if.if_ierrors++; 493 } else 494 ecread(ec, ec->sc_hmem->txbuf[bix], rmd->count & 0x2f); 495 rmd->count = 0; 496 rmd->rfd0 = 0; 497 ECNEXTRCOM; 498 ec->sc_rxnum = bix; 499 } 500 } 501 502 void 503 ecread(ec, buf, len) 504 register struct ec_softc *ec; 505 char *buf; 506 int len; 507 { 508 struct ether_header *et, eh; 509 struct mbuf *m; 510 int off, resid, unit = ec->sc_if.if_unit; 511 512 ec->sc_if.if_ipackets++; 513 et = (struct ether_header *)buf; 514 et->ether_type = ntohs((u_short)et->ether_type); 515 bcopy((caddr_t)et, &eh, sizeof(eh)); 516 /* adjust input length to account for header */ 517 len = len - sizeof(struct ether_header); 518 519 #define ecdataaddr(et, off, type) ((type)(((caddr_t)((et)+1)+(off)))) 520 if (et->ether_type >= ETHERTYPE_TRAIL && 521 et->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) { 522 off = (et->ether_type - ETHERTYPE_TRAIL) * 512; 523 if (off >= ETHERMTU) 524 return; /* sanity */ 525 et->ether_type = ntohs(*ecdataaddr(et, off, u_short *)); 526 resid = ntohs(*(ecdataaddr(et, off+2, u_short *))); 527 if (off + resid > len) 528 return; /* sanity */ 529 len = off + resid; 530 } else 531 off = 0; 532 533 if (len <= 0) { 534 if (ecdebug) 535 log(LOG_WARNING, 536 "ec%d: ierror(runt packet): from %s: len=%d\n", 537 unit, ether_sprintf(et->ether_shost), len); 538 ec->sc_runt++; 539 ec->sc_if.if_ierrors++; 540 return; 541 } 542 #if NBPFILTER > 0 543 /* 544 * Check if there's a bpf filter listening on this interface. 545 * If so, hand off the raw packet to bpf, which must deal with 546 * trailers in its own way. 547 */ 548 if (ec->sc_bpf) 549 bpf_tap(ec->sc_bpf, buf, len + sizeof(struct ether_header)); 550 #endif 551 #if defined(ISO) || NBPFILTER > 0 552 /* 553 * Note that the interface cannot be in promiscuous mode if 554 * there are no bpf listeners. If we are in promiscuous 555 * mode, we have to check if this packet is really ours. 556 * However, there may be appropriate multicate addresses involved 557 */ 558 #define NOT_TO(p) (bcmp(et->ether_dhost, p, sizeof(et->ether_dhost)) != 0) 559 if (et->ether_dhost[0] & 1) { 560 if (NOT_TO(etherbroadcastaddr) 561 #ifdef ISO 562 && NOT_TO(all_es_snpa) && NOT_TO(all_is_snpa) 563 && NOT_TO(all_l1is_snpa) && NOT_TO(all_l2is_snpa) 564 #endif 565 ) return; 566 } else if ((ec->sc_if.if_flags & IFF_PROMISC) && NOT_TO(ec->sc_addr)) 567 return; 568 #endif 569 /* 570 * Pull packet off interface. Off is nonzero if packet 571 * has trailing header; m_devget will then force this header 572 * information to be at the front, but we still have to drop 573 * the type and length which are at the front of any trailer data. 574 */ 575 m = m_devget((char *)(et + 1), len, off, &ec->sc_if, 0); 576 if (m == 0) 577 return; 578 ether_input(&ec->sc_if, &eh, m); 579 } 580 581 /* 582 * Routine to copy from mbuf chain to transmit 583 * buffer in board local memory. 584 */ 585 ecput(ecbuf, m) 586 register char *ecbuf; 587 register struct mbuf *m; 588 { 589 register struct mbuf *mp; 590 register int len, tlen = 0; 591 592 for (mp = m; mp; mp = mp->m_next) { 593 len = mp->m_len; 594 if (len == 0) 595 continue; 596 tlen += len; 597 bcopy(mtod(mp, char *), ecbuf, len); 598 ecbuf += len; 599 } 600 m_freem(m); 601 if (tlen < ECMINSIZE) { 602 bzero(ecbuf, ECMINSIZE - tlen); 603 tlen = ECMINSIZE; 604 } 605 return(tlen); 606 } 607 608 /* 609 * Process an ioctl request. 610 */ 611 ecioctl(ifp, cmd, data) 612 register struct ifnet *ifp; 613 int cmd; 614 caddr_t data; 615 { 616 register struct ifaddr *ifa = (struct ifaddr *)data; 617 struct ec_softc *ec = &ec_softc[ifp->if_unit]; 618 int s = splimp(), error = 0; 619 620 switch (cmd) { 621 622 case SIOCSIFADDR: 623 ifp->if_flags |= IFF_UP; 624 switch (ifa->ifa_addr->sa_family) { 625 #ifdef INET 626 case AF_INET: 627 ecinit(ifp->if_unit); /* before arpwhohas */ 628 ((struct arpcom *)ifp)->ac_ipaddr = 629 IA_SIN(ifa)->sin_addr; 630 arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr); 631 break; 632 #endif 633 #ifdef NS 634 case AF_NS: 635 { 636 register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); 637 638 if (ns_nullhost(*ina)) 639 ina->x_host = *(union ns_host *)(ec->sc_addr); 640 else { 641 ifp->if_flags &= ~IFF_RUNNING; 642 bcopy((caddr_t)ina->x_host.c_host, 643 (caddr_t)ec->sc_addr, sizeof(ec->sc_addr)); 644 } 645 ecinit(ifp->if_unit); 646 break; 647 } 648 #endif 649 default: 650 ecinit(ifp->if_unit); 651 break; 652 } 653 break; 654 655 case SIOCSIFFLAGS: 656 if ((ifp->if_flags & IFF_UP) == 0 && 657 ifp->if_flags & IFF_RUNNING) { 658 ifp->if_flags &= ~IFF_RUNNING; 659 ecreset(ifp->if_unit); 660 } else if (ifp->if_flags & IFF_UP && 661 (ifp->if_flags & IFF_RUNNING) == 0) 662 ecinit(ifp->if_unit); 663 /* 664 * If the state of the promiscuous bit changes, the interface 665 * must be reset to effect the change. 666 */ 667 if (((ifp->if_flags ^ ec->sc_iflags) & IFF_PROMISC) && 668 (ifp->if_flags & IFF_RUNNING)) { 669 ec->sc_iflags = ifp->if_flags & ~IFF_OACTIVE; 670 ecreset(ifp->if_unit); 671 ecstart(ifp); 672 } 673 break; 674 675 default: 676 error = EINVAL; 677 } 678 splx(s); 679 return (error); 680 } 681 682 ecrerror(unit, msg) 683 int unit; 684 char *msg; 685 { 686 register struct ec_softc *ec = &ec_softc[unit]; 687 register struct ec_rfd *rmd; 688 int len; 689 690 if (!ecdebug) 691 return; 692 693 rmd = &ec->sc_hmem->rcom[ec->sc_rxnum]; 694 len = rmd->count; 695 log(LOG_WARNING, 696 "ec%d: ierror(%s): from %s: buf=%d, len=%d, rmd1=%b\n", 697 unit, msg, 698 len > 11 ? ether_sprintf(&ec->sc_hmem->rxbuf[ec->sc_rxnum][6]) : "unknown", 699 ec->sc_rxnum, len, 700 rmd->rfd0, "\14\14LEN\13CRC\12ALGN\11NBUF\10DMAL\07SHRT"); 701 } 702 703 ecxerror(unit) 704 int unit; 705 { 706 register struct ec_softc *ec = &ec_softc[unit]; 707 register struct ec_transmit *tmd; 708 int len; 709 710 if (!ecdebug) 711 return; 712 713 tmd = &ec->sc_hmem->tcom[ec->sc_txnum]; 714 len = tmd->count; 715 log(LOG_WARNING, 716 "ec%d: oerror: to %s: buf=%d, len=%d, com0=%b\n", 717 unit, 718 len > 5 ? ether_sprintf(ec->sc_hmem->txbuf[ec->sc_txnum]) : "unknown", 719 ec->sc_txnum, len, 720 tmd->com0, 721 "\14\14ABRT\13LCOLL\12NCAR\11NCTS\10DMAL\07TDEF\06HRBT\05XCOL"); 722 } 723 #endif 724