e1000e: 82571 check for link fix on 82571 serdes
authorBruce Allan <bruce.w.allan@intel.com>
Sat, 22 Nov 2008 00:50:34 +0000 (16:50 -0800)
committerDavid S. Miller <davem@davemloft.net>
Sat, 22 Nov 2008 00:50:34 +0000 (16:50 -0800)
Check for link test does not work properly for 82571 parts in a blade
environment with an unterminated serdes link partner.  Make the test more
robust by checking the invalid bit.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/e1000e/lib.c

index 089578f6855a21500188034b6f4fd09809658dfc..37753d13cd2290383c3daa81352181012ede94e5 100644 (file)
@@ -575,20 +575,42 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw)
                 */
                /* SYNCH bit and IV bit are sticky. */
                udelay(10);
-               if (E1000_RXCW_SYNCH & er32(RXCW)) {
+               rxcw = er32(RXCW);
+               if (rxcw & E1000_RXCW_SYNCH) {
                        if (!(rxcw & E1000_RXCW_IV)) {
-                               mac->serdes_has_link = 1;
-                               hw_dbg(hw, "SERDES: Link is up.\n");
+                               mac->serdes_has_link = true;
+                               hw_dbg(hw, "SERDES: Link up - forced.\n");
                        }
                } else {
-                       mac->serdes_has_link = 0;
-                       hw_dbg(hw, "SERDES: Link is down.\n");
+                       mac->serdes_has_link = false;
+                       hw_dbg(hw, "SERDES: Link down - force failed.\n");
                }
        }
 
        if (E1000_TXCW_ANE & er32(TXCW)) {
                status = er32(STATUS);
-               mac->serdes_has_link = (status & E1000_STATUS_LU);
+               if (status & E1000_STATUS_LU) {
+                       /* SYNCH bit and IV bit are sticky, so reread rxcw.  */
+                       udelay(10);
+                       rxcw = er32(RXCW);
+                       if (rxcw & E1000_RXCW_SYNCH) {
+                               if (!(rxcw & E1000_RXCW_IV)) {
+                                       mac->serdes_has_link = true;
+                                       hw_dbg(hw, "SERDES: Link up - autoneg "
+                                          "completed sucessfully.\n");
+                               } else {
+                                       mac->serdes_has_link = false;
+                                       hw_dbg(hw, "SERDES: Link down - invalid"
+                                          "codewords detected in autoneg.\n");
+                               }
+                       } else {
+                               mac->serdes_has_link = false;
+                               hw_dbg(hw, "SERDES: Link down - no sync.\n");
+                       }
+               } else {
+                       mac->serdes_has_link = false;
+                       hw_dbg(hw, "SERDES: Link down - autoneg failed\n");
+               }
        }
 
        return 0;