net/i40e: store tunnel filter
[dpdk.git] / drivers / net / i40e / i40e_ethdev.c
index ca515dd..51b59d4 100644 (file)
@@ -51,6 +51,7 @@
 #include <rte_dev.h>
 #include <rte_eth_ctrl.h>
 #include <rte_tailq.h>
+#include <rte_hash_crc.h>
 
 #include "i40e_logs.h"
 #include "base/i40e_prototype.h"
                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 | \
@@ -325,6 +325,8 @@ static int i40e_dev_queue_stats_mapping_set(struct rte_eth_dev *dev,
                                            uint16_t queue_id,
                                            uint8_t stat_idx,
                                            uint8_t is_rx);
+static int i40e_fw_version_get(struct rte_eth_dev *dev,
+                               char *fw_version, size_t fw_size);
 static void i40e_dev_info_get(struct rte_eth_dev *dev,
                              struct rte_eth_dev_info *dev_info);
 static int i40e_vlan_filter_set(struct rte_eth_dev *dev,
@@ -374,8 +376,8 @@ static void i40e_stat_update_48(struct i40e_hw *hw,
                               uint64_t *offset,
                               uint64_t *stat);
 static void i40e_pf_config_irq0(struct i40e_hw *hw, bool no_queue);
-static void i40e_dev_interrupt_handler(
-               __rte_unused struct rte_intr_handle *handle, void *param);
+static void i40e_dev_interrupt_handler(struct rte_intr_handle *handle,
+                                      void *param);
 static int i40e_res_pool_init(struct i40e_res_pool_info *pool,
                                uint32_t base, uint32_t num);
 static void i40e_res_pool_destroy(struct i40e_res_pool_info *pool);
@@ -462,6 +464,18 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 
 static int i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 
+static int i40e_ethertype_filter_convert(
+       const struct rte_eth_ethertype_filter *input,
+       struct i40e_ethertype_filter *filter);
+static int i40e_sw_ethertype_filter_insert(struct i40e_pf *pf,
+                                  struct i40e_ethertype_filter *filter);
+
+static int i40e_tunnel_filter_convert(
+       struct i40e_aqc_add_remove_cloud_filters_element_data *cld_filter,
+       struct i40e_tunnel_filter *tunnel_filter);
+static int i40e_sw_tunnel_filter_insert(struct i40e_pf *pf,
+                               struct i40e_tunnel_filter *tunnel_filter);
+
 static const struct rte_pci_id pci_id_i40e_map[] = {
        { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_XL710) },
        { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QEMU) },
@@ -504,6 +518,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
        .stats_reset                  = i40e_dev_stats_reset,
        .xstats_reset                 = i40e_dev_stats_reset,
        .queue_stats_mapping_set      = i40e_dev_queue_stats_mapping_set,
+       .fw_version_get               = i40e_fw_version_get,
        .dev_infos_get                = i40e_dev_info_get,
        .dev_supported_ptypes_get     = i40e_dev_supported_ptypes_get,
        .vlan_filter_set              = i40e_vlan_filter_set,
