aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e100.c
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2009-10-29 09:42:41 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-30 01:48:31 -0400
commit8fbd962e39517dfb2bfd363eba4b51cdfa299593 (patch)
tree90ac9d3448f10d5bcde2f748b9f729277302a026 /drivers/net/e100.c
parentb5dd884e682cae6b8c037f9d11f3b623b4cf2011 (diff)
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>
Diffstat (limited to 'drivers/net/e100.c')
-rw-r--r--drivers/net/e100.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 679965c2bb86..d19b0845970a 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1426,19 +1426,31 @@ static int e100_phy_init(struct nic *nic)
1426 } else 1426 } else
1427 DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id); 1427 DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id);
1428 1428
1429 /* Isolate all the PHY ids */
1430 for (addr = 0; addr < 32; addr++)
1431 mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE);
1432 /* Select the discovered PHY */
1433 bmcr &= ~BMCR_ISOLATE;
1434 mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr);
1435
1436 /* Get phy ID */ 1429 /* Get phy ID */
1437 id_lo = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID1); 1430 id_lo = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID1);
1438 id_hi = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID2); 1431 id_hi = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID2);
1439 nic->phy = (u32)id_hi << 16 | (u32)id_lo; 1432 nic->phy = (u32)id_hi << 16 | (u32)id_lo;
1440 DPRINTK(HW, DEBUG, "phy ID = 0x%08X\n", nic->phy); 1433 DPRINTK(HW, DEBUG, "phy ID = 0x%08X\n", nic->phy);
1441 1434
1435 /* Select the phy and isolate the rest */
1436 for (addr = 0; addr < 32; addr++) {
1437 if (addr != nic->mii.phy_id) {
1438 mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE);
1439 } else if (nic->phy != phy_82552_v) {
1440 bmcr = mdio_read(netdev, addr, MII_BMCR);
1441 mdio_write(netdev, addr, MII_BMCR,
1442 bmcr & ~BMCR_ISOLATE);
1443 }
1444 }
1445 /*
1446 * Workaround for 82552:
1447 * Clear the ISOLATE bit on selected phy_id last (mirrored on all
1448 * other phy_id's) using bmcr value from addr discovery loop above.
1449 */
1450 if (nic->phy == phy_82552_v)
1451 mdio_write(netdev, nic->mii.phy_id, MII_BMCR,
1452 bmcr & ~BMCR_ISOLATE);
1453
1442 /* Handle National tx phys */ 1454 /* Handle National tx phys */
1443#define NCS_PHY_MODEL_MASK 0xFFF0FFFF 1455#define NCS_PHY_MODEL_MASK 0xFFF0FFFF
1444 if ((nic->phy & NCS_PHY_MODEL_MASK) == phy_nsc_tx) { 1456 if ((nic->phy & NCS_PHY_MODEL_MASK) == phy_nsc_tx) {