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.
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.
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.
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).
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.
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.
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.
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.
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.
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.
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.