@@ -672,8 +687,7 @@ static const struct rte_i40e_xstats_name_off rte_i40e_txq_prio_strings[] = {
 static struct eth_driver rte_i40e_pmd = {
        .pci_drv = {
                .id_table = pci_id_i40e_map,
-               .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
-                       RTE_PCI_DRV_DETACHABLE,
+               .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
                .probe = rte_eth_dev_pci_probe,
                .remove = rte_eth_dev_pci_remove,
        },
@@ -712,6 +726,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))
@@ -908,7 +923,7 @@ is_floating_veb_supported(struct rte_devargs *devargs)
 static void
 config_floating_veb(struct rte_eth_dev *dev)
 {
-       struct rte_pci_device *pci_dev = dev->pci_dev;
+       struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
        struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -928,10 +943,97 @@ config_floating_veb(struct rte_eth_dev *dev)
 #define I40E_L2_TAGS_S_TAG_SHIFT 1
 #define I40E_L2_TAGS_S_TAG_MASK I40E_MASK(0x1, I40E_L2_TAGS_S_TAG_SHIFT)
 
+static int
+i40e_init_ethtype_filter_list(struct rte_eth_dev *dev)
+{
+       struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+       struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype;
+       char ethertype_hash_name[RTE_HASH_NAMESIZE];
+       int ret;
+
+       struct rte_hash_parameters ethertype_hash_params = {
+               .name = ethertype_hash_name,
+               .entries = I40E_MAX_ETHERTYPE_FILTER_NUM,
+               .key_len = sizeof(struct i40e_ethertype_filter_input),
+               .hash_func = rte_hash_crc,
+       };
+
+       /* Initialize ethertype filter rule list and hash */
+       TAILQ_INIT(&ethertype_rule->ethertype_list);
+       snprintf(ethertype_hash_name, RTE_HASH_NAMESIZE,
+                "ethertype_%s", dev->data->name);
+       ethertype_rule->hash_table = rte_hash_create(&ethertype_hash_params);
+       if (!ethertype_rule->hash_table) {
+               PMD_INIT_LOG(ERR, "Failed to create ethertype hash table!");
+               return -EINVAL;
+       }
+       ethertype_rule->hash_map = rte_zmalloc("i40e_ethertype_hash_map",
+                                      sizeof(struct i40e_ethertype_filter *) *
+                                      I40E_MAX_ETHERTYPE_FILTER_NUM,
+                                      0);
+       if (!ethertype_rule->hash_map) {
+               PMD_INIT_LOG(ERR,
+                            "Failed to allocate memory for ethertype hash map!");
+               ret = -ENOMEM;
+               goto err_ethertype_hash_map_alloc;
+       }
+
+       return 0;
+
+err_ethertype_hash_map_alloc:
+       rte_hash_free(ethertype_rule->hash_table);
+
+       return ret;
+}
+
+static int
+i40e_init_tunnel_filter_list(struct rte_eth_dev *dev)
+{
+       struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+       struct i40e_tunnel_rule *tunnel_rule = &pf->tunnel;
+       char tunnel_hash_name[RTE_HASH_NAMESIZE];
+       int ret;
+
+       struct rte_hash_parameters tunnel_hash_params = {
+               .name = tunnel_hash_name,
+               .entries = I40E_MAX_TUNNEL_FILTER_NUM,
+               .key_len = sizeof(struct i40e_tunnel_filter_input),
+               .hash_func = rte_hash_crc,
+       };
+
+       /* Initialize tunnel filter rule list and hash */
+       TAILQ_INIT(&tunnel_rule->tunnel_list);
+       snprintf(tunnel_hash_name, RTE_HASH_NAMESIZE,
+                "tunnel_%s", dev->data->name);
+       tunnel_rule->hash_table = rte_hash_create(&tunnel_hash_params);
+       if (!tunnel_rule->hash_table) {
+               PMD_INIT_LOG(ERR, "Failed to create tunnel hash table!");
+               return -EINVAL;
+       }
+       tunnel_rule->hash_map = rte_zmalloc("i40e_tunnel_hash_map",
+                                   sizeof(struct i40e_tunnel_filter *) *
+                                   I40E_MAX_TUNNEL_FILTER_NUM,
+                                   0);
+       if (!tunnel_rule->hash_map) {
+               PMD_INIT_LOG(ERR,
+                            "Failed to allocate memory for tunnel hash map!");
+               ret = -ENOMEM;
+               goto err_tunnel_hash_map_alloc;
+       }
+
+       return 0;
+
+err_tunnel_hash_map_alloc:
+       rte_hash_free(tunnel_rule->hash_table);
+
+       return ret;
+}
+
 static int
 eth_i40e_dev_init(struct rte_eth_dev *dev)
 {
        struct rte_pci_device *pci_dev;
+       struct rte_intr_handle *intr_handle;
        struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct i40e_vsi *vsi;
@@ -944,6 +1046,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
        dev->dev_ops = &i40e_eth_dev_ops;
        dev->rx_pkt_burst = i40e_recv_pkts;
        dev->tx_pkt_burst = i40e_xmit_pkts;
+       dev->tx_pkt_prepare = i40e_prep_pkts;
 
        /* for secondary processes, we don't initialise any further as primary
         * has already done this work. Only check we don't need a different
@@ -953,9 +1056,11 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
                i40e_set_tx_function(dev);
                return 0;
        }
-       pci_dev = dev->pci_dev;
+       pci_dev = I40E_DEV_TO_PCI(dev);
+       intr_handle = &pci_dev->intr_handle;
 
        rte_eth_copy_pci_info(dev, pci_dev);
+       dev->data->dev_flags = RTE_ETH_DEV_DETACHABLE;
 
        pf->adapter = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
        pf->adapter->eth_dev = dev;
@@ -1121,11 +1226,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)
@@ -1147,15 +1254,15 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
        i40e_pf_host_init(dev);
 
        /* register callback func to eal lib */
-       rte_intr_callback_register(&(pci_dev->intr_handle),
-               i40e_dev_interrupt_handler, (void *)dev);
+       rte_intr_callback_register(intr_handle,
+                                  i40e_dev_interrupt_handler, dev);
 
        /* configure and enable device interrupt */
        i40e_pf_config_irq0(hw, TRUE);
        i40e_pf_enable_irq0(hw);
 
        /* enable uio intr after callback register */
-       rte_intr_enable(&(pci_dev->intr_handle));
+       rte_intr_enable(intr_handle);
        /*
         * Add an ethertype filter to drop all flow control frames transmitted
         * from VSIs. By doing so, we stop VF from sending out PAUSE or PFC
@@ -1178,8 +1285,20 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
                pf->flags &= ~I40E_FLAG_DCB;
        }
 
+       ret = i40e_init_ethtype_filter_list(dev);
+       if (ret < 0)
+               goto err_init_ethtype_filter_list;
+       ret = i40e_init_tunnel_filter_list(dev);
+       if (ret < 0)
+               goto err_init_tunnel_filter_list;
+
        return 0;
 
+err_init_tunnel_filter_list:
+       rte_free(pf->ethertype.hash_table);
+       rte_free(pf->ethertype.hash_map);
+err_init_ethtype_filter_list:
+       rte_free(dev->data->mac_addrs);
 err_mac_alloc:
        i40e_vsi_release(pf->main_vsi);
 err_setup_pf_switch:
@@ -1199,10 +1318,51 @@ err_sync_phy_type:
        return ret;
 }
 
+static void
+i40e_rm_ethtype_filter_list(struct i40e_pf *pf)
+{
+       struct i40e_ethertype_filter *p_ethertype;
+       struct i40e_ethertype_rule *ethertype_rule;
+
+       ethertype_rule = &pf->ethertype;
+       /* Remove all ethertype filter rules and hash */
+       if (ethertype_rule->hash_map)
+               rte_free(ethertype_rule->hash_map);
+       if (ethertype_rule->hash_table)
+               rte_hash_free(ethertype_rule->hash_table);
+
+       while ((p_ethertype = TAILQ_FIRST(&ethertype_rule->ethertype_list))) {
+               TAILQ_REMOVE(&ethertype_rule->ethertype_list,
+                            p_ethertype, rules);
+               rte_free(p_ethertype);
+       }
+}
+
+static void
+i40e_rm_tunnel_filter_list(struct i40e_pf *pf)
+{
+       struct i40e_tunnel_filter *p_tunnel;
+       struct i40e_tunnel_rule *tunnel_rule;
+
+       tunnel_rule = &pf->tunnel;
+       /* Remove all tunnel director rules and hash */
+       if (tunnel_rule->hash_map)
+               rte_free(tunnel_rule->hash_map);
+       if (tunnel_rule->hash_table)
+               rte_hash_free(tunnel_rule->hash_table);
+
+       while ((p_tunnel = TAILQ_FIRST(&tunnel_rule->tunnel_list))) {
+               TAILQ_REMOVE(&tunnel_rule->tunnel_list, p_tunnel, rules);
+               rte_free(p_tunnel);
+       }
+}
+
 static int
 eth_i40e_dev_uninit(struct rte_eth_dev *dev)
 {
+       struct i40e_pf *pf;
        struct rte_pci_device *pci_dev;
+       struct rte_intr_handle *intr_handle;
        struct i40e_hw *hw;
        struct i40e_filter_control_settings settings;
        int ret;
@@ -1213,8 +1373,10 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev)
        if (rte_eal_process_type() != RTE_PROC_PRIMARY)
                return 0;
 
+       pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
        hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       pci_dev = dev->pci_dev;
+       pci_dev = I40E_DEV_TO_PCI(dev);
+       intr_handle = &pci_dev->intr_handle;
 
        if (hw->adapter_stopped == 0)
                i40e_dev_close(dev);
@@ -1223,11 +1385,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);
 
