Emulating EtherLink

Spurred by the discovery of a pre-release OS/2 NetWare Requester from early 1988 with a very thin selection of drivers, several months ago I decided to write emulation of the classic 3Com 10Mbps Ethernet 3C501 card, also known as EtherLink. The developer documentation from 3Com was available, and didn’t look all that terrifying, just a couple of pages.

A 3Com 3C501 Etherlink adapter.
A non-emulated 3C501 EtherLink adapter manufactured in 1986.

The 3C501 is known for the comments made about it by Donald Becker, the author of many Linux networking drivers in the mid-1990s: “Don’t purchase this card, even as a joke.” The comments were not unjustified when they were made; the 3C501 was already an obsolete design in 1992 or so. The problem was that the card has a tiny buffer, only big enough for one packet, and three mutually exclusive modes: Send, receive, and buffer access by the host (obviously no full-duplex Ethernet there). Once a packet is received, further reception stops until the packet buffer is emptied by the host and receive re-started again. That leads to many dropped packets and very poor performance in busy networks, particularly networks with a lot of broadcast or multicast traffic.

Fortunately, the virtual switch in a hypervisor has the ability to buffer packets, and packet loss is far less of a problem in a VM. Which is not to say the emulated EtherLink is some kind of a great performer, but it can certainly handle much more than 10Mbps.

Driver Support

Besides the pre-release NetWare OS/2 Requester and Linux, is there any other networking software a 3C501 can work with? Yes, more or less every Ethernet-capable networking package from the late 1980s comes with 3C501 drivers, and nearly everything from the early 1990s either comes with a 3C501 driver or can have one added.

A screenshot of OS/2 1.0 booting up with a pre-release version of Novell's OS/2 Requester from early 1988.
Pre-release Novell OS/2 requester using 3C501 driver (1988)

That includes DOS NDIS, ODI, and packet drivers, OS/2, NetWare shell drivers, and various UNIX and BSD variants. It also includes SCO TCP/IP for XENIX (1988) and SCO UNIX (1989), Microsoft LAN Manager (1988), NetWare 2.0a (1987) or 3Com’s EtherSeries (early 1980s).

A screenshot of 3Com's XNS networking stack booting on DOS 5.0, using a 3C501 EtherLink driver (circa 1988).
3Com’s XNS networking stack on 3C501 (1988)

Old SCO networking packages only support the 3C501 and WD8003 NICs out of the box. Over time, support for other adapters was added (primarily newer 3Com cards) but 3C501 support survived until modern installable drivers became available. Other UNIX System V derivatives for the 386 also tended to have 3C501 drivers.

Some true exotics also work with the 3C501 emulation; that includes for example Mt Xinu’s Mach 386 (1992). Sun’s PC-NFS 3.0 and earlier likewise comes with 3C501 drivers, and PC-NFS 3.0.1 (1989) is known to work. ELS NetWare 286 2.0a (1987) also supports 3C501 as the only Ethernet adapter besides Novell’s own NE1000.

A screenshot of networking tools (netstat, ping) running in a Mach 386 based Mt Xinu (1992).
Mt Xinu Mach 386 (1992) happily networking with 3C501

An interesting behavior of some drivers, but not nearly all of them, is that they may require the network card’s MAC address to have the 3Com OUI (02 60 8C). That is the case for Linux and BSDs, as well as 3Com’s EtherSeries drivers (ETH.SYS), but not NDIS or NetWare drivers.

How Old Is This Thing?

When I started writing the 3C501 emulation, I assumed the card was a design from 1986 or 1987. That turned out to be both right and wrong. The 3C501, also known as IE-4, was indeed introduced approximately in 1986. However, several mentions of “3C500/3C501” piqued my curiosity. What’s a 3C500?

The 3C500 was 3Com’s original IBM Ethernet (IE) adapter, introduced in October 1982, certainly one of the first PC Ethernet adapters, if not the very first one.

The 3C500 (IE) was also nearly identical to the newer 3C501 (IE-4), and software written for the 3C500 should work on a 3C501. How do I know the IE and IE-4 are almost the same? Because their technical references are nearly identical, word for word.

