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