net: add rte prefix to ether structures
[dpdk.git] / drivers / net / i40e / i40e_ethdev.c
index 014bfce..85fdf35 100644 (file)
@@ -24,7 +24,6 @@
 #include <rte_memcpy.h>
 #include <rte_alarm.h>
 #include <rte_dev.h>
-#include <rte_eth_ctrl.h>
 #include <rte_tailq.h>
 #include <rte_hash_crc.h>
 
@@ -42,6 +41,9 @@
 
 #define ETH_I40E_FLOATING_VEB_ARG      "enable_floating_veb"
 #define ETH_I40E_FLOATING_VEB_LIST_ARG "floating_veb_list"
+#define ETH_I40E_SUPPORT_MULTI_DRIVER  "support-multi-driver"
+#define ETH_I40E_QUEUE_NUM_PER_VF_ARG  "queue-num-per-vf"
+#define ETH_I40E_USE_LATEST_VEC        "use-latest-supported-vec"
 
 #define I40E_CLEAR_PXE_WAIT_MS     200
 
@@ -263,7 +265,7 @@ static int i40e_flow_ctrl_set(struct rte_eth_dev *dev,
 static int i40e_priority_flow_ctrl_set(struct rte_eth_dev *dev,
                                       struct rte_eth_pfc_conf *pfc_conf);
 static int i40e_macaddr_add(struct rte_eth_dev *dev,
-                           struct ether_addr *mac_addr,
+                           struct rte_ether_addr *mac_addr,
                            uint32_t index,
                            uint32_t pool);
 static void i40e_macaddr_remove(struct rte_eth_dev *dev, uint32_t index);
@@ -290,6 +292,7 @@ static void i40e_stat_update_48(struct i40e_hw *hw,
                               uint64_t *stat);
 static void i40e_pf_config_irq0(struct i40e_hw *hw, bool no_queue);
 static void i40e_dev_interrupt_handler(void *param);
+static void i40e_dev_alarm_handler(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);
@@ -376,7 +379,7 @@ static int i40e_get_module_eeprom(struct rte_eth_dev *dev,
                                  struct rte_dev_eeprom_info *info);
 
 static int i40e_set_default_mac_addr(struct rte_eth_dev *dev,
-                                     struct ether_addr *mac_addr);
+                                     struct rte_ether_addr *mac_addr);
 
 static int i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 
@@ -387,7 +390,7 @@ 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_rm_cloud_filt_elem_ext *cld_filter,
+       struct i40e_aqc_cloud_filters_element_bb *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);
@@ -401,6 +404,14 @@ static void i40e_notify_all_vfs_link_status(struct rte_eth_dev *dev);
 int i40e_logtype_init;
 int i40e_logtype_driver;
 
+static const char *const valid_keys[] = {
+       ETH_I40E_FLOATING_VEB_ARG,
+       ETH_I40E_FLOATING_VEB_LIST_ARG,
+       ETH_I40E_SUPPORT_MULTI_DRIVER,
+       ETH_I40E_QUEUE_NUM_PER_VF_ARG,
+       ETH_I40E_USE_LATEST_VEC,
+       NULL};
+
 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) },
@@ -422,6 +433,9 @@ static const struct rte_pci_id pci_id_i40e_map[] = {
        { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_1G_BASE_T_X722) },
        { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T_X722) },
        { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_I_X722) },
+       { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_X710_N3000) },
+       { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_XXV710_N3000) },
+       { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T_BC) },
        { .vendor_id = 0, /* sentinel */ },
 };
 
@@ -698,12 +712,16 @@ i40e_write_global_rx_ctl(struct i40e_hw *hw, uint32_t reg_addr,
                         uint32_t reg_val)
 {
        uint32_t ori_reg_val;
+       struct rte_eth_dev *dev;
 
        ori_reg_val = i40e_read_rx_ctl(hw, reg_addr);
+       dev = ((struct i40e_adapter *)hw->back)->eth_dev;
        i40e_write_rx_ctl(hw, reg_addr, reg_val);
-       PMD_DRV_LOG(DEBUG,
-                   "Global register [0x%08x] original: 0x%08x, after: 0x%08x",
-                   reg_addr, ori_reg_val, reg_val);
+       if (ori_reg_val != reg_val)
+               PMD_DRV_LOG(WARNING,
+                           "i40e device %s changed global register [0x%08x]."
+                           " original: 0x%08x, new: 0x%08x",
+                           dev->device->name, reg_addr, ori_reg_val, reg_val);
 }
 
 RTE_PMD_REGISTER_PCI(net_i40e, rte_i40e_pmd);
@@ -730,7 +748,6 @@ static inline void i40e_GLQF_reg_init(struct i40e_hw *hw)
         */
        I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(40), 0x00000029);
        I40E_WRITE_GLB_REG(hw, I40E_GLQF_PIT(9), 0x00009420);
-       i40e_global_cfg_warning(I40E_WARNING_QINQ_PARSER);
 }
 
 static inline void i40e_config_automask(struct i40e_pf *pf)
@@ -849,7 +866,7 @@ config_vf_floating_veb(struct rte_devargs *devargs,
        if (devargs == NULL)
                return;
 
-       kvlist = rte_kvargs_parse(devargs->args, NULL);
+       kvlist = rte_kvargs_parse(devargs->args, valid_keys);
        if (kvlist == NULL)
                return;
 
@@ -890,7 +907,7 @@ is_floating_veb_supported(struct rte_devargs *devargs)
        if (devargs == NULL)
                return 0;
 
-       kvlist = rte_kvargs_parse(devargs->args, NULL);
+       kvlist = rte_kvargs_parse(devargs->args, valid_keys);
        if (kvlist == NULL)
                return 0;
 
@@ -1097,8 +1114,6 @@ i40e_init_queue_region_conf(struct rte_eth_dev *dev)
        memset(info, 0, sizeof(struct i40e_queue_regions));
 }
 
-#define ETH_I40E_SUPPORT_MULTI_DRIVER  "support-multi-driver"
-
 static int
 i40e_parse_multi_drv_handler(__rte_unused const char *key,
                               const char *value,
@@ -1130,9 +1145,8 @@ static int
 i40e_support_multi_driver(struct rte_eth_dev *dev)
 {
        struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-       static const char *const valid_keys[] = {
-               ETH_I40E_SUPPORT_MULTI_DRIVER, NULL};
        struct rte_kvargs *kvlist;
+       int kvargs_count;
 
        /* Enable global configuration by default */
        pf->support_multi_driver = false;
@@ -1144,7 +1158,13 @@ i40e_support_multi_driver(struct rte_eth_dev *dev)
        if (!kvlist)
                return -EINVAL;
 
-       if (rte_kvargs_count(kvlist, ETH_I40E_SUPPORT_MULTI_DRIVER) > 1)
+       kvargs_count = rte_kvargs_count(kvlist, ETH_I40E_SUPPORT_MULTI_DRIVER);
+       if (!kvargs_count) {
+               rte_kvargs_free(kvlist);
+               return 0;
+       }
+
+       if (kvargs_count > 1)
                PMD_DRV_LOG(WARNING, "More than one argument \"%s\" and only "
                            "the first invalid or last valid one is used !",
                            ETH_I40E_SUPPORT_MULTI_DRIVER);
@@ -1165,6 +1185,7 @@ i40e_aq_debug_write_global_register(struct i40e_hw *hw,
                                    struct i40e_asq_cmd_details *cmd_details)
 {
        uint64_t ori_reg_val;
+       struct rte_eth_dev *dev;
        int ret;
 
        ret = i40e_aq_debug_read_register(hw, reg_addr, &ori_reg_val, NULL);
@@ -1174,15 +1195,77 @@ i40e_aq_debug_write_global_register(struct i40e_hw *hw,
                            reg_addr);
                return -EIO;
        }
+       dev = ((struct i40e_adapter *)hw->back)->eth_dev;
 
-       PMD_DRV_LOG(DEBUG,
-                   "Global register [0x%08x] original: 0x%"PRIx64
-                   ", after: 0x%"PRIx64,
-                   reg_addr, ori_reg_val, reg_val);
+       if (ori_reg_val != reg_val)
+               PMD_DRV_LOG(WARNING,
+                           "i40e device %s changed global register [0x%08x]."
+                           " original: 0x%"PRIx64", after: 0x%"PRIx64,
+                           dev->device->name, reg_addr, ori_reg_val, reg_val);
 
        return i40e_aq_debug_write_register(hw, reg_addr, reg_val, cmd_details);
 }
 
+static int
+i40e_parse_latest_vec_handler(__rte_unused const char *key,
+                               const char *value,
+                               void *opaque)
+{
+       struct i40e_adapter *ad;
+       int use_latest_vec;
+
+       ad = (struct i40e_adapter *)opaque;
+
+       use_latest_vec = atoi(value);
+
+       if (use_latest_vec != 0 && use_latest_vec != 1)
+               PMD_DRV_LOG(WARNING, "Value should be 0 or 1, set it as 1!");
+
+       ad->use_latest_vec = (uint8_t)use_latest_vec;
+
+       return 0;
+}
+
+static int
+i40e_use_latest_vec(struct rte_eth_dev *dev)
+{
+       struct i40e_adapter *ad =
+               I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+       struct rte_kvargs *kvlist;
+       int kvargs_count;
+
+       ad->use_latest_vec = false;
+
+       if (!dev->device->devargs)
+               return 0;
+
+       kvlist = rte_kvargs_parse(dev->device->devargs->args, valid_keys);
+       if (!kvlist)
+               return -EINVAL;
+
+       kvargs_count = rte_kvargs_count(kvlist, ETH_I40E_USE_LATEST_VEC);
+       if (!kvargs_count) {
+               rte_kvargs_free(kvlist);
+               return 0;
+       }
+
+       if (kvargs_count > 1)
+               PMD_DRV_LOG(WARNING, "More than one argument \"%s\" and only "
+                           "the first invalid or last valid one is used !",
+                           ETH_I40E_USE_LATEST_VEC);
+
+       if (rte_kvargs_process(kvlist, ETH_I40E_USE_LATEST_VEC,
+                               i40e_parse_latest_vec_handler, ad) < 0) {
+               rte_kvargs_free(kvlist);
+               return -EINVAL;
+       }
+
+       rte_kvargs_free(kvlist);
+       return 0;
+}
+
+#define I40E_ALARM_INTERVAL 50000 /* us */
+
 static int
 eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused)
 {
@@ -1192,7 +1275,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused)
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct i40e_vsi *vsi;
        int ret;
-       uint32_t len;
+       uint32_t len, val;
        uint8_t aq_fail = 0;
 
        PMD_INIT_FUNC_TRACE();
@@ -1235,16 +1318,32 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused)
        hw->bus.device = pci_dev->addr.devid;
        hw->bus.func = pci_dev->addr.function;
        hw->adapter_stopped = 0;
