drivers: advertise kmod dependencies in pmdinfo
[dpdk.git] / drivers / net / i40e / i40e_ethdev.c
index ca515dd..b0c0fbf 100644 (file)
                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 | \
@@ -712,6 +711,7 @@ rte_i40e_dev_atomic_write_link_status(struct rte_eth_dev *dev,
 
 RTE_PMD_REGISTER_PCI(net_i40e, rte_i40e_pmd.pci_drv);
 RTE_PMD_REGISTER_PCI_TABLE(net_i40e, pci_id_i40e_map);
+RTE_PMD_REGISTER_KMOD_DEP(net_i40e, "* igb_uio | uio_pci_generic | vfio");
 
 #ifndef I40E_GLQF_ORT
 #define I40E_GLQF_ORT(_i)    (0x00268900 + ((_i) * 4))
@@ -1121,11 +1121,13 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
        /* Disable double vlan by default */
        i40e_vsi_config_double_vlan(vsi, FALSE);
 
-       /* Disable S-TAG identification by default */
-       ret = I40E_READ_REG(hw, I40E_PRT_L2TAGSEN);
-       if (ret & I40E_L2_TAGS_S_TAG_MASK) {
-               ret &= ~I40E_L2_TAGS_S_TAG_MASK;
-               I40E_WRITE_REG(hw, I40E_PRT_L2TAGSEN, ret);
+       /* Disable S-TAG identification when floating_veb is disabled */
+       if (!pf->floating_veb) {
+               ret = I40E_READ_REG(hw, I40E_PRT_L2TAGSEN);
+               if (ret & I40E_L2_TAGS_S_TAG_MASK) {
+                       ret &= ~I40E_L2_TAGS_S_TAG_MASK;
+                       I40E_WRITE_REG(hw, I40E_PRT_L2TAGSEN, ret);
+               }
        }
 
        if (!vsi->max_macaddrs)
@@ -1223,11 +1225,6 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev)
        dev->rx_pkt_burst = NULL;
        dev->tx_pkt_burst = NULL;
 
-       /* Disable LLDP */
-       ret = i40e_aq_stop_lldp(hw, true, NULL);
-       if (ret != I40E_SUCCESS) /* Its failure can be ignored */
-               PMD_INIT_LOG(INFO, "Failed to stop lldp");
-
        /* Clear PXE mode */
        i40e_clear_pxe_mode(hw);
 
@@ -1782,6 +1779,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 */
@@ -2000,6 +2007,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));
@@ -2008,7 +2016,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;
@@ -5434,6 +5443,24 @@ i40e_dev_handle_vfr_event(struct rte_eth_dev *dev)
        }
 }
 
+static void
+i40e_notify_all_vfs_link_status(struct rte_eth_dev *dev)
+{
+       struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+       struct i40e_virtchnl_pf_event event;
+       int i;
+
+       event.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE;
+       event.event_data.link_event.link_status =
+               dev->data->dev_link.link_status;
+       event.event_data.link_event.link_speed =
+               (enum i40e_aq_link_speed)dev->data->dev_link.link_speed;
+
+       for (i = 0; i < pf->vf_num; i++)
+               i40e_pf_host_send_msg_to_vf(&pf->vfs[i], I40E_VIRTCHNL_OP_EVENT,
+                               I40E_SUCCESS, (uint8_t *)&event, sizeof(event));
+}
+
 static void
 i40e_dev_handle_aq_msg(struct rte_eth_dev *dev)
 {
@@ -5470,6 +5497,14 @@ 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) {
+                               i40e_notify_all_vfs_link_status(dev);
+                               _rte_eth_dev_callback_process(dev,
+                                       RTE_ETH_EVENT_INTR_LSC, NULL);
+                       }
+                       break;
                default:
                        PMD_DRV_LOG(ERR, "Request %u is not supported yet",
                                    opcode);
@@ -5479,57 +5514,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, NULL);
-
-       i40e_pf_enable_irq0(hw);
-       rte_intr_enable(&(dev->pci_dev->intr_handle));
-}
-
 /**
  * Interrupt handler triggered by NIC  for handling
  * specific interrupt.
@@ -5587,30 +5571,6 @@ i40e_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
                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, NULL);
-       }
-
 done:
        /* Enable interrupt */
        i40e_pf_enable_irq0(hw);
@@ -9432,17 +9392,13 @@ i40e_dcb_init_configure(struct rte_eth_dev *dev, bool sw_dcb)
         * LLDP MIB change event.
         */
        if (sw_dcb == TRUE) {
-               ret = i40e_aq_stop_lldp(hw, TRUE, NULL);
-               if (ret != I40E_SUCCESS)
-                       PMD_INIT_LOG(DEBUG, "Failed to stop lldp");
-
                ret = i40e_init_dcb(hw);
-               /* if sw_dcb, lldp agent is stopped, the return from
+               /* If lldp agent is stopped, the return value from
                 * i40e_init_dcb we expect is failure with I40E_AQ_RC_EPERM
-                * adminq status.
+                * adminq status. Otherwise, it should return success.
                 */
-               if (ret != I40E_SUCCESS &&
-                   hw->aq.asq_last_status == I40E_AQ_RC_EPERM) {
+               if ((ret == I40E_SUCCESS) || (ret != I40E_SUCCESS &&
+                   hw->aq.asq_last_status == I40E_AQ_RC_EPERM)) {
                        memset(&hw->local_dcbx_config, 0,
                                sizeof(struct i40e_dcbx_config));
                        /* set dcb default configuration */
@@ -9471,8 +9427,8 @@ i40e_dcb_init_configure(struct rte_eth_dev *dev, bool sw_dcb)
                                return -ENOSYS;
                        }
                } else {
-                       PMD_INIT_LOG(ERR, "DCBX configuration failed, err = %d,"
-                                         " aq_err = %d.", ret,
+                       PMD_INIT_LOG(ERR, "DCB initialization in FW fails,"
+                                         " err = %d, aq_err = %d.", ret,
                                          hw->aq.asq_last_status);
                        return -ENOTSUP;
                }