[vortex] 3c590 media selection
Donald Becker
becker@scyld.com
Sun, 7 Jan 2001 03:23:49 -0500 (EST)
On Sun, 7 Jan 2001, Andrew Morton wrote:
> I've been looking into a 590 problem report where if the
> 10baseT cable is pulled out the NIC goes inoperative.
>
> What happens is that the selection logic rotates to
> 10base2 and then gets stuck there because 10base2
> has no link beat indication.
Yes, that's a problem. It's a hardware limitation.
IIRC, we must select the 10baseT transceiver for some significant time to
reliably detect 10baseT link beat, so we risk dropping a 10base2 packet if
we poll.
> The comment in the code says "Other media types handled
> by Tx timeouts."
We can detect a 10base2 cable by
Receiving a packet with a good CRC.
Transmitting a packet without a 16 collision error.
The problem with this is that we might have a quiet 10base2 network, and
having the driver construct a test packet is evil.
So we assume that the protocol code will eventually send a packet, perhaps a
keep-alive or retransmit, and that we can detect a disconnected cable that
way.
> It doesn't work very well, because we seem to be able to
> send packets into thin air across 10base2. I would _occasionally_
> get a tx timeout, and the driver would then advance to
> AUI and get completely stuck, because we can happily transmit
> packets into thin air across AUI as well.
Yup, 10base2 is bad but AUI is worse. You can't use heartbeat.
> I don't really see a sensible algorithmic fix for this,
> so I took the tx timeout logic out again.
>
> So we're left with forcing the media type via
> module parameters.
That was my conclusion.
The alternative is logic that combines
If we have ever seen 10baseT link beat, poll 10baseT when we have no Rx
traffic for T seconds.
If we have ever received 10base2 packets, don't switch to AUI.
But this doesn't seem worthwhile, given that the 3c590 is ancient.
> But there's a problem with the vortex_timer logic. Even
> if we try to force 10baseT via `options=0', this code:
>
> media_status = inw(ioaddr + Wn4_Media);
> switch (dev->if_port) {
> case XCVR_10baseT: case XCVR_100baseTx: case XCVR_100baseFx:
> if (media_status & Media_LnkBeat) {
> ok = 1;
> if (vortex_debug > 1)
> printk(KERN_DEBUG "%s: Media %s has link beat, %x.\n",
> dev->name, media_tbl[dev->if_port].name, media_status);
> } else if (vortex_debug > 1)
> printk(KERN_DEBUG "%s: Media %s is has no link beat, %x.\n",
> dev->name, media_tbl[dev->if_port].name, media_status);
> break;
>
> will always cause the driver to advance onto the next media type,
> which causes it to get stuck on 10base2.
It shouldn't -- see the ok=1 path.
> So what I did was to add a new flag to the device structure
> `media_was_forced'. Set it in the processing of module
I use the name medialock in my drivers.
I frequently also need duplex_lock
Donald Becker becker@scyld.com
Scyld Computing Corporation http://www.scyld.com
410 Severn Ave. Suite 210 Second Generation Beowulf Clusters
Annapolis MD 21403 410-990-9993