From: Maciej Żenczykowski <[email protected]> This change removes an un-needed final pause in case of timeout and reworks the "link is up" detection logic.
Signed-off-by: David Decotigny <[email protected]> --- drivers/net/ethernet/intel/e1000e/phy.c | 64 +++++++++++++++++++------------ 1 files changed, 39 insertions(+), 25 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c index 8666476..f487a7f 100644 --- a/drivers/net/ethernet/intel/e1000e/phy.c +++ b/drivers/net/ethernet/intel/e1000e/phy.c @@ -1775,39 +1775,53 @@ static s32 e1000_wait_autoneg(struct e1000_hw *hw) * Polls the PHY status register for link, 'iterations' number of times. **/ s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, - u32 usec_interval, bool *success) + u32 usec_interval, bool *success) { - s32 ret_val = 0; - u16 i, phy_status; + u32 i; + u16 phy_reg; + int good_reads_phy_status = 0; + + } + + /* + * Remember that e1e_rphy may fail because of another entity + * (like the firmware) holding the lock, we need to handle + * this gracefully - by waiting and trying again. + * + * Some PHYs require the PHY_STATUS register to be read twice + * due to the link bit being sticky. No harm doing it across + * the board. + */ + for (i = 0; i < iterations; /* i incremented manually */) { + if (0 == e1e_rphy(hw, PHY_STATUS, &phy_reg)) { + if (++good_reads_phy_status < 2) + continue; /* Re-read once, to make sure */ - for (i = 0; i < iterations; i++) { - /* - * Some PHYs require the PHY_STATUS register to be read - * twice due to the link bit being sticky. No harm doing - * it across the board. - */ - ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status); - if (ret_val) /* - * If the first read fails, another entity may have - * ownership of the resources, wait and try again to - * see if they have relinquished the resources yet. + * Great, we got at least 2 successfull reads */ - udelay(usec_interval); - ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status); - if (ret_val) - break; - if (phy_status & MII_SR_LINK_STATUS) - break; - if (usec_interval >= 1000) - mdelay(usec_interval/1000); + + if (phy_reg & MII_SR_LINK_STATUS) { + /* success: link up */ + *success = true; + return 0; + } + } + + /* Pause now and re-iterate */ + if (++i >= iterations) + break; /* Pause not needed after last iteration */ + else if (usec_interval >= 1000) + mdelay(usec_interval / 1000); else udelay(usec_interval); } - *success = (i < iterations); - - return ret_val; + /* no success in for(;;) loop */ + *success = false; + if (good_reads_phy_status < 2) + return -E1000_ERR_PHY; + return 0; } /** -- 1.7.3.1 ------------------------------------------------------------------------------ All the data continuously generated in your IT infrastructure contains a definitive record of customers, application performance, security threats, fraudulent activity, and more. Splunk takes this data and makes sense of it. IT sense. And common sense. http://p.sf.net/sfu/splunk-novd2d _______________________________________________ E1000-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/e1000-devel To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
