Re: forcedeth as a module only?

From: Manfred Spraul
Date: Fri Jun 17 2005 - 15:49:35 EST


Christian Kujau wrote:

are there any known issues with the forcedeth driver when statically
compiled in?

No.
But there are known issues with link detection: Some users report bad performance, and misconfigured links are one possible explanation.

eth0: forcedeth.c: subsystem: 01462:0250 bound to 0000:00:05.0
eth0: no link during initialization



Very interesting. The message itself is not fatal: It merely means that there was no link during ifup. This typically happens when the hardware initialization was not yet finished during ifup. Theoretically, an interrupt should happen when the hardware initialization is completed and that interrupt then sets up the link.
Somehow it doesn't work for you.

Could you try the attached patch? It polls for link changes instead of relying on the irq. Additionally, I have enabled some debug output.

--
Manfred


--- 2.6/drivers/net/forcedeth.c 2005-06-05 17:29:12.000000000 +0200
+++ build-2.6/drivers/net/forcedeth.c 2005-06-17 22:44:18.000000000 +0200
@@ -1298,7 +1299,7 @@
mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ);

if (!(mii_status & BMSR_LSTATUS)) {
- dprintk(KERN_DEBUG "%s: no link detected by phy - falling back to 10HD.\n",
+ printk(KERN_DEBUG "%s: no link detected by phy - falling back to 10HD.\n",
dev->name);
newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
newdup = 0;
@@ -1307,7 +1308,7 @@
}

if (np->autoneg == 0) {
- dprintk(KERN_DEBUG "%s: nv_update_linkspeed: autoneg off, PHY set to 0x%04x.\n",
+ printk(KERN_DEBUG "%s: nv_update_linkspeed: autoneg off, PHY set to 0x%04x.\n",
dev->name, np->fixed_mode);
if (np->fixed_mode & LPA_100FULL) {
newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_100;
@@ -1331,7 +1332,7 @@
newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
newdup = 0;
retval = 0;
- dprintk(KERN_DEBUG "%s: autoneg not completed - falling back to 10HD.\n", dev->name);
+ printk(KERN_DEBUG "%s: autoneg not completed - falling back to 10HD.\n", dev->name);
goto set_speed;
}

@@ -1342,7 +1343,7 @@

if ((control_1000 & ADVERTISE_1000FULL) &&
(status_1000 & LPA_1000FULL)) {
- dprintk(KERN_DEBUG "%s: nv_update_linkspeed: GBit ethernet detected.\n",
+ printk(KERN_DEBUG "%s: nv_update_linkspeed: GBit ethernet detected.\n",
dev->name);
newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_1000;
newdup = 1;
@@ -1352,7 +1353,7 @@

adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ);
lpa = mii_rw(dev, np->phyaddr, MII_LPA, MII_READ);
- dprintk(KERN_DEBUG "%s: nv_update_linkspeed: PHY advertises 0x%04x, lpa 0x%04x.\n",
+ printk(KERN_DEBUG "%s: nv_update_linkspeed: PHY advertises 0x%04x, lpa 0x%04x.\n",
dev->name, adv, lpa);

/* FIXME: handle parallel detection properly */
@@ -1370,7 +1371,7 @@
newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
newdup = 0;
} else {
- dprintk(KERN_DEBUG "%s: bad ability %04x - falling back to 10HD.\n", dev->name, lpa);
+ printk(KERN_DEBUG "%s: bad ability %04x - falling back to 10HD.\n", dev->name, lpa);
newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
newdup = 0;
}
@@ -1379,7 +1380,7 @@
if (np->duplex == newdup && np->linkspeed == newls)
return retval;

- dprintk(KERN_INFO "%s: changing link setting from %d/%d to %d/%d.\n",
+ printk(KERN_INFO "%s: changing link setting from %d/%d to %d/%d.\n",
dev->name, np->linkspeed, np->duplex, newls, newdup);

np->duplex = newdup;
@@ -1442,11 +1443,11 @@

miistat = readl(base + NvRegMIIStatus);
writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
- dprintk(KERN_INFO "%s: link change irq, status 0x%x.\n", dev->name, miistat);
+ printk(KERN_INFO "%s: link change irq, status 0x%x.\n", dev->name, miistat);

if (miistat & (NVREG_MIISTAT_LINKCHANGE))
nv_linkchange(dev);
- dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name);
+ printk(KERN_DEBUG "%s: link change notification done.\n", dev->name);
}

static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs)
@@ -2088,8 +2091,8 @@
np->irqmask = NVREG_IRQMASK_WANTED_2;
if (id->driver_data & DEV_NEED_TIMERIRQ)
np->irqmask |= NVREG_IRQ_TIMER;
- if (id->driver_data & DEV_NEED_LINKTIMER) {
- dprintk(KERN_INFO "%s: link timer on.\n", pci_name(pci_dev));
+ if (id->driver_data & DEV_NEED_LINKTIMER || 1) {
+ printk(KERN_INFO "%s: link timer on.\n", pci_name(pci_dev));
np->need_linktimer = 1;
np->link_timeout = jiffies + LINK_TIMEOUT;
} else {