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