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:0.091 / U:1.504 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site