diff options
Diffstat (limited to 'patches/dpdk_custom_patch/i40e-fix-link-status-change-interrupt.patch')
-rwxr-xr-x | patches/dpdk_custom_patch/i40e-fix-link-status-change-interrupt.patch | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/patches/dpdk_custom_patch/i40e-fix-link-status-change-interrupt.patch b/patches/dpdk_custom_patch/i40e-fix-link-status-change-interrupt.patch new file mode 100755 index 00000000..1510b36c --- /dev/null +++ b/patches/dpdk_custom_patch/i40e-fix-link-status-change-interrupt.patch @@ -0,0 +1,150 @@ +diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c +index d0aeb70..9c1f542 100644 +--- a/drivers/net/i40e/i40e_ethdev.c ++++ b/drivers/net/i40e/i40e_ethdev.c +@@ -108,7 +108,6 @@ + I40E_PFINT_ICR0_ENA_GRST_MASK | \ + I40E_PFINT_ICR0_ENA_PCI_EXCEPTION_MASK | \ + I40E_PFINT_ICR0_ENA_STORM_DETECT_MASK | \ +- I40E_PFINT_ICR0_ENA_LINK_STAT_CHANGE_MASK | \ + I40E_PFINT_ICR0_ENA_HMC_ERR_MASK | \ + I40E_PFINT_ICR0_ENA_PE_CRITERR_MASK | \ + I40E_PFINT_ICR0_ENA_VFLR_MASK | \ +@@ -1768,6 +1767,16 @@ i40e_dev_start(struct rte_eth_dev *dev) + if (dev->data->dev_conf.intr_conf.lsc != 0) + PMD_INIT_LOG(INFO, "lsc won't enable because of" + " no intr multiplex\n"); ++ } else if (dev->data->dev_conf.intr_conf.lsc != 0) { ++ ret = i40e_aq_set_phy_int_mask(hw, ++ ~(I40E_AQ_EVENT_LINK_UPDOWN | ++ I40E_AQ_EVENT_MODULE_QUAL_FAIL | ++ I40E_AQ_EVENT_MEDIA_NA), NULL); ++ if (ret != I40E_SUCCESS) ++ PMD_DRV_LOG(WARNING, "Fail to set phy mask"); ++ ++ /* Call get_link_info aq commond to enable LSE */ ++ i40e_dev_link_update(dev, 0); + } + + /* enable uio intr after callback register */ +@@ -1984,6 +1993,7 @@ i40e_dev_link_update(struct rte_eth_dev *dev, + struct rte_eth_link link, old; + int status; + unsigned rep_cnt = MAX_REPEAT_TIME; ++ bool enable_lse = dev->data->dev_conf.intr_conf.lsc ? true : false; + + memset(&link, 0, sizeof(link)); + memset(&old, 0, sizeof(old)); +@@ -1992,7 +2002,8 @@ i40e_dev_link_update(struct rte_eth_dev *dev, + + do { + /* Get link status information from hardware */ +- status = i40e_aq_get_link_info(hw, false, &link_status, NULL); ++ status = i40e_aq_get_link_info(hw, enable_lse, ++ &link_status, NULL); + if (status != I40E_SUCCESS) { + link.link_speed = ETH_SPEED_NUM_100M; + link.link_duplex = ETH_LINK_FULL_DUPLEX; +@@ -5442,6 +5453,12 @@ i40e_dev_handle_aq_msg(struct rte_eth_dev *dev) + info.msg_buf, + info.msg_len); + break; ++ case i40e_aqc_opc_get_link_status: ++ ret = i40e_dev_link_update(dev, 0); ++ if (!ret) ++ _rte_eth_dev_callback_process(dev, ++ RTE_ETH_EVENT_INTR_LSC); ++ break; + default: + PMD_DRV_LOG(ERR, "Request %u is not supported yet", + opcode); +@@ -5451,57 +5468,6 @@ i40e_dev_handle_aq_msg(struct rte_eth_dev *dev) + rte_free(info.msg_buf); + } + +-/* +- * Interrupt handler is registered as the alarm callback for handling LSC +- * interrupt in a definite of time, in order to wait the NIC into a stable +- * state. Currently it waits 1 sec in i40e for the link up interrupt, and +- * no need for link down interrupt. +- */ +-static void +-i40e_dev_interrupt_delayed_handler(void *param) +-{ +- struct rte_eth_dev *dev = (struct rte_eth_dev *)param; +- struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); +- uint32_t icr0; +- +- /* read interrupt causes again */ +- icr0 = I40E_READ_REG(hw, I40E_PFINT_ICR0); +- +-#ifdef RTE_LIBRTE_I40E_DEBUG_DRIVER +- if (icr0 & I40E_PFINT_ICR0_ECC_ERR_MASK) +- PMD_DRV_LOG(ERR, "ICR0: unrecoverable ECC error\n"); +- if (icr0 & I40E_PFINT_ICR0_MAL_DETECT_MASK) +- PMD_DRV_LOG(ERR, "ICR0: malicious programming detected\n"); +- if (icr0 & I40E_PFINT_ICR0_GRST_MASK) +- PMD_DRV_LOG(INFO, "ICR0: global reset requested\n"); +- if (icr0 & I40E_PFINT_ICR0_PCI_EXCEPTION_MASK) +- PMD_DRV_LOG(INFO, "ICR0: PCI exception\n activated\n"); +- if (icr0 & I40E_PFINT_ICR0_STORM_DETECT_MASK) +- PMD_DRV_LOG(INFO, "ICR0: a change in the storm control " +- "state\n"); +- if (icr0 & I40E_PFINT_ICR0_HMC_ERR_MASK) +- PMD_DRV_LOG(ERR, "ICR0: HMC error\n"); +- if (icr0 & I40E_PFINT_ICR0_PE_CRITERR_MASK) +- PMD_DRV_LOG(ERR, "ICR0: protocol engine critical error\n"); +-#endif /* RTE_LIBRTE_I40E_DEBUG_DRIVER */ +- +- if (icr0 & I40E_PFINT_ICR0_VFLR_MASK) { +- PMD_DRV_LOG(INFO, "INT:VF reset detected\n"); +- i40e_dev_handle_vfr_event(dev); +- } +- if (icr0 & I40E_PFINT_ICR0_ADMINQ_MASK) { +- PMD_DRV_LOG(INFO, "INT:ADMINQ event\n"); +- i40e_dev_handle_aq_msg(dev); +- } +- +- /* handle the link up interrupt in an alarm callback */ +- i40e_dev_link_update(dev, 0); +- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC); +- +- i40e_pf_enable_irq0(hw); +- rte_intr_enable(&(dev->pci_dev->intr_handle)); +-} +- + /** + * Interrupt handler triggered by NIC for handling + * specific interrupt. +@@ -5558,31 +5524,6 @@ i40e_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle, + PMD_DRV_LOG(INFO, "ICR0: adminq event"); + i40e_dev_handle_aq_msg(dev); + } +- +- /* Link Status Change interrupt */ +- if (icr0 & I40E_PFINT_ICR0_LINK_STAT_CHANGE_MASK) { +-#define I40E_US_PER_SECOND 1000000 +- struct rte_eth_link link; +- +- PMD_DRV_LOG(INFO, "ICR0: link status changed\n"); +- memset(&link, 0, sizeof(link)); +- rte_i40e_dev_atomic_read_link_status(dev, &link); +- i40e_dev_link_update(dev, 0); +- +- /* +- * For link up interrupt, it needs to wait 1 second to let the +- * hardware be a stable state. Otherwise several consecutive +- * interrupts can be observed. +- * For link down interrupt, no need to wait. +- */ +- if (!link.link_status && rte_eal_alarm_set(I40E_US_PER_SECOND, +- i40e_dev_interrupt_delayed_handler, (void *)dev) >= 0) +- return; +- else +- _rte_eth_dev_callback_process(dev, +- RTE_ETH_EVENT_INTR_LSC); +- } +- + done: + /* Enable interrupt */ + i40e_pf_enable_irq0(hw); |