[vortex] 3c905 oddities 2

Donald Becker becker@scyld.com
Wed, 13 Dec 2000 09:12:30 -0500 (EST)


On Wed, 13 Dec 2000, Bogdan Costescu wrote:

> On Tue, 12 Dec 2000, Donald Becker wrote:
> 
> > > 1) will a timeout of 4000000 as suggested in previous emails cause a
> > > performance hit? (ie should I try and optimize)
> >
> > No, it's in the initialization and error recovery path.  So it's a one-time
> > pause when the interface is started.
> 
> If this is needed only for the RxReset command, the above statement is
> true. Don, do you have any info to support it ? (other than the
> observation of the 3 CX cards that appeared on this list).

Yes, I'm assuming that it's only happening with RxReset.

> In a previous message, Andrew expressed the "fear" that other commands
> might need longer cycles too.

The manual indicates maximum times for some commands.  While developing
drivers I do note the documented max times (it's rarely documented),
but _always_ measure how many loop iterations it actually takes for
operations to complete.  I do that with

  for (i = 0; i < 100000; i++)
      if (check_status(dev))  break;
  printk("%s: status took %d ticks.\n", dev->name, i);

I multiply the maximum observed value by a big "engineering margin" and
clean up the code before release.

This approach can fail when the hardware changes.  Here we have a usual
case: 3Com comes out with an apparently new chip revision that is nominally
backwards compatible.  No updated manualis available, and the changes might
not be documented long after the design is updated again.

> > and the clock lost three seconds each time the interface was started.  You
> > sometimes see the same effect with Windows device drivers.
> 
> Is this because the CPU is kept busy or because the PCI bus is kept busy
> too (or both) ? Would it make sense to use another method of waiting
> (instead of the tight 'in' loop) for the commands known to take long time?

The big problem is that the CPU is busy.  Other bus masters are slowed by
the constant PCI accesses, but the important bus masters should be doing
bursts anyway.  This will shorten the PCI bursts, but that can't be helped.

Using udelay() is not a better solution.  If you must, use udelay(1) instead
of udelay(10): there is no point in wasting 10 microseconds for an operation
that usually completes instantly.  And as I frequently warn: never assume
that udelay() is accurate,

Many programmers initially assume that long in-kernel timing loops are not a
big deal.  They even run a few tests and don't notice anything.  But the
driver can end up blocking major parts of the kernel.  The x86 allows
rotating interrupt priorities.  Your interrupt handler might end
interrupting another interrupt handler.  If you do a long timing loop, you
have just blocked both interrupts.  A similar thing happens when you
interrupt code that has just disabled a specific IRQ.

> > The second related problem is with detecting MII transceivers.
> > There are two changes that might make a difference.  The first is adding an
> > extra preamble, ...
> 
> Why ?

I'm guessing here.  This transceiver might lose MDIO bit stream sync when it
is put into low-power mode.

> > -	for (phy = 1; phy <= 32 && phy_idx < sizeof(vp->phys); phy++) {
> > -		int mii_status, phyx = phy & 0x1f;
> > +	for (phy = 0; phy < 32 && phy_idx < 1; phy++) {
> > +		int mii_status, phyx = (phy == 0 ? 24 : phy == 24 );
> 							why -^^^^
> ... I don't understand your code. Should it be

Yup, typo.
     phyx = (phy == 0 ? 24 : phy == 24 ? 0 : phy);

> Anyway, you are not getting a phyx = 0 case, while in a previous message
> you said that external transceivers at PHYAD 0 should be tested last,
> which was how the old code was working. Is this not true anymore ?

Correct.  We will not detect PHY0 with the above typo.

I was considering doing
     /* Change MII scan order to detect #24 first. */
     phyx = phy ^ 0x18;
but that seemed a little obscure, even with a comment.

> And the last one 8-): you are now bailing out at the first transceiver
> found (phy_idx < 1); is this intentional ? If so, why ?

We don't have the driver code to switch transceivers, and I haven't seen a
3Com card design that supports multiple MII transceivers.

A few years ago I expected MII connectors to be as common as AUI, and
I wanted the driver update to be only a small addition to the media monitor.
I also expected that we would need driver-independent MII support routines,
including one that would monitor link beat and switch transceivers as needed.
Neither has happened.

The only common cards that have multiple MII transceivers are HPNA cards
from AMD and ADMtek.  Both are one-chip implementation, and both have design
quirks that require a priori knowledge of the transceiver address based on
the chip ID.  The ADMtek chip only powers one transceiver at a time, based
on a register bit, and the unpowered transceiver doesn't respond to MII
register reads.

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