igb: add link check function
authorAlexander Duyck <alexander.h.duyck@intel.com>
Fri, 6 Feb 2009 23:16:24 +0000 (23:16 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sat, 7 Feb 2009 10:43:04 +0000 (02:43 -0800)
Add a link check function to contain all activities related to verifying
that the link is present.  The current approach is a bit cludgy and needs
to be cleaned up.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/igb/igb_main.c

index 13b10ba8a3c472a1017f876f0e7c4a99424bf8a4..b59088eace1da7080c1f0624f6be1667a7caffd8 100644 (file)
@@ -2260,6 +2260,46 @@ static void igb_update_phy_info(unsigned long data)
        igb_get_phy_info(&adapter->hw);
 }
 
+/**
+ * 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
@@ -2285,25 +2325,10 @@ static void igb_watchdog_task(struct work_struct *work)
        s32 ret_val;
        int i;
 
-       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;