[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