The 3C500 is so old that finding any information about it (besides that technical reference) is nearly impossible. My current assumption is that the biggest difference between IE and IE-4 is that the latter replaced a large number of discrete chips with a custom ASIC.

In 1983, a group at MIT (led by Prof. Saltzer of Multics fame) developed one of the first TCP/IP based networking packages for the IBM PC. It supported one Ethernet card, the 3Com EtherLink. The package was called PC/IP and later turned into FTP Software’s PC/TCP. Surviving source archives of PC/IP from 1985 and 1986 are available.

And a few months before PC/IP was started, the EtherLink was the hardware component of 3Com’s EtherSeries (1982), an Ethernet-based hardware and software package providing electronic mail, disk sharing, and more.

In other words, the 3C501/3C500 is very, very old.

Hardware Architecture

The EtherLink is built around the SEEQ 8001 EDLC (Ethernet Data Link Controller) which handles all Ethernet specifics. 3Com added a 2KB packet buffer and circuitry required for interfacing the EDLC with an IBM PC. The SEEQ 8001 appears to have been developed by SEEQ for and with 3Com; both companies were linked through Silicon Valley venture capital firms.

The EtherLink is an 8-bit card (of course) which requires a 16-byte I/O port range, one interrupt, and optionally a DMA channel.

3Com 3C501 Etherlink (late 1986), an 8-bit Ethernet ISA controller. Includes a SEEQ 8001 Ethernet chip.
3Com 3C501 EtherLink (late 1986) with a SEEQ 8001 EDLC (upper left)

The packet buffer is not mapped in the PC’s memory. It can be accessed through a one-byte window mapped in the I/O port range, or via DMA. Old drivers and drivers designed to run on a PC or PC/XT tend to use DMA, because it is faster than reading or writing the I/O port in a loop by a rather slow CPU. Drivers designed to run on a PC/AT tend to use string I/O instructions (insb and outsb) available on a 286 because those are faster than DMA and much easier to use.

Some drivers (e.g. the 3C501.DOS NDIS driver) are software configurable and can be set up to run either in DMA mode or in programmed I/O mode. For virtualization, it is preferable to not use DMA as long as string I/O is used. The reasons are much the same as on PC/AT machines — there are no worries about DMA channel clashes, and the transfers are faster.


Figuring out all the details needed for successful 3C501 emulation was not entirely trivial. The 3Com documentation is decent, but sometimes even after reading and re-reading it’s not clear what the authors really meant to say. This was true especially for the receive behavior, notably the definition of “interesting packets”.

What helped a lot was 3Com’s diagnostic utility, which exercises the various modes using loopback. It took a number of iterations before the diagnostics passed with “flying colors” on the emulated card, but eventually they did.

3Com Ethernet diagnostics for the EtherLink (1983) passing with flying colors.
3Com EtherLink diagnostics (1983)

Only when everything was working I discovered that there’s a separate SEEQ 8001 EDLC datasheet, and that a number of registers on the EtherLink are simply SEEQ 8001 registers. And the SEEQ datasheet provides a better description of the EDLC than the 3Com documentation, at least subjectively speaking. Or maybe it just made more sense to me after slogging through 3Com’s text.

Newer 3Com Ethernet diagnostics for the EtherLink (1986), again passing with flying colors.
Newer 3Com diagnostics (1986)

Several minor implementation details were worked out only after examining a real EtherLink card. For example, the 3Com documentation claims that the receive buffer pointer is reset by writing to its low byte. Yet nearly all drivers write a zero to the LSB and MSB of the receive buffer pointer, treating it the same as the GP (General Purpose) buffer pointer. Examining actual hardware confirmed that the documentation is correct, and writing anything to the low byte of the receive buffer pointer zeroes all 16 bits of it. Which means that those drivers just waste time writing to an unused register.

Using a real 3Com card also made me understand the peculiar way in which loopback worked on old Ethernet hardware. The SEEQ 8001 EDLC is perfectly capable of simultaneously sending and receiving. But this capability is only applicable when the EtherLink is in loopback mode; under normal circumstances, only one station at a time can be sending, which means it’s pointless to send and receive at the same time — the station could only listen to itself. But that is precisely what loopback does; and because the loopback is not internal, it works by actually sending data to the ‘ether’ and receiving it. For that reason, loopback requires an Ethernet cable to be connected, or at least a special loopback plug installed in lieu of a cable.

