diff options
author | David S. Miller <davem@davemloft.net> | 2012-07-16 23:18:47 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-07-16 23:19:26 -0700 |
commit | 5dcaba7ed5be7fcedde7732111f31692e2e39ef9 (patch) | |
tree | 8fd80363f3c4cb7d00e69043599060d0f597b3ab /drivers | |
parent | 96f80d123eff05c3cd4701463786b87952a6c3ac (diff) | |
parent | a52359b56c29f55aaadf1dab80a0e1043b982676 (diff) | |
download | lwn-5dcaba7ed5be7fcedde7732111f31692e2e39ef9.tar.gz lwn-5dcaba7ed5be7fcedde7732111f31692e2e39ef9.zip |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net
Jeff Kirsher says:
====================
This series contains fixes to e1000e.
...
Bruce Allan (1):
e1000e: fix test for PHY being accessible on 82577/8/9 and I217
Tushar Dave (1):
e1000e: Correct link check logic for 82571 serdes
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/82571.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/ich8lan.c | 42 |
2 files changed, 35 insertions, 10 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index 36db4df09aed..1f063dcd8f85 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c @@ -1572,6 +1572,9 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) ctrl = er32(CTRL); status = er32(STATUS); rxcw = er32(RXCW); + /* SYNCH bit and IV bit are sticky */ + udelay(10); + rxcw = er32(RXCW); if ((rxcw & E1000_RXCW_SYNCH) && !(rxcw & E1000_RXCW_IV)) { diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 238ab2f8a5e7..e3a7b07df629 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -325,24 +325,46 @@ static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val) **/ static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw) { - u16 phy_reg; - u32 phy_id; + u16 phy_reg = 0; + u32 phy_id = 0; + s32 ret_val; + u16 retry_count; + + for (retry_count = 0; retry_count < 2; retry_count++) { + ret_val = e1e_rphy_locked(hw, PHY_ID1, &phy_reg); + if (ret_val || (phy_reg == 0xFFFF)) + continue; + phy_id = (u32)(phy_reg << 16); - e1e_rphy_locked(hw, PHY_ID1, &phy_reg); - phy_id = (u32)(phy_reg << 16); - e1e_rphy_locked(hw, PHY_ID2, &phy_reg); - phy_id |= (u32)(phy_reg & PHY_REVISION_MASK); + ret_val = e1e_rphy_locked(hw, PHY_ID2, &phy_reg); + if (ret_val || (phy_reg == 0xFFFF)) { + phy_id = 0; + continue; + } + phy_id |= (u32)(phy_reg & PHY_REVISION_MASK); + break; + } if (hw->phy.id) { if (hw->phy.id == phy_id) return true; - } else { - if ((phy_id != 0) && (phy_id != PHY_REVISION_MASK)) - hw->phy.id = phy_id; + } else if (phy_id) { + hw->phy.id = phy_id; + hw->phy.revision = (u32)(phy_reg & ~PHY_REVISION_MASK); return true; } - return false; + /* + * In case the PHY needs to be in mdio slow mode, + * set slow mode and try to get the PHY id again. + */ + hw->phy.ops.release(hw); + ret_val = e1000_set_mdio_slow_mode_hv(hw); + if (!ret_val) + ret_val = e1000e_get_phy_id(hw); + hw->phy.ops.acquire(hw); + + return !ret_val; } /** |