+       hw->adapter_closed = 0;
+
+       /*
+        * Switch Tag value should not be identical to either the First Tag
+        * or Second Tag values. So set something other than common Ethertype
+        * for internal switching.
+        */
+       hw->switch_tag = 0xffff;
+
+       val = I40E_READ_REG(hw, I40E_GL_FWSTS);
+       if (val & I40E_GL_FWSTS_FWS1B_MASK) {
+               PMD_INIT_LOG(ERR, "\nERROR: "
+                       "Firmware recovery mode detected. Limiting functionality.\n"
+                       "Refer to the Intel(R) Ethernet Adapters and Devices "
+                       "User Guide for details on firmware recovery mode.");
+               return -EIO;
+       }
 
        /* Check if need to support multi-driver */
        i40e_support_multi_driver(dev);
+       /* Check if users want the latest supported vec path */
+       i40e_use_latest_vec(dev);
 
        /* Make sure all is clean before doing PF reset */
        i40e_clear_hw(hw);
 
-       /* Initialize the hardware */
-       i40e_hw_init(dev);
-
        /* Reset here to make sure all is clean for each PF */
        ret = i40e_pf_reset(hw);
        if (ret) {
@@ -1259,6 +1358,23 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused)
                return ret;
        }
 
+       /* Initialize the parameters for adminq */
+       i40e_init_adminq_parameter(hw);
+       ret = i40e_init_adminq(hw);
+       if (ret != I40E_SUCCESS) {
+               PMD_INIT_LOG(ERR, "Failed to init adminq: %d", ret);
+               return -EIO;
+       }
+       PMD_INIT_LOG(INFO, "FW %d.%d API %d.%d NVM %02d.%02d.%02d eetrack %04x",
+                    hw->aq.fw_maj_ver, hw->aq.fw_min_ver,
+                    hw->aq.api_maj_ver, hw->aq.api_min_ver,
+                    ((hw->nvm.version >> 12) & 0xf),
+                    ((hw->nvm.version >> 4) & 0xff),
+                    (hw->nvm.version & 0xf), hw->nvm.eetrack);
+
+       /* Initialize the hardware */
+       i40e_hw_init(dev);
+
        i40e_config_automask(pf);
 
        i40e_set_default_pctype_table(dev);
@@ -1274,20 +1390,6 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused)
        /* Initialize the input set for filters (hash and fd) to default value */
        i40e_filter_input_set_init(pf);
 
-       /* Initialize the parameters for adminq */
-       i40e_init_adminq_parameter(hw);
-       ret = i40e_init_adminq(hw);
-       if (ret != I40E_SUCCESS) {
-               PMD_INIT_LOG(ERR, "Failed to init adminq: %d", ret);
-               return -EIO;
-       }
-       PMD_INIT_LOG(INFO, "FW %d.%d API %d.%d NVM %02d.%02d.%02d eetrack %04x",
-                    hw->aq.fw_maj_ver, hw->aq.fw_min_ver,
-                    hw->aq.api_maj_ver, hw->aq.api_min_ver,
-                    ((hw->nvm.version >> 12) & 0xf),
-                    ((hw->nvm.version >> 4) & 0xff),
-                    (hw->nvm.version & 0xf), hw->nvm.eetrack);
-
        /* initialise the L3_MAP register */
        if (!pf->support_multi_driver) {
                ret = i40e_aq_debug_write_global_register(hw,
@@ -1299,7 +1401,6 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused)
                PMD_INIT_LOG(DEBUG,
                             "Global register 0x%08x is changed with 0x28",
                             I40E_GLQF_L3_MAP(40));
-               i40e_global_cfg_warning(I40E_WARNING_QINQ_CLOUD_FILTER);
        }
 
        /* Need the special FW version to support floating VEB */
@@ -1368,8 +1469,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused)
                goto err_get_mac_addr;
        }
        /* Copy the permanent MAC address */
-       ether_addr_copy((struct ether_addr *) hw->mac.addr,
-                       (struct ether_addr *) hw->mac.perm_addr);
+       ether_addr_copy((struct rte_ether_addr *)hw->mac.addr,
+                       (struct rte_ether_addr *)hw->mac.perm_addr);
 
        /* Disable flow control */
        hw->fc.requested_mode = I40E_FC_NONE;
@@ -1394,9 +1495,6 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused)
                goto err_setup_pf_switch;
        }
 
-       /* reset all stats of the device, including pf and main vsi */
-       i40e_dev_stats_reset(dev);
-
        vsi = pf->main_vsi;
 
        /* Disable double vlan by default */
@@ -1423,7 +1521,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused)
                        "Failed to allocated memory for storing mac address");
                goto err_mac_alloc;
        }
-       ether_addr_copy((struct ether_addr *)hw->mac.perm_addr,
+       ether_addr_copy((struct rte_ether_addr *)hw->mac.perm_addr,
                                        &dev->data->mac_addrs[0]);
 
        /* Init dcb to sw mode by default */
@@ -1491,6 +1589,9 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused)
        memset(&pf->rss_info, 0,
                sizeof(struct i40e_rte_flow_rss_conf));
 
+       /* reset all stats of the device, including pf and main vsi */
+       i40e_dev_stats_reset(dev);
+
        return 0;
 
 err_init_fdir_filter_list:
@@ -1586,7 +1687,6 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
        I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(33), 0x00000000);
        I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(34), 0x00000000);
        I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(35), 0x00000000);
-       i40e_global_cfg_warning(I40E_WARNING_DIS_FLX_PLD);
 }
 
 static int
@@ -1616,7 +1716,7 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev)
        if (ret)
                PMD_INIT_LOG(WARNING, "failed to free switch domain: %d", ret);
 
-       if (hw->adapter_stopped == 0)
+       if (hw->adapter_closed == 0)
                i40e_dev_close(dev);
 
        dev->dev_ops = NULL;
@@ -1640,9 +1740,6 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev)
        /* uninitialize pf host driver */
        i40e_pf_host_uninit(dev);
 
-       rte_free(dev->data->mac_addrs);
-       dev->data->mac_addrs = NULL;
-
        /* disable uio intr before callback unregister */
        rte_intr_disable(intr_handle);
 
@@ -1699,6 +1796,10 @@ i40e_dev_configure(struct rte_eth_dev *dev)
        ad->tx_simple_allowed = true;
        ad->tx_vec_allowed = true;
 
+       /* Only legacy filter API needs the following fdir config. So when the
+        * legacy filter API is deprecated, the following codes should also be
+        * removed.
+        */
        if (dev->data->dev_conf.fdir_conf.mode == RTE_FDIR_MODE_PERFECT) {
                ret = i40e_fdir_setup(pf);
                if (ret != I40E_SUCCESS) {
@@ -1756,7 +1857,11 @@ err_dcb:
        rte_free(pf->vmdq);
        pf->vmdq = NULL;
 err:
-       /* need to release fdir resource if exists */
+       /* Need to release fdir resource if exists.
+        * Only legacy filter API needs the following fdir config. So when the
+        * legacy filter API is deprecated, the following code should also be
+        * removed.
+        */
        i40e_fdir_teardown(pf);
        return ret;
 }
@@ -1829,8 +1934,7 @@ __vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t msix_vect,
        /* Write first RX queue to Link list register as the head element */
        if (vsi->type != I40E_VSI_SRIOV) {
                uint16_t interval =
-                       i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL, 1,
-                                              pf->support_multi_driver);
+                       i40e_calc_itr_interval(1, pf->support_multi_driver);
 
                if (msix_vect == I40E_MISC_VEC_ID) {
                        I40E_WRITE_REG(hw, I40E_PFINT_LNKLST0,
@@ -2026,27 +2130,40 @@ i40e_phy_conf_link(struct i40e_hw *hw,
        struct i40e_aq_get_phy_abilities_resp phy_ab;
        struct i40e_aq_set_phy_config phy_conf;
        enum i40e_aq_phy_type cnt;
+       uint8_t avail_speed;
        uint32_t phy_type_mask = 0;
 
        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_25GB |
-                       I40E_LINK_SPEED_10GB |
-                       I40E_LINK_SPEED_1GB |
-                       I40E_LINK_SPEED_100MB;
        int ret = -ENOTSUP;
 
+       /* To get phy capabilities of available speeds. */
+       status = i40e_aq_get_phy_capabilities(hw, false, true, &phy_ab,
+                                             NULL);
+       if (status) {
+               PMD_DRV_LOG(ERR, "Failed to get PHY capabilities: %d\n",
+                               status);
+               return ret;
+       }
+       avail_speed = phy_ab.link_speed;
 
+       /* To get the current phy config. */
        status = i40e_aq_get_phy_capabilities(hw, false, false, &phy_ab,
                                              NULL);
-       if (status)
+       if (status) {
+               PMD_DRV_LOG(ERR, "Failed to get the current PHY config: %d\n",
+                               status);
                return ret;
+       }
 
-       /* If link already up, no need to set up again */
-       if (is_up && phy_ab.phy_type != 0)
+       /* If link needs to go up and it is in autoneg mode the speed is OK,
+        * no need to set up again.
+        */
+       if (is_up && phy_ab.phy_type != 0 &&
+                    abilities & I40E_AQ_PHY_AN_ENABLED &&
+                    phy_ab.link_speed != 0)
                return I40E_SUCCESS;
 
        memset(&phy_conf, 0, sizeof(phy_conf));
@@ -2055,18 +2172,20 @@ i40e_phy_conf_link(struct i40e_hw *hw,
        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 = is_up ? force_speed : phy_ab.link_speed;
-
        phy_conf.abilities = abilities;
 
+       /* If link needs to go up, but the force speed is not supported,
+        * Warn users and config the default available speeds.
+        */
+       if (is_up && !(force_speed & avail_speed)) {
+               PMD_DRV_LOG(WARNING, "Invalid speed setting, set to default!\n");
+               phy_conf.link_speed = avail_speed;
+       } else {
+               phy_conf.link_speed = is_up ? force_speed : avail_speed;
+       }
 
-
-       /* To enable link, phy_type mask needs to include each type */
-       for (cnt = I40E_PHY_TYPE_SGMII; cnt < I40E_PHY_TYPE_MAX; cnt++)
+       /* PHY type mask needs to include each type except PHY type extension */
+       for (cnt = I40E_PHY_TYPE_SGMII; cnt < I40E_PHY_TYPE_25GBASE_KR; cnt++)
                phy_type_mask |= 1 << cnt;
 
        /* use get_phy_abilities_resp value for the rest */
@@ -2099,11 +2218,18 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct rte_eth_conf *conf = &dev->data->dev_conf;
 
+       if (conf->link_speeds == ETH_LINK_SPEED_AUTONEG) {
+               conf->link_speeds = ETH_LINK_SPEED_40G |
+                                   ETH_LINK_SPEED_25G |
+                                   ETH_LINK_SPEED_20G |
+                                   ETH_LINK_SPEED_10G |
+                                   ETH_LINK_SPEED_1G |
+                                   ETH_LINK_SPEED_100M;
+       }
        speed = i40e_parse_link_speeds(conf->link_speeds);
-       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;
+       abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK |
+                    I40E_AQ_PHY_AN_ENABLED |
+                    I40E_AQ_PHY_LINK_ENABLED;
 
        return i40e_phy_conf_link(hw, abilities, speed, true);
 }
@@ -2220,13 +2346,6 @@ i40e_dev_start(struct rte_eth_dev *dev)
        }
 
        /* Apply link configure */
-       if (dev->data->dev_conf.link_speeds & ~(ETH_LINK_SPEED_100M |
-                               ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
-                               ETH_LINK_SPEED_20G | ETH_LINK_SPEED_25G |
-                               ETH_LINK_SPEED_40G)) {
-               PMD_DRV_LOG(ERR, "Invalid link setting");
-               goto err_up;
-       }
        ret = i40e_apply_link_speed(dev);
        if (I40E_SUCCESS != ret) {
                PMD_DRV_LOG(ERR, "Fail to apply link setting");
@@ -2256,8 +2375,13 @@ i40e_dev_start(struct rte_eth_dev *dev)
                i40e_dev_link_update(dev, 0);
        }
 
-       /* enable uio intr after callback register */
-       rte_intr_enable(intr_handle);
+       if (dev->data->dev_conf.intr_conf.rxq == 0) {
+               rte_eal_alarm_set(I40E_ALARM_INTERVAL,
+                                 i40e_dev_alarm_handler, dev);
+       } else {
+               /* enable uio intr after callback register */
+               rte_intr_enable(intr_handle);
+       }
 
        i40e_filter_restore(pf);
 
@@ -2287,6 +2411,12 @@ i40e_dev_stop(struct rte_eth_dev *dev)
 
        if (hw->adapter_stopped == 1)
                return;
+
+       if (dev->data->dev_conf.intr_conf.rxq == 0) {
+               rte_eal_alarm_cancel(i40e_dev_alarm_handler, dev);
+               rte_intr_enable(intr_handle);
+       }
+
        /* Disable all queues */
        i40e_dev_switch_queues(pf, FALSE);
 
@@ -2326,6 +2456,8 @@ i40e_dev_stop(struct rte_eth_dev *dev)
        pf->tm_conf.committed = false;
 
        hw->adapter_stopped = 1;
+
+       pf->adapter->rss_reta_updated = 0;
 }
 
 static void
@@ -2369,6 +2501,13 @@ i40e_dev_close(struct rte_eth_dev *dev)
        i40e_pf_disable_irq0(hw);
        rte_intr_disable(intr_handle);
 
+       /*
+        * Only legacy filter API needs the following fdir config. So when the
+        * legacy filter API is deprecated, the following code should also be
+        * removed.
+        */
+       i40e_fdir_teardown(pf);
+
        /* shutdown and destroy the HMC */
        i40e_shutdown_lan_hmc(hw);
 
@@ -2380,7 +2519,6 @@ i40e_dev_close(struct rte_eth_dev *dev)
        pf->vmdq = NULL;
 
        /* release all the existing VSIs and VEBs */
-       i40e_fdir_teardown(pf);
        i40e_vsi_release(pf->main_vsi);
 
        /* shutdown the adminq */
@@ -2399,6 +2537,8 @@ i40e_dev_close(struct rte_eth_dev *dev)
        I40E_WRITE_REG(hw, I40E_PFGEN_CTRL,
                        (reg | I40E_PFGEN_CTRL_PFSWR_MASK));
        I40E_WRITE_FLUSH(hw);
+
+       hw->adapter_closed = 1;
 }
 
 /*
@@ -2460,6 +2600,10 @@ i40e_dev_promiscuous_disable(struct rte_eth_dev *dev)
        if (status != I40E_SUCCESS)
                PMD_DRV_LOG(ERR, "Failed to disable unicast promiscuous");
 
+       /* must remain in all_multicast mode */
+       if (dev->data->all_multicast == 1)
+               return;
+
        status = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid,
                                                        false, NULL);
        if (status != I40E_SUCCESS)