@@ -1249,11 +1406,14 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev)
        dev->data->mac_addrs = NULL;
 
        /* disable uio intr before callback unregister */
-       rte_intr_disable(&(pci_dev->intr_handle));
+       rte_intr_disable(intr_handle);
 
        /* register callback func to eal lib */
-       rte_intr_callback_unregister(&(pci_dev->intr_handle),
-               i40e_dev_interrupt_handler, (void *)dev);
+       rte_intr_callback_unregister(intr_handle,
+                                    i40e_dev_interrupt_handler, dev);
+
+       i40e_rm_ethtype_filter_list(pf);
+       i40e_rm_tunnel_filter_list(pf);
 
        return 0;
 }
@@ -1339,7 +1499,8 @@ void
 i40e_vsi_queues_unbind_intr(struct i40e_vsi *vsi)
 {
        struct rte_eth_dev *dev = vsi->adapter->eth_dev;
-       struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+       struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
        uint16_t msix_vect = vsi->msix_intr;
        uint16_t i;
@@ -1452,7 +1613,8 @@ void
 i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi)
 {
        struct rte_eth_dev *dev = vsi->adapter->eth_dev;
-       struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+       struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
        uint16_t msix_vect = vsi->msix_intr;
        uint16_t nb_msix = RTE_MIN(vsi->nb_msix, intr_handle->nb_efd);
@@ -1523,7 +1685,8 @@ static void
 i40e_vsi_enable_queues_intr(struct i40e_vsi *vsi)
 {
        struct rte_eth_dev *dev = vsi->adapter->eth_dev;
-       struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+       struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
        uint16_t interval = i40e_calc_itr_interval(\
                RTE_LIBRTE_I40E_ITR_INTERVAL);
@@ -1554,7 +1717,8 @@ static void
 i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
 {
        struct rte_eth_dev *dev = vsi->adapter->eth_dev;
-       struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+       struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
        uint16_t msix_intr, i;
 
@@ -1632,6 +1796,8 @@ i40e_phy_conf_link(struct i40e_hw *hw,
 
        /* use get_phy_abilities_resp value for the rest */
        phy_conf.phy_type = phy_ab.phy_type;
+       phy_conf.phy_type_ext = phy_ab.phy_type_ext;
+       phy_conf.fec_config = phy_ab.fec_cfg_curr_mod_ext_info;
        phy_conf.eee_capability = phy_ab.eee_capability;
        phy_conf.eeer = phy_ab.eeer_val;
        phy_conf.low_power_ctrl = phy_ab.d3_lpan;
@@ -1657,8 +1823,7 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)
        struct rte_eth_conf *conf = &dev->data->dev_conf;
 
        speed = i40e_parse_link_speeds(conf->link_speeds);
-       if (!I40E_PHY_TYPE_SUPPORT_25G(hw->phy.phy_types))
-               abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
+       abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
        if (!(conf->link_speeds & ETH_LINK_SPEED_FIXED))
                abilities |= I40E_AQ_PHY_AN_ENABLED;
        abilities |= I40E_AQ_PHY_LINK_ENABLED;
@@ -1679,7 +1844,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct i40e_vsi *main_vsi = pf->main_vsi;
        int ret, i;
-       struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+       struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        uint32_t intr_vector = 0;
 
        hw->adapter_stopped = 0;
@@ -1782,6 +1948,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 */
@@ -1802,7 +1978,8 @@ i40e_dev_stop(struct rte_eth_dev *dev)
        struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
        struct i40e_vsi *main_vsi = pf->main_vsi;
        struct i40e_mirror_rule *p_mirror;
-       struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+       struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        int i;
 
        /* Disable all queues */
@@ -1853,6 +2030,8 @@ i40e_dev_close(struct rte_eth_dev *dev)
 {
        struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        uint32_t reg;
        int i;
 
@@ -1864,7 +2043,7 @@ i40e_dev_close(struct rte_eth_dev *dev)
 
        /* Disable interrupt */
        i40e_pf_disable_irq0(hw);
-       rte_intr_disable(&(dev->pci_dev->intr_handle));
+       rte_intr_disable(intr_handle);
 
        /* shutdown and destroy the HMC */
        i40e_shutdown_lan_hmc(hw);
@@ -1984,8 +2163,7 @@ i40e_dev_set_link_down(struct rte_eth_dev *dev)
        uint8_t abilities = 0;
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-       if (!I40E_PHY_TYPE_SUPPORT_25G(hw->phy.phy_types))
-               abilities = I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
+       abilities = I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
        return i40e_phy_conf_link(hw, abilities, speed);
 }
 
@@ -2000,6 +2178,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 +2187,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;
@@ -2524,6 +2704,7 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
        for (i = 0; i < I40E_NB_ETH_XSTATS; i++) {
                xstats[count].value = *(uint64_t *)(((char *)&hw_stats->eth) +
                        rte_i40e_stats_strings[i].offset);
+               xstats[count].id = count;
                count++;
        }
 
@@ -2531,6 +2712,7 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
        for (i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) {
                xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
                        rte_i40e_hw_port_strings[i].offset);
+               xstats[count].id = count;
                count++;
        }
 
@@ -2540,6 +2722,7 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
                                *(uint64_t *)(((char *)hw_stats) +
                                rte_i40e_rxq_prio_strings[i].offset +
                                (sizeof(uint64_t) * prio));
+                       xstats[count].id = count;
                        count++;
                }
        }