A slight complication with many EtherLink drivers is that they like to reset the EDLC quite a lot, presumably in an effort to avoid hardware quirks. The real card will of course lose incoming packets when it’s in reset for a brief period. The emulated card should not, otherwise it might suffer severe performance degradation.

Backward Compatibility

As mentioned above, I do have a real EtherLink card to test with. Given that the card itself was made in 1986, and the Ethernet chip is a circa 1982 design, one might wonder if it actually works in a modern network at all.

The answer is simple—it does. The card obviously does not support twisted pair, but an AUI to TP transceiver takes care of that. With the transceiver in place, it’s no problem connecting an antique EtherLink to a modern Gigabit Ethernet switch and communicating with contemporary systems.

Now, it needs to be understood that the performance is horrible due to the hopeless can’t-walk-and-chew-gum design of the EtherLink. On a modern network with typical chatty broadcast and multicast traffic, there is a lot of distraction, and obviously the EtherLink can’t possibly keep up with systems on Gigabit Ethernet.

That is to say, all the warnings about the 3C501 being awful made 25 years ago are just as true today, and probably more so. But the antique design and a nearly 35 year old card is still perfectly capable of sending and receiving Ethernet traffic on a modern network. Just not very quickly.

This entry was posted in 3Com, Networking, PC hardware, PC history, Virtualization. Bookmark the permalink.