@@ -2521,7 +2665,7 @@ i40e_dev_set_link_down(struct rte_eth_dev *dev)
 }
 
 static __rte_always_inline void
-update_link_no_wait(struct i40e_hw *hw, struct rte_eth_link *link)
+update_link_reg(struct i40e_hw *hw, struct rte_eth_link *link)
 {
 /* Link status registers and values*/
 #define I40E_PRTMAC_LINKSTA            0x001E2420
@@ -2529,11 +2673,11 @@ update_link_no_wait(struct i40e_hw *hw, struct rte_eth_link *link)
 #define I40E_PRTMAC_MACC               0x001E24E0
 #define I40E_REG_MACC_25GB             0x00020000
 #define I40E_REG_SPEED_MASK            0x38000000
-#define I40E_REG_SPEED_100MB           0x00000000
-#define I40E_REG_SPEED_1GB             0x08000000
-#define I40E_REG_SPEED_10GB            0x10000000
-#define I40E_REG_SPEED_20GB            0x20000000
-#define I40E_REG_SPEED_25_40GB         0x18000000
+#define I40E_REG_SPEED_0               0x00000000
+#define I40E_REG_SPEED_1               0x08000000
+#define I40E_REG_SPEED_2               0x10000000
+#define I40E_REG_SPEED_3               0x18000000
+#define I40E_REG_SPEED_4               0x20000000
        uint32_t link_speed;
        uint32_t reg_val;
 
@@ -2547,26 +2691,35 @@ update_link_no_wait(struct i40e_hw *hw, struct rte_eth_link *link)
 
        /* Parse the link status */
        switch (link_speed) {
-       case I40E_REG_SPEED_100MB:
+       case I40E_REG_SPEED_0:
                link->link_speed = ETH_SPEED_NUM_100M;
                break;
-       case I40E_REG_SPEED_1GB:
+       case I40E_REG_SPEED_1:
                link->link_speed = ETH_SPEED_NUM_1G;
                break;
-       case I40E_REG_SPEED_10GB:
-               link->link_speed = ETH_SPEED_NUM_10G;
-               break;
-       case I40E_REG_SPEED_20GB:
-               link->link_speed = ETH_SPEED_NUM_20G;
+       case I40E_REG_SPEED_2:
+               if (hw->mac.type == I40E_MAC_X722)
+                       link->link_speed = ETH_SPEED_NUM_2_5G;
+               else
+                       link->link_speed = ETH_SPEED_NUM_10G;
                break;
-       case I40E_REG_SPEED_25_40GB:
-               reg_val = I40E_READ_REG(hw, I40E_PRTMAC_MACC);
+       case I40E_REG_SPEED_3:
+               if (hw->mac.type == I40E_MAC_X722) {
+                       link->link_speed = ETH_SPEED_NUM_5G;
+               } else {
+                       reg_val = I40E_READ_REG(hw, I40E_PRTMAC_MACC);
 
-               if (reg_val & I40E_REG_MACC_25GB)
-                       link->link_speed = ETH_SPEED_NUM_25G;
+                       if (reg_val & I40E_REG_MACC_25GB)
+                               link->link_speed = ETH_SPEED_NUM_25G;
+                       else
+                               link->link_speed = ETH_SPEED_NUM_40G;
+               }
+               break;
+       case I40E_REG_SPEED_4:
+               if (hw->mac.type == I40E_MAC_X722)
+                       link->link_speed = ETH_SPEED_NUM_10G;
                else
-                       link->link_speed = ETH_SPEED_NUM_40G;
-
+                       link->link_speed = ETH_SPEED_NUM_20G;
                break;
        default:
                PMD_DRV_LOG(ERR, "Unknown link speed info %u", link_speed);
@@ -2575,8 +2728,8 @@ update_link_no_wait(struct i40e_hw *hw, struct rte_eth_link *link)
 }
 
 static __rte_always_inline void
-update_link_wait(struct i40e_hw *hw, struct rte_eth_link *link,
-       bool enable_lse)
+update_link_aq(struct i40e_hw *hw, struct rte_eth_link *link,
+       bool enable_lse, int wait_to_complete)
 {
 #define CHECK_INTERVAL             100  /* 100ms */
 #define MAX_REPEAT_TIME            10  /* 1s (10 * 100ms) in total */
@@ -2600,7 +2753,7 @@ update_link_wait(struct i40e_hw *hw, struct rte_eth_link *link,
                }
 
                link->link_status = link_status.link_info & I40E_AQ_LINK_UP;
-               if (unlikely(link->link_status != 0))
+               if (!wait_to_complete || link->link_status)
                        break;
 
                rte_delay_ms(CHECK_INTERVAL);
@@ -2648,10 +2801,10 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
        link.link_autoneg = !(dev->data->dev_conf.link_speeds &
                        ETH_LINK_SPEED_FIXED);
 
-       if (!wait_to_complete)
-               update_link_no_wait(hw, &link);
+       if (!wait_to_complete && !enable_lse)
+               update_link_reg(hw, &link);
        else
-               update_link_wait(hw, &link, enable_lse);
+               update_link_aq(hw, &link, enable_lse, wait_to_complete);
 
        ret = rte_eth_linkstatus_set(dev, &link);
        i40e_notify_all_vfs_link_status(dev);
@@ -3032,20 +3185,20 @@ i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
        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_hw_port_stats *ns = &pf->stats; /* new stats */
+       struct i40e_vsi *vsi;
        unsigned i;
 
        /* call read registers - updates values, now write them to struct */
        i40e_read_stats_registers(pf, hw);
 
-       stats->ipackets = ns->eth.rx_unicast +
-                       ns->eth.rx_multicast +
-                       ns->eth.rx_broadcast -
-                       ns->eth.rx_discards -
+       stats->ipackets = pf->main_vsi->eth_stats.rx_unicast +
+                       pf->main_vsi->eth_stats.rx_multicast +
+                       pf->main_vsi->eth_stats.rx_broadcast -
                        pf->main_vsi->eth_stats.rx_discards;
        stats->opackets = ns->eth.tx_unicast +
                        ns->eth.tx_multicast +
                        ns->eth.tx_broadcast;
-       stats->ibytes   = ns->eth.rx_bytes;
+       stats->ibytes   = pf->main_vsi->eth_stats.rx_bytes;
        stats->obytes   = ns->eth.tx_bytes;
        stats->oerrors  = ns->eth.tx_errors +
                        pf->main_vsi->eth_stats.tx_errors;
@@ -3057,6 +3210,21 @@ i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
                        ns->rx_length_errors + ns->rx_undersize +
                        ns->rx_oversize + ns->rx_fragments + ns->rx_jabber;
 
+       if (pf->vfs) {
+               for (i = 0; i < pf->vf_num; i++) {
+                       vsi = pf->vfs[i].vsi;
+                       i40e_update_vsi_stats(vsi);
+
+                       stats->ipackets += (vsi->eth_stats.rx_unicast +
+                                       vsi->eth_stats.rx_multicast +
+                                       vsi->eth_stats.rx_broadcast -
+                                       vsi->eth_stats.rx_discards);
+                       stats->ibytes   += vsi->eth_stats.rx_bytes;
+                       stats->oerrors  += vsi->eth_stats.tx_errors;
+                       stats->imissed  += vsi->eth_stats.rx_discards;
+               }
+       }
+
        PMD_DRV_LOG(DEBUG, "***************** PF stats start *******************");
        PMD_DRV_LOG(DEBUG, "rx_bytes:            %"PRIu64"", ns->eth.rx_bytes);
        PMD_DRV_LOG(DEBUG, "rx_unicast:          %"PRIu64"", ns->eth.rx_unicast);
@@ -3167,17 +3335,17 @@ static int i40e_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
 
        /* Get stats from i40e_eth_stats struct */
        for (i = 0; i < I40E_NB_ETH_XSTATS; i++) {
-               snprintf(xstats_names[count].name,
-                        sizeof(xstats_names[count].name),
-                        "%s", rte_i40e_stats_strings[i].name);
+               strlcpy(xstats_names[count].name,
+                       rte_i40e_stats_strings[i].name,
+                       sizeof(xstats_names[count].name));
                count++;
        }
 
        /* Get individiual stats from i40e_hw_port struct */
        for (i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) {
-               snprintf(xstats_names[count].name,
-                       sizeof(xstats_names[count].name),
-                        "%s", rte_i40e_hw_port_strings[i].name);
+               strlcpy(xstats_names[count].name,
+                       rte_i40e_hw_port_strings[i].name,
+                       sizeof(xstats_names[count].name));
                count++;
        }
 
@@ -3303,6 +3471,31 @@ i40e_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
                return 0;
 }
 
+/*
+ * When using NVM 6.01(for X710 XL710 XXV710)/3.33(for X722) or later,
+ * the Rx data path does not hang if the FW LLDP is stopped.
+ * return true if lldp need to stop
+ * return false if we cannot disable the LLDP to avoid Rx data path blocking.
+ */
+static bool
+i40e_need_stop_lldp(struct rte_eth_dev *dev)
+{
+       double nvm_ver;
+       char ver_str[64] = {0};
+       struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+       i40e_fw_version_get(dev, ver_str, 64);
+       nvm_ver = atof(ver_str);
+       if ((hw->mac.type == I40E_MAC_X722 ||
+            hw->mac.type == I40E_MAC_X722_VF) &&
+            ((uint32_t)(nvm_ver * 1000) >= (uint32_t)(3.33 * 1000)))
+               return true;
+       else if ((uint32_t)(nvm_ver * 1000) >= (uint32_t)(6.01 * 1000))
+               return true;
+
+       return false;
+}
+
 static void
 i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
@@ -3317,6 +3510,8 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
        dev_info->max_rx_pktlen = I40E_FRAME_SIZE_MAX;
        dev_info->max_mac_addrs = vsi->max_macaddrs;
        dev_info->max_vfs = pci_dev->max_vfs;
+       dev_info->max_mtu = dev_info->max_rx_pktlen - I40E_ETH_OVERHEAD;
+       dev_info->min_mtu = ETHER_MIN_MTU;
        dev_info->rx_queue_offload_capa = 0;
        dev_info->rx_offload_capa =
                DEV_RX_OFFLOAD_VLAN_STRIP |
@@ -3325,7 +3520,8 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
                DEV_RX_OFFLOAD_UDP_CKSUM |
                DEV_RX_OFFLOAD_TCP_CKSUM |
                DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM |
-               DEV_RX_OFFLOAD_CRC_STRIP |
+               DEV_RX_OFFLOAD_KEEP_CRC |
+               DEV_RX_OFFLOAD_SCATTER |
                DEV_RX_OFFLOAD_VLAN_EXTEND |
                DEV_RX_OFFLOAD_VLAN_FILTER |
                DEV_RX_OFFLOAD_JUMBO_FRAME;
@@ -3500,8 +3696,6 @@ i40e_vlan_tpid_set_by_registers(struct rte_eth_dev *dev,
                    "Global register 0x%08x is changed with value 0x%08x",
                    I40E_GL_SWT_L2TAGCTRL(reg_id), (uint32_t)reg_w);
 
-       i40e_global_cfg_warning(I40E_WARNING_TPID);
-
        return 0;
 }
 