@@ -2550,6 +2733,7 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
                                *(uint64_t *)(((char *)hw_stats) +
                                rte_i40e_txq_prio_strings[i].offset +
                                (sizeof(uint64_t) * prio));
+                       xstats[count].id = count;
                        count++;
                }
        }
@@ -2568,19 +2752,49 @@ i40e_dev_queue_stats_mapping_set(__rte_unused struct rte_eth_dev *dev,
        return -ENOSYS;
 }
 
+static int
+i40e_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
+{
+       struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       u32 full_ver;
+       u8 ver, patch;
+       u16 build;
+       int ret;
+
+       full_ver = hw->nvm.oem_ver;
+       ver = (u8)(full_ver >> 24);
+       build = (u16)((full_ver >> 8) & 0xffff);
+       patch = (u8)(full_ver & 0xff);
+
+       ret = snprintf(fw_version, fw_size,
+                "%d.%d%d 0x%08x %d.%d.%d",
+                ((hw->nvm.version >> 12) & 0xf),
+                ((hw->nvm.version >> 4) & 0xff),
+                (hw->nvm.version & 0xf), hw->nvm.eetrack,
+                ver, build, patch);
+
+       ret += 1; /* add the size of '\0' */
+       if (fw_size < (u32)ret)
+               return ret;
+       else
+               return 0;
+}
+
 static void
 i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
        struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct i40e_vsi *vsi = pf->main_vsi;
+       struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
 
+       dev_info->pci_dev = pci_dev;
        dev_info->max_rx_queues = vsi->nb_qps;
        dev_info->max_tx_queues = vsi->nb_qps;
        dev_info->min_rx_bufsize = I40E_BUF_SIZE_MIN;
        dev_info->max_rx_pktlen = I40E_FRAME_SIZE_MAX;
        dev_info->max_mac_addrs = vsi->max_macaddrs;
-       dev_info->max_vfs = dev->pci_dev->max_vfs;
+       dev_info->max_vfs = pci_dev->max_vfs;
        dev_info->rx_offload_capa =
                DEV_RX_OFFLOAD_VLAN_STRIP |
                DEV_RX_OFFLOAD_QINQ_STRIP |
@@ -2637,6 +2851,8 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
                .nb_max = I40E_MAX_RING_DESC,
                .nb_min = I40E_MIN_RING_DESC,
                .nb_align = I40E_ALIGN_RING_DESC,
