It's GPL'ed of course, but looking over it tonight I learned of Yet Another
Fast EtherLink XL Adapter: the 3c980C server adapter. This is basically
an updated version of the 3c980 that uses the Tornado ASIC instead of the
earlier Hurricane ASIC. The only change here is to add the new PCI device
ID (0x9805) and corresponding table entries.
external NatSemi PHY chip was programmed to respond to MII address 24.
In the 3c905B ASICs, the transceiver is internal but it's still mapped
to MII address 24. But *some* 3Com 3c905B ASIC revisions map the
transceiver control registers to *all* MII addresses (0 through 31).
The miibus code probes for PHYs at all MII addresses and because of
this unusual behavior, it will attempt to map the same PHY registers
several times over, which doesn't work.
Naturally, the 3c905B NIC that I tested happened not to exhibit this
behavior.
The fix is to tweak xl_miibus_readreg() and xl_miibus_writereg()
to only respond when attempting to read from MII address 24. This
is safe to do since the 3Com documentation indicates that the PHY
and/or internal transceiver will always be mapped to address 24,
and there are no 3Com XL NICs with more than one PHY.
due to the fact that there are non-MII cards supported by the same
driver and I don't have all of the cards available for testing. There's
also the 3c905B-COMBO which has MII, AUI and BNC media ports all in one
package. Supporting the COMBO is difficult because we have to add the
10base5 and 10base2 media types to the same ifmedia struct as the
MII-attached types, however there is no way to force the miibus and
child PHYs into existence before xl_attach() completes, so there is
no ifmedia struct available in xl_attach(). What we do inistead is
use the mediainit method as a callback: when a child PHY is attached,
it calls the miibus mediainit routine which selects a default media.
This routing also calls the NIC driver's mediainit method (if it
implements one) at which point we can safely add the other media
types.
reset command.
I observed some anomalous behavior while testing a 3c905C with a
Dell PowerEdge 4300/500 dual PIII 500Mhz system. The NIC would seem
to work correctly most of the time but would sometimes fail to receive
certain packets, in particular NFS create requests. I could mount
an NFS filesystem from the PowerEdge and do an ls on it, but trying
to do a "touch foo" would hang. Monitoring traffic from another host
revealed that the client was properly sending an NFS create request
but the server was not receiving it. It *did* receive it when I
ran the same test with an Intel fxp card.
I don't understand the exact mechanics of this strange behavior, but
resetting the receiver and transmitter seems to get rid of it. I used
to perform an RX and TX reset in xl_init(), but stopped doing it there
because on 3c905B and later cards this causes the autoneg session to
restart, which would lead to the NIC waiting a long time before exchanging
traffic after being brought up the first time. Apparently the receiver
and transmitter resets should be performed at least once when initializing
the card.
Hopefully this will cure problems that people have been having with the
3c905C -- this was the only strange behavior that I have observed with
the 3c905C so far which does not appear with the 3c905B or 3c905.
been booted works too -- very neat. However I don't want the system to
stop for 5 seconds when the MII autoprobe is triggered in the xl and
tl drivers since that's lame. Instead, only use the hard delay when
we've been cold booted. If not, use the timeout mechanism instead.
(The SysKonnect driver doesn't use the same autonegotiation scheme, so
no change is required there.)
into a loadable module, and all of the platform dependencies are gone
(except for the alpha_XXX_dmamap() thing, which is another issue -- I
still don't know how to use the busdma stuff with a network driver).
Also increase the delay in xl_reset(); testing on a 486/66 with a 3c905C
shows that reading the EEPROM fails immediately after a reset. Waiting
a little longer after the reset completes seems to fix it.
clears out the transmit queue and zeroes the downlist pointer register,
but xl_txeof() isn't called before xl_start() tries to queue more packets,
xl_start() will think that the DMA is still in progress and not update
the downlist register again, thus causing packets to sit in the transmit
queue forever.
Patch provided by: Russell T Hunt <alaric@MIT.EDU>
compiles cleanly on the Alpha. (On the alpha, the port type is an int,
not a short).
Cast a couple of pointers to ints via 'uintptr_t' rather than 'unsigned
int' since uintptr_t is long (64 bit) on Alpha, as are pointers.
happens if you have a BIOS with a 'Plug & Play OS' setting and you leave
it set to 'Yes.' This is wrong for FreeBSD (and LoseNT): it should be set
to 'No.' Apparently it's still possible to map the iobase of the NIC and
have the card work by reading the config space manually (which is what
the driver does if pci_map_port() fails) but we need to warn the user to
do fix their machine anyway. Anyway, warn the user to check the 'Plug &
Play OS' setting in their BIOS if mapping the io space fails.
chipset. First you thrilled to the 3c905, then you trembled at the
3c905B, now gaze in wonder at: the 3c905C! This appears to be another
3c90X series chip called the Tornado (PCI ID 0x10B7/0x9200) and should
be equivalent (from the driver API perspective) to the 3c905B, so all
we have to do is add the PCI ID to the list.
#define COMPAT_PCI_DRIVER(name,data) DATA_SET(pcidevice_set,data)
.. to 2.2.x and 3.x if people think it's worth it. Driver writers can do
this if it's not defined. (The reason for this is that I'm trying to
progressively eliminate use of linker_sets where it hurts modularity and
runtime load capability, and these DATA_SET's keep getting in the way.)
uses the AUI port with an on-board AUI to 10baseFL transceiver, not the
10baseT port like I had earlier suspected. The 3c900B-FL should be properly
supported now.
- Try to unbreak what I broke by screwing with the tx queuing again.
I'm waiting for a few more people to test out this code and report back
before I move it into current. Hopefully it will be soon. Basically I
reverted to the old TX queuing strategy.
- Add experimental support for the 3c900B-FL (10mbps ST fiber). The card
should be detected properly and the 10baseFL mode supported, but again
I'm still waiting for word from a tester to see if this actually works.
It shouldn't affect the other cards though; all the differences are in
media selection.
- Set the TX start threshold register to get better performance.
- Increase the size of the RX and TX rings. UDP performance was pretty
bad because the TX ring was too small. Should be substantially better
now (I can saturate the link with either TCP or UDP now).
- Change some of the #defines to reflect proper 3Com ASIC names (boomerang,
cyclone, krakatoa, hurricane).
- Simplify and reorganize interrupt handler; ack all interrupts right
away and then process them. This avoids a potential race condition.
(Noted by Matt Dillon.)
- Reorganize the bridging code to eliminate using a goto to jump into
the middle of an if() {} clause. Sorry, that just made my brain itch.
- Use m_adj() in xl_rxeof().
- Make the payload alignment in xl_newbuf() the default (instead of
just conditionally defined for the alpha) to improve NFS performance
(avoids need for nfs_realign()).
i386 platform boots, it is no longer ISA-centric, and is fully dynamic.
Most old drivers compile and run without modification via 'compatability
shims' to enable a smoother transition. eisa, isapnp and pccard* are
not yet using the new resource manager. Once fully converted, all drivers
will be loadable, including PCI and ISA.
(Some other changes appear to have snuck in, including a port of Soren's
ATA driver to the Alpha. Soren, back this out if you need to.)
This is a checkpoint of work-in-progress, but is quite functional.
The bulk of the work was done over the last few years by Doug Rabson and
Garrett Wollman.
Approved by: core
3c900B-TPC (twisted pair and coax). Treated similarly to the
3c900B-COMBO, except no AUI port.
- Fix media selection so that it's possible to select the AUI and BNC
ports on the 3c905B-COMBO. This board is now fully supported.
- Change TX queueing strategy to hopefully be more efficient by avoiding
register accesses in xl_start(). Should provide small performance
improvement and a little better reliability.
(cut-down version of the "cyclone" for the small office/home office
"cheap bastard" market). Basically the same as a 3c905B but without
Wake-on-LAN, ROM socket, etc...
- Wait longer for the reset to complete in xl_attach() to try and avoid
'command never completed' warnings.
- Clean up a few odds and ends in xl_attach().
- Add PCI ID for the 3c905B-COMBO (a new card). Right now this is
treated as a 3c905B; I need to dig up one of these cards for testing
before I can make the AUI and BNC ports work.
- Add a hack to force reading the I/O address directly from the PCI
registers if pci_map_port() fails. I SHOULD NOT HAVE TO DO THIS:
SOMEBODY WITH MORE PCI CLUES THAN I SHOULD INVESTIGATE WHY THIS
HAPPENS.
sys/alpha/conf/GENERIC.
Note: the PNIC ignores the lower few bits of the RX buffer DMA address,
which means we have to add yet another kludge to make it happy. Since
we can't offset the packet data, we copy the first few bytes of the
received data into a separate mbuf with proper alignment. This puts
the IP header where it needs to be to prevent unaligned accesses.
Also modified the PNIC driver to use a non-interrupt driven TX
strategy. This improves performance somewhat on x86/SMP systems where
interrupt delivery doesn't seem to be as fast with an SMP kernel as
with a UP kernel.
3c905B, the RX and TX reset commands also reset the cyclone chip's internal
PHY, which causes it to restart its autonegotiation session. This takes a
second or two to complete, which makes the interface seem to stop responding
for a few seconds every time you do something that reinitializes it.
Issuing the RX and TX resets on the older 3c905 boomerang adapters doesn't
cause any delay because the boomerang chip requires an external PHY.
This should fix the problem where people doing network installs via 3c905B
cards experience a delay after the interface is first initialized, among
other things.
apparently possible) event that the transmit start routine is
called with and empty if_snd queue, bail out instead of dereferencing
unilitialized transmit list pointers and panicking.
Revert the transmission packet queueing strategy changes. Clearly I missed
something while debugging this, although I never encountered any problems
on my test machines.
Also make one other minor change: jack up the TX reclaim threshold for
3c90xB adapters in order to stave off 'transmission error: 82' errors.
Document the existence of the tx reclaim register (for inspecting the
current reclaim threshold) in register window 5 (if_xlreg.h).
agressive. With the old code, if a descriptor chain was already on its
way to the chip, xl_start() would try to splice new chains onto the end
of the current chain by stopping the transmitter, modifying the tail
pointer of the current chain to point to the head of the new chain, then
restart the transmitter. The manual says you're allowed to do this and
it works, but I'm not too keen on it anymore.
The new code waits until the eixsting chain has been sent and then
queues the next waiting chain in the 'transmit ok' handler.
Performance still looks good one way or the other.
This is a 100BaseFX board with SC fiber media connectors. I don't actually
have one of these but I've been told it works with the xl driver.
Submitted by: Jason Wright from the openbsd group
the OpenBSD group to fix a problem with the default ifmedia not being
set properly in some cases with a 3c905B, leading to a panic in ifmedia_set().
Also apply a patch to force the transmit start routine to check the
transmitter to make sure it isn't wedged if the outbound tx queue appears
full. This seems to cure some problems with 'watchdog timeout' errors
cropping up in some cases. I tried to do this before by checking for the
IFF_OACTIVE flag on entry to xl_start(), but if the IFF_OACTIVE flag is
set, ether_output() won't even call xl_start(). It should work now.
Lastly, increase the size of the TX queue from 10 descriptors to 16 to
hopefully make it less likely that the TX queue will fill up.
transmitter is wedged. If so, try to unwedge it, process any descriptors
that might need to be free()d, then proceed.
- Disable the 'background' autonegotiation performed during bootstrap.
What happens currently is that the driver starts an autoneg session,
the sets a timeout in the ifnet structure and returns. Later, when the
timer expires, the watchdog routine calls the autoneg handler to check
the results of the session. The problem with this is that the session
may not complete until some point after we have started to mount NFS
filesystems, which can cause the mounts to fail. This is especially
troublesome if booting with an NFS rootfs: we need the interface up
and running before reaching the mountroot() code.
The default behavior now is to do the autoneg synchronously, i.e. wait
5 seconds for the autoneg to complete before exiting the driver attach
routine. People who want the old behavior can compile the driver with
XL_BACKGROUND_AUTONEG #defined. This has no effect on autoneg sessions
initiated by 'ifconfig xl0 media autoselect.'
This slows the probe down a little, but it's either that or botching
NFS mounts at bootup.
- If xl_setmode_mii() is called and there's an autoneg session in progress,
cancel it, _then_ set the modes.
generating a trap 12 panic. The code blindly assumed that in the event
of a transmit error, the packet that caused the error would still be
at the head of the driver's transmit queue (sc->xl_cdata.xl_tx_head).
However in the case of error 82 (which indicates that a transmit error
occurred after part of the transmit FIFO memory has been reclaimed)
this is not true: the TX queue has already been flushed, and the
pointer to the head of the queue is NULL, so trying to dereference
the pointer to find the transmit descriptor address causes a crash.
The code now checks for a NULL pointer before trying to reload the
chip's download pointer register. There may still be error messages
printed warning of the transmit error, but no panic should occur.
Note that this eror code is only generated with "cyclone" chipsets
(3c900B, 3c905B, and presumeably the 3c980 server adapter). It should
only appear during periods of heavy traffic, probably only on
non-switched networks.
Problem reported by: Darcy Buskermolen <darcy@ok-connect.com>
XCVR value read from the EEPROM is completely wrong. I've had one report
of a 3c900 card that returns an xcvr value of 14, which is impossible
(the manual states that all vales above 8 are reserved). If the value
is out of the expe
Add PCI vendor ID for the 3c980-TX server adapter card, which apparently
also uses the cyclone chip. Graciously supplied Mats O Jansson
<maja@cntw.com>.
Also noted by Mats, the 10mpbs cyclone adapters should be named 3c900B,
not 3c905B. I haven't actually encountered a 10mbps only cyclone adapter
yet, nor anybody who has one, but this makes sense given the naming
scheme used for the older boomerang adapters.
cluster from the RX descriptor is passed up to the higher layers and
replaced with an empty buffer for the next time the descriptor comes
up in the RX ring. The xl_newbuf() routine returns ENOBUFS if it can't
obtain a new mbuf cluster, but this return value was being ignored.
Now, if buffer allocation fails, we leave the old one in place and
drop the packet. This is rude, but there's not much else that can be
done in this situation.
Without this, the driver can cause a panic if the system runs out of
MBUF clusters. Now it will complain loudly, but it shouldn't cause a
panic.
Also added another pair of missing newlines to some printf()s.
delay controls how long the driver waits for autonegotiation to
complete after setting the 'autoneg restart bit' in a PHY. In some
cases, it seems 3 seconds is not long enough: with 3c905-TX cards
(external PHY), you sometimes see 'autoneg not complete; no carrier'
errors due to the timeout being too short. (3c905B adapters seem to
be happy with 3 seconds though.)
If I'm reading the manual correctly, the 3c905B actually loses its
PCI configuration during the transition from D3(hot) back to D0, not
during the transition from D0 to D3(hot). This means it should be possible
to save the existing PCI settings, restet the power state, then restore
the PCI settings afterwards. Changed xl_attach() to attempt this first
thing before the normal PCI setup. I'm not certain this will work correctly,
but it shouldn't hurt.
If xl_init() is called while an autoneg session is in progress, the
autoneg timeout and chip state will get clobbered. Try to avoid this
by checking sc->xl_autoneg at the start of xl_init() and defer
the initialization until later if it's set. (xl_init() is always called
at the end of an autoneg session by xl_autoneg_mii().)
Problem pointed out by: Larry Baird <lab@gta.com>
stability now. ALso modify /sys/conf/files, /sys/i386/conf/GENERIC
and /sys/i386/conf/LINT to add entries for the XL driver. Deactivate
support for the XL adapters in the vortex driver. LAstly, add a man
page.
(Also added an MLINKS entry for the ThunderLAN man page which I forgot
previously.)