lkml.org 
[lkml]   [2011]   [Nov]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH net-next v2 3/4] net-e1000e: reworked carrier detection logic
    Date
    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/

    \
     
     \ /
      Last update: 2011-11-22 20:27    [W:4.256 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site