+               .nb_seg_max = I40E_TX_MAX_SEG,
+               .nb_mtu_seg_max = I40E_TX_MAX_MTU_SEG,
        };
 
        if (pf->flags & I40E_FLAG_VMDQ) {
@@ -3482,9 +3698,10 @@ i40e_pf_parameter_init(struct rte_eth_dev *dev)
 {
        struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
        struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+       struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
        uint16_t qp_count = 0, vsi_count = 0;
 
-       if (dev->pci_dev->max_vfs && !hw->func_caps.sr_iov_1_1) {
+       if (pci_dev->max_vfs && !hw->func_caps.sr_iov_1_1) {
                PMD_INIT_LOG(ERR, "HW configuration doesn't support SRIOV");
                return -EINVAL;
        }
@@ -3525,10 +3742,10 @@ i40e_pf_parameter_init(struct rte_eth_dev *dev)
 
        /* VF queue/VSI allocation */
        pf->vf_qp_offset = pf->lan_qp_offset + pf->lan_nb_qps;
-       if (hw->func_caps.sr_iov_1_1 && dev->pci_dev->max_vfs) {
+       if (hw->func_caps.sr_iov_1_1 && pci_dev->max_vfs) {
                pf->flags |= I40E_FLAG_SRIOV;
                pf->vf_nb_qps = RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF;
-               pf->vf_num = dev->pci_dev->max_vfs;
+               pf->vf_num = pci_dev->max_vfs;
                PMD_DRV_LOG(DEBUG, "%u VF VSIs, %u queues per VF VSI, "
                            "in total %u queues", pf->vf_num, pf->vf_nb_qps,
                            pf->vf_nb_qps * pf->vf_num);
@@ -4099,7 +4316,7 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
        ret = i40e_aq_get_veb_parameters(hw, veb->seid, NULL, NULL,
                                &veb->stats_idx, NULL, NULL, NULL);
        if (ret != I40E_SUCCESS) {
-               PMD_DRV_LOG(ERR, "Get veb statics index failed, aq_err: %d",
+               PMD_DRV_LOG(ERR, "Get veb statistics index failed, aq_err: %d",
                            hw->aq.asq_last_status);
                goto fail;
        }
@@ -5434,6 +5651,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 +5705,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 +5722,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.
@@ -5543,7 +5735,7 @@ i40e_dev_interrupt_delayed_handler(void *param)
  *  void
  */
 static void
-i40e_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
+i40e_dev_interrupt_handler(struct rte_intr_handle *intr_handle,
                           void *param)
 {
        struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
@@ -5587,34 +5779,10 @@ 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);
-       rte_intr_enable(&(dev->pci_dev->intr_handle));
+       rte_intr_enable(intr_handle);
 }
 
 static int
@@ -6239,18 +6407,14 @@ i40e_parse_hena(uint64_t flags)
                rss_hf |= ETH_RSS_FRAG_IPV4;
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP))
                rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
-#ifdef X722_SUPPORT
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK))
                rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
-#endif
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP))
                rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
-#ifdef X722_SUPPORT
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP))
                rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP))
                rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
-#endif
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP))
                rss_hf |= ETH_RSS_NONFRAG_IPV4_SCTP;
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER))
@@ -6259,18 +6423,14 @@ i40e_parse_hena(uint64_t flags)
                rss_hf |= ETH_RSS_FRAG_IPV6;
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP))
                rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
-#ifdef X722_SUPPORT
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK))
                rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
-#endif
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP))
                rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
-#ifdef X722_SUPPORT
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP))
                rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP))
                rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
-#endif
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP))
                rss_hf |= ETH_RSS_NONFRAG_IPV6_SCTP;
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER))
@@ -6468,6 +6628,85 @@ i40e_dev_get_filter_type(uint16_t filter_type, uint16_t *flag)
        return 0;
 }
 
+/* Convert tunnel filter structure */
+static int
+i40e_tunnel_filter_convert(struct i40e_aqc_add_remove_cloud_filters_element_data
+                          *cld_filter,
+                          struct i40e_tunnel_filter *tunnel_filter)
+{
+       ether_addr_copy((struct ether_addr *)&cld_filter->outer_mac,
+                       (struct ether_addr *)&tunnel_filter->input.outer_mac);
+       ether_addr_copy((struct ether_addr *)&cld_filter->inner_mac,
+                       (struct ether_addr *)&tunnel_filter->input.inner_mac);
+       tunnel_filter->input.inner_vlan = cld_filter->inner_vlan;
+       tunnel_filter->input.flags = cld_filter->flags;
+       tunnel_filter->input.tenant_id = cld_filter->tenant_id;
+       tunnel_filter->queue = cld_filter->queue_number;
+
+       return 0;
+}
+
+/* Check if there exists the tunnel filter */
+struct i40e_tunnel_filter *
+i40e_sw_tunnel_filter_lookup(struct i40e_tunnel_rule *tunnel_rule,
+                            const struct i40e_tunnel_filter_input *input)
+{
+       int ret;
+
+       ret = rte_hash_lookup(tunnel_rule->hash_table, (const void *)input);
+       if (ret < 0)
+               return NULL;
+
+       return tunnel_rule->hash_map[ret];
+}
+
+/* Add a tunnel filter into the SW list */
+static int
+i40e_sw_tunnel_filter_insert(struct i40e_pf *pf,
+                            struct i40e_tunnel_filter *tunnel_filter)
+{
+       struct i40e_tunnel_rule *rule = &pf->tunnel;
+       int ret;
+
+       ret = rte_hash_add_key(rule->hash_table, &tunnel_filter->input);
+       if (ret < 0) {
+               PMD_DRV_LOG(ERR,
+                           "Failed to insert tunnel filter to hash table %d!",
+                           ret);
+               return ret;
+       }
+       rule->hash_map[ret] = tunnel_filter;
+
+       TAILQ_INSERT_TAIL(&rule->tunnel_list, tunnel_filter, rules);
+
+       return 0;
+}
+
+/* Delete a tunnel filter from the SW list */
+int
+i40e_sw_tunnel_filter_del(struct i40e_pf *pf,
+                         struct i40e_tunnel_filter_input *input)
+{
+       struct i40e_tunnel_rule *rule = &pf->tunnel;
+       struct i40e_tunnel_filter *tunnel_filter;
+       int ret;
+
+       ret = rte_hash_del_key(rule->hash_table, input);
+       if (ret < 0) {
+               PMD_DRV_LOG(ERR,
+                           "Failed to delete tunnel filter to hash table %d!",
+                           ret);
+               return ret;
+       }
+       tunnel_filter = rule->hash_map[ret];
+       rule->hash_map[ret] = NULL;
+
+       TAILQ_REMOVE(&rule->tunnel_list, tunnel_filter, rules);
+       rte_free(tunnel_filter);
+
+       return 0;
+}
+
 static int
 i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
                        struct rte_eth_tunnel_filter_conf *tunnel_filter,
