summaryrefslogtreecommitdiffstats
path: root/patches/dpdk_custom_patch/i40e-fix-link-management.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/dpdk_custom_patch/i40e-fix-link-management.patch')
-rw-r--r--patches/dpdk_custom_patch/i40e-fix-link-management.patch169
1 files changed, 169 insertions, 0 deletions
diff --git a/patches/dpdk_custom_patch/i40e-fix-link-management.patch b/patches/dpdk_custom_patch/i40e-fix-link-management.patch
new file mode 100644
index 00000000..af2c9a47
--- /dev/null
+++ b/patches/dpdk_custom_patch/i40e-fix-link-management.patch
@@ -0,0 +1,169 @@
+From ca7e599d4506f3d6b89dd846c901d09d46ea593c Mon Sep 17 00:00:00 2001
+From: Jingjing Wu <jingjing.wu@intel.com>
+Date: Thu, 12 May 2016 15:21:04 +0800
+Subject: [PATCH] net/i40e: fix link management
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Previously, there was a known issue "On Intel® 40G Ethernet
+Controller stopping the port does not really down the port link."
+
+There were two reasons why the port was always kept up.
+1. Old firmware versions had issues when "Set PHY config command"
+ was used on 40G NICs.
+2. The kernel i40e driver didn't call "Set PHY config command" when
+ ifconfig up/down was used, it assumes the link is always up. But
+ in DPDK, ports are forced down when an applications quits. So if
+ the port is then switched to being controlled by kernel the driver,
+ the port can not be brought up through "ifconfig <ethx> up".
+
+This patch fixes this issue by adding in "Set PHY config command"
+into our driver. This is now possible because with newer firmware
+there is no longer a problem using this command.
+
+With this fix, after DPDK quit, if the port is switched to being used
+by the kernel driver, "ethtool -s <ethx> autoneg on" can be used to
+turn on the auto negotiation, and then port can be brought up through
+"ifconfig <ethx> up".
+NOTE: requires kernel i40e driver version >= 1.4.X
+
+Fixes: 2f1e22817420 ("i40e: skip link control as firmware workaround")
+Fixes: 16c979f9adf2 ("i40e: disable setting of PHY configuration")
+
+Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
+---
+ doc/guides/rel_notes/known_issues.rst | 19 ---------
+ drivers/net/i40e/i40e_ethdev.c | 72 +++++++++++++++++++++++++++++------
+ 2 files changed, 60 insertions(+), 31 deletions(-)
+
+diff --git a/doc/guides/rel_notes/known_issues.rst b/doc/guides/rel_notes/known_issues.rst
+index e464eca..5ec1987 100644
+--- a/doc/guides/rel_notes/known_issues.rst
++++ b/doc/guides/rel_notes/known_issues.rst
+@@ -532,25 +532,6 @@ Cannot set link speed on Intel® 40G Ethernet controller
+ Poll Mode Driver (PMD).
+
+
+-Stopping the port does not down the link on Intel® 40G Ethernet controller
+---------------------------------------------------------------------------
+-
+-**Description**:
+- On Intel® 40G Ethernet Controller stopping the port does not really down the port link.
+-
+-**Implication**:
+- The port link will be still up after stopping the port.
+-
+-**Resolution/Workaround**:
+- None
+-
+-**Affected Environment/Platform**:
+- All.
+-
+-**Driver/Module**:
+- Poll Mode Driver (PMD).
+-
+-
+ Devices bound to igb_uio with VT-d enabled do not work on Linux kernel 3.15-3.17
+ --------------------------------------------------------------------------------
+
+diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
+index f94ad87..7a94663 100644
+--- a/drivers/net/i40e/i40e_ethdev.c
++++ b/drivers/net/i40e/i40e_ethdev.c
+@@ -1407,15 +1407,58 @@ i40e_parse_link_speeds(uint16_t link_speeds)
+ }
+
+ static int
+-i40e_phy_conf_link(__rte_unused struct i40e_hw *hw,
+- __rte_unused uint8_t abilities,
+- __rte_unused uint8_t force_speed)
+-{
+- /* Skip any phy config on both 10G and 40G interfaces, as a workaround
+- * for the link control limitation of that all link control should be
+- * handled by firmware. It should follow up if link control will be
+- * opened to software driver in future firmware versions.
+- */
++i40e_phy_conf_link(struct i40e_hw *hw,
++ uint8_t abilities,
++ uint8_t force_speed)
++{
++ enum i40e_status_code status;
++ struct i40e_aq_get_phy_abilities_resp phy_ab;
++ struct i40e_aq_set_phy_config phy_conf;
++ const uint8_t mask = I40E_AQ_PHY_FLAG_PAUSE_TX |
++ I40E_AQ_PHY_FLAG_PAUSE_RX |
++ I40E_AQ_PHY_FLAG_PAUSE_RX |
++ I40E_AQ_PHY_FLAG_LOW_POWER;
++ const uint8_t advt = I40E_LINK_SPEED_40GB |
++ I40E_LINK_SPEED_10GB |
++ I40E_LINK_SPEED_1GB |
++ I40E_LINK_SPEED_100MB;
++ int ret = -ENOTSUP;
++
++
++ status = i40e_aq_get_phy_capabilities(hw, false, false, &phy_ab,
++ NULL);
++ if (status)
++ return ret;
++
++ memset(&phy_conf, 0, sizeof(phy_conf));
++
++ /* bits 0-2 use the values from get_phy_abilities_resp */
++ abilities &= ~mask;
++ abilities |= phy_ab.abilities & mask;
++
++ /* update ablities and speed */
++ if (abilities & I40E_AQ_PHY_AN_ENABLED)
++ phy_conf.link_speed = advt;
++ else
++ phy_conf.link_speed = force_speed;
++
++ phy_conf.abilities = abilities;
++
++ /* use get_phy_abilities_resp value for the rest */
++ phy_conf.phy_type = phy_ab.phy_type;
++ phy_conf.eee_capability = phy_ab.eee_capability;
++ phy_conf.eeer = phy_ab.eeer_val;
++ phy_conf.low_power_ctrl = phy_ab.d3_lpan;
++
++ PMD_DRV_LOG(DEBUG, "\tCurrent: abilities %x, link_speed %x",
++ phy_ab.abilities, phy_ab.link_speed);
++ PMD_DRV_LOG(DEBUG, "\tConfig: abilities %x, link_speed %x",
++ phy_conf.abilities, phy_conf.link_speed);
++
++ status = i40e_aq_set_phy_config(hw, &phy_conf, NULL);
++ if (status)
++ return ret;
++
+ return I40E_SUCCESS;
+ }
+
+@@ -1431,8 +1474,13 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)
+ abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
+ if (!(conf->link_speeds & ETH_LINK_SPEED_FIXED))
+ abilities |= I40E_AQ_PHY_AN_ENABLED;
+- else
+- abilities |= I40E_AQ_PHY_LINK_ENABLED;
++ abilities |= I40E_AQ_PHY_LINK_ENABLED;
++
++ /* Skip changing speed on 40G interfaces, FW does not support */
++ if (i40e_is_40G_device(hw->device_id)) {
++ speed = I40E_LINK_SPEED_UNKNOWN;
++ abilities |= I40E_AQ_PHY_AN_ENABLED;
++ }
+
+ return i40e_phy_conf_link(hw, abilities, speed);
+ }
+@@ -1742,7 +1790,7 @@ i40e_dev_set_link_up(struct rte_eth_dev *dev)
+ * Set device link down.
+ */
+ static int
+-i40e_dev_set_link_down(__rte_unused struct rte_eth_dev *dev)
++i40e_dev_set_link_down(struct rte_eth_dev *dev)
+ {
+ uint8_t speed = I40E_LINK_SPEED_UNKNOWN;
+ uint8_t abilities = I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
+--
+2.7.4
+