@@ -3540,7 +3734,7 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev,
                        if (vlan_type == ETH_VLAN_TYPE_OUTER)
                                hw->second_tag = rte_cpu_to_le_16(tpid);
                }
-               ret = i40e_aq_set_switch_config(hw, 0, 0, NULL);
+               ret = i40e_aq_set_switch_config(hw, 0, 0, 0, NULL);
                if (ret != I40E_SUCCESS) {
                        PMD_DRV_LOG(ERR,
                                    "Set switch config failed aq_err: %d",
@@ -3796,7 +3990,6 @@ i40e_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
                I40E_WRITE_GLB_REG(hw, I40E_GLRPB_GLW,
                                   pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
                                   << I40E_KILOSHIFT);
-               i40e_global_cfg_warning(I40E_WARNING_FLOW_CTL);
        } else {
                PMD_DRV_LOG(ERR,
                            "Water marker configuration is not supported.");
@@ -3819,7 +4012,7 @@ i40e_priority_flow_ctrl_set(__rte_unused struct rte_eth_dev *dev,
 /* Add a MAC address, and update filters */
 static int
 i40e_macaddr_add(struct rte_eth_dev *dev,
-                struct ether_addr *mac_addr,
+                struct rte_ether_addr *mac_addr,
                 __rte_unused uint32_t index,
                 uint32_t pool)
 {
@@ -3870,7 +4063,7 @@ i40e_macaddr_remove(struct rte_eth_dev *dev, uint32_t index)
        struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
        struct i40e_vsi *vsi;
        struct rte_eth_dev_data *data = dev->data;
-       struct ether_addr *macaddr;
+       struct rte_ether_addr *macaddr;
        int ret;
        uint32_t i;
        uint64_t pool_sel;
@@ -3911,8 +4104,8 @@ i40e_vf_mac_filter_set(struct i40e_pf *pf,
 {
        struct i40e_hw *hw;
        struct i40e_mac_filter_info mac_filter;
-       struct ether_addr old_mac;
-       struct ether_addr *new_mac;
+       struct rte_ether_addr old_mac;
+       struct rte_ether_addr *new_mac;
        struct i40e_pf_vf *vf = NULL;
        uint16_t vf_id;
        int ret;
@@ -3973,7 +4166,7 @@ i40e_vf_mac_filter_set(struct i40e_pf *pf,
 
                /* Clear device address as it has been removed */
                if (is_same_ether_addr(&(pf->dev_addr), new_mac))
-                       memset(&pf->dev_addr, 0, sizeof(struct ether_addr));
+                       memset(&pf->dev_addr, 0, sizeof(struct rte_ether_addr));
        }
 
        return 0;
@@ -4028,7 +4221,8 @@ i40e_get_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size)
                return -EINVAL;
 
        if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) {
-               ret = i40e_aq_get_rss_lut(hw, vsi->vsi_id, TRUE,
+               ret = i40e_aq_get_rss_lut(hw, vsi->vsi_id,
+                                         vsi->type != I40E_VSI_SRIOV,
                                          lut, lut_size);
                if (ret) {
                        PMD_DRV_LOG(ERR, "Failed to get RSS lookup table");
@@ -4067,7 +4261,8 @@ i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size)
        hw = I40E_VSI_TO_HW(vsi);
 
        if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) {
-               ret = i40e_aq_set_rss_lut(hw, vsi->vsi_id, TRUE,
+               ret = i40e_aq_set_rss_lut(hw, vsi->vsi_id,
+                                         vsi->type != I40E_VSI_SRIOV,
                                          lut, lut_size);
                if (ret) {
                        PMD_DRV_LOG(ERR, "Failed to set RSS lookup table");
@@ -4129,6 +4324,8 @@ i40e_dev_rss_reta_update(struct rte_eth_dev *dev,
        }
        ret = i40e_set_rss_lut(pf->main_vsi, lut, reta_size);
 
+       pf->adapter->rss_reta_updated = 1;
+
 out:
        rte_free(lut);
 
@@ -4333,7 +4530,6 @@ i40e_get_cap(struct i40e_hw *hw)
 }
 
 #define RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF       4
-#define QUEUE_NUM_PER_VF_ARG                   "queue-num-per-vf"
 
 static int i40e_pf_parse_vf_queue_number_handler(const char *key,
                const char *value,
@@ -4367,9 +4563,9 @@ static int i40e_pf_parse_vf_queue_number_handler(const char *key,
 
 static int i40e_pf_config_vf_rxq_number(struct rte_eth_dev *dev)
 {
-       static const char * const valid_keys[] = {QUEUE_NUM_PER_VF_ARG, NULL};
        struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
        struct rte_kvargs *kvlist;
+       int kvargs_count;
 
        /* set default queue number per VF as 4 */
        pf->vf_nb_qp_max = RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF;
@@ -4381,12 +4577,18 @@ static int i40e_pf_config_vf_rxq_number(struct rte_eth_dev *dev)
        if (kvlist == NULL)
                return -(EINVAL);
 
-       if (rte_kvargs_count(kvlist, QUEUE_NUM_PER_VF_ARG) > 1)
+       kvargs_count = rte_kvargs_count(kvlist, ETH_I40E_QUEUE_NUM_PER_VF_ARG);
+       if (!kvargs_count) {
+               rte_kvargs_free(kvlist);
+               return 0;
+       }
+
+       if (kvargs_count > 1)
                PMD_DRV_LOG(WARNING, "More than one argument \"%s\" and only "
                            "the first invalid or last valid one is used !",
-                           QUEUE_NUM_PER_VF_ARG);
+                           ETH_I40E_QUEUE_NUM_PER_VF_ARG);
 
-       rte_kvargs_process(kvlist, QUEUE_NUM_PER_VF_ARG,
+       rte_kvargs_process(kvlist, ETH_I40E_QUEUE_NUM_PER_VF_ARG,
                           i40e_pf_parse_vf_queue_number_handler, pf);
 
        rte_kvargs_free(kvlist);
@@ -5141,7 +5343,7 @@ i40e_update_default_filter_setting(struct i40e_vsi *vsi)
        ret = i40e_aq_remove_macvlan(hw, vsi->seid, &def_filter, 1, NULL);
        if (ret != I40E_SUCCESS) {
                struct i40e_mac_filter *f;
-               struct ether_addr *mac;
+               struct rte_ether_addr *mac;
 
                PMD_DRV_LOG(DEBUG,
                            "Cannot remove the default macvlan filter");
@@ -5161,7 +5363,7 @@ i40e_update_default_filter_setting(struct i40e_vsi *vsi)
                return ret;
        }
        rte_memcpy(&filter.mac_addr,
-               (struct ether_addr *)(hw->mac.perm_addr), ETH_ADDR_LEN);
+               (struct rte_ether_addr *)(hw->mac.perm_addr), ETH_ADDR_LEN);
        filter.filter_type = RTE_MACVLAN_PERFECT_MATCH;
        return i40e_vsi_add_mac(vsi, &filter);
 }
@@ -5241,7 +5443,7 @@ i40e_enable_pf_lb(struct i40e_pf *pf)
        int ret;
 
        /* Use the FW API if FW >= v5.0 */
-       if (hw->aq.fw_maj_ver < 5) {
+       if (hw->aq.fw_maj_ver < 5 && hw->mac.type != I40E_MAC_X722) {
                PMD_INIT_LOG(ERR, "FW < v5.0, cannot enable loopback");
                return;
        }
@@ -5279,7 +5481,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
        struct i40e_mac_filter_info filter;
        int ret;
        struct i40e_vsi_context ctxt;
-       struct ether_addr broadcast =
+       struct rte_ether_addr broadcast =
                {.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
 
        if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
@@ -5512,7 +5714,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
                ctxt.flags = I40E_AQ_VSI_TYPE_VF;
 
                /* Use the VEB configuration if FW >= v5.0 */
-               if (hw->aq.fw_maj_ver >= 5) {
+               if (hw->aq.fw_maj_ver >= 5 || hw->mac.type == I40E_MAC_X722) {
                        /* Configure switch ID */
                        ctxt.info.valid_sections |=
                        rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SWITCH_VALID);
@@ -6508,7 +6710,53 @@ i40e_dev_interrupt_handler(void *param)
 done:
        /* Enable interrupt */
        i40e_pf_enable_irq0(hw);
-       rte_intr_enable(dev->intr_handle);
+}
+
+static void
+i40e_dev_alarm_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;
+
+       /* Disable interrupt */
+       i40e_pf_disable_irq0(hw);
+
+       /* read out interrupt causes */
+       icr0 = I40E_READ_REG(hw, I40E_PFINT_ICR0);
+
+       /* No interrupt event indicated */
+       if (!(icr0 & I40E_PFINT_ICR0_INTEVENT_MASK))
+               goto done;
+       if (icr0 & I40E_PFINT_ICR0_ECC_ERR_MASK)
+               PMD_DRV_LOG(ERR, "ICR0: unrecoverable ECC error");
+       if (icr0 & I40E_PFINT_ICR0_MAL_DETECT_MASK)
+               PMD_DRV_LOG(ERR, "ICR0: malicious programming detected");
+       if (icr0 & I40E_PFINT_ICR0_GRST_MASK)
+               PMD_DRV_LOG(INFO, "ICR0: global reset requested");
+       if (icr0 & I40E_PFINT_ICR0_PCI_EXCEPTION_MASK)
+               PMD_DRV_LOG(INFO, "ICR0: PCI exception activated");
+       if (icr0 & I40E_PFINT_ICR0_STORM_DETECT_MASK)
+               PMD_DRV_LOG(INFO, "ICR0: a change in the storm control state");
+       if (icr0 & I40E_PFINT_ICR0_HMC_ERR_MASK)
+               PMD_DRV_LOG(ERR, "ICR0: HMC error");
+       if (icr0 & I40E_PFINT_ICR0_PE_CRITERR_MASK)
+               PMD_DRV_LOG(ERR, "ICR0: protocol engine critical error");
+
+       if (icr0 & I40E_PFINT_ICR0_VFLR_MASK) {
+               PMD_DRV_LOG(INFO, "ICR0: VF reset detected");
+               i40e_dev_handle_vfr_event(dev);
+       }
+       if (icr0 & I40E_PFINT_ICR0_ADMINQ_MASK) {
+               PMD_DRV_LOG(INFO, "ICR0: adminq event");
+               i40e_dev_handle_aq_msg(dev);
+       }
+
+done:
+       /* Enable interrupt */
+       i40e_pf_enable_irq0(hw);
+       rte_eal_alarm_set(I40E_ALARM_INTERVAL,
+                         i40e_dev_alarm_handler, dev);
 }
 
 int
@@ -6660,7 +6908,7 @@ DONE:
 /* Find out specific MAC filter */
 static struct i40e_mac_filter *
 i40e_find_mac_filter(struct i40e_vsi *vsi,
-                        struct ether_addr *macaddr)
+                        struct rte_ether_addr *macaddr)
 {
        struct i40e_mac_filter *f;
 
@@ -6744,7 +6992,7 @@ i40e_set_vlan_filter(struct i40e_vsi *vsi,
 int
 i40e_find_all_vlan_for_mac(struct i40e_vsi *vsi,
                           struct i40e_macvlan_filter *mv_f,
-                          int num, struct ether_addr *addr)
+                          int num, struct rte_ether_addr *addr)
 {
        int i;
        uint32_t j, k;
@@ -7038,7 +7286,7 @@ DONE:
 }
 
 int
-i40e_vsi_delete_mac(struct i40e_vsi *vsi, struct ether_addr *addr)
+i40e_vsi_delete_mac(struct i40e_vsi *vsi, struct rte_ether_addr *addr)
 {
        struct i40e_mac_filter *f;
        struct i40e_macvlan_filter *mv_f;
@@ -7199,7 +7447,7 @@ i40e_get_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t *key_len)
        int ret;
 
        if (!key || !key_len)
-               return -EINVAL;
+               return 0;
 
        if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) {
                ret = i40e_aq_get_rss_key(hw, vsi->vsi_id,
@@ -7282,9 +7530,15 @@ i40e_dev_rss_hash_conf_get(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);
        uint64_t hena;
+       int ret;
 
-       i40e_get_rss_key(pf->main_vsi, rss_conf->rss_key,
+       if (!rss_conf)
+               return -EINVAL;
+
+       ret = i40e_get_rss_key(pf->main_vsi, rss_conf->rss_key,
                         &rss_conf->rss_key_len);
+       if (ret)
+               return ret;
 
        hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
        hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
@@ -7329,13 +7583,13 @@ i40e_dev_get_filter_type(uint16_t filter_type, uint16_t *flag)
 /* Convert tunnel filter structure */
 static int
 i40e_tunnel_filter_convert(
-       struct i40e_aqc_add_rm_cloud_filt_elem_ext *cld_filter,
+       struct i40e_aqc_cloud_filters_element_bb *cld_filter,
        struct i40e_tunnel_filter *tunnel_filter)
 {
-       ether_addr_copy((struct ether_addr *)&cld_filter->element.outer_mac,
-                       (struct ether_addr *)&tunnel_filter->input.outer_mac);
-       ether_addr_copy((struct ether_addr *)&cld_filter->element.inner_mac,
-                       (struct ether_addr *)&tunnel_filter->input.inner_mac);
+       ether_addr_copy((struct rte_ether_addr *)&cld_filter->element.outer_mac,
+               (struct rte_ether_addr *)&tunnel_filter->input.outer_mac);
+       ether_addr_copy((struct rte_ether_addr *)&cld_filter->element.inner_mac,
+               (struct rte_ether_addr *)&tunnel_filter->input.inner_mac);
        tunnel_filter->input.inner_vlan = cld_filter->element.inner_vlan;
        if ((rte_le_to_cpu_16(cld_filter->element.flags) &
             I40E_AQC_ADD_CLOUD_FLAGS_IPV6) ==
@@ -7427,8 +7681,8 @@ i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
        int val, ret = 0;
        struct i40e_hw *hw = I40E_PF_TO_HW(pf);
        struct i40e_vsi *vsi = pf->main_vsi;
-       struct i40e_aqc_add_rm_cloud_filt_elem_ext *cld_filter;
-       struct i40e_aqc_add_rm_cloud_filt_elem_ext *pfilter;
+       struct i40e_aqc_cloud_filters_element_bb *cld_filter;
+       struct i40e_aqc_cloud_filters_element_bb *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 */
@@ -7444,9 +7698,9 @@ i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
        pfilter = cld_filter;
 
        ether_addr_copy(&tunnel_filter->outer_mac,
-                       (struct ether_addr *)&pfilter->element.outer_mac);
+                       (struct rte_ether_addr *)&pfilter->element.outer_mac);
        ether_addr_copy(&tunnel_filter->inner_mac,
-                       (struct ether_addr *)&pfilter->element.inner_mac);
+                       (struct rte_ether_addr *)&pfilter->element.inner_mac);
 
        pfilter->element.inner_vlan =
                rte_cpu_to_le_16(tunnel_filter->inner_vlan);
@@ -7479,6 +7733,9 @@ i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
        case RTE_TUNNEL_TYPE_IP_IN_GRE:
                tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_IP;
                break;
+       case RTE_TUNNEL_TYPE_VXLAN_GPE:
+               tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_VXLAN_GPE;
+               break;
        default:
                /* Other tunnel types is not supported. */
                PMD_DRV_LOG(ERR, "tunnel type is not supported.");
@@ -7536,7 +7793,7 @@ i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
                if (ret < 0)
                        rte_free(tunnel);
        } else {
-               ret = i40e_aq_remove_cloud_filters(hw, vsi->seid,
+               ret = i40e_aq_rem_cloud_filters(hw, vsi->seid,
                                                   &cld_filter->element, 1);
                if (ret < 0) {
                        PMD_DRV_LOG(ERR, "Failed to delete a tunnel filter.");
@@ -7564,6 +7821,7 @@ i40e_status_code i40e_replace_mpls_l1_filter(struct i40e_pf *pf)
        struct i40e_aqc_replace_cloud_filters_cmd  filter_replace;
        struct i40e_aqc_replace_cloud_filters_cmd_buf  filter_replace_buf;
        struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+       struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;
        enum i40e_status_code status = I40E_SUCCESS;
 
        if (pf->support_multi_driver) {
@@ -7607,13 +7865,14 @@ i40e_status_code i40e_replace_mpls_l1_filter(struct i40e_pf *pf)
 
        status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
                                               &filter_replace_buf);
-       if (!status) {
-               i40e_global_cfg_warning(I40E_WARNING_RPL_CLD_FILTER);
-               PMD_DRV_LOG(DEBUG, "Global configuration modification: "
-                           "cloud l1 type is changed from 0x%x to 0x%x",
+       if (!status && (filter_replace.old_filter_type !=
+                       filter_replace.new_filter_type))
+               PMD_DRV_LOG(WARNING, "i40e device %s changed cloud l1 type."
+                           " original: 0x%x, new: 0x%x",
+                           dev->device->name,
                            filter_replace.old_filter_type,
                            filter_replace.new_filter_type);
-       }
+
        return status;
 }
 
@@ -7623,6 +7882,7 @@ i40e_status_code i40e_replace_mpls_cloud_filter(struct i40e_pf *pf)
        struct i40e_aqc_replace_cloud_filters_cmd  filter_replace;
        struct i40e_aqc_replace_cloud_filters_cmd_buf  filter_replace_buf;
        struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+       struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;
        enum i40e_status_code status = I40E_SUCCESS;
 
        if (pf->support_multi_driver) {
@@ -7651,10 +7911,13 @@ i40e_status_code i40e_replace_mpls_cloud_filter(struct i40e_pf *pf)
                                               &filter_replace_buf);
        if (status < 0)
                return status;
-       PMD_DRV_LOG(DEBUG, "Global configuration modification: "
-                   "cloud filter type is changed from 0x%x to 0x%x",
-                   filter_replace.old_filter_type,
-                   filter_replace.new_filter_type);
+       if (filter_replace.old_filter_type !=
+           filter_replace.new_filter_type)
+               PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type."
+                           " original: 0x%x, new: 0x%x",
+                           dev->device->name,
+                           filter_replace.old_filter_type,
+                           filter_replace.new_filter_type);
 
        /* For MPLSoGRE */
        memset(&filter_replace, 0,
@@ -7677,13 +7940,14 @@ i40e_status_code i40e_replace_mpls_cloud_filter(struct i40e_pf *pf)
 
        status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
                                               &filter_replace_buf);
-       if (!status) {
-               i40e_global_cfg_warning(I40E_WARNING_RPL_CLD_FILTER);
-               PMD_DRV_LOG(DEBUG, "Global configuration modification: "
-                           "cloud filter type is changed from 0x%x to 0x%x",
+       if (!status && (filter_replace.old_filter_type !=
+                       filter_replace.new_filter_type))
+               PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type."
+                           " original: 0x%x, new: 0x%x",
+                           dev->device->name,
                            filter_replace.old_filter_type,
                            filter_replace.new_filter_type);
-       }
+
        return status;
 }
 
@@ -7693,6 +7957,7 @@ i40e_replace_gtp_l1_filter(struct i40e_pf *pf)
        struct i40e_aqc_replace_cloud_filters_cmd  filter_replace;
        struct i40e_aqc_replace_cloud_filters_cmd_buf  filter_replace_buf;
        struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+       struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;
        enum i40e_status_code status = I40E_SUCCESS;
 
        if (pf->support_multi_driver) {
@@ -7728,10 +7993,13 @@ i40e_replace_gtp_l1_filter(struct i40e_pf *pf)
                                               &filter_replace_buf);
        if (status < 0)
                return status;
-       PMD_DRV_LOG(DEBUG, "Global configuration modification: "
-                   "cloud l1 type is changed from 0x%x to 0x%x",
-                   filter_replace.old_filter_type,
-                   filter_replace.new_filter_type);
+       if (filter_replace.old_filter_type !=
+           filter_replace.new_filter_type)
+               PMD_DRV_LOG(WARNING, "i40e device %s changed cloud l1 type."
+                           " original: 0x%x, new: 0x%x",
+                           dev->device->name,
+                           filter_replace.old_filter_type,
+                           filter_replace.new_filter_type);
 
        /* for GTP-U */
        memset(&filter_replace, 0,
@@ -7760,13 +8028,14 @@ i40e_replace_gtp_l1_filter(struct i40e_pf *pf)
 
        status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
                                               &filter_replace_buf);
-       if (!status) {
-               i40e_global_cfg_warning(I40E_WARNING_RPL_CLD_FILTER);
-               PMD_DRV_LOG(DEBUG, "Global configuration modification: "
-                           "cloud l1 type is changed from 0x%x to 0x%x",
+       if (!status && (filter_replace.old_filter_type !=
+                       filter_replace.new_filter_type))
+               PMD_DRV_LOG(WARNING, "i40e device %s changed cloud l1 type."
+                           " original: 0x%x, new: 0x%x",
+                           dev->device->name,
                            filter_replace.old_filter_type,
                            filter_replace.new_filter_type);
-       }
+
        return status;
 }
 
@@ -7776,6 +8045,7 @@ i40e_status_code i40e_replace_gtp_cloud_filter(struct i40e_pf *pf)
        struct i40e_aqc_replace_cloud_filters_cmd  filter_replace;
        struct i40e_aqc_replace_cloud_filters_cmd_buf  filter_replace_buf;
        struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+       struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;
        enum i40e_status_code status = I40E_SUCCESS;
 
        if (pf->support_multi_driver) {
@@ -7803,10 +8073,13 @@ i40e_status_code i40e_replace_gtp_cloud_filter(struct i40e_pf *pf)
                                               &filter_replace_buf);
        if (status < 0)
                return status;
-       PMD_DRV_LOG(DEBUG, "Global configuration modification: "
-                   "cloud filter type is changed from 0x%x to 0x%x",
-                   filter_replace.old_filter_type,
-                   filter_replace.new_filter_type);
+       if (filter_replace.old_filter_type !=
+           filter_replace.new_filter_type)
+               PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type."
+                           " original: 0x%x, new: 0x%x",
+                           dev->device->name,
+                           filter_replace.old_filter_type,
+                           filter_replace.new_filter_type);
 
        /* for GTP-U */
        memset(&filter_replace, 0,
@@ -7828,13 +8101,14 @@ i40e_status_code i40e_replace_gtp_cloud_filter(struct i40e_pf *pf)
 
        status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
                                               &filter_replace_buf);
-       if (!status) {
-               i40e_global_cfg_warning(I40E_WARNING_RPL_CLD_FILTER);
-               PMD_DRV_LOG(DEBUG, "Global configuration modification: "
-                           "cloud filter type is changed from 0x%x to 0x%x",
+       if (!status && (filter_replace.old_filter_type !=
+                       filter_replace.new_filter_type))
+               PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type."
+                           " original: 0x%x, new: 0x%x",
+                           dev->device->name,
                            filter_replace.old_filter_type,
                            filter_replace.new_filter_type);
-       }
+
        return status;
 }
 
@@ -7852,8 +8126,8 @@ i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,
        struct i40e_pf_vf *vf = NULL;
        struct i40e_hw *hw = I40E_PF_TO_HW(pf);
        struct i40e_vsi *vsi;
-       struct i40e_aqc_add_rm_cloud_filt_elem_ext *cld_filter;
-       struct i40e_aqc_add_rm_cloud_filt_elem_ext *pfilter;
+       struct i40e_aqc_cloud_filters_element_bb *cld_filter;
+       struct i40e_aqc_cloud_filters_element_bb *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 */
@@ -7871,9 +8145,9 @@ i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,
        pfilter = cld_filter;
 
        ether_addr_copy(&tunnel_filter->outer_mac,
-                       (struct ether_addr *)&pfilter->element.outer_mac);
+                       (struct rte_ether_addr *)&pfilter->element.outer_mac);
        ether_addr_copy(&tunnel_filter->inner_mac,
-                       (struct ether_addr *)&pfilter->element.inner_mac);
+                       (struct rte_ether_addr *)&pfilter->element.inner_mac);
 
        pfilter->element.inner_vlan =
                rte_cpu_to_le_16(tunnel_filter->inner_vlan);
@@ -8056,7 +8330,7 @@ i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,
 
        if (add) {
                if (big_buffer)
-                       ret = i40e_aq_add_cloud_filters_big_buffer(hw,
+                       ret = i40e_aq_add_cloud_filters_bb(hw,
                                                   vsi->seid, cld_filter, 1);
                else
                        ret = i40e_aq_add_cloud_filters(hw,
@@ -8079,11 +8353,11 @@ i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,
                        rte_free(tunnel);
        } else {
                if (big_buffer)
-                       ret = i40e_aq_remove_cloud_filters_big_buffer(
+                       ret = i40e_aq_rem_cloud_filters_bb(
                                hw, vsi->seid, cld_filter, 1);
                else
-                       ret = i40e_aq_remove_cloud_filters(hw, vsi->seid,
-                                                  &cld_filter->element, 1);
+                       ret = i40e_aq_rem_cloud_filters(hw, vsi->seid,
+                                               &cld_filter->element, 1);
                if (ret < 0) {
                        PMD_DRV_LOG(ERR, "Failed to delete a tunnel filter.");
                        rte_free(cld_filter);
@@ -8110,7 +8384,7 @@ i40e_get_vxlan_port_idx(struct i40e_pf *pf, uint16_t port)
 }
 
 static int
-i40e_add_vxlan_port(struct i40e_pf *pf, uint16_t port)
+i40e_add_vxlan_port(struct i40e_pf *pf, uint16_t port, int udp_type)
 {
        int  idx, ret;
        uint8_t filter_idx;
@@ -8133,7 +8407,7 @@ i40e_add_vxlan_port(struct i40e_pf *pf, uint16_t port)
                return -ENOSPC;
        }
 
-       ret =  i40e_aq_add_udp_tunnel(hw, port, I40E_AQC_TUNNEL_TYPE_VXLAN,
+       ret =  i40e_aq_add_udp_tunnel(hw, port, udp_type,
                                        &filter_idx, NULL);
        if (ret < 0) {
                PMD_DRV_LOG(ERR, "Failed to add VXLAN UDP port %d", port);
@@ -8201,9 +8475,13 @@ i40e_dev_udp_tunnel_port_add(struct rte_eth_dev *dev,
 
        switch (udp_tunnel->prot_type) {
        case RTE_TUNNEL_TYPE_VXLAN:
-               ret = i40e_add_vxlan_port(pf, udp_tunnel->udp_port);
+               ret = i40e_add_vxlan_port(pf, udp_tunnel->udp_port,
+                                         I40E_AQC_TUNNEL_TYPE_VXLAN);
+               break;
+       case RTE_TUNNEL_TYPE_VXLAN_GPE:
+               ret = i40e_add_vxlan_port(pf, udp_tunnel->udp_port,
+                                         I40E_AQC_TUNNEL_TYPE_VXLAN_GPE);
                break;
-
        case RTE_TUNNEL_TYPE_GENEVE:
        case RTE_TUNNEL_TYPE_TEREDO:
                PMD_DRV_LOG(ERR, "Tunnel type is not supported now.");
@@ -8232,6 +8510,7 @@ i40e_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
 
        switch (udp_tunnel->prot_type) {
        case RTE_TUNNEL_TYPE_VXLAN:
+       case RTE_TUNNEL_TYPE_VXLAN_GPE:
                ret = i40e_del_vxlan_port(pf, udp_tunnel->udp_port);
                break;
        case RTE_TUNNEL_TYPE_GENEVE:
@@ -8295,13 +8574,16 @@ i40e_pf_config_rss(struct i40e_pf *pf)
                return -ENOTSUP;
        }
 
-       for (i = 0, j = 0; i < hw->func_caps.rss_table_size; i++, j++) {
-               if (j == num)
-                       j = 0;
-               lut = (lut << 8) | (j & ((0x1 <<
-                       hw->func_caps.rss_table_entry_width) - 1));
-               if ((i & 3) == 3)
-                       I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i >> 2), lut);
+       if (pf->adapter->rss_reta_updated == 0) {
+               for (i = 0, j = 0; i < hw->func_caps.rss_table_size; i++, j++) {
+                       if (j == num)
+                               j = 0;
+                       lut = (lut << 8) | (j & ((0x1 <<
+                               hw->func_caps.rss_table_entry_width) - 1));
+                       if ((i & 3) == 3)
+                               I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i >> 2),
+                                              rte_bswap32(lut));
+               }
        }
 
        rss_conf = pf->dev_data->dev_conf.rx_adv_conf.rss_conf;
@@ -8394,7 +8676,6 @@ i40e_dev_set_gre_key_len(struct i40e_hw *hw, uint8_t len)
                PMD_DRV_LOG(DEBUG, "Global register 0x%08x is changed "
                            "with value 0x%08x",
                            I40E_GL_PRS_FVBM(2), reg);
-               i40e_global_cfg_warning(I40E_WARNING_GRE_KEY_LEN);
        } else {
                ret = 0;
        }
@@ -8660,7 +8941,6 @@ i40e_set_hash_filter_global_config(struct i40e_hw *hw,
                                                          I40E_GLQF_HSYM(j),
                                                          reg);
                        }
-                       i40e_global_cfg_warning(I40E_WARNING_HSYM);
                }
        }
 
@@ -8686,7 +8966,6 @@ i40e_set_hash_filter_global_config(struct i40e_hw *hw,
                goto out;
 
        i40e_write_global_rx_ctl(hw, I40E_GLQF_CTL, reg);
-       i40e_global_cfg_warning(I40E_WARNING_QF_CTL);
 
 out:
        I40E_WRITE_FLUSH(hw);
@@ -9279,12 +9558,17 @@ void
 i40e_check_write_global_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 {
        uint32_t reg = i40e_read_rx_ctl(hw, addr);
+       struct rte_eth_dev *dev;
 
-       if (reg != val)
+       dev = ((struct i40e_adapter *)hw->back)->eth_dev;
+       if (reg != val) {
                i40e_write_rx_ctl(hw, addr, val);
-       PMD_DRV_LOG(DEBUG,
-                   "Global register [0x%08x] original: 0x%08x, after: 0x%08x",
-                   addr, reg, (uint32_t)i40e_read_rx_ctl(hw, addr));
+               PMD_DRV_LOG(WARNING,
+                           "i40e device %s changed global register [0x%08x]."
+                           " original: 0x%08x, new: 0x%08x",
+                           dev->device->name, addr, reg,
+                           (uint32_t)i40e_read_rx_ctl(hw, addr));
+       }
 }
 
 static void
@@ -9358,12 +9642,6 @@ i40e_filter_input_set_init(struct i40e_pf *pf)
                        pf->hash_input_set[pctype] = input_set;
                pf->fdir.input_set[pctype] = input_set;
        }
-
-       if (!pf->support_multi_driver) {
-               i40e_global_cfg_warning(I40E_WARNING_HASH_INSET);
-               i40e_global_cfg_warning(I40E_WARNING_FD_MSK);
-               i40e_global_cfg_warning(I40E_WARNING_HASH_MSK);
-       }
 }
 
 int
@@ -9429,7 +9707,6 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
        i40e_check_write_global_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
                                    (uint32_t)((inset_reg >>
                                    I40E_32_BIT_WIDTH) & UINT32_MAX));
-       i40e_global_cfg_warning(I40E_WARNING_HASH_INSET);
 
        for (i = 0; i < num; i++)
                i40e_check_write_global_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
@@ -9438,7 +9715,6 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
        for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
                i40e_check_write_global_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
                                            0);
-       i40e_global_cfg_warning(I40E_WARNING_HASH_MSK);
        I40E_WRITE_FLUSH(hw);
 
        pf->hash_input_set[pctype] = input_set;
@@ -9519,7 +9795,6 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
                        i40e_check_write_global_reg(hw,
                                                    I40E_GLQF_FD_MSK(i, pctype),
                                                    0);
-               i40e_global_cfg_warning(I40E_WARNING_FD_MSK);
        } else {
                PMD_DRV_LOG(ERR, "FDIR bit mask is not supported.");
        }
@@ -10002,6 +10277,60 @@ i40e_pctype_to_flowtype(const struct i40e_adapter *adapter,
 #define I40E_GL_SWR_PM_UP_THR_SF_VALUE   0x06060606
 #define I40E_GL_SWR_PM_UP_THR            0x269FBC
 
+/*
+ * GL_SWR_PM_UP_THR:
+ * The value is not impacted from the link speed, its value is set according
+ * to the total number of ports for a better pipe-monitor configuration.
+ */
+static bool
+i40e_get_swr_pm_cfg(struct i40e_hw *hw, uint32_t *value)
+{
+#define I40E_GL_SWR_PM_EF_DEVICE(dev) \
+               .device_id = (dev),   \
+               .val = I40E_GL_SWR_PM_UP_THR_EF_VALUE
+
+#define I40E_GL_SWR_PM_SF_DEVICE(dev) \
+               .device_id = (dev),   \
+               .val = I40E_GL_SWR_PM_UP_THR_SF_VALUE
+
+       static const struct {
+               uint16_t device_id;
+               uint32_t val;
+       } swr_pm_table[] = {
+               { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_SFP_XL710) },
+               { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_KX_C) },
+               { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_10G_BASE_T) },
+               { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_10G_BASE_T4) },
+
+               { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_KX_B) },
+               { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_QSFP_A) },
+               { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_QSFP_B) },
+               { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_20G_KR2) },
+               { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_20G_KR2_A) },
+               { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_25G_B) },
+               { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_25G_SFP28) },
+       };
+       uint32_t i;
+
+       if (value == NULL) {
+               PMD_DRV_LOG(ERR, "value is NULL");
+               return false;
+       }
+
+       for (i = 0; i < RTE_DIM(swr_pm_table); i++) {
+               if (hw->device_id == swr_pm_table[i].device_id) {
+                       *value = swr_pm_table[i].val;
+
+                       PMD_DRV_LOG(DEBUG, "Device 0x%x with GL_SWR_PM_UP_THR "
+                                   "value - 0x%08x",
+                                   hw->device_id, *value);
+                       return true;
+               }
+       }
+
+       return false;
+}
+
 static int
 i40e_dev_sync_phy_type(struct i40e_hw *hw)
 {
@@ -10066,13 +10395,16 @@ i40e_configure_registers(struct i40e_hw *hw)
                }
 
                if (reg_table[i].addr == I40E_GL_SWR_PM_UP_THR) {
-                       if (I40E_PHY_TYPE_SUPPORT_40G(hw->phy.phy_types) || /* For XL710 */
-                           I40E_PHY_TYPE_SUPPORT_25G(hw->phy.phy_types)) /* For XXV710 */
-                               reg_table[i].val =
-                                       I40E_GL_SWR_PM_UP_THR_SF_VALUE;
-                       else /* For X710 */
-                               reg_table[i].val =
-                                       I40E_GL_SWR_PM_UP_THR_EF_VALUE;
+                       uint32_t cfg_val;
+
+                       if (!i40e_get_swr_pm_cfg(hw, &cfg_val)) {
+                               PMD_DRV_LOG(DEBUG, "Device 0x%x skips "
+                                           "GL_SWR_PM_UP_THR value fixup",
+                                           hw->device_id);
+                               continue;
+                       }
+
+                       reg_table[i].val = cfg_val;
                }
 
                ret = i40e_aq_debug_read_register(hw, reg_table[i].addr,
@@ -10519,6 +10851,7 @@ i40e_start_timecounters(struct rte_eth_dev *dev)
 
        switch (link.link_speed) {
        case ETH_SPEED_NUM_40G:
+       case ETH_SPEED_NUM_25G:
                tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF;
                tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32;
                break;
@@ -11141,6 +11474,12 @@ i40e_dcb_init_configure(struct rte_eth_dev *dev, bool sw_dcb)
         * LLDP MIB change event.
         */
        if (sw_dcb == TRUE) {
+               if (i40e_need_stop_lldp(dev)) {
+                       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 lldp agent is stopped, the return value from
                 * i40e_init_dcb we expect is failure with I40E_AQ_RC_EPERM
@@ -11355,6 +11694,32 @@ i40e_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
        return 0;
 }
 
+/**
+ * This function is used to check if the register is valid.
+ * Below is the valid registers list for X722 only:
+ * 0x2b800--0x2bb00
+ * 0x38700--0x38a00
+ * 0x3d800--0x3db00
+ * 0x208e00--0x209000
+ * 0x20be00--0x20c000
+ * 0x263c00--0x264000
+ * 0x265c00--0x266000
+ */
+static inline int i40e_valid_regs(enum i40e_mac_type type, uint32_t reg_offset)
+{
+       if ((type != I40E_MAC_X722) &&
+           ((reg_offset >= 0x2b800 && reg_offset <= 0x2bb00) ||
+            (reg_offset >= 0x38700 && reg_offset <= 0x38a00) ||
+            (reg_offset >= 0x3d800 && reg_offset <= 0x3db00) ||
+            (reg_offset >= 0x208e00 && reg_offset <= 0x209000) ||
+            (reg_offset >= 0x20be00 && reg_offset <= 0x20c000) ||
+            (reg_offset >= 0x263c00 && reg_offset <= 0x264000) ||
+            (reg_offset >= 0x265c00 && reg_offset <= 0x266000)))
+               return 0;
+       else
+               return 1;
+}
+
 static int i40e_get_regs(struct rte_eth_dev *dev,
                         struct rte_dev_reg_info *regs)
 {
@@ -11396,8 +11761,11 @@ static int i40e_get_regs(struct rte_eth_dev *dev,
                                reg_offset = arr_idx * reg_info->stride1 +
                                        arr_idx2 * reg_info->stride2;
                                reg_offset += reg_info->base_addr;
-                               ptr_data[reg_offset >> 2] =
-                                       I40E_READ_REG(hw, reg_offset);
+                               if (!i40e_valid_regs(hw->mac.type, reg_offset))
+                                       ptr_data[reg_offset >> 2] = 0;
+                               else
+                                       ptr_data[reg_offset >> 2] =
+                                               I40E_READ_REG(hw, reg_offset);
                        }
        }
 
@@ -11476,7 +11844,7 @@ static int i40e_get_module_info(struct rte_eth_dev *dev,
        case I40E_MODULE_TYPE_SFP:
                status = i40e_aq_get_phy_register(hw,
                                I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
-                               I40E_I2C_EEPROM_DEV_ADDR,
+                               I40E_I2C_EEPROM_DEV_ADDR, 1,
                                I40E_MODULE_SFF_8472_COMP,
                                &sff8472_comp, NULL);
                if (status)
@@ -11484,7 +11852,7 @@ static int i40e_get_module_info(struct rte_eth_dev *dev,
 
                status = i40e_aq_get_phy_register(hw,
                                I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
-                               I40E_I2C_EEPROM_DEV_ADDR,
+                               I40E_I2C_EEPROM_DEV_ADDR, 1,
                                I40E_MODULE_SFF_8472_SWAP,
                                &sff8472_swap, NULL);
                if (status)
@@ -11512,7 +11880,7 @@ static int i40e_get_module_info(struct rte_eth_dev *dev,
                /* Read from memory page 0. */
                status = i40e_aq_get_phy_register(hw,
                                I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
-                               0,
+                               0, 1,
                                I40E_MODULE_REVISION_ADDR,
                                &sff8636_rev, NULL);
                if (status)
@@ -11544,16 +11912,17 @@ static int i40e_get_module_eeprom(struct rte_eth_dev *dev,
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        bool is_sfp = false;
        i40e_status status;
-       uint8_t *data = info->data;
+       uint8_t *data;
        uint32_t value = 0;
        uint32_t i;
 
-       if (!info || !info->length || !data)
+       if (!info || !info->length || !info->data)
                return -EINVAL;
 
        if (hw->phy.link_info.module_type[0] == I40E_MODULE_TYPE_SFP)
                is_sfp = true;
 
+       data = info->data;
        for (i = 0; i < info->length; i++) {
                u32 offset = i + info->offset;
                u32 addr = is_sfp ? I40E_I2C_EEPROM_DEV_ADDR : 0;
@@ -11573,7 +11942,7 @@ static int i40e_get_module_eeprom(struct rte_eth_dev *dev,
                }
                status = i40e_aq_get_phy_register(hw,
                                I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
-                               addr, offset, &value, NULL);
+                               addr, offset, 1, &value, NULL);
                if (status)
                        return -EIO;
                data[i] = (uint8_t)value;
@@ -11582,7 +11951,7 @@ static int i40e_get_module_eeprom(struct rte_eth_dev *dev,
 }
 
 static int i40e_set_default_mac_addr(struct rte_eth_dev *dev,
-                                    struct ether_addr *mac_addr)
+                                    struct rte_ether_addr *mac_addr)
 {
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
@@ -11704,7 +12073,7 @@ i40e_tunnel_filter_restore(struct i40e_pf *pf)
        struct i40e_tunnel_filter_list
                *tunnel_list = &pf->tunnel.tunnel_list;
        struct i40e_tunnel_filter *f;
-       struct i40e_aqc_add_rm_cloud_filt_elem_ext cld_filter;
+       struct i40e_aqc_cloud_filters_element_bb cld_filter;
        bool big_buffer = 0;
 
        TAILQ_FOREACH(f, tunnel_list, rules) {
@@ -11715,10 +12084,10 @@ i40e_tunnel_filter_restore(struct i40e_pf *pf)
                        vsi = vf->vsi;
                }
                memset(&cld_filter, 0, sizeof(cld_filter));
-               ether_addr_copy((struct ether_addr *)&f->input.outer_mac,
-                       (struct ether_addr *)&cld_filter.element.outer_mac);
-               ether_addr_copy((struct ether_addr *)&f->input.inner_mac,
-                       (struct ether_addr *)&cld_filter.element.inner_mac);
+               ether_addr_copy((struct rte_ether_addr *)&f->input.outer_mac,
+                       (struct rte_ether_addr *)&cld_filter.element.outer_mac);
+               ether_addr_copy((struct rte_ether_addr *)&f->input.inner_mac,
+                       (struct rte_ether_addr *)&cld_filter.element.inner_mac);
                cld_filter.element.inner_vlan = f->input.inner_vlan;
                cld_filter.element.flags = f->input.flags;
                cld_filter.element.tenant_id = f->input.tenant_id;
@@ -11739,8 +12108,8 @@ i40e_tunnel_filter_restore(struct i40e_pf *pf)
                        big_buffer = 1;
 
                if (big_buffer)
-                       i40e_aq_add_cloud_filters_big_buffer(hw,
-                                            vsi->seid, &cld_filter, 1);
+                       i40e_aq_add_cloud_filters_bb(hw,
+                                       vsi->seid, &cld_filter, 1);
                else
                        i40e_aq_add_cloud_filters(hw, vsi->seid,
                                                  &cld_filter.element, 1);
@@ -11855,8 +12224,8 @@ i40e_update_customized_pctype(struct rte_eth_dev *dev, uint8_t *pkg,
                        for (n = 0; n < proto_num; n++) {
                                if (proto[n].proto_id != proto_id)
                                        continue;
-                               strcat(name, proto[n].name);
-                               strcat(name, "_");
+                               strlcat(name, proto[n].name, sizeof(name));
+                               strlcat(name, "_", sizeof(name));
                                break;
                        }
                }
@@ -12069,7 +12438,8 @@ i40e_update_customized_ptype(struct rte_eth_dev *dev, uint8_t *pkg,
                                        ptype_mapping[i].sw_ptype |=
                                                RTE_PTYPE_TUNNEL_GRENAT;
                                        in_tunnel = true;
-                               } else if (!strncasecmp(name, "L2TPV2CTL", 9)) {
+                               } else if (!strncasecmp(name, "L2TPV2CTL", 9) ||
+                                          !strncasecmp(name, "L2TPV2", 6)) {
                                        ptype_mapping[i].sw_ptype |=
                                                RTE_PTYPE_TUNNEL_L2TP;
                                        in_tunnel = true;
@@ -12213,6 +12583,7 @@ i40e_cloud_filter_qinq_create(struct i40e_pf *pf)
        struct i40e_aqc_replace_cloud_filters_cmd  filter_replace;
        struct i40e_aqc_replace_cloud_filters_cmd_buf  filter_replace_buf;
        struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+       struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;
 
        if (pf->support_multi_driver) {
                PMD_DRV_LOG(ERR, "Replace cloud filter is not supported.");
@@ -12249,10 +12620,14 @@ i40e_cloud_filter_qinq_create(struct i40e_pf *pf)
                        &filter_replace_buf);
        if (ret != I40E_SUCCESS)
                return ret;
-       PMD_DRV_LOG(DEBUG, "Global configuration modification: "
-                   "cloud l1 type is changed from 0x%x to 0x%x",
-                   filter_replace.old_filter_type,
-                   filter_replace.new_filter_type);
+
+       if (filter_replace.old_filter_type !=
+           filter_replace.new_filter_type)
+               PMD_DRV_LOG(WARNING, "i40e device %s changed cloud l1 type."
+                           " original: 0x%x, new: 0x%x",
+                           dev->device->name,
+                           filter_replace.old_filter_type,
+                           filter_replace.new_filter_type);
 
        /* Apply the second L2 cloud filter */
        memset(&filter_replace, 0,
@@ -12274,13 +12649,14 @@ i40e_cloud_filter_qinq_create(struct i40e_pf *pf)
                I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
        ret = i40e_aq_replace_cloud_filters(hw, &filter_replace,
                        &filter_replace_buf);
-       if (!ret) {
-               i40e_global_cfg_warning(I40E_WARNING_RPL_CLD_FILTER);
-               PMD_DRV_LOG(DEBUG, "Global configuration modification: "
-                           "cloud filter type is changed from 0x%x to 0x%x",
+       if (!ret && (filter_replace.old_filter_type !=
+                    filter_replace.new_filter_type))
+               PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type."
+                           " original: 0x%x, new: 0x%x",
+                           dev->device->name,
                            filter_replace.old_filter_type,
                            filter_replace.new_filter_type);
-       }
+
        return ret;
 }
 
@@ -12291,16 +12667,19 @@ i40e_rss_conf_init(struct i40e_rte_flow_rss_conf *out,
        if (in->key_len > RTE_DIM(out->key) ||
            in->queue_num > RTE_DIM(out->queue))
                return -EINVAL;
+       if (!in->key && in->key_len)
+               return -EINVAL;
        out->conf = (struct rte_flow_action_rss){
                .func = in->func,
                .level = in->level,
                .types = in->types,
                .key_len = in->key_len,
                .queue_num = in->queue_num,
-               .key = memcpy(out->key, in->key, in->key_len),
                .queue = memcpy(out->queue, in->queue,
                                sizeof(*in->queue) * in->queue_num),
        };
+       if (in->key)
+               out->conf.key = memcpy(out->key, in->key, in->key_len);
        return 0;
 }
 
@@ -12343,9 +12722,6 @@ i40e_config_rss_filter(struct i40e_pf *pf,
                return -EINVAL;
        }
 
-       if (rss_info->conf.queue_num)
-               return -EINVAL;
-
        /* If both VMDQ and RSS enabled, not all of PF queues are configured.
         * It's necessary to calculate the actual PF queues that are configured.
         */
@@ -12388,6 +12764,8 @@ i40e_config_rss_filter(struct i40e_pf *pf,
                rss_conf.rss_key = (uint8_t *)rss_key_default;
                rss_conf.rss_key_len = (I40E_PFQF_HKEY_MAX_INDEX + 1) *
                                                        sizeof(uint32_t);
+               PMD_DRV_LOG(INFO,
+                       "No valid RSS key config for i40e, using default\n");
        }
 
        i40e_hw_rss_hash_set(pf, &rss_conf);
@@ -12398,9 +12776,7 @@ i40e_config_rss_filter(struct i40e_pf *pf,
        return 0;
 }
 
-RTE_INIT(i40e_init_log);
-static void
-i40e_init_log(void)
+RTE_INIT(i40e_init_log)
 {
        i40e_logtype_init = rte_log_register("pmd.net.i40e.init");
        if (i40e_logtype_init >= 0)
@@ -12411,5 +12787,8 @@ i40e_init_log(void)
 }
 
 RTE_PMD_REGISTER_PARAM_STRING(net_i40e,
-                             QUEUE_NUM_PER_VF_ARG "=1|2|4|8|16"
-                             ETH_I40E_SUPPORT_MULTI_DRIVER "=1");
+                             ETH_I40E_FLOATING_VEB_ARG "=1"
+                             ETH_I40E_FLOATING_VEB_LIST_ARG "=<string>"
+                             ETH_I40E_QUEUE_NUM_PER_VF_ARG "=1|2|4|8|16"
+                             ETH_I40E_SUPPORT_MULTI_DRIVER "=1"
+                             ETH_I40E_USE_LATEST_VEC "=0|1");