@@ -6483,6 +6722,9 @@ i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
        struct i40e_vsi *vsi = pf->main_vsi;
        struct i40e_aqc_add_remove_cloud_filters_element_data  *cld_filter;
        struct i40e_aqc_add_remove_cloud_filters_element_data  *pfilter;
+       struct i40e_tunnel_rule *tunnel_rule = &pf->tunnel;
+       struct i40e_tunnel_filter *tunnel, *node;
+       struct i40e_tunnel_filter check_filter; /* Check if filter exists */
 
        cld_filter = rte_zmalloc("tunnel_filter",
                sizeof(struct i40e_aqc_add_remove_cloud_filters_element_data),
@@ -6545,11 +6787,38 @@ i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
        pfilter->tenant_id = rte_cpu_to_le_32(tunnel_filter->tenant_id);
        pfilter->queue_number = rte_cpu_to_le_16(tunnel_filter->queue_id);
 
-       if (add)
+       /* Check if there is the filter in SW list */
+       memset(&check_filter, 0, sizeof(check_filter));
+       i40e_tunnel_filter_convert(cld_filter, &check_filter);
+       node = i40e_sw_tunnel_filter_lookup(tunnel_rule, &check_filter.input);
+       if (add && node) {
+               PMD_DRV_LOG(ERR, "Conflict with existing tunnel rules!");
+               return -EINVAL;
+       }
+
+       if (!add && !node) {
+               PMD_DRV_LOG(ERR, "There's no corresponding tunnel filter!");
+               return -EINVAL;
+       }
+
+       if (add) {
                ret = i40e_aq_add_cloud_filters(hw, vsi->seid, cld_filter, 1);
-       else
+               if (ret < 0) {
+                       PMD_DRV_LOG(ERR, "Failed to add a tunnel filter.");
+                       return ret;
+               }
+               tunnel = rte_zmalloc("tunnel_filter", sizeof(*tunnel), 0);
+               rte_memcpy(tunnel, &check_filter, sizeof(check_filter));
+               ret = i40e_sw_tunnel_filter_insert(pf, tunnel);
+       } else {
                ret = i40e_aq_remove_cloud_filters(hw, vsi->seid,
-                                               cld_filter, 1);
+                                                  cld_filter, 1);
+               if (ret < 0) {
+                       PMD_DRV_LOG(ERR, "Failed to delete a tunnel filter.");
+                       return ret;
+               }
+               ret = i40e_sw_tunnel_filter_del(pf, &node->input);
+       }
 
        rte_free(cld_filter);
        return ret;
@@ -7142,7 +7411,6 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
                        I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
                        I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
                        I40E_INSET_FLEX_PAYLOAD,
-#ifdef X722_SUPPORT
                [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] =
                        I40E_INSET_DMAC | I40E_INSET_SMAC |
                        I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
@@ -7161,7 +7429,6 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
                        I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
                        I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
                        I40E_INSET_FLEX_PAYLOAD,
