diff options
Diffstat (limited to 'patches/dpdk_custom_patch/i40e-fix-link-management.patch')
-rw-r--r-- | patches/dpdk_custom_patch/i40e-fix-link-management.patch | 169 |
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 + |