ixgbe/base: rework flow control
authorJijiang Liu <jijiang.liu@intel.com>
Wed, 18 Jun 2014 17:53:16 +0000 (19:53 +0200)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Wed, 18 Jun 2014 21:31:36 +0000 (23:31 +0200)
Signed-off-by: Jijiang Liu <jijiang.liu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
Tested-by: Waterman Cao <waterman.cao@intel.com>
[Thomas: split code drop]

lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.c
lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.h
lib/librte_pmd_ixgbe/ixgbe/ixgbe_dcb_82599.c

index 57859b1..7b768fa 100644 (file)
@@ -151,19 +151,46 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw)
  * autonegotiation, and false if it does not.
  *
  **/
-s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
+bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
 {
+       bool supported = false;
+       ixgbe_link_speed speed;
+       bool link_up;
 
        DEBUGFUNC("ixgbe_device_supports_autoneg_fc");
 
-       switch (hw->device_id) {
-       case IXGBE_DEV_ID_X540T:
-       case IXGBE_DEV_ID_X540T1:
-       case IXGBE_DEV_ID_82599_T3_LOM:
-               return IXGBE_SUCCESS;
+       switch (hw->phy.media_type) {
+       case ixgbe_media_type_fiber:
+               hw->mac.ops.check_link(hw, &speed, &link_up, false);
+               /* if link is down, assume supported */
+               if (link_up)
+                       supported = speed == IXGBE_LINK_SPEED_1GB_FULL ?
+                               true : false;
+               else
+                       supported = true;
+               break;
+       case ixgbe_media_type_backplane:
+               supported = true;
+               break;
+       case ixgbe_media_type_copper:
+               /* only some copper devices support flow control autoneg */
+               switch (hw->device_id) {
+               case IXGBE_DEV_ID_82599_T3_LOM:
+               case IXGBE_DEV_ID_X540T:
+               case IXGBE_DEV_ID_X540T1:
+                       supported = true;
+                       break;
+               default:
+                       supported = false;
+               }
        default:
-               return IXGBE_ERR_FC_NOT_SUPPORTED;
+               break;
        }
+
+       ERROR_REPORT2(IXGBE_ERROR_UNSUPPORTED,
+                     "Device %x does not support flow control autoneg",
+                     hw->device_id);
+       return supported;
 }
 
 /**
@@ -2763,10 +2790,11 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw)
                        /*
                         * In order to prevent Tx hangs when the internal Tx
                         * switch is enabled we must set the high water mark
-                        * to the maximum FCRTH value.  This allows the Tx
-                        * switch to function even under heavy Rx workloads.
+                        * to the Rx packet buffer size - 24KB.  This allows
+                        * the Tx switch to function even under heavy Rx
+                        * workloads.
                         */
-                       fcrth = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 32;
+                       fcrth = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 24576;
                }
 
                IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), fcrth);
@@ -2993,7 +3021,7 @@ void ixgbe_fc_autoneg(struct ixgbe_hw *hw)
 
        /* Autoneg flow control on copper adapters */
        case ixgbe_media_type_copper:
-               if (ixgbe_device_supports_autoneg_fc(hw) == IXGBE_SUCCESS)
+               if (ixgbe_device_supports_autoneg_fc(hw))
                        ret_val = ixgbe_fc_autoneg_copper(hw);
                break;
 
index a30bd68..0413f19 100644 (file)
@@ -112,7 +112,7 @@ s32 ixgbe_disable_sec_rx_path_generic(struct ixgbe_hw *hw);
 s32 ixgbe_enable_sec_rx_path_generic(struct ixgbe_hw *hw);
 
 s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw);
-s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw);
+bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw);
 void ixgbe_fc_autoneg(struct ixgbe_hw *hw);
 
 s32 ixgbe_validate_mac_addr(u8 *mac_addr);
index cc7ce7a..5075e4f 100644 (file)
@@ -329,7 +329,14 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en, u8 *map)
                        fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
                        IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl);
                } else {
-                       reg = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 32;
+                       /*
+                        * In order to prevent Tx hangs when the internal Tx
+                        * switch is enabled we must set the high water mark
+                        * to the Rx packet buffer size - 24KB.  This allows
+                        * the Tx switch to function even under heavy Rx
+                        * workloads.
+                        */
+                       reg = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 24576;
                        IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0);
                }