-#endif
                [I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
                        I40E_INSET_DMAC | I40E_INSET_SMAC |
                        I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
@@ -7171,7 +7438,6 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
                        I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
                        I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
                        I40E_INSET_TCP_FLAGS | I40E_INSET_FLEX_PAYLOAD,
-#ifdef X722_SUPPORT
                [I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] =
                        I40E_INSET_DMAC | I40E_INSET_SMAC |
                        I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
@@ -7181,7 +7447,6 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
                        I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
                        I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
                        I40E_INSET_TCP_FLAGS | I40E_INSET_FLEX_PAYLOAD,
-#endif
                [I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
                        I40E_INSET_DMAC | I40E_INSET_SMAC |
                        I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
@@ -7215,7 +7480,6 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
                        I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC |
                        I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT |
                        I40E_INSET_DST_PORT | I40E_INSET_FLEX_PAYLOAD,
-#ifdef X722_SUPPORT
                [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] =
                        I40E_INSET_DMAC | I40E_INSET_SMAC |
                        I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
@@ -7234,7 +7498,6 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
                        I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT |
                        I40E_INSET_DST_PORT | I40E_INSET_TCP_FLAGS |
                        I40E_INSET_FLEX_PAYLOAD,
-#endif
                [I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
                        I40E_INSET_DMAC | I40E_INSET_SMAC |
                        I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
@@ -7244,7 +7507,6 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
                        I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT |
                        I40E_INSET_DST_PORT | I40E_INSET_TCP_FLAGS |
                        I40E_INSET_FLEX_PAYLOAD,
-#ifdef X722_SUPPORT
                [I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] =
                        I40E_INSET_DMAC | I40E_INSET_SMAC |
                        I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
@@ -7254,7 +7516,6 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
                        I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT |
                        I40E_INSET_DST_PORT | I40E_INSET_TCP_FLAGS |
                        I40E_INSET_FLEX_PAYLOAD,
-#endif
                [I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
                        I40E_INSET_DMAC | I40E_INSET_SMAC |
                        I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
@@ -7294,7 +7555,6 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
                I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
                I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
                I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
-#ifdef X722_SUPPORT
                [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] =
                I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
                I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
@@ -7305,19 +7565,16 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
                I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
                I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
                I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
-#endif
                [I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
                I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
                I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
                I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
                I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
-#ifdef X722_SUPPORT
                [I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] =
                I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
                I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
                I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
                I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
-#endif
                [I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
                I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
                I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
@@ -7339,7 +7596,6 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
                I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
                I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
                I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
-#ifdef X722_SUPPORT
                [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] =
                I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
                I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
@@ -7350,19 +7606,16 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
                I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
                I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
                I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
-#endif
                [I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
                I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
                I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
                I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
                I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
-#ifdef X722_SUPPORT
                [I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] =
                I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
                I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
                I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
                I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
-#endif
                [I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
                I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
                I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
@@ -7415,22 +7668,18 @@ i40e_get_default_input_set(uint16_t pctype)
                [I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
                        I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
                        I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
-#ifdef X722_SUPPORT
                [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] =
                        I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
                        I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
                [I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP] =
                        I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
                        I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
-#endif
                [I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
                        I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
                        I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
-#ifdef X722_SUPPORT
                [I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] =
                        I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
                        I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
-#endif
                [I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
                        I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
                        I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
@@ -7442,22 +7691,18 @@ i40e_get_default_input_set(uint16_t pctype)
                [I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
                        I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
                        I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
-#ifdef X722_SUPPORT
                [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] =
                        I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
                        I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
                [I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP] =
                        I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
                        I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
-#endif
                [I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
                        I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
                        I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
-#ifdef X722_SUPPORT
                [I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] =
                        I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
                        I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
-#endif
                [I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
                        I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
                        I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
@@ -8027,6 +8272,82 @@ i40e_hash_filter_ctrl(struct rte_eth_dev *dev,
        return ret;
 }
 
+/* Convert ethertype filter structure */
+static int
+i40e_ethertype_filter_convert(const struct rte_eth_ethertype_filter *input,
+                             struct i40e_ethertype_filter *filter)
+{
+       rte_memcpy(&filter->input.mac_addr, &input->mac_addr, ETHER_ADDR_LEN);
+       filter->input.ether_type = input->ether_type;
+       filter->flags = input->flags;
+       filter->queue = input->queue;
+
+       return 0;
+}
+
+/* Check if there exists the ehtertype filter */
+struct i40e_ethertype_filter *
+i40e_sw_ethertype_filter_lookup(struct i40e_ethertype_rule *ethertype_rule,
+                               const struct i40e_ethertype_filter_input *input)
+{
+       int ret;
+
+       ret = rte_hash_lookup(ethertype_rule->hash_table, (const void *)input);
+       if (ret < 0)
+               return NULL;
+
+       return ethertype_rule->hash_map[ret];
+}
+
+/* Add ethertype filter in SW list */
+static int
+i40e_sw_ethertype_filter_insert(struct i40e_pf *pf,
+                               struct i40e_ethertype_filter *filter)
+{
+       struct i40e_ethertype_rule *rule = &pf->ethertype;
+       int ret;
+
+       ret = rte_hash_add_key(rule->hash_table, &filter->input);
+       if (ret < 0) {
+               PMD_DRV_LOG(ERR,
+                           "Failed to insert ethertype filter"
+                           " to hash table %d!",
+                           ret);
+               return ret;
+       }
+       rule->hash_map[ret] = filter;
+
+       TAILQ_INSERT_TAIL(&rule->ethertype_list, filter, rules);
+
+       return 0;
+}
+
+/* Delete ethertype filter in SW list */
+int
+i40e_sw_ethertype_filter_del(struct i40e_pf *pf,
+                            struct i40e_ethertype_filter_input *input)
+{
+       struct i40e_ethertype_rule *rule = &pf->ethertype;
+       struct i40e_ethertype_filter *filter;
+       int ret;
+
+       ret = rte_hash_del_key(rule->hash_table, input);
+       if (ret < 0) {
+               PMD_DRV_LOG(ERR,
+                           "Failed to delete ethertype filter"
+                           " to hash table %d!",
+                           ret);
+               return ret;
+       }
+       filter = rule->hash_map[ret];
+       rule->hash_map[ret] = NULL;
+
+       TAILQ_REMOVE(&rule->ethertype_list, filter, rules);
+       rte_free(filter);
+
+       return 0;
+}
+
 /*
  * Configure ethertype filter, which can director packet by filtering
  * with mac address and ether_type or only ether_type
@@ -8037,6 +8358,9 @@ i40e_ethertype_filter_set(struct i40e_pf *pf,
                        bool add)
 {
        struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+       struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype;
+       struct i40e_ethertype_filter *ethertype_filter, *node;
+       struct i40e_ethertype_filter check_filter;
        struct i40e_control_filter_stats stats;
        uint16_t flags = 0;
        int ret;
@@ -8055,6 +8379,21 @@ i40e_ethertype_filter_set(struct i40e_pf *pf,
                PMD_DRV_LOG(WARNING, "filter vlan ether_type in first tag is"
                        " not supported.");
 
+       /* Check if there is the filter in SW list */
+       memset(&check_filter, 0, sizeof(check_filter));
+       i40e_ethertype_filter_convert(filter, &check_filter);
+       node = i40e_sw_ethertype_filter_lookup(ethertype_rule,
+                                              &check_filter.input);
+       if (add && node) {
+               PMD_DRV_LOG(ERR, "Conflict with existing ethertype rules!");
+               return -EINVAL;
+       }
+
+       if (!add && !node) {
+               PMD_DRV_LOG(ERR, "There's no corresponding ethertype filter!");
+               return -EINVAL;
+       }
+
        if (!(filter->flags & RTE_ETHTYPE_FLAGS_MAC))
                flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC;
        if (filter->flags & RTE_ETHTYPE_FLAGS_DROP)
@@ -8075,7 +8414,19 @@ i40e_ethertype_filter_set(struct i40e_pf *pf,
                         stats.mac_etype_free, stats.etype_free);
        if (ret < 0)
                return -ENOSYS;
-       return 0;
+
+       /* Add or delete a filter in SW list */
+       if (add) {
+               ethertype_filter = rte_zmalloc("ethertype_filter",
+                                      sizeof(*ethertype_filter), 0);
+               rte_memcpy(ethertype_filter, &check_filter,
+                          sizeof(check_filter));
+               ret = i40e_sw_ethertype_filter_insert(pf, ethertype_filter);
+       } else {
+               ret = i40e_sw_ethertype_filter_del(pf, &node->input);
+       }
+
+       return ret;
 }
 
 /*
@@ -8165,10 +8516,11 @@ i40e_dev_filter_ctrl(struct rte_eth_dev *dev,
 static void
 i40e_enable_extended_tag(struct rte_eth_dev *dev)
 {
+       struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
        uint32_t buf = 0;
        int ret;
 
-       ret = rte_eal_pci_read_config(dev->pci_dev, &buf, sizeof(buf),
+       ret = rte_eal_pci_read_config(pci_dev, &buf, sizeof(buf),
                                      PCI_DEV_CAP_REG);
        if (ret < 0) {
                PMD_DRV_LOG(ERR, "Failed to read PCI offset 0x%x",
@@ -8181,7 +8533,7 @@ i40e_enable_extended_tag(struct rte_eth_dev *dev)
        }
 
        buf = 0;
-       ret = rte_eal_pci_read_config(dev->pci_dev, &buf, sizeof(buf),
+       ret = rte_eal_pci_read_config(pci_dev, &buf, sizeof(buf),
                                      PCI_DEV_CTRL_REG);
        if (ret < 0) {
                PMD_DRV_LOG(ERR, "Failed to read PCI offset 0x%x",
@@ -8193,7 +8545,7 @@ i40e_enable_extended_tag(struct rte_eth_dev *dev)
                return;
        }
        buf |= PCI_DEV_CTRL_EXT_TAG_MASK;
-       ret = rte_eal_pci_write_config(dev->pci_dev, &buf, sizeof(buf),
+       ret = rte_eal_pci_write_config(pci_dev, &buf, sizeof(buf),
                                       PCI_DEV_CTRL_REG);
        if (ret < 0) {
                PMD_DRV_LOG(ERR, "Failed to write PCI offset 0x%x",
@@ -8256,18 +8608,14 @@ i40e_pctype_to_flowtype(enum i40e_filter_pctype pctype)
                [I40E_FILTER_PCTYPE_FRAG_IPV4] = RTE_ETH_FLOW_FRAG_IPV4,
                [I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
                        RTE_ETH_FLOW_NONFRAG_IPV4_UDP,
-#ifdef X722_SUPPORT
                [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] =
                        RTE_ETH_FLOW_NONFRAG_IPV4_UDP,
                [I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP] =
                        RTE_ETH_FLOW_NONFRAG_IPV4_UDP,
-#endif
                [I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
                        RTE_ETH_FLOW_NONFRAG_IPV4_TCP,
-#ifdef X722_SUPPORT
                [I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] =
                        RTE_ETH_FLOW_NONFRAG_IPV4_TCP,
-#endif
                [I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
                        RTE_ETH_FLOW_NONFRAG_IPV4_SCTP,
                [I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
@@ -8275,18 +8623,14 @@ i40e_pctype_to_flowtype(enum i40e_filter_pctype pctype)
                [I40E_FILTER_PCTYPE_FRAG_IPV6] = RTE_ETH_FLOW_FRAG_IPV6,
                [I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
                        RTE_ETH_FLOW_NONFRAG_IPV6_UDP,
-#ifdef X722_SUPPORT
                [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] =
                        RTE_ETH_FLOW_NONFRAG_IPV6_UDP,
                [I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP] =
                        RTE_ETH_FLOW_NONFRAG_IPV6_UDP,
-#endif
                [I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
                        RTE_ETH_FLOW_NONFRAG_IPV6_TCP,
-#ifdef X722_SUPPORT
                [I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] =
                        RTE_ETH_FLOW_NONFRAG_IPV6_TCP,
-#endif
                [I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
                        RTE_ETH_FLOW_NONFRAG_IPV6_SCTP,
                [I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
@@ -9432,17 +9776,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 +9811,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;
                }
@@ -9600,7 +9940,8 @@ i40e_dev_get_dcb_info(struct rte_eth_dev *dev,
 static int
 i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
-       struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+       struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        uint16_t interval =
                i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL);
@@ -9625,7 +9966,7 @@ i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
                                I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT));
 
        I40E_WRITE_FLUSH(hw);
-       rte_intr_enable(&dev->pci_dev->intr_handle);
+       rte_intr_enable(&pci_dev->intr_handle);
 
        return 0;
 }
@@ -9633,7 +9974,8 @@ i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
 static int
 i40e_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
-       struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+       struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        uint16_t msix_intr;