1 /* 2 * Copyright (c) 1993 Dean Huxley <dean@fsa.ca> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Dean Huxley. 16 * 4. The name of Dean Huxley may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * $Id: if_eg.c,v 1.3 1994/08/25 20:18:25 deraadt Exp $ 31 */ 32 33 /* To do: 34 * - multicast 35 * - promiscuous 36 */ 37 #include "bpfilter.h" 38 39 #include <sys/types.h> 40 #include <sys/param.h> 41 #include <sys/mbuf.h> 42 #include <sys/socket.h> 43 #include <sys/ioctl.h> 44 #include <sys/errno.h> 45 #include <sys/syslog.h> 46 #include <sys/select.h> 47 #include <sys/device.h> 48 49 #include <net/if.h> 50 #include <net/netisr.h> 51 #include <net/if_dl.h> 52 #include <net/if_types.h> 53 #include <net/netisr.h> 54 55 #ifdef INET 56 #include <netinet/in.h> 57 #include <netinet/in_systm.h> 58 #include <netinet/in_var.h> 59 #include <netinet/ip.h> 60 #include <netinet/if_ether.h> 61 #endif 62 63 #ifdef NS 64 #include <netns/ns.h> 65 #include <netns/ns_if.h> 66 #endif 67 68 #if NBPFILTER > 0 69 #include <net/bpf.h> 70 #include <net/bpfdesc.h> 71 #endif 72 73 #include <machine/cpu.h> 74 #include <machine/pio.h> 75 76 #include <i386/isa/isavar.h> 77 #include <i386/isa/if_egreg.h> 78 #include <i386/isa/elink.h> 79 80 /* for debugging convenience */ 81 #ifdef EGDEBUG 82 #define dprintf(x) printf x 83 #else 84 #define dprintf(x) 85 #endif 86 87 #define ETHER_MIN_LEN 64 88 #define ETHER_MAX_LEN 1518 89 #define ETHER_ADDR_LEN 6 90 91 #define EG_INLEN 10 92 #define EG_BUFLEN 0x0670 93 94 /* 95 * Ethernet software status per interface. 96 */ 97 struct eg_softc { 98 struct device sc_dev; 99 struct intrhand sc_ih; 100 struct arpcom sc_arpcom; /* Ethernet common part */ 101 u_short eg_cmd; /* Command register R/W */ 102 u_short eg_ctl; /* Control register R/W (EG_CTL_*) */ 103 u_short eg_stat; /* Status register R/O (EG_STAT_*) */ 104 u_short eg_data; /* Data register R/W (16 bits) */ 105 u_char eg_rom_major; /* Cards ROM version (major number) */ 106 u_char eg_rom_minor; /* Cards ROM version (minor number) */ 107 short eg_ram; /* Amount of RAM on the card */ 108 u_char eg_pcb[64]; /* Primary Command Block buffer */ 109 u_char eg_incount; /* Number of buffers currently used */ 110 u_char *eg_inbuf; /* Incoming packet buffer */ 111 u_char *eg_outbuf; /* Outgoing packet buffer */ 112 }; 113 114 static int egprobe(); 115 static void egattach(); 116 117 struct cfdriver egcd = { 118 NULL, "eg", egprobe, egattach, DV_IFNET, sizeof(struct eg_softc) 119 }; 120 121 int egintr __P((struct eg_softc *)); 122 static void eginit __P((struct eg_softc *)); 123 static int egioctl __P((struct ifnet *, int, caddr_t)); 124 static int egrecv __P((struct eg_softc *)); 125 static int egstart __P((struct ifnet *)); 126 static int egwatchdog __P((int)); 127 static void egreset __P((struct eg_softc *)); 128 static inline void egread __P((struct eg_softc *, caddr_t, int)); 129 static struct mbuf *egget __P((caddr_t, int, struct ifnet *)); 130 static void egstop __P((struct eg_softc *)); 131 132 /* 133 * Support stuff 134 */ 135 136 static inline void 137 egprintpcb(sc) 138 struct eg_softc *sc; 139 { 140 int i; 141 142 for (i = 0; i < sc->eg_pcb[1] + 2; i++) 143 dprintf(("pcb[%2d] = %x\n", i, sc->eg_pcb[i])); 144 } 145 146 147 static inline void 148 egprintstat(b) 149 u_char b; 150 { 151 dprintf(("%s %s %s %s %s %s %s\n", 152 (b & EG_STAT_HCRE)?"HCRE":"", 153 (b & EG_STAT_ACRF)?"ACRF":"", 154 (b & EG_STAT_DIR )?"DIR ":"", 155 (b & EG_STAT_DONE)?"DONE":"", 156 (b & EG_STAT_ASF3)?"ASF3":"", 157 (b & EG_STAT_ASF2)?"ASF2":"", 158 (b & EG_STAT_ASF1)?"ASF1":"")); 159 } 160 161 static int 162 egoutPCB(sc, b) 163 struct eg_softc *sc; 164 u_char b; 165 { 166 int i; 167 168 for (i=0; i < 4000; i++) { 169 if (inb(sc->eg_stat) & EG_STAT_HCRE) { 170 outb(sc->eg_cmd, b); 171 return 0; 172 } 173 delay(10); 174 } 175 dprintf(("egoutPCB failed\n")); 176 return 1; 177 } 178 179 static int 180 egreadPCBstat(sc, statb) 181 struct eg_softc *sc; 182 u_char statb; 183 { 184 int i; 185 186 for (i=0; i < 5000; i++) { 187 if (EG_PCB_STAT(inb(sc->eg_stat))) 188 break; 189 delay(10); 190 } 191 if (EG_PCB_STAT(inb(sc->eg_stat)) == statb) 192 return 0; 193 return 1; 194 } 195 196 static int 197 egreadPCBready(sc) 198 struct eg_softc *sc; 199 { 200 int i; 201 202 for (i=0; i < 10000; i++) { 203 if (inb(sc->eg_stat) & EG_STAT_ACRF) 204 return 0; 205 delay(5); 206 } 207 dprintf(("PCB read not ready\n")); 208 return 1; 209 } 210 211 static int 212 egwritePCB(sc) 213 struct eg_softc *sc; 214 { 215 int i; 216 u_char len; 217 218 outb(sc->eg_ctl, EG_PCB_MASK(inb(sc->eg_ctl))); 219 220 len = sc->eg_pcb[1] + 2; 221 for (i = 0; i < len; i++) 222 egoutPCB(sc, sc->eg_pcb[i]); 223 224 for (i=0; i < 4000; i++) { 225 if (inb(sc->eg_stat) & EG_STAT_HCRE) 226 break; 227 delay(10); 228 } 229 outb(sc->eg_ctl, EG_PCB_MASK(inb(sc->eg_ctl)) | EG_PCB_DONE); 230 egoutPCB(sc, len); 231 232 if (egreadPCBstat(sc, EG_PCB_ACCEPT)) 233 return 1; 234 return 0; 235 } 236 237 static int 238 egreadPCB(sc) 239 struct eg_softc *sc; 240 { 241 int i; 242 u_char b; 243 244 outb(sc->eg_ctl, EG_PCB_MASK(inb(sc->eg_ctl))); 245 246 bzero(sc->eg_pcb, sizeof(sc->eg_pcb)); 247 248 if (egreadPCBready(sc)) 249 return 1; 250 251 sc->eg_pcb[0] = inb(sc->eg_cmd); 252 253 if (egreadPCBready(sc)) 254 return 1; 255 256 sc->eg_pcb[1] = inb(sc->eg_cmd); 257 258 if (sc->eg_pcb[1] > 62) { 259 dprintf(("len %d too large\n", sc->eg_pcb[1])); 260 return 1; 261 } 262 263 for (i = 0; i < sc->eg_pcb[1]; i++) { 264 if (egreadPCBready(sc)) 265 return 1; 266 sc->eg_pcb[2+i] = inb(sc->eg_cmd); 267 } 268 if (egreadPCBready(sc)) 269 return 1; 270 if (egreadPCBstat(sc, EG_PCB_DONE)) 271 return 1; 272 if ((b = inb(sc->eg_cmd)) != sc->eg_pcb[1]+2) { 273 dprintf(("%d != %d\n", b, sc->eg_pcb[1]+2)); 274 return 1; 275 } 276 outb(sc->eg_ctl, EG_PCB_MASK(inb(sc->eg_ctl)) | EG_PCB_ACCEPT); 277 return 0; 278 } 279 280 /* 281 * Real stuff 282 */ 283 284 int 285 egprobe(parent, self, aux) 286 struct device *parent, *self; 287 void *aux; 288 { 289 struct eg_softc *sc = (void *)self; 290 struct isa_attach_args *ia = aux; 291 int i; 292 293 if (ia->ia_iobase & ~0x07f0 != 0) { 294 dprintf(("Weird iobase %x\n", ia->ia_iobase)); 295 return 0; 296 } 297 298 sc->eg_cmd = ia->ia_iobase + EG_COMMAND; 299 sc->eg_ctl = ia->ia_iobase + EG_CONTROL; 300 sc->eg_stat = ia->ia_iobase + EG_STATUS; 301 sc->eg_data = ia->ia_iobase + EG_DATA; 302 303 /* hard reset card */ 304 outb(sc->eg_ctl, EG_CTL_RESET); 305 outb(sc->eg_ctl, 0); 306 for (i = 0; i < 5000; i++) { 307 delay(1000); 308 if (EG_PCB_STAT(inb(sc->eg_stat)) == 0) 309 break; 310 } 311 if (EG_PCB_STAT(inb(sc->eg_stat)) != 0) { 312 dprintf(("eg: Reset failed\n")); 313 return 0; 314 } 315 sc->eg_pcb[0] = EG_CMD_GETINFO; /* Get Adapter Info */ 316 sc->eg_pcb[1] = 0; 317 if (egwritePCB(sc) != 0) 318 return 0; 319 320 if (egreadPCB(sc) != 0) { 321 egprintpcb(sc); 322 return 0; 323 } 324 325 if (sc->eg_pcb[0] != EG_RSP_GETINFO || /* Get Adapter Info Response */ 326 sc->eg_pcb[1] != 0x0a) { 327 egprintpcb(sc); 328 return 0; 329 } 330 sc->eg_rom_major = sc->eg_pcb[3]; 331 sc->eg_rom_minor = sc->eg_pcb[2]; 332 sc->eg_ram = sc->eg_pcb[6] | (sc->eg_pcb[7] << 8); 333 334 ia->ia_iosize = 0x08; 335 ia->ia_msize = 0; 336 return 1; 337 } 338 339 static void 340 egattach(parent, self, aux) 341 struct device *parent, *self; 342 void *aux; 343 { 344 struct eg_softc *sc = (void *)self; 345 struct isa_attach_args *ia = aux; 346 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 347 int i; 348 349 egstop(sc); 350 351 sc->eg_pcb[0] = EG_CMD_GETEADDR; /* Get Station address */ 352 sc->eg_pcb[1] = 0; 353 if (egwritePCB(sc) != 0) { 354 dprintf(("write error\n")); 355 return; 356 } 357 if (egreadPCB(sc) != 0) { 358 dprintf(("read error\n")); 359 egprintpcb(sc); 360 return; 361 } 362 363 /* check Get station address response */ 364 if (sc->eg_pcb[0] != EG_RSP_GETEADDR || sc->eg_pcb[1] != 0x06) { 365 dprintf(("parse error\n")); 366 egprintpcb(sc); 367 return; 368 } 369 bcopy(&sc->eg_pcb[2], sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN); 370 371 printf(": ROM v%d.%02d %dk address %s\n", 372 sc->eg_rom_major, sc->eg_rom_minor, sc->eg_ram, 373 ether_sprintf(sc->sc_arpcom.ac_enaddr)); 374 375 sc->eg_pcb[0] = EG_CMD_SETEADDR; /* Set station address */ 376 if (egwritePCB(sc) != 0) { 377 dprintf(("write error2\n")); 378 return; 379 } 380 if (egreadPCB(sc) != 0) { 381 dprintf(("read error2\n")); 382 egprintpcb(sc); 383 return; 384 } 385 if (sc->eg_pcb[0] != EG_RSP_SETEADDR || sc->eg_pcb[1] != 0x02 || 386 sc->eg_pcb[2] != 0 || sc->eg_pcb[3] != 0) { 387 dprintf(("parse error2\n")); 388 egprintpcb(sc); 389 return; 390 } 391 392 /* Initialize ifnet structure. */ 393 ifp->if_unit = sc->sc_dev.dv_unit; 394 ifp->if_name = egcd.cd_name; 395 ifp->if_output = ether_output; 396 ifp->if_start = egstart; 397 ifp->if_ioctl = egioctl; 398 ifp->if_watchdog = egwatchdog; 399 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS; 400 401 /* Now we can attach the interface. */ 402 if_attach(ifp); 403 ether_ifattach(ifp); 404 405 #if NBPFILTER > 0 406 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); 407 #endif 408 409 sc->sc_ih.ih_fun = egintr; 410 sc->sc_ih.ih_arg = sc; 411 sc->sc_ih.ih_level = IPL_NET; 412 intr_establish(ia->ia_irq, &sc->sc_ih); 413 } 414 415 static void 416 eginit(sc) 417 register struct eg_softc *sc; 418 { 419 register struct ifnet *ifp = &sc->sc_arpcom.ac_if; 420 421 /* Address not known. */ 422 if (ifp->if_addrlist == 0) 423 return; 424 425 /* soft reset the board */ 426 outb(sc->eg_ctl, EG_CTL_FLSH); 427 delay(100); 428 outb(sc->eg_ctl, EG_CTL_ATTN); 429 delay(100); 430 outb(sc->eg_ctl, 0); 431 delay(200); 432 433 sc->eg_pcb[0] = EG_CMD_CONFIG82586; /* Configure 82586 */ 434 sc->eg_pcb[1] = 2; 435 sc->eg_pcb[2] = 3; /* receive broadcast & multicast */ 436 sc->eg_pcb[3] = 0; 437 if (egwritePCB(sc) != 0) 438 dprintf(("write error3\n")); 439 440 if (egreadPCB(sc) != 0) { 441 dprintf(("read error\n")); 442 egprintpcb(sc); 443 } else if (sc->eg_pcb[2] != 0 || sc->eg_pcb[3] != 0) 444 printf("eg: configure card command failed.\n"); 445 446 if (sc->eg_inbuf == NULL) 447 sc->eg_inbuf = malloc(EG_BUFLEN, M_TEMP, M_NOWAIT); 448 sc->eg_incount = 0; 449 450 if (sc->eg_outbuf == NULL) 451 sc->eg_outbuf = malloc(EG_BUFLEN, M_TEMP, M_NOWAIT); 452 453 ifp->if_flags |= IFF_RUNNING; 454 ifp->if_flags &= ~IFF_OACTIVE; 455 456 outb(sc->eg_ctl, EG_CTL_CMDE); 457 458 egstart(ifp); 459 egrecv(sc); 460 } 461 462 static int 463 egrecv(sc) 464 struct eg_softc *sc; 465 { 466 467 while (sc->eg_incount < EG_INLEN) { 468 sc->eg_pcb[0] = EG_CMD_RECVPACKET; 469 sc->eg_pcb[1] = 0x08; 470 sc->eg_pcb[2] = 0; /* address not used.. we send zero */ 471 sc->eg_pcb[3] = 0; 472 sc->eg_pcb[4] = 0; 473 sc->eg_pcb[5] = 0; 474 sc->eg_pcb[6] = EG_BUFLEN & 0xff; /* our buffer size */ 475 sc->eg_pcb[7] = (EG_BUFLEN >> 8) & 0xff; 476 sc->eg_pcb[8] = 0; /* timeout, 0 == none */ 477 sc->eg_pcb[9] = 0; 478 if (egwritePCB(sc) == 0) 479 sc->eg_incount++; 480 else 481 break; 482 } 483 } 484 485 static int 486 egstart(ifp) 487 struct ifnet *ifp; 488 { 489 register struct eg_softc *sc = egcd.cd_devs[ifp->if_unit]; 490 struct mbuf *m0, *m; 491 int len; 492 short *ptr; 493 494 /* Don't transmit if interface is busy or not running */ 495 if ((sc->sc_arpcom.ac_if.if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING) 496 return 0; 497 498 /* Dequeue the next datagram. */ 499 IF_DEQUEUE(&sc->sc_arpcom.ac_if.if_snd, m0); 500 if (m0 == NULL) 501 return 0; 502 503 sc->sc_arpcom.ac_if.if_flags |= IFF_OACTIVE; 504 505 /* Copy the datagram to the buffer. */ 506 len = 0; 507 for (m = m0; m; m = m->m_next) { 508 if (m->m_len == 0) 509 continue; 510 if (len + m->m_len > EG_BUFLEN) { 511 dprintf(("Packet too large to send\n")); 512 m_freem(m0); 513 sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE; 514 sc->sc_arpcom.ac_if.if_oerrors++; 515 return 0; 516 } 517 bcopy(mtod(m, caddr_t), sc->eg_outbuf + len, m->m_len); 518 len += m->m_len; 519 } 520 #if NBPFILTER > 0 521 if (sc->sc_arpcom.ac_if.if_bpf) 522 bpf_mtap(sc->sc_arpcom.ac_if.if_bpf, m0); 523 #endif 524 m_freem(m0); 525 526 /* length must be a minimum of ETHER_MIN_LEN bytes */ 527 len = max(len, ETHER_MIN_LEN); 528 529 /* set direction bit: host -> adapter */ 530 outb(sc->eg_ctl, inb(sc->eg_ctl) & ~EG_CTL_DIR); 531 532 sc->eg_pcb[0] = EG_CMD_SENDPACKET; 533 sc->eg_pcb[1] = 0x06; 534 sc->eg_pcb[2] = 0; /* address not used, we send zero */ 535 sc->eg_pcb[3] = 0; 536 sc->eg_pcb[4] = 0; 537 sc->eg_pcb[5] = 0; 538 sc->eg_pcb[6] = len & 0xff; /* length of packet */ 539 sc->eg_pcb[7] = (len >> 8) & 0xff; 540 if (egwritePCB(sc) == 0) { 541 for (ptr = (short *) sc->eg_outbuf; len > 0; len -= 2) { 542 outw(sc->eg_data, *ptr++); 543 while (!(inb(sc->eg_stat) & EG_STAT_HRDY)) 544 ; /* XXX need timeout here */ 545 } 546 } else { 547 dprintf(("egwritePCB in egstart failed\n")); 548 sc->sc_arpcom.ac_if.if_oerrors++; 549 sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE; 550 } 551 552 /* Set direction bit : Adapter -> host */ 553 outb(sc->eg_ctl, inb(sc->eg_ctl) | EG_CTL_DIR); 554 555 return 0; 556 } 557 558 int 559 egintr(sc) 560 register struct eg_softc *sc; 561 { 562 int i, len; 563 short *ptr; 564 565 while (inb(sc->eg_stat) & EG_STAT_ACRF) { 566 egreadPCB(sc); 567 switch (sc->eg_pcb[0]) { 568 case EG_RSP_RECVPACKET: 569 len = sc->eg_pcb[6]+(sc->eg_pcb[7]<<8); 570 for (ptr = (short *) sc->eg_inbuf; len > 0; len -= 2) { 571 while (!(inb(sc->eg_stat) & EG_STAT_HRDY)) 572 ; 573 *ptr++ = inw(sc->eg_data); 574 } 575 len = sc->eg_pcb[8]+(sc->eg_pcb[9]<<8); 576 egrecv(sc); 577 sc->sc_arpcom.ac_if.if_ipackets++; 578 egread(sc, sc->eg_inbuf, len); 579 sc->eg_incount--; 580 break; 581 582 case EG_RSP_SENDPACKET: 583 if (sc->eg_pcb[6] || sc->eg_pcb[7]) { 584 dprintf(("packet dropped\n")); 585 sc->sc_arpcom.ac_if.if_oerrors++; 586 } else 587 sc->sc_arpcom.ac_if.if_opackets++; 588 sc->sc_arpcom.ac_if.if_collisions += sc->eg_pcb[8] & 0xf; 589 sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE; 590 egstart(&sc->sc_arpcom.ac_if); 591 break; 592 593 case EG_RSP_GETSTATS: 594 dprintf(("Card Statistics\n")); 595 bcopy(&sc->eg_pcb[2], &i, sizeof(i)); 596 dprintf(("Receive Packets %d\n", i)); 597 bcopy(&sc->eg_pcb[6], &i, sizeof(i)); 598 dprintf(("Transmit Packets %d\n", i)); 599 dprintf(("CRC errors %d\n", *(short*) &sc->eg_pcb[10])); 600 dprintf(("alignment errors %d\n", *(short*) &sc->eg_pcb[12])); 601 dprintf(("no resources errors %d\n", *(short*) &sc->eg_pcb[14])); 602 dprintf(("overrun errors %d\n", *(short*) &sc->eg_pcb[16])); 603 break; 604 605 default: 606 dprintf(("egintr: Unknown response %x??\n", 607 sc->eg_pcb[0])); 608 egprintpcb(sc); 609 break; 610 } 611 } 612 613 return 0; 614 } 615 616 /* 617 * Pass a packet up to the higher levels. 618 */ 619 static inline void 620 egread(sc, buf, len) 621 struct eg_softc *sc; 622 caddr_t buf; 623 int len; 624 { 625 struct ifnet *ifp; 626 struct mbuf *m; 627 struct ether_header *eh; 628 629 if (len <= sizeof(struct ether_header) || 630 len > ETHER_MAX_LEN) { 631 dprintf(("Unacceptable packet size %d\n", len)); 632 sc->sc_arpcom.ac_if.if_ierrors++; 633 return; 634 } 635 636 /* Pull packet off interface. */ 637 ifp = &sc->sc_arpcom.ac_if; 638 m = egget(buf, len, ifp); 639 if (m == 0) { 640 dprintf(("egget returned 0\n")); 641 sc->sc_arpcom.ac_if.if_ierrors++; 642 return; 643 } 644 645 /* We assume the header fit entirely in one mbuf. */ 646 eh = mtod(m, struct ether_header *); 647 648 #if NBPFILTER > 0 649 /* 650 * Check if there's a BPF listener on this interface. 651 * If so, hand off the raw packet to BPF. 652 */ 653 if (ifp->if_bpf) { 654 bpf_mtap(ifp->if_bpf, m); 655 656 /* 657 * Note that the interface cannot be in promiscuous mode if 658 * there are no BPF listeners. And if we are in promiscuous 659 * mode, we have to check if this packet is really ours. 660 */ 661 if ((ifp->if_flags & IFF_PROMISC) && 662 (eh->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */ 663 bcmp(eh->ether_dhost, sc->sc_arpcom.ac_enaddr, 664 sizeof(eh->ether_dhost)) != 0) { 665 m_freem(m); 666 return; 667 } 668 } 669 #endif 670 671 /* We assume the header fit entirely in one mbuf. */ 672 m->m_pkthdr.len -= sizeof(*eh); 673 m->m_len -= sizeof(*eh); 674 m->m_data += sizeof(*eh); 675 676 ether_input(ifp, eh, m); 677 } 678 679 /* 680 * convert buf into mbufs 681 */ 682 static struct mbuf * 683 egget(buf, totlen, ifp) 684 caddr_t buf; 685 int totlen; 686 struct ifnet *ifp; 687 { 688 struct mbuf *top, **mp, *m; 689 int len; 690 691 MGETHDR(m, M_DONTWAIT, MT_DATA); 692 if (m == 0) { 693 dprintf(("MGETHDR returns 0\n")); 694 return 0; 695 } 696 m->m_pkthdr.rcvif = ifp; 697 m->m_pkthdr.len = totlen; 698 len = MHLEN; 699 top = 0; 700 mp = ⊤ 701 702 while (totlen > 0) { 703 if (top) { 704 MGET(m, M_DONTWAIT, MT_DATA); 705 if (m == 0) { 706 m_freem(top); 707 dprintf(("MGET returns 0\n")); 708 return 0; 709 } 710 len = MLEN; 711 } 712 if (totlen >= MINCLSIZE) { 713 MCLGET(m, M_DONTWAIT); 714 if (m->m_flags & M_EXT) 715 len = MCLBYTES; 716 } 717 m->m_len = len = min(totlen, len); 718 bcopy((caddr_t)buf, mtod(m, caddr_t), len); 719 buf += len; 720 totlen -= len; 721 *mp = m; 722 mp = &m->m_next; 723 } 724 725 return top; 726 } 727 728 static int 729 egioctl(ifp, command, data) 730 register struct ifnet *ifp; 731 int command; 732 caddr_t data; 733 { 734 struct eg_softc *sc = egcd.cd_devs[ifp->if_unit]; 735 register struct ifaddr *ifa = (struct ifaddr *)data; 736 struct ifreq *ifr = (struct ifreq *)data; 737 int s, error = 0; 738 739 s = splimp(); 740 741 switch (command) { 742 743 case SIOCSIFADDR: 744 ifp->if_flags |= IFF_UP; 745 746 switch (ifa->ifa_addr->sa_family) { 747 #ifdef INET 748 case AF_INET: 749 eginit(sc); /* before arpwhohas */ 750 sc->sc_arpcom.ac_ipaddr = IA_SIN(ifa)->sin_addr; 751 arpwhohas(&sc->sc_arpcom, &IA_SIN(ifa)->sin_addr); 752 break; 753 #endif 754 #ifdef NS 755 case AF_NS: 756 { 757 register struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; 758 759 if (ns_nullhost(*ina)) 760 ina->x_host = 761 *(union ns_host *)(sc->sc_arpcom.ac_enaddr); 762 else 763 bcopy(ina->x_host.c_host, 764 sc->sc_arpcom.ac_enaddr, 765 sizeof(sc->sc_arpcom.ac_enaddr)); 766 /* Set new address. */ 767 eginit(sc); 768 break; 769 } 770 #endif 771 default: 772 eginit(sc); 773 break; 774 } 775 break; 776 777 case SIOCSIFFLAGS: 778 if ((ifp->if_flags & IFF_UP) == 0 && 779 (ifp->if_flags & IFF_RUNNING) != 0) { 780 /* 781 * If interface is marked down and it is running, then 782 * stop it. 783 */ 784 egstop(sc); 785 ifp->if_flags &= ~IFF_RUNNING; 786 } else if ((ifp->if_flags & IFF_UP) != 0 && 787 (ifp->if_flags & IFF_RUNNING) == 0) { 788 /* 789 * If interface is marked up and it is stopped, then 790 * start it. 791 */ 792 eginit(sc); 793 } else { 794 sc->eg_pcb[0] = EG_CMD_GETSTATS; 795 sc->eg_pcb[1] = 0; 796 if (egwritePCB(sc) != 0) 797 dprintf(("write error\n")); 798 /* 799 * XXX deal with flags changes: 800 * IFF_MULTICAST, IFF_PROMISC, 801 * IFF_LINK0, IFF_LINK1, 802 */ 803 } 804 break; 805 806 default: 807 error = EINVAL; 808 } 809 810 splx(s); 811 return error; 812 } 813 814 static void 815 egreset(sc) 816 struct eg_softc *sc; 817 { 818 int s; 819 820 dprintf(("egreset()\n")); 821 s = splimp(); 822 egstop(sc); 823 eginit(sc); 824 splx(s); 825 } 826 827 static int 828 egwatchdog(unit) 829 int unit; 830 { 831 struct eg_softc *sc = egcd.cd_devs[unit]; 832 833 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname); 834 sc->sc_arpcom.ac_if.if_oerrors++; 835 836 egreset(sc); 837 return 0; 838 } 839 840 static void 841 egstop(sc) 842 register struct eg_softc *sc; 843 { 844 845 outb(sc->eg_ctl, 0); 846 } 847