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&#174; Ethernet, visit 
http://communities.intel.com/community/wired

Reply via email to