Messages in this thread Patch in this message | | | From | David Decotigny <> | Subject | [PATCH net-next v2 3/4] net-e1000e: reworked carrier detection logic | Date | Tue, 22 Nov 2011 11:23:37 -0800 |
| |
From: Maciej Żenczykowski <zenczykowski@gmail.com>
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 <david.decotigny@google.com> --- 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |