Sophie

Sophie

distrib > Scientific%20Linux > 5x > i386 > by-pkgid > 351d529f9beeb4e5d936a6d5e3e7813a > files > 1514

kernel-2.6.18-128.29.1.el5.src.rpm

From: Jiri Pirko <jpirko@redhat.com>
Date: Mon, 4 Jan 2010 14:05:08 +0100
Subject: [net] igb: add link check function
Message-id: 20100104130508.GB2467@psychotron.lab.eng.brq.redhat.com
O-Subject: [RHEL5.3.z patch] BZ548023 net: igb: add link check function
Bugzilla: 548023
RH-Acked-by: Stefan Assmann <sassmann@redhat.com>
RH-Acked-by: Neil Horman <nhorman@redhat.com>
RH-Acked-by: Michal Schmidt <mschmidt@redhat.com>

BZ548023
https://bugzilla.redhat.com/show_bug.cgi?id=548023

Description:
In case of SerDes interface ethernet ports, the link status must be checked in
'PCS status register'. But the current igb driver (provided in RHEL5.3) checks
the link status by way of monitoring 'MAC status register'.
This patch solves the issue.

Upstream:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=4d6b725e4d8e499fad012a25381c8d9bf53fbf4b

Brew:
https://brewweb.devel.redhat.com/taskinfo?taskID=2155259

Test:
Sucessfully tested by FJ.

Jirka

Signed-off-by: Jiri Pirko <jpirko@redhat.com>

diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index ce192fc..3489a17 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -2214,6 +2214,46 @@ static void igb_update_phy_info(unsigned long data)
 }
 
 /**
+ * igb_has_link - check shared code for link and determine up/down
+ * @adapter: pointer to driver private info
+ **/
+static bool igb_has_link(struct igb_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	bool link_active = false;
+	s32 ret_val = 0;
+
+	/* get_link_status is set on LSC (link status) interrupt or
+	 * rx sequence error interrupt.  get_link_status will stay
+	 * false until the e1000_check_for_link establishes link
+	 * for copper adapters ONLY
+	 */
+	switch (hw->phy.media_type) {
+	case e1000_media_type_copper:
+		if (hw->mac.get_link_status) {
+			ret_val = hw->mac.ops.check_for_link(hw);
+			link_active = !hw->mac.get_link_status;
+		} else {
+			link_active = true;
+		}
+		break;
+	case e1000_media_type_fiber:
+		ret_val = hw->mac.ops.check_for_link(hw);
+		link_active = !!(rd32(E1000_STATUS) & E1000_STATUS_LU);
+		break;
+	case e1000_media_type_internal_serdes:
+		ret_val = hw->mac.ops.check_for_link(hw);
+		link_active = hw->mac.serdes_has_link;
+		break;
+	default:
+	case e1000_media_type_unknown:
+		break;
+	}
+
+	return link_active;
+}
+
+/**
  * igb_watchdog - Timer Call-back
  * @data: pointer to adapter cast into an unsigned long
  **/
@@ -2233,25 +2273,10 @@ static void igb_watchdog_task(struct igb_adapter *adapter)
 	u32 link;
 	s32 ret_val;
 
-	if ((netif_carrier_ok(netdev)) &&
-	    (rd32(E1000_STATUS) & E1000_STATUS_LU))
+	link = igb_has_link(adapter);
+	if ((netif_carrier_ok(netdev)) && link)
 		goto link_up;
 
-	ret_val = hw->mac.ops.check_for_link(&adapter->hw);
-	if ((ret_val == E1000_ERR_PHY) &&
-	    (hw->phy.type == e1000_phy_igp_3) &&
-	    (rd32(E1000_CTRL) &
-	     E1000_PHY_CTRL_GBE_DISABLE))
-		dev_info(&adapter->pdev->dev,
-			 "Gigabit has been disabled, downgrading speed\n");
-
-	if ((hw->phy.media_type == e1000_media_type_internal_serdes) &&
-	    !(rd32(E1000_TXCW) & E1000_TXCW_ANE))
-		link = mac->serdes_has_link;
-	else
-		link = rd32(E1000_STATUS) &
-				      E1000_STATUS_LU;
-
 	if (link) {
 		if (!netif_carrier_ok(netdev)) {
 			u32 ctrl;