33 Responses to Emulating EtherLink

  1. Darkstar says:

    Nice! The 3c501 is probably the oldest Ethernet card I have ever seen myself… too bad I don’t have it anymore (or maybe not that bad, seeing as how limited it was)

    For which emulator did you write your emulation? qemu, pcem/86box/varcem, mame, or something else entirely?

  2. Yuhong Bao says:

    https://www.spinics.net/lists/netdev/msg199142.html says that “The 3c500 is all TTL
    and an amazing beast, its so big it won’t fit a 16bit slot as it has to
    drop down after the connector to get all the chips on.”
    With the introduction of the IBM PC AT this became a problem. I wonder if this is why 3Com asked SEEQ to create the ASIC used in the 3C501 in 1985.

  3. Michal Necasek says:

    Here’s the only photo of a 3C500 I could find: https://www.3comstory.com/gallery?pgid=jpa4g60u-e6c4595a-882b-4365-a2ac-3a93e1c42eac (may take a while to load). And yes, it sure looks like it couldn’t possibly fit into a 16-bit slot, it is absolutely gigantic.

  4. Michal Necasek says:

    I wrote it for VirtualBox, since the connectivity options are very good. And no, it is not publicly available at this point. Maybe at some point in the future.

    So far I’ve not been able to confirm if the 3C500 was the oldest PC Ethernet card. Excelan and U-B are two other likely suspects, but finding reliable data that far back is difficult. There are some claims that the 3C500 was in fact the first, circa September 1982.

  5. Chris M. says:

    Are those tuning coils on the 3C500? I’ve never seen anything like that on an ISA card. Also looks like it’ll only fit in an original IBM PC due to using the larger width card bracket and those bulky components (unless you want to give up a neighboring slot).

  6. Michal Necasek says:

    It looks like coils for sure. The whole thing looks like there’s a 10BASE2 transceiver on the board but it’s not at all integrated like on the 3C501. The 3C500 looks like it would have been quite expensive to manufacture with the huge PCB, many discrete components, and a zoo of patch wires.

  7. Richard Wells says:

    The 3C500 was a major cost reduction compared to the 3C200 and 3C300 which were priced on the order of $2,000 and $3,000 respectively. Note that different magazines listed different prices. Those were for the PDP-11 Q-Bus and Unibus. The transceiver portion of the 3C500 looks very similar; the major change beyond swapping the bus interface was reducing the RAM from 32k to 2k. Since the manuals indicated that only 4 buffers (8k) were needed in all but the most extreme workloads, the PDP cards were overkill. The reviews a few years later indicated that the 8k for buffers on the 3c503 gave little benefit over the 2k in the 3C501, certainly not enough to be worth paying an extra $150 for the privilege.

    Doing an ASIC shouldn’t happen until the card design is largely debugged and the company can be sure to be getting many thousands of orders.

  8. Michal Necasek says:

    Yes. Note that the 3C500 in the photo is from 1985, 3 years after the initial release, when 3Com was selling hardware in decent numbers. It is also possible that the minicomputer variants were simply priced higher because customers were willing to pay more, not because they were more expensive to build.

    It is interesting that the second-gen cheap network cards (NE2000, WD8003) all had 8-16 KB onboard memory, although I’m sure memory was significantly cheaper by then. I will also note that the 3C501 (and presumably 3C500) used SRAM, whereas pretty much everything newer used cheaper DRAMs.

    It makes sense to me that 8K instead of 32K buffer space was 99% as good. I have trouble believing 2K was anywhere near as good as 8K, especially since the 3C500/3C501 could really only store a single packet regardless of length. But how much of a problem the single-packet capability was probably strongly depended on the networking protocol(s) and software used. With 1990s TCP/IP, it was not good at all, but that doesn’t mean it wasn’t good enough for 3Com’s EtherSeries in the 1980s or for NetWare IPX.

  9. Rich Shealer says:

    I’m pretty sure I used a 3C500 in our first 3COM network in 1985. It was installed in a Canon A-200 an 8086 Based PC clone. I had to add a jumper wire to the motherboard because by design it didn’t have the required DMA TC connected to the 8-bit ISA slot for some reason.

  10. Rich Shealer says:

    We connected the Canon to an HP-150 II Touchscreen. The 8088 MS-DOS non-clone. It had a unique bus and a therefore a proprietary 3Com card the HP 45644A EtherLink-150 Card.

    After this demo system, we moved to Novell and ArcNet for a long time.

    A nice of the HP card picture here: http://www.hpmuseum.net/images/45644A.jpg

    Software HP sold for it was a custom version of the 3Com suite.

    EtherSeries™ Local Area Networking products from 3Com™ provide a cost-effective way to share information and peripherals, such as large-capacity discs and printers, using a Touchscreen MAX II as the LAN hub. Link to other Touchscreens and IBM PCs.

    HP 45644A EtherLink™ / 150
    HP 45645A EtherShare™/ 150
    HP 45646A EtherPrint™ / 150
    HP 45647A EtherMail™ / 150 Server Software
    HP 45639A EtherMail™ / 150 User Software
    HP 45649A EtherStart™ / 150

  11. Michal Necasek says:

    Very interesting card. It looks like an intermediate step between the PC versions of the 3C500 (gigantic) and 3C501 (on the smaller side). Makes sense given the timeline.

  12. rasz_pl says:

    and nowadays you can achieve similar result with just the smallest of microcontrollers almost entirely in software (+ hardware serializing block) 🙂 https://www.youtube.com/watch?v=m4f4OzEyueg https://github.com/cnlohr/ethertiny

  13. Richard Wells says:

    Conversely, the size of the full featured 3Com ethernet cards can be seen at https://www.wikiwand.com/en/Sun-2 Go down a bunch and scroll the picture list to the right and there is a picture of the 3C400, the Multibus variation. Makes it easy to see how much 3Com had to remove from the card to meet the smaller size of ISA.

  14. Andreas Kohl says:

    Did you try it with 3Com’s EtherShare software? You can find a version 2.4 at bitsavers.

  15. Michal Necasek says:

    I found the EtherShare disk, but it’s just the client side and doesn’t do a lot by itself. The diagnostics work, and the stuff starts up, but without a server there’s not much to do.

  16. Andreas Kohl says:

    Without a 3Server machine it should be possible to serve via LAN Manager with NBP/XNS protocols activated. For later LM versions the XNS protocol stack was still available on an optional diskette. The documentation for EtherShare/EtherSeries (scans available through bitsavers) contains some information about the EtherLink card revisions. Assembly Number 0345 and 34-0780 for the long sized and 1221 for the half sized (that should fit to the image here) were mentioned.

  17. Michal Necasek says:

    I’m not sure how that would work. Yes, it’s possible to use the XNS transport with LAN Manager, but it’s still LAN Manager talking SMB, not EtherShare.

    But I’m no expert on 3Com’s networking software, that was all before my time so to speak.

  18. Yuhong Bao says:

    TIL the original 3c509 had only a 4K buffer, and is basically 3c501 with separate transmit and receive buffers.

  19. Yuhong Bao says:

    (They fixed this later with the 3C509B which have at least a 8K buffer)

  20. Michal Necasek says:

    There is a huge difference between the 3C509 and 3C501 in that the 3C509 can receive multiple packets as long as there is room in the buffer. The 3C501 just can’t do that. This alone should make packet loss much less of a problem on the 3C509. Not having to switch between transmit/receive/host buffer access mode should also help.

  21. Yuhong Bao says:

    The point is that the original 3C509 did not have the space for more than one packet.

  22. Michal Necasek says:

    Sure it did. It did not have the space for two full-size Ethernet packets, that is true. But it did have space for more than one packet. For example with IPX, probably the most common protocol in use at the time, the packet size was typically limited to 576 bytes.

  23. Andrew Bird says:

    Hi Michal,
    Did you have any more thoughts about releasing your source code, and could it be under a permissive or GPLv2 licence? Also any chance to a link to the 3c501 docs you used to create it please? My interest is in getting PC-NFS to work on Dosemu2.


  24. Michal Necasek says:

    I will see about getting the source code out. Bitsavers has a 3C500 technical document which is not hard to find and probably has pretty much all the information. The actual 3C501 Tech Ref is much much harder to locate but can be found e.g. here.

  25. Andrew Bird says:

    Thanks Michal, that’s great.

  26. KJ says:

    Oh, gawd…the 3c501. What an awful little thing.

    It was bad enough for simple things (telnet, ftp), but when you got to things like NFS or X10/X11, it really showed what a dog it was. To even attempt a reliable NFS connection, you needed to manually override the NFS packet size down to something like 512 bytes (from 8k) or you’d just overrun the thing. Which made NFS draaaaaag. The wd8003 was better in almost every respect, and by the time you got to the 3c509, 3com had a winner.

    Don Becker wasn’t kidding.

  27. Michal Necasek says:

    I’m not sure that says more about the 3C501 or about UDP. The 3C501 was definitely bad at TCP/IP, but it was also never designed for it. It was designed for 3Com’s EtherSeries, and as far as I know, worked reasonably well with NetWare. I suppose the biggest problem was that people were using a 1981 design in the 1990s expecting it to behave differently from a 10-year old hard disk or a 10-year old CPU.

  28. KJ says:

    That’s a fair statement, though the problems with the 3c501 weren’t limited to the small buffer. However, some people didn’t see the over-time change the same way as the 10yo CPU because 10Mb ethernet was still 10Mb ethernet, amiright, and why should I have to buy a new (or more expensive) network card for the ‘same’ network. Caused all sorts of support problems, and whenever someone showed up with a 3c501, they got a hard Nope until they replaced it.

  29. Michal Necasek says:

    Yes, I guess Ethernet was really ahead of its time by standardizing on 10 Mbps rates circa 1980. And it then took about 15 years for Fast Ethernet to arrive (whereas GbE turned up almost immediately after, some 3 years later). The 3C501 was perfectly capable of participating in an Ethernet network, heck it can even do that today. It’s just absolutely incapable of keeping up with what less ancient hardware can throw at it, and TCP/IP is very sensitive to packet loss.

    The hardware definitely had quirks, and resetting it was commonly used as a workaround. I’m not even sure how much of it was real hardware bugs and how much it was driver bugs and problems caused with massively faster CPUs. In the end no one should have been running those cards in the 1990s, it just wasn’t worth the trouble. I think telling 3C501 users to “go get something else” was a very reasonable response.

  30. Andrew Bird says:

    Hello Michal,
    Sorry to drag up this old post, but did you ever get around to releasing your source code?

    Many thanks,


  31. Andrew Bird says:

    Excellent, plenty to look at thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.