Change MDIO read/write to poll for completion rather than waiting an arbitrary length of time. Note this changes the semantics of the MDIO_DELAY definition - it is now a maximal loop count, rather than a time delay in microseconds. --- linux-2.6.8-rc3/drivers/net/ibm_emac/ibm_emac_core.c 2004-08-05 14:54:56.000000000 -0400 +++ linux-2.6-devel/drivers/net/ibm_emac/ibm_emac_core.c 2004-08-05 15:08:50.000000000 -0400 @@ -367,6 +371,7 @@ int emac_phy_read(struct net_device *dev, int mii_id, int reg) { + int count; uint32_t stacr; struct ocp_enet_private *fep = dev->priv; emac_t *emacp = fep->emacp; @@ -398,8 +403,11 @@ out_be32(&emacp->em0stacr, stacr); - udelay(MDIO_DELAY); - stacr = in_be32(&emacp->em0stacr); + count = 0; + while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0) + && (count++ < MDIO_DELAY)) + udelay(1); + MDIO_DEBUG((" (count was %d)\n", count)); if ((stacr & EMAC_STACR_OC) == 0) { printk(KERN_WARNING "%s: PHY read timeout #2!\n", dev->name); @@ -419,6 +427,7 @@ void emac_phy_write(struct net_device *dev, int mii_id, int reg, int data) { + int count; uint32_t stacr; struct ocp_enet_private *fep = dev->priv; emac_t *emacp = fep->emacp; @@ -451,9 +460,13 @@ out_be32(&emacp->em0stacr, stacr); - udelay(MDIO_DELAY); + count = 0; + while (((stacr = in_be32(&emacp->em0stacr) & EMAC_STACR_OC) == 0) + && (count++ < 5000)) + udelay(1); + MDIO_DEBUG((" (count was %d)\n", count)); - if (((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0) + if ((stacr & EMAC_STACR_OC) == 0) printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name); /* Check for a write error */