Sophie

Sophie

distrib > CentOS > 5 > x86_64 > by-pkgid > ea32411352494358b8d75a78402a4713 > files > 2899

kernel-2.6.18-238.19.1.el5.centos.plus.src.rpm

From: Don Howard <dhoward@redhat.com>
Date: Thu, 05 May 2011 16:14:16 -0000
Subject: [net] ixgbe: fix for link failure on SFP+ DA cables
Message-id: <1304612056-25088-1-git-send-email-dhoward@redhat.com>
Patchwork-id: 35820
O-Subject: [RHEL5.6z PATCH] ixgbe: fix for link failure on SFP+ DA cables
Bugzilla: 696181
RH-Acked-by: Jiri Pirko <jpirko@redhat.com>
RH-Acked-by: John Linville <linville@redhat.com>
RH-Acked-by: Andy Gospodarek <gospo@redhat.com>
RH-Acked-by: David S. Miller <davem@redhat.com>

Fixes 5.6z bug 696181.

Brew build running as we speak: 
http://brewweb.devel.redhat.com/brew/taskinfo?taskID=3304182


This patch went into 5.7 as part of rhel 5.7 commit a014c6585d,
linux-2.6-net-ixgbe-update-to-upstream-version-3-2-9-k2.patch.

commit a7f5a5fcd9f13afd3471a0de8c1fdaa8f989497c
Author: Don Skidmore <donald.c.skidmore@intel.com>
Date:   Fri Dec 3 13:23:30 2010 +0000

    ixgbe: fix for link failure on SFP+ DA cables

    This patch helps prevent FW/SW semaphore collision from leading
    to link establishment failure.  The collision might mess up the
    PHY registers so we reset the PHY.  However there are SFI/KR areas
    in the PHY that are not reset with a Reset_AN so we need to change
    LMS to reset it.  Also wait until AN state machine is AN_GOOD

    Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
    Tested-by: Stephen Ko <stephen.s.ko@intel.com>
    Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>

Signed-off-by: Don Howard <dhoward@redhat.com>
---
 drivers/net/ixgbe/ixgbe_82599.c |   28 +++++++++++++++++++++++++---
 drivers/net/ixgbe/ixgbe_type.h  |    3 +++
 2 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index fc6a4ee..e543350 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -93,6 +93,8 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
 static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
 {
 	s32 ret_val = 0;
+	u32 reg_anlp1 = 0;
+	u32 i = 0;
 	u16 list_offset, data_offset, data_value;
 
 	if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) {
@@ -119,14 +121,34 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
 			IXGBE_WRITE_FLUSH(hw);
 			hw->eeprom.ops.read(hw, ++data_offset, &data_value);
 		}
-		/* Now restart DSP by setting Restart_AN */
-		IXGBE_WRITE_REG(hw, IXGBE_AUTOC,
-		    (IXGBE_READ_REG(hw, IXGBE_AUTOC) | IXGBE_AUTOC_AN_RESTART));
 
 		/* Release the semaphore */
 		ixgbe_release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
 		/* Delay obtaining semaphore again to allow FW access */
 		msleep(hw->eeprom.semaphore_delay);
+
+		/* Now restart DSP by setting Restart_AN and clearing LMS */
+		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((IXGBE_READ_REG(hw,
+		                IXGBE_AUTOC) & ~IXGBE_AUTOC_LMS_MASK) |
+		                IXGBE_AUTOC_AN_RESTART));
+
+		/* Wait for AN to leave state 0 */
+		for (i = 0; i < 10; i++) {
+			msleep(4);
+			reg_anlp1 = IXGBE_READ_REG(hw, IXGBE_ANLP1);
+			if (reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)
+				break;
+		}
+		if (!(reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)) {
+			hw_dbg(hw, "sfp module setup not complete\n");
+			ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE;
+			goto setup_sfp_out;
+		}
+
+		/* Restart DSP by setting Restart_AN and return to SFI mode */
+		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (IXGBE_READ_REG(hw,
+		                IXGBE_AUTOC) | IXGBE_AUTOC_LMS_10G_SERIAL |
+		                IXGBE_AUTOC_AN_RESTART));
 	}
 
 setup_sfp_out:
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 376339e..56cc371 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -1459,6 +1459,8 @@
 #define IXGBE_ANLP1_PAUSE               0x0C00
 #define IXGBE_ANLP1_SYM_PAUSE           0x0400
 #define IXGBE_ANLP1_ASM_PAUSE           0x0800
+#define IXGBE_ANLP1_AN_STATE_MASK       0x000f0000
+
 
 /* SW Semaphore Register bitmasks */
 #define IXGBE_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
@@ -2606,6 +2608,7 @@ struct ixgbe_info {
 #define IXGBE_ERR_NO_SPACE                      -25
 #define IXGBE_ERR_OVERTEMP                      -26
 #define IXGBE_ERR_RAR_INDEX                     -27
+#define IXGBE_ERR_SFP_SETUP_NOT_COMPLETE        -30
 #define IXGBE_NOT_IMPLEMENTED                   0x7FFFFFFF
 
 /* defined in drivers/net/ixgbe/ixgbe_dcb_82599.h upstream */