net/ixgbe/base: bypass checking link for crosstalk
authorXiao Wang <xiao.w.wang@intel.com>
Sun, 25 Sep 2016 08:59:57 +0000 (16:59 +0800)
committerBruce Richardson <bruce.richardson@intel.com>
Fri, 30 Sep 2016 10:27:18 +0000 (12:27 +0200)
When HW starts, first read the NVM to see if the crosstalk fix should
be used on the given HW and cache that information in the HW structure.

When we check_link we first see if 1) NVM requests this fix 2) if
we are an SFP+ device 3) see if a module is not in the SFP+ cage.
If all the above are true then don't bother checking the link, just
say it is down.

Signed-off-by: Xiao Wang <xiao.w.wang@intel.com>
Acked-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
drivers/net/ixgbe/base/ixgbe_common.c
drivers/net/ixgbe/base/ixgbe_type.h

index e46af23..1c7263d 100644 (file)
@@ -372,6 +372,7 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
 {
        s32 ret_val;
        u32 ctrl_ext;
+       u16 device_caps;
 
        DEBUGFUNC("ixgbe_start_hw_generic");
 
@@ -397,6 +398,22 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
        if (ret_val != IXGBE_SUCCESS)
                goto out;
 
+       /* Cache bit indicating need for crosstalk fix */
+       switch (hw->mac.type) {
+       case ixgbe_mac_82599EB:
+       case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_X550EM_a:
+               hw->mac.ops.get_device_caps(hw, &device_caps);
+               if (device_caps & IXGBE_DEVICE_CAPS_NO_CROSSTALK_WR)
+                       hw->need_crosstalk_fix = false;
+               else
+                       hw->need_crosstalk_fix = true;
+               break;
+       default:
+               hw->need_crosstalk_fix = false;
+               break;
+       }
+
        /* Clear adapter stopped flag */
        hw->adapter_stopped = false;
 
@@ -4025,6 +4042,32 @@ s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw)
        return IXGBE_SUCCESS;
 }
 
+/**
+ *  ixgbe_need_crosstalk_fix - Determine if we need to do cross talk fix
+ *  @hw: pointer to hardware structure
+ *
+ *  Contains the logic to identify if we need to verify link for the
+ *  crosstalk fix
+ **/
+static bool ixgbe_need_crosstalk_fix(struct ixgbe_hw *hw)
+{
+
+       /* Does FW say we need the fix */
+       if (!hw->need_crosstalk_fix)
+               return false;
+
+       /* Only consider SFP+ PHYs i.e. media type fiber */
+       switch (hw->mac.ops.get_media_type(hw)) {
+       case ixgbe_media_type_fiber:
+       case ixgbe_media_type_fiber_qsfp:
+               break;
+       default:
+               return false;
+       }
+
+       return true;
+}
+
 /**
  *  ixgbe_check_mac_link_generic - Determine link and speed status
  *  @hw: pointer to hardware structure
@@ -4042,6 +4085,35 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
 
        DEBUGFUNC("ixgbe_check_mac_link_generic");
 
+       /* If Crosstalk fix enabled do the sanity check of making sure
+        * the SFP+ cage is full.
+        */
+       if (ixgbe_need_crosstalk_fix(hw)) {
+               u32 sfp_cage_full;
+
+               switch (hw->mac.type) {
+               case ixgbe_mac_82599EB:
+                       sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) &
+                                       IXGBE_ESDP_SDP2;
+                       break;
+               case ixgbe_mac_X550EM_x:
+               case ixgbe_mac_X550EM_a:
+                       sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) &
+                                       IXGBE_ESDP_SDP0;
+                       break;
+               default:
+                       /* sanity check - No SFP+ devices here */
+                       sfp_cage_full = false;
+                       break;
+               }
+
+               if (!sfp_cage_full) {
+                       *link_up = false;
+                       *speed = IXGBE_LINK_SPEED_UNKNOWN;
+                       return IXGBE_SUCCESS;
+               }
+       }
+
        /* clear the old state */
        links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS);
 
index 1fc7c02..262f656 100644 (file)
@@ -4084,6 +4084,7 @@ struct ixgbe_hw {
        bool force_full_reset;
        bool allow_unsupported_sfp;
        bool wol_enabled;
+       bool need_crosstalk_fix;
 };
 
 #define ixgbe_call_func(hw, func, params, error) \