dect
/
linux-2.6
Archived
13
0
Fork 0

e100: e100_phy_init() isolates selected PHY, causes 10 second boot delay

A change in how PHYs are electrically isolated caused all PHYs to be
isolated followed by reverting that isolation for the selected PHY.
Unfortunately, isolating the selected PHY for even a short period of
time can result in DHCP negotiation taking more than 10 seconds on certain
embedded configurations delaying boot time as reported by Bernhard Kaindl.
This patch reverts the change to how PHYs are isolated yet still works
around the issue for 82552 needing the selected PHY's BMCR register to
be written after the unused PHYs are isolated.  This code is moved below
the setting of nic->phy ID in order to do the 82552-specific workaround.

Cc: Bernhard Kaindl <bernhard.kaindl@gmx.net>
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Bruce Allan 2009-10-29 13:42:41 +00:00 committed by David S. Miller
parent b5dd884e68
commit 8fbd962e39
1 changed files with 19 additions and 7 deletions

View File

@ -1426,19 +1426,31 @@ static int e100_phy_init(struct nic *nic)
} else
DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id);
/* Isolate all the PHY ids */
for (addr = 0; addr < 32; addr++)
mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE);
/* Select the discovered PHY */
bmcr &= ~BMCR_ISOLATE;
mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr);
/* Get phy ID */
id_lo = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID1);
id_hi = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID2);
nic->phy = (u32)id_hi << 16 | (u32)id_lo;
DPRINTK(HW, DEBUG, "phy ID = 0x%08X\n", nic->phy);
/* Select the phy and isolate the rest */
for (addr = 0; addr < 32; addr++) {
if (addr != nic->mii.phy_id) {
mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE);
} else if (nic->phy != phy_82552_v) {
bmcr = mdio_read(netdev, addr, MII_BMCR);
mdio_write(netdev, addr, MII_BMCR,
bmcr & ~BMCR_ISOLATE);
}
}
/*
* Workaround for 82552:
* Clear the ISOLATE bit on selected phy_id last (mirrored on all
* other phy_id's) using bmcr value from addr discovery loop above.
*/
if (nic->phy == phy_82552_v)
mdio_write(netdev, nic->mii.phy_id, MII_BMCR,
bmcr & ~BMCR_ISOLATE);
/* Handle National tx phys */
#define NCS_PHY_MODEL_MASK 0xFFF0FFFF
if ((nic->phy & NCS_PHY_MODEL_MASK) == phy_nsc_tx) {