1 /* $OpenBSD: if_el.c,v 1.23 2014/08/11 12:45:45 mpi Exp $ */ 2 /* $NetBSD: if_el.c,v 1.39 1996/05/12 23:52:32 mycroft Exp $ */ 3 4 /* 5 * Copyright (c) 1994, Matthew E. Kimmel. Permission is hereby granted 6 * to use, copy, modify and distribute this software provided that both 7 * the copyright notice and this permission notice appear in all copies 8 * of the software, derivative works or modified versions, and any 9 * portions thereof. 10 */ 11 12 /* 13 * 3COM Etherlink 3C501 device driver 14 */ 15 16 /* 17 * Bugs/possible improvements: 18 * - Does not currently support DMA 19 * - Does not currently support multicasts 20 */ 21 22 #include "bpfilter.h" 23 24 #include <sys/param.h> 25 #include <sys/systm.h> 26 #include <sys/errno.h> 27 #include <sys/ioctl.h> 28 #include <sys/mbuf.h> 29 #include <sys/socket.h> 30 #include <sys/syslog.h> 31 #include <sys/device.h> 32 33 #include <net/if.h> 34 #include <net/if_dl.h> 35 #include <net/if_types.h> 36 37 #include <netinet/in.h> 38 #include <netinet/if_ether.h> 39 40 #if NBPFILTER > 0 41 #include <net/bpf.h> 42 #endif 43 44 #include <machine/cpu.h> 45 #include <machine/intr.h> 46 #include <machine/pio.h> 47 48 #include <dev/isa/isavar.h> 49 #include <dev/isa/if_elreg.h> 50 51 /* for debugging convenience */ 52 #ifdef EL_DEBUG 53 #define dprintf(x) printf x 54 #else 55 #define dprintf(x) 56 #endif 57 58 /* 59 * per-line info and status 60 */ 61 struct el_softc { 62 struct device sc_dev; 63 void *sc_ih; 64 65 struct arpcom sc_arpcom; /* ethernet common */ 66 int sc_iobase; /* base I/O addr */ 67 }; 68 69 /* 70 * prototypes 71 */ 72 int elintr(void *); 73 void elinit(struct el_softc *); 74 int elioctl(struct ifnet *, u_long, caddr_t); 75 void elstart(struct ifnet *); 76 void elwatchdog(struct ifnet *); 77 void elreset(struct el_softc *); 78 void elstop(struct el_softc *); 79 static int el_xmit(struct el_softc *); 80 void elread(struct el_softc *, int); 81 struct mbuf *elget(struct el_softc *sc, int); 82 static inline void el_hardreset(struct el_softc *); 83 84 int elprobe(struct device *, void *, void *); 85 void elattach(struct device *, struct device *, void *); 86 87 struct cfattach el_ca = { 88 sizeof(struct el_softc), elprobe, elattach 89 }; 90 91 struct cfdriver el_cd = { 92 NULL, "el", DV_IFNET 93 }; 94 95 /* 96 * Probe routine. 97 * 98 * See if the card is there and at the right place. 99 * (XXX - cgd -- needs help) 100 */ 101 int 102 elprobe(parent, match, aux) 103 struct device *parent; 104 void *match, *aux; 105 { 106 struct el_softc *sc = match; 107 struct isa_attach_args *ia = aux; 108 int iobase = ia->ia_iobase; 109 u_char station_addr[ETHER_ADDR_LEN]; 110 int i; 111 112 /* First check the base. */ 113 if (iobase < 0x280 || iobase > 0x3f0) 114 return 0; 115 116 /* Grab some info for our structure. */ 117 sc->sc_iobase = iobase; 118 119 /* 120 * Now attempt to grab the station address from the PROM and see if it 121 * contains the 3com vendor code. 122 */ 123 dprintf(("Probing 3c501 at 0x%x...\n", iobase)); 124 125 /* Reset the board. */ 126 dprintf(("Resetting board...\n")); 127 outb(iobase+EL_AC, EL_AC_RESET); 128 delay(5); 129 outb(iobase+EL_AC, 0); 130 131 /* Now read the address. */ 132 dprintf(("Reading station address...\n")); 133 for (i = 0; i < ETHER_ADDR_LEN; i++) { 134 outb(iobase+EL_GPBL, i); 135 station_addr[i] = inb(iobase+EL_EAW); 136 } 137 dprintf(("Address is %s\n", ether_sprintf(station_addr))); 138 139 /* 140 * If the vendor code is ok, return a 1. We'll assume that whoever 141 * configured this system is right about the IRQ. 142 */ 143 if (station_addr[0] != 0x02 || station_addr[1] != 0x60 || 144 station_addr[2] != 0x8c) { 145 dprintf(("Bad vendor code.\n")); 146 return 0; 147 } 148 149 dprintf(("Vendor code ok.\n")); 150 /* Copy the station address into the arpcom structure. */ 151 bcopy(station_addr, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN); 152 153 ia->ia_iosize = 4; /* XXX */ 154 ia->ia_msize = 0; 155 return 1; 156 } 157 158 /* 159 * Attach the interface to the kernel data structures. By the time this is 160 * called, we know that the card exists at the given I/O address. We still 161 * assume that the IRQ given is correct. 162 */ 163 void 164 elattach(parent, self, aux) 165 struct device *parent, *self; 166 void *aux; 167 { 168 struct el_softc *sc = (void *)self; 169 struct isa_attach_args *ia = aux; 170 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 171 172 dprintf(("Attaching %s...\n", sc->sc_dev.dv_xname)); 173 174 /* Stop the board. */ 175 elstop(sc); 176 177 /* Initialize ifnet structure. */ 178 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); 179 ifp->if_softc = sc; 180 ifp->if_start = elstart; 181 ifp->if_ioctl = elioctl; 182 ifp->if_watchdog = elwatchdog; 183 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS; 184 IFQ_SET_READY(&ifp->if_snd); 185 186 /* Now we can attach the interface. */ 187 dprintf(("Attaching interface...\n")); 188 if_attach(ifp); 189 ether_ifattach(ifp); 190 191 /* Print out some information for the user. */ 192 printf(": address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr)); 193 194 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE, 195 IPL_NET, elintr, sc, sc->sc_dev.dv_xname); 196 197 dprintf(("elattach() finished.\n")); 198 } 199 200 /* 201 * Reset interface. 202 */ 203 void 204 elreset(sc) 205 struct el_softc *sc; 206 { 207 int s; 208 209 dprintf(("elreset()\n")); 210 s = splnet(); 211 elstop(sc); 212 elinit(sc); 213 splx(s); 214 } 215 216 /* 217 * Stop interface. 218 */ 219 void 220 elstop(sc) 221 struct el_softc *sc; 222 { 223 224 outb(sc->sc_iobase+EL_AC, 0); 225 } 226 227 /* 228 * Do a hardware reset of the board, and upload the ethernet address again in 229 * case the board forgets. 230 */ 231 static inline void 232 el_hardreset(sc) 233 struct el_softc *sc; 234 { 235 int iobase = sc->sc_iobase; 236 int i; 237 238 outb(iobase+EL_AC, EL_AC_RESET); 239 delay(5); 240 outb(iobase+EL_AC, 0); 241 242 for (i = 0; i < ETHER_ADDR_LEN; i++) 243 outb(iobase+i, sc->sc_arpcom.ac_enaddr[i]); 244 } 245 246 /* 247 * Initialize interface. 248 */ 249 void 250 elinit(sc) 251 struct el_softc *sc; 252 { 253 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 254 int iobase = sc->sc_iobase; 255 256 /* First, reset the board. */ 257 el_hardreset(sc); 258 259 /* Configure rx. */ 260 dprintf(("Configuring rx...\n")); 261 if (ifp->if_flags & IFF_PROMISC) 262 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_PROMISC); 263 else 264 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_ABROAD); 265 outb(iobase+EL_RBC, 0); 266 267 /* Configure TX. */ 268 dprintf(("Configuring tx...\n")); 269 outb(iobase+EL_TXC, 0); 270 271 /* Start reception. */ 272 dprintf(("Starting reception...\n")); 273 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX); 274 275 /* Set flags appropriately. */ 276 ifp->if_flags |= IFF_RUNNING; 277 ifp->if_flags &= ~IFF_OACTIVE; 278 279 /* And start output. */ 280 elstart(ifp); 281 } 282 283 /* 284 * Start output on interface. Get datagrams from the queue and output them, 285 * giving the receiver a chance between datagrams. Call only from splnet or 286 * interrupt level! 287 */ 288 void 289 elstart(ifp) 290 struct ifnet *ifp; 291 { 292 struct el_softc *sc = ifp->if_softc; 293 int iobase = sc->sc_iobase; 294 struct mbuf *m, *m0; 295 int s, i, off, retries; 296 297 dprintf(("elstart()...\n")); 298 s = splnet(); 299 300 /* Don't do anything if output is active. */ 301 if ((ifp->if_flags & IFF_OACTIVE) != 0) { 302 splx(s); 303 return; 304 } 305 306 ifp->if_flags |= IFF_OACTIVE; 307 308 /* 309 * The main loop. They warned me against endless loops, but would I 310 * listen? NOOO.... 311 */ 312 for (;;) { 313 /* Dequeue the next datagram. */ 314 IFQ_DEQUEUE(&ifp->if_snd, m0); 315 316 /* If there's nothing to send, return. */ 317 if (m0 == 0) 318 break; 319 320 #if NBPFILTER > 0 321 /* Give the packet to the bpf, if any. */ 322 if (ifp->if_bpf) 323 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT); 324 #endif 325 326 /* Disable the receiver. */ 327 outb(iobase+EL_AC, EL_AC_HOST); 328 outb(iobase+EL_RBC, 0); 329 330 /* Transfer datagram to board. */ 331 dprintf(("el: xfr pkt length=%d...\n", m0->m_pkthdr.len)); 332 off = EL_BUFSIZ - max(m0->m_pkthdr.len, ETHER_MIN_LEN); 333 outb(iobase+EL_GPBL, off); 334 outb(iobase+EL_GPBH, off >> 8); 335 336 /* Copy the datagram to the buffer. */ 337 for (m = m0; m != 0; m = m->m_next) 338 outsb(iobase+EL_BUF, mtod(m, caddr_t), m->m_len); 339 for (i = 0; 340 i < ETHER_MIN_LEN - ETHER_CRC_LEN - m0->m_pkthdr.len; i++) 341 outb(iobase+EL_BUF, 0); 342 343 m_freem(m0); 344 345 /* Now transmit the datagram. */ 346 retries = 0; 347 for (;;) { 348 outb(iobase+EL_GPBL, off); 349 outb(iobase+EL_GPBH, off >> 8); 350 if (el_xmit(sc)) { 351 ifp->if_oerrors++; 352 break; 353 } 354 /* Check out status. */ 355 i = inb(iobase+EL_TXS); 356 dprintf(("tx status=0x%x\n", i)); 357 if ((i & EL_TXS_READY) == 0) { 358 dprintf(("el: err txs=%x\n", i)); 359 if (i & (EL_TXS_COLL | EL_TXS_COLL16)) { 360 ifp->if_collisions++; 361 if ((i & EL_TXC_DCOLL16) == 0 && 362 retries < 15) { 363 retries++; 364 outb(iobase+EL_AC, EL_AC_HOST); 365 } 366 } else { 367 ifp->if_oerrors++; 368 break; 369 } 370 } else { 371 ifp->if_opackets++; 372 break; 373 } 374 } 375 376 /* 377 * Now give the card a chance to receive. 378 * Gotta love 3c501s... 379 */ 380 (void)inb(iobase+EL_AS); 381 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX); 382 splx(s); 383 /* Interrupt here. */ 384 s = splnet(); 385 } 386 387 (void)inb(iobase+EL_AS); 388 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX); 389 ifp->if_flags &= ~IFF_OACTIVE; 390 splx(s); 391 } 392 393 /* 394 * This function actually attempts to transmit a datagram downloaded to the 395 * board. Call at splnet or interrupt, after downloading data! Returns 0 on 396 * success, non-0 on failure. 397 */ 398 static int 399 el_xmit(sc) 400 struct el_softc *sc; 401 { 402 int iobase = sc->sc_iobase; 403 int i; 404 405 /* 406 * XXX 407 * This busy-waits for the tx completion. Can we get an interrupt 408 * instead? 409 */ 410 411 dprintf(("el: xmit...")); 412 outb(iobase+EL_AC, EL_AC_TXFRX); 413 i = 20000; 414 while ((inb(iobase+EL_AS) & EL_AS_TXBUSY) && (i > 0)) 415 i--; 416 if (i == 0) { 417 dprintf(("tx not ready\n")); 418 return -1; 419 } 420 dprintf(("%d cycles.\n", 20000 - i)); 421 return 0; 422 } 423 424 /* 425 * Controller interrupt. 426 */ 427 int 428 elintr(arg) 429 void *arg; 430 { 431 register struct el_softc *sc = arg; 432 int iobase = sc->sc_iobase; 433 int rxstat, len; 434 435 dprintf(("elintr: ")); 436 437 /* Check board status. */ 438 if ((inb(iobase+EL_AS) & EL_AS_RXBUSY) != 0) { 439 (void)inb(iobase+EL_RXC); 440 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX); 441 return 0; 442 } 443 444 for (;;) { 445 rxstat = inb(iobase+EL_RXS); 446 if (rxstat & EL_RXS_STALE) 447 break; 448 449 /* If there's an overflow, reinit the board. */ 450 if ((rxstat & EL_RXS_NOFLOW) == 0) { 451 dprintf(("overflow.\n")); 452 el_hardreset(sc); 453 /* Put board back into receive mode. */ 454 if (sc->sc_arpcom.ac_if.if_flags & IFF_PROMISC) 455 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_PROMISC); 456 else 457 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_ABROAD); 458 (void)inb(iobase+EL_AS); 459 outb(iobase+EL_RBC, 0); 460 break; 461 } 462 463 /* Incoming packet. */ 464 len = inb(iobase+EL_RBL); 465 len |= inb(iobase+EL_RBH) << 8; 466 dprintf(("receive len=%d rxstat=%x ", len, rxstat)); 467 outb(iobase+EL_AC, EL_AC_HOST); 468 469 /* Pass data up to upper levels. */ 470 elread(sc, len); 471 472 /* Is there another packet? */ 473 if ((inb(iobase+EL_AS) & EL_AS_RXBUSY) != 0) 474 break; 475 476 dprintf(("<rescan> ")); 477 } 478 479 (void)inb(iobase+EL_RXC); 480 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX); 481 return 1; 482 } 483 484 /* 485 * Pass a packet to the higher levels. 486 */ 487 void 488 elread(sc, len) 489 register struct el_softc *sc; 490 int len; 491 { 492 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 493 struct mbuf *m; 494 495 if (len <= sizeof(struct ether_header) || 496 len > ETHER_MAX_LEN) { 497 printf("%s: invalid packet size %d; dropping\n", 498 sc->sc_dev.dv_xname, len); 499 ifp->if_ierrors++; 500 return; 501 } 502 503 /* Pull packet off interface. */ 504 m = elget(sc, len); 505 if (m == 0) { 506 ifp->if_ierrors++; 507 return; 508 } 509 510 ifp->if_ipackets++; 511 512 #if NBPFILTER > 0 513 /* 514 * Check if there's a BPF listener on this interface. 515 * If so, hand off the raw packet to BPF. 516 */ 517 if (ifp->if_bpf) 518 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN); 519 #endif 520 521 ether_input_mbuf(ifp, m); 522 } 523 524 /* 525 * Pull read data off a interface. Len is length of data, with local net 526 * header stripped. We copy the data into mbufs. When full cluster sized 527 * units are present we copy into clusters. 528 */ 529 struct mbuf * 530 elget(sc, totlen) 531 struct el_softc *sc; 532 int totlen; 533 { 534 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 535 int iobase = sc->sc_iobase; 536 struct mbuf *top, **mp, *m; 537 int len; 538 539 MGETHDR(m, M_DONTWAIT, MT_DATA); 540 if (m == 0) 541 return 0; 542 m->m_pkthdr.rcvif = ifp; 543 m->m_pkthdr.len = totlen; 544 len = MHLEN; 545 top = 0; 546 mp = ⊤ 547 548 outb(iobase+EL_GPBL, 0); 549 outb(iobase+EL_GPBH, 0); 550 551 while (totlen > 0) { 552 if (top) { 553 MGET(m, M_DONTWAIT, MT_DATA); 554 if (m == 0) { 555 m_freem(top); 556 return 0; 557 } 558 len = MLEN; 559 } 560 if (totlen >= MINCLSIZE) { 561 MCLGET(m, M_DONTWAIT); 562 if (m->m_flags & M_EXT) 563 len = MCLBYTES; 564 } 565 m->m_len = len = min(totlen, len); 566 insb(iobase+EL_BUF, mtod(m, caddr_t), len); 567 totlen -= len; 568 *mp = m; 569 mp = &m->m_next; 570 } 571 572 outb(iobase+EL_RBC, 0); 573 outb(iobase+EL_AC, EL_AC_RX); 574 575 return top; 576 } 577 578 /* 579 * Process an ioctl request. This code needs some work - it looks pretty ugly. 580 */ 581 int 582 elioctl(ifp, cmd, data) 583 register struct ifnet *ifp; 584 u_long cmd; 585 caddr_t data; 586 { 587 struct el_softc *sc = ifp->if_softc; 588 struct ifaddr *ifa = (struct ifaddr *)data; 589 int s, error = 0; 590 591 s = splnet(); 592 593 switch (cmd) { 594 case SIOCSIFADDR: 595 ifp->if_flags |= IFF_UP; 596 597 switch (ifa->ifa_addr->sa_family) { 598 #ifdef INET 599 case AF_INET: 600 elinit(sc); 601 arp_ifinit(&sc->sc_arpcom, ifa); 602 break; 603 #endif 604 default: 605 elinit(sc); 606 break; 607 } 608 break; 609 610 case SIOCSIFFLAGS: 611 if ((ifp->if_flags & IFF_UP) == 0 && 612 (ifp->if_flags & IFF_RUNNING) != 0) { 613 /* 614 * If interface is marked down and it is running, then 615 * stop it. 616 */ 617 elstop(sc); 618 ifp->if_flags &= ~IFF_RUNNING; 619 } else if ((ifp->if_flags & IFF_UP) != 0 && 620 (ifp->if_flags & IFF_RUNNING) == 0) { 621 /* 622 * If interface is marked up and it is stopped, then 623 * start it. 624 */ 625 elinit(sc); 626 } else { 627 /* 628 * Some other important flag might have changed, so 629 * reset. 630 */ 631 elreset(sc); 632 } 633 break; 634 635 default: 636 error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data); 637 } 638 639 splx(s); 640 return error; 641 } 642 643 /* 644 * Device timeout routine. 645 */ 646 void 647 elwatchdog(ifp) 648 struct ifnet *ifp; 649 { 650 struct el_softc *sc = ifp->if_softc; 651 652 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname); 653 sc->sc_arpcom.ac_if.if_oerrors++; 654 655 elreset(sc); 656 } 657