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