net/ice: refine debug build option
[dpdk.git] / drivers / net / ice / ice_ethdev.c
index cfd357b..5082c22 100644 (file)
@@ -3,7 +3,7 @@
  */
 
 #include <rte_string_fns.h>
-#include <rte_ethdev_pci.h>
+#include <ethdev_pci.h>
 
 #include <stdio.h>
 #include <sys/types.h>
@@ -33,7 +33,7 @@ static const char * const ice_valid_args[] = {
 };
 
 static const struct rte_mbuf_dynfield ice_proto_xtr_metadata_param = {
-       .name = "ice_dynfield_proto_xtr_metadata",
+       .name = "intel_pmd_dynfield_proto_xtr_metadata",
        .size = sizeof(uint32_t),
        .align = __alignof__(uint32_t),
        .flags = 0,
@@ -49,35 +49,33 @@ static bool ice_proto_xtr_hw_support[PROTO_XTR_MAX];
 
 static struct proto_xtr_ol_flag ice_proto_xtr_ol_flag_params[] = {
        [PROTO_XTR_VLAN] = {
-               .param = { .name = "ice_dynflag_proto_xtr_vlan" },
+               .param = { .name = "intel_pmd_dynflag_proto_xtr_vlan" },
                .ol_flag = &rte_net_ice_dynflag_proto_xtr_vlan_mask },
        [PROTO_XTR_IPV4] = {
-               .param = { .name = "ice_dynflag_proto_xtr_ipv4" },
+               .param = { .name = "intel_pmd_dynflag_proto_xtr_ipv4" },
                .ol_flag = &rte_net_ice_dynflag_proto_xtr_ipv4_mask },
        [PROTO_XTR_IPV6] = {
-               .param = { .name = "ice_dynflag_proto_xtr_ipv6" },
+               .param = { .name = "intel_pmd_dynflag_proto_xtr_ipv6" },
                .ol_flag = &rte_net_ice_dynflag_proto_xtr_ipv6_mask },
        [PROTO_XTR_IPV6_FLOW] = {
-               .param = { .name = "ice_dynflag_proto_xtr_ipv6_flow" },
+               .param = { .name = "intel_pmd_dynflag_proto_xtr_ipv6_flow" },
                .ol_flag = &rte_net_ice_dynflag_proto_xtr_ipv6_flow_mask },
        [PROTO_XTR_TCP] = {
-               .param = { .name = "ice_dynflag_proto_xtr_tcp" },
+               .param = { .name = "intel_pmd_dynflag_proto_xtr_tcp" },
                .ol_flag = &rte_net_ice_dynflag_proto_xtr_tcp_mask },
        [PROTO_XTR_IP_OFFSET] = {
-               .param = { .name = "ice_dynflag_proto_xtr_ip_offset" },
+               .param = { .name = "intel_pmd_dynflag_proto_xtr_ip_offset" },
                .ol_flag = &rte_net_ice_dynflag_proto_xtr_ip_offset_mask },
 };
 
-#define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100
-
 #define ICE_OS_DEFAULT_PKG_NAME                "ICE OS Default Package"
 #define ICE_COMMS_PKG_NAME                     "ICE COMMS Package"
 #define ICE_MAX_RES_DESC_NUM        1024
 
 static int ice_dev_configure(struct rte_eth_dev *dev);
 static int ice_dev_start(struct rte_eth_dev *dev);
-static void ice_dev_stop(struct rte_eth_dev *dev);
-static void ice_dev_close(struct rte_eth_dev *dev);
+static int ice_dev_stop(struct rte_eth_dev *dev);
+static int ice_dev_close(struct rte_eth_dev *dev);
 static int ice_dev_reset(struct rte_eth_dev *dev);
 static int ice_dev_info_get(struct rte_eth_dev *dev,
                            struct rte_eth_dev_info *dev_info);
@@ -131,10 +129,8 @@ static int ice_xstats_get(struct rte_eth_dev *dev,
 static int ice_xstats_get_names(struct rte_eth_dev *dev,
                                struct rte_eth_xstat_name *xstats_names,
                                unsigned int limit);
-static int ice_dev_filter_ctrl(struct rte_eth_dev *dev,
-                       enum rte_filter_type filter_type,
-                       enum rte_filter_op filter_op,
-                       void *arg);
+static int ice_dev_flow_ops_get(struct rte_eth_dev *dev,
+                               const struct rte_flow_ops **ops);
 static int ice_dev_udp_tunnel_port_add(struct rte_eth_dev *dev,
                        struct rte_eth_udp_tunnel *udp_tunnel);
 static int ice_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
@@ -152,6 +148,11 @@ static const struct rte_pci_id pci_id_ice_map[] = {
        { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E810_XXV_BACKPLANE) },
        { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E810_XXV_QSFP) },
        { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E810_XXV_SFP) },
+       { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E823C_BACKPLANE) },
+       { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E823C_QSFP) },
+       { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E823C_SFP) },
+       { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E823C_10G_BASE_T) },
+       { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E823C_SGMII) },
        { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E822C_BACKPLANE) },
        { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E822C_QSFP) },
        { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E822C_SFP) },
@@ -212,10 +213,11 @@ static const struct eth_dev_ops ice_eth_dev_ops = {
        .xstats_get                   = ice_xstats_get,
        .xstats_get_names             = ice_xstats_get_names,
        .xstats_reset                 = ice_stats_reset,
-       .filter_ctrl                  = ice_dev_filter_ctrl,
+       .flow_ops_get                 = ice_dev_flow_ops_get,
        .udp_tunnel_port_add          = ice_dev_udp_tunnel_port_add,
        .udp_tunnel_port_del          = ice_dev_udp_tunnel_port_del,
        .tx_done_cleanup              = ice_tx_done_cleanup,
+       .get_monitor_addr             = ice_get_monitor_addr,
 };
 
 /* store statistics names and its offset in stats structure */
@@ -805,7 +807,7 @@ ice_init_mac_address(struct rte_eth_dev *dev)
                (struct rte_ether_addr *)hw->port_info[0].mac.perm_addr);
 
        dev->data->mac_addrs =
-               rte_zmalloc(NULL, sizeof(struct rte_ether_addr), 0);
+               rte_zmalloc(NULL, sizeof(struct rte_ether_addr) * ICE_NUM_MACADDR_MAX, 0);
        if (!dev->data->mac_addrs) {
                PMD_INIT_LOG(ERR,
                             "Failed to allocate memory to store mac address");
@@ -944,12 +946,13 @@ DONE:
 
 /* Find out specific VLAN filter */
 static struct ice_vlan_filter *
-ice_find_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id)
+ice_find_vlan_filter(struct ice_vsi *vsi, struct ice_vlan *vlan)
 {
        struct ice_vlan_filter *f;
 
        TAILQ_FOREACH(f, &vsi->vlan_list, next) {
-               if (vlan_id == f->vlan_info.vlan_id)
+               if (vlan->tpid == f->vlan_info.vlan.tpid &&
+                   vlan->vid == f->vlan_info.vlan.vid)
                        return f;
        }
 
@@ -957,7 +960,7 @@ ice_find_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id)
 }
 
 static int
-ice_add_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id)
+ice_add_vlan_filter(struct ice_vsi *vsi, struct ice_vlan *vlan)
 {
        struct ice_fltr_list_entry *v_list_itr = NULL;
        struct ice_vlan_filter *f;
@@ -965,13 +968,13 @@ ice_add_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id)
        struct ice_hw *hw;
        int ret = 0;
 
-       if (!vsi || vlan_id > RTE_ETHER_MAX_VLAN_ID)
+       if (!vsi || vlan->vid > RTE_ETHER_MAX_VLAN_ID)
                return -EINVAL;
 
        hw = ICE_VSI_TO_HW(vsi);
 
        /* If it's added and configured, return. */
-       f = ice_find_vlan_filter(vsi, vlan_id);
+       f = ice_find_vlan_filter(vsi, vlan);
        if (f) {
                PMD_DRV_LOG(INFO, "This VLAN filter already exists.");
                return 0;
@@ -988,7 +991,9 @@ ice_add_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id)
                ret = -ENOMEM;
                goto DONE;
        }
-       v_list_itr->fltr_info.l_data.vlan.vlan_id = vlan_id;
+       v_list_itr->fltr_info.l_data.vlan.vlan_id = vlan->vid;
+       v_list_itr->fltr_info.l_data.vlan.tpid = vlan->tpid;
+       v_list_itr->fltr_info.l_data.vlan.tpid_valid = true;
        v_list_itr->fltr_info.src_id = ICE_SRC_ID_VSI;
        v_list_itr->fltr_info.fltr_act = ICE_FWD_TO_VSI;
        v_list_itr->fltr_info.lkup_type = ICE_SW_LKUP_VLAN;
@@ -1012,7 +1017,8 @@ ice_add_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id)
                ret = -ENOMEM;
                goto DONE;
        }
-       f->vlan_info.vlan_id = vlan_id;
+       f->vlan_info.vlan.tpid = vlan->tpid;
+       f->vlan_info.vlan.vid = vlan->vid;
        TAILQ_INSERT_TAIL(&vsi->vlan_list, f, next);
        vsi->vlan_num++;
 
@@ -1024,7 +1030,7 @@ DONE:
 }
 
 static int
-ice_remove_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id)
+ice_remove_vlan_filter(struct ice_vsi *vsi, struct ice_vlan *vlan)
 {
        struct ice_fltr_list_entry *v_list_itr = NULL;
        struct ice_vlan_filter *f;
@@ -1032,17 +1038,13 @@ ice_remove_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id)
        struct ice_hw *hw;
        int ret = 0;
 
-       /**
-        * Vlan 0 is the generic filter for untagged packets
-        * and can't be removed.
-        */
-       if (!vsi || vlan_id == 0 || vlan_id > RTE_ETHER_MAX_VLAN_ID)
+       if (!vsi || vlan->vid > RTE_ETHER_MAX_VLAN_ID)
                return -EINVAL;
 
        hw = ICE_VSI_TO_HW(vsi);
 
        /* Can't find it, return an error */
-       f = ice_find_vlan_filter(vsi, vlan_id);
+       f = ice_find_vlan_filter(vsi, vlan);
        if (!f)
                return -EINVAL;
 
@@ -1055,7 +1057,9 @@ ice_remove_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id)
                goto DONE;
        }
 
-       v_list_itr->fltr_info.l_data.vlan.vlan_id = vlan_id;
+       v_list_itr->fltr_info.l_data.vlan.vlan_id = vlan->vid;
+       v_list_itr->fltr_info.l_data.vlan.tpid = vlan->tpid;
+       v_list_itr->fltr_info.l_data.vlan.tpid_valid = true;
        v_list_itr->fltr_info.src_id = ICE_SRC_ID_VSI;
        v_list_itr->fltr_info.fltr_act = ICE_FWD_TO_VSI;
        v_list_itr->fltr_info.lkup_type = ICE_SW_LKUP_VLAN;
@@ -1105,7 +1109,7 @@ ice_remove_all_mac_vlan_filters(struct ice_vsi *vsi)
                return 0;
 
        TAILQ_FOREACH(v_f, &vsi->vlan_list, next) {
-               ret = ice_remove_vlan_filter(vsi, v_f->vlan_info.vlan_id);
+               ret = ice_remove_vlan_filter(vsi, &v_f->vlan_info.vlan);
                if (ret != ICE_SUCCESS) {
                        ret = -EINVAL;
                        goto DONE;
@@ -1116,127 +1120,6 @@ DONE:
        return ret;
 }
 
-static int
-ice_vsi_config_qinq_insertion(struct ice_vsi *vsi, bool on)
-{
-       struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
-       struct ice_vsi_ctx ctxt;
-       uint8_t qinq_flags;
-       int ret = 0;
-
-       /* Check if it has been already on or off */
-       if (vsi->info.valid_sections &
-               rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID)) {
-               if (on) {
-                       if ((vsi->info.outer_tag_flags &
-                            ICE_AQ_VSI_OUTER_TAG_ACCEPT_HOST) ==
-                           ICE_AQ_VSI_OUTER_TAG_ACCEPT_HOST)
-                               return 0; /* already on */
-               } else {
-                       if (!(vsi->info.outer_tag_flags &
-                             ICE_AQ_VSI_OUTER_TAG_ACCEPT_HOST))
-                               return 0; /* already off */
-               }
-       }
-
-       if (on)
-               qinq_flags = ICE_AQ_VSI_OUTER_TAG_ACCEPT_HOST;
-       else
-               qinq_flags = 0;
-       /* clear global insertion and use per packet insertion */
-       vsi->info.outer_tag_flags &= ~(ICE_AQ_VSI_OUTER_TAG_INSERT);
-       vsi->info.outer_tag_flags &= ~(ICE_AQ_VSI_OUTER_TAG_ACCEPT_HOST);
-       vsi->info.outer_tag_flags |= qinq_flags;
-       /* use default vlan type 0x8100 */
-       vsi->info.outer_tag_flags &= ~(ICE_AQ_VSI_OUTER_TAG_TYPE_M);
-       vsi->info.outer_tag_flags |= ICE_DFLT_OUTER_TAG_TYPE <<
-                                    ICE_AQ_VSI_OUTER_TAG_TYPE_S;
-       (void)rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
-       ctxt.info.valid_sections =
-                       rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID);
-       ctxt.vsi_num = vsi->vsi_id;
-       ret = ice_update_vsi(hw, vsi->idx, &ctxt, NULL);
-       if (ret) {
-               PMD_DRV_LOG(INFO,
-                           "Update VSI failed to %s qinq stripping",
-                           on ? "enable" : "disable");
-               return -EINVAL;
-       }
-
-       vsi->info.valid_sections |=
-               rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID);
-
-       return ret;
-}
-
-static int
-ice_vsi_config_qinq_stripping(struct ice_vsi *vsi, bool on)
-{
-       struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
-       struct ice_vsi_ctx ctxt;
-       uint8_t qinq_flags;
-       int ret = 0;
-
-       /* Check if it has been already on or off */
-       if (vsi->info.valid_sections &
-               rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID)) {
-               if (on) {
-                       if ((vsi->info.outer_tag_flags &
-                            ICE_AQ_VSI_OUTER_TAG_MODE_M) ==
-                           ICE_AQ_VSI_OUTER_TAG_COPY)
-                               return 0; /* already on */
-               } else {
-                       if ((vsi->info.outer_tag_flags &
-                            ICE_AQ_VSI_OUTER_TAG_MODE_M) ==
-                           ICE_AQ_VSI_OUTER_TAG_NOTHING)
-                               return 0; /* already off */
-               }
-       }
-
-       if (on)
-               qinq_flags = ICE_AQ_VSI_OUTER_TAG_COPY;
-       else
-               qinq_flags = ICE_AQ_VSI_OUTER_TAG_NOTHING;
-       vsi->info.outer_tag_flags &= ~(ICE_AQ_VSI_OUTER_TAG_MODE_M);
-       vsi->info.outer_tag_flags |= qinq_flags;
-       /* use default vlan type 0x8100 */
-       vsi->info.outer_tag_flags &= ~(ICE_AQ_VSI_OUTER_TAG_TYPE_M);
-       vsi->info.outer_tag_flags |= ICE_DFLT_OUTER_TAG_TYPE <<
-                                    ICE_AQ_VSI_OUTER_TAG_TYPE_S;
-       (void)rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
-       ctxt.info.valid_sections =
-                       rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID);
-       ctxt.vsi_num = vsi->vsi_id;
-       ret = ice_update_vsi(hw, vsi->idx, &ctxt, NULL);
-       if (ret) {
-               PMD_DRV_LOG(INFO,
-                           "Update VSI failed to %s qinq stripping",
-                           on ? "enable" : "disable");
-               return -EINVAL;
-       }
-
-       vsi->info.valid_sections |=
-               rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID);
-
-       return ret;
-}
-
-static int
-ice_vsi_config_double_vlan(struct ice_vsi *vsi, int on)
-{
-       int ret;
-
-       ret = ice_vsi_config_qinq_stripping(vsi, on);
-       if (ret)
-               PMD_DRV_LOG(ERR, "Fail to set qinq stripping - %d", ret);
-
-       ret = ice_vsi_config_qinq_insertion(vsi, on);
-       if (ret)
-               PMD_DRV_LOG(ERR, "Fail to set qinq insertion - %d", ret);
-
-       return ret;
-}
-
 /* Enable IRQ0 */
 static void
 ice_pf_enable_irq0(struct ice_hw *hw)
@@ -1579,10 +1462,20 @@ ice_setup_vsi(struct ice_pf *pf, enum ice_vsi_type type)
                vsi_ctx.info.sw_id = hw->port_info->sw_id;
                vsi_ctx.info.sw_flags2 = ICE_AQ_VSI_SW_FLAG_LAN_ENA;
                /* Allow all untagged or tagged packets */
-               vsi_ctx.info.vlan_flags = ICE_AQ_VSI_VLAN_MODE_ALL;
-               vsi_ctx.info.vlan_flags |= ICE_AQ_VSI_VLAN_EMOD_NOTHING;
+               vsi_ctx.info.inner_vlan_flags = ICE_AQ_VSI_INNER_VLAN_TX_MODE_ALL;
+               vsi_ctx.info.inner_vlan_flags |= ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING;
                vsi_ctx.info.q_opt_rss = ICE_AQ_VSI_Q_OPT_RSS_LUT_PF |
                                         ICE_AQ_VSI_Q_OPT_RSS_TPLZ;
+               if (ice_is_dvm_ena(hw)) {
+                       vsi_ctx.info.outer_vlan_flags =
+                               (ICE_AQ_VSI_OUTER_VLAN_TX_MODE_ALL <<
+                                ICE_AQ_VSI_OUTER_VLAN_TX_MODE_S) &
+                               ICE_AQ_VSI_OUTER_VLAN_TX_MODE_M;
+                       vsi_ctx.info.outer_vlan_flags |=
+                               (ICE_AQ_VSI_OUTER_TAG_VLAN_8100 <<
+                                ICE_AQ_VSI_OUTER_TAG_TYPE_S) &
+                               ICE_AQ_VSI_OUTER_TAG_TYPE_M;
+               }
 
                /* FDIR */
                cfg = ICE_AQ_VSI_PROP_SECURITY_VALID |
@@ -1753,53 +1646,6 @@ ice_pf_setup(struct ice_pf *pf)
        return 0;
 }
 
-/* PCIe configuration space setting */
-#define PCI_CFG_SPACE_SIZE          256
-#define PCI_CFG_SPACE_EXP_SIZE      4096
-#define PCI_EXT_CAP_ID(header)      (int)((header) & 0x0000ffff)
-#define PCI_EXT_CAP_NEXT(header)    (((header) >> 20) & 0xffc)
-#define PCI_EXT_CAP_ID_DSN          0x03
-
-static int
-ice_pci_find_next_ext_capability(struct rte_pci_device *dev, int cap)
-{
-       uint32_t header;
-       int ttl;
-       int pos = PCI_CFG_SPACE_SIZE;
-
-       /* minimum 8 bytes per capability */
-       ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
-
-       if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
-               PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
-               return -1;
-       }
-
-       /*
-        * If we have no capabilities, this is indicated by cap ID,
-        * cap version and next pointer all being 0.
-        */
-       if (header == 0)
-               return 0;
-
-       while (ttl-- > 0) {
-               if (PCI_EXT_CAP_ID(header) == cap)
-                       return pos;
-
-               pos = PCI_EXT_CAP_NEXT(header);
-
-               if (pos < PCI_CFG_SPACE_SIZE)
-                       break;
-
-               if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
-                       PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
 /*
  * Extract device serial number from PCIe Configuration Space and
  * determine the pkg file path according to the DSN.
@@ -1807,16 +1653,22 @@ ice_pci_find_next_ext_capability(struct rte_pci_device *dev, int cap)
 static int
 ice_pkg_file_search_path(struct rte_pci_device *pci_dev, char *pkg_file)
 {
-       int pos;
+       off_t pos;
        char opt_ddp_filename[ICE_MAX_PKG_FILENAME_SIZE];
        uint32_t dsn_low, dsn_high;
        memset(opt_ddp_filename, 0, ICE_MAX_PKG_FILENAME_SIZE);
 
-       pos = ice_pci_find_next_ext_capability(pci_dev, PCI_EXT_CAP_ID_DSN);
+       pos = rte_pci_find_ext_capability(pci_dev, RTE_PCI_EXT_CAP_ID_DSN);
 
        if (pos) {
-               rte_pci_read_config(pci_dev, &dsn_low, 4, pos + 4);
-               rte_pci_read_config(pci_dev, &dsn_high, 4, pos + 8);
+               if (rte_pci_read_config(pci_dev, &dsn_low, 4, pos + 4) < 0) {
+                       PMD_INIT_LOG(ERR, "Failed to read pci config space\n");
+                       return -1;
+               }
+               if (rte_pci_read_config(pci_dev, &dsn_high, 4, pos + 8) < 0) {
+                       PMD_INIT_LOG(ERR, "Failed to read pci config space\n");
+                       return -1;
+               }
                snprintf(opt_ddp_filename, ICE_MAX_PKG_FILENAME_SIZE,
                         "ice-%08x%08x.pkg", dsn_high, dsn_low);
        } else {
@@ -1857,10 +1709,11 @@ ice_load_pkg_type(struct ice_hw *hw)
        else
                package_type = ICE_PKG_TYPE_UNKNOWN;
 
-       PMD_INIT_LOG(NOTICE, "Active package is: %d.%d.%d.%d, %s",
+       PMD_INIT_LOG(NOTICE, "Active package is: %d.%d.%d.%d, %s (%s VLAN mode)",
                hw->active_pkg_ver.major, hw->active_pkg_ver.minor,
                hw->active_pkg_ver.update, hw->active_pkg_ver.draft,
-               hw->active_pkg_name);
+               hw->active_pkg_name,
+               ice_is_dvm_ena(hw) ? "double" : "single");
 
        return package_type;
 }
@@ -1878,7 +1731,11 @@ static int ice_load_pkg(struct rte_eth_dev *dev)
        struct ice_adapter *ad =
                ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 
-       ice_pkg_file_search_path(pci_dev, pkg_file);
+       err = ice_pkg_file_search_path(pci_dev, pkg_file);
+       if (err) {
+               PMD_INIT_LOG(ERR, "failed to search file path\n");
+               return err;
+       }
 
        file = fopen(pkg_file, "rb");
        if (!file)  {
@@ -2134,14 +1991,7 @@ ice_reset_fxp_resource(struct ice_hw *hw)
 static void
 ice_rss_ctx_init(struct ice_pf *pf)
 {
-       ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv4);
-       ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv6);
-
-       ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv4_udp);
-       ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv6_udp);
-
-       ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv4_tcp);
-       ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv6_tcp);
+       memset(&pf->hash_ctx, 0, sizeof(pf->hash_ctx));
 }
 
 static uint64_t
@@ -2191,6 +2041,8 @@ ice_dev_init(struct rte_eth_dev *dev)
                return 0;
        }
 
+       dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
+
        ice_set_default_ptype_table(dev);
        pci_dev = RTE_DEV_TO_PCI(dev->device);
        intr_handle = &pci_dev->intr_handle;
@@ -2245,11 +2097,6 @@ ice_dev_init(struct rte_eth_dev *dev)
                goto err_init_mac;
        }
 
-       /* Pass the information to the rte_eth_dev_close() that it should also
-        * release the private port resources.
-        */
-       dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE;
-
        ret = ice_res_pool_init(&pf->msix_pool, 1,
                                hw->func_caps.common_cap.num_msix_vectors - 1);
        if (ret) {
@@ -2271,9 +2118,6 @@ ice_dev_init(struct rte_eth_dev *dev)
 
        vsi = pf->main_vsi;
 
-       /* Disable double vlan by default */
-       ice_vsi_config_double_vlan(vsi, false);
-
        ret = ice_aq_stop_lldp(hw, true, false, NULL);
        if (ret != ICE_SUCCESS)
                PMD_INIT_LOG(DEBUG, "lldp has already stopped\n");
@@ -2390,7 +2234,7 @@ ice_vsi_disable_queues_intr(struct ice_vsi *vsi)
                ICE_WRITE_REG(hw, GLINT_DYN_CTL(0), GLINT_DYN_CTL_WB_ON_ITR_M);
 }
 
-static void
+static int
 ice_dev_stop(struct rte_eth_dev *dev)
 {
        struct rte_eth_dev_data *data = dev->data;
@@ -2402,7 +2246,7 @@ ice_dev_stop(struct rte_eth_dev *dev)
 
        /* avoid stopping again */
        if (pf->adapter_stopped)
-               return;
+               return 0;
 
        /* stop and clear all Rx queues */
        for (i = 0; i < data->nb_rx_queues; i++)
@@ -2428,9 +2272,12 @@ ice_dev_stop(struct rte_eth_dev *dev)
        }
 
        pf->adapter_stopped = true;
+       dev->data->dev_started = 0;
+
+       return 0;
 }
 
-static void
+static int
 ice_dev_close(struct rte_eth_dev *dev)
 {
        struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
@@ -2439,6 +2286,10 @@ ice_dev_close(struct rte_eth_dev *dev)
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct ice_adapter *ad =
                ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+       int ret;
+
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
 
        /* Since stop will make link down, then the link event will be
         * triggered, disable the irq firstly to avoid the port_infoe etc
@@ -2447,7 +2298,7 @@ ice_dev_close(struct rte_eth_dev *dev)
         */
        ice_pf_disable_irq0(hw);
 
-       ice_dev_stop(dev);
+       ret = ice_dev_stop(dev);
 
        if (!ad->is_safe_mode)
                ice_flow_uninit(ad);
@@ -2465,19 +2316,14 @@ ice_dev_close(struct rte_eth_dev *dev)
        rte_free(pf->proto_xtr);
        pf->proto_xtr = NULL;
 
-       dev->dev_ops = NULL;
-       dev->rx_pkt_burst = NULL;
-       dev->tx_pkt_burst = NULL;
-
-       rte_free(dev->data->mac_addrs);
-       dev->data->mac_addrs = NULL;
-
        /* disable uio intr before callback unregister */
        rte_intr_disable(intr_handle);
 
        /* unregister callback func from eal lib */
        rte_intr_callback_unregister(intr_handle,
                                     ice_interrupt_handler, dev);
+
+       return ret;
 }
 
 static int
@@ -2488,268 +2334,473 @@ ice_dev_uninit(struct rte_eth_dev *dev)
        return 0;
 }
 
+static bool
+is_hash_cfg_valid(struct ice_rss_hash_cfg *cfg)
+{
+       return (cfg->hash_flds != 0 && cfg->addl_hdrs != 0) ? true : false;
+}
+
+static void
+hash_cfg_reset(struct ice_rss_hash_cfg *cfg)
+{
+       cfg->hash_flds = 0;
+       cfg->addl_hdrs = 0;
+       cfg->symm = 0;
+       cfg->hdr_type = ICE_RSS_OUTER_HEADERS;
+}
+
 static int
-ice_add_rss_cfg_post(struct ice_pf *pf, uint32_t hdr, uint64_t fld, bool symm)
+ice_hash_moveout(struct ice_pf *pf, struct ice_rss_hash_cfg *cfg)
 {
+       enum ice_status status = ICE_SUCCESS;
        struct ice_hw *hw = ICE_PF_TO_HW(pf);
        struct ice_vsi *vsi = pf->main_vsi;
 
-       if (hdr & ICE_FLOW_SEG_HDR_GTPU_EH) {
-               if ((hdr & ICE_FLOW_SEG_HDR_IPV4) &&
-                   (hdr & ICE_FLOW_SEG_HDR_UDP)) {
-                       pf->gtpu_hash_ctx.ipv4_udp.pkt_hdr = hdr;
-                       pf->gtpu_hash_ctx.ipv4_udp.hash_fld = fld;
-                       pf->gtpu_hash_ctx.ipv4_udp.symm = symm;
-               } else if ((hdr & ICE_FLOW_SEG_HDR_IPV6) &&
-                          (hdr & ICE_FLOW_SEG_HDR_UDP)) {
-                       pf->gtpu_hash_ctx.ipv6_udp.pkt_hdr = hdr;
-                       pf->gtpu_hash_ctx.ipv6_udp.hash_fld = fld;
-                       pf->gtpu_hash_ctx.ipv6_udp.symm = symm;
-               } else if ((hdr & ICE_FLOW_SEG_HDR_IPV4) &&
-                          (hdr & ICE_FLOW_SEG_HDR_TCP)) {
-                       pf->gtpu_hash_ctx.ipv4_tcp.pkt_hdr = hdr;
-                       pf->gtpu_hash_ctx.ipv4_tcp.hash_fld = fld;
-                       pf->gtpu_hash_ctx.ipv4_tcp.symm = symm;
-               } else if ((hdr & ICE_FLOW_SEG_HDR_IPV6) &&
-                          (hdr & ICE_FLOW_SEG_HDR_TCP)) {
-                       pf->gtpu_hash_ctx.ipv6_tcp.pkt_hdr = hdr;
-                       pf->gtpu_hash_ctx.ipv6_tcp.hash_fld = fld;
-                       pf->gtpu_hash_ctx.ipv6_tcp.symm = symm;
-               } else if (hdr & ICE_FLOW_SEG_HDR_IPV4) {
-                       pf->gtpu_hash_ctx.ipv4.pkt_hdr = hdr;
-                       pf->gtpu_hash_ctx.ipv4.hash_fld = fld;
-                       pf->gtpu_hash_ctx.ipv4.symm = symm;
-                       ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv4_udp);
-                       ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv4_tcp);
-               } else if (hdr & ICE_FLOW_SEG_HDR_IPV6) {
-                       pf->gtpu_hash_ctx.ipv6.pkt_hdr = hdr;
-                       pf->gtpu_hash_ctx.ipv6.hash_fld = fld;
-                       pf->gtpu_hash_ctx.ipv6.symm = symm;
-                       ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv6_udp);
-                       ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv6_tcp);
-               }
-       }
+       if (!is_hash_cfg_valid(cfg))
+               return -ENOENT;
 
-       if (hdr & (ICE_FLOW_SEG_HDR_GTPU_DWN |
-           ICE_FLOW_SEG_HDR_GTPU_UP)) {
-               if ((hdr & ICE_FLOW_SEG_HDR_IPV4) &&
-                   (hdr & ICE_FLOW_SEG_HDR_UDP)) {
-                       if (ICE_HASH_CFG_IS_ROTATING(&pf->gtpu_hash_ctx.ipv4)) {
-                               ice_add_rss_cfg(hw, vsi->idx,
-                                       pf->gtpu_hash_ctx.ipv4.hash_fld,
-                                       pf->gtpu_hash_ctx.ipv4.pkt_hdr,
-                                       pf->gtpu_hash_ctx.ipv4.symm);
-                               ICE_HASH_CFG_ROTATE_STOP(&pf->gtpu_hash_ctx.ipv4);
-                       }
-               } else if ((hdr & ICE_FLOW_SEG_HDR_IPV6) &&
-                          (hdr & ICE_FLOW_SEG_HDR_UDP)) {
-                       if (ICE_HASH_CFG_IS_ROTATING(&pf->gtpu_hash_ctx.ipv6)) {
-                               ice_add_rss_cfg(hw, vsi->idx,
-                                       pf->gtpu_hash_ctx.ipv6.hash_fld,
-                                       pf->gtpu_hash_ctx.ipv6.pkt_hdr,
-                                       pf->gtpu_hash_ctx.ipv6.symm);
-                               ICE_HASH_CFG_ROTATE_STOP(&pf->gtpu_hash_ctx.ipv6);
-                       }
-               } else if ((hdr & ICE_FLOW_SEG_HDR_IPV4) &&
-                          (hdr & ICE_FLOW_SEG_HDR_TCP)) {
-                       if (ICE_HASH_CFG_IS_ROTATING(&pf->gtpu_hash_ctx.ipv4)) {
-                               ice_add_rss_cfg(hw, vsi->idx,
-                                       pf->gtpu_hash_ctx.ipv4.hash_fld,
-                                       pf->gtpu_hash_ctx.ipv4.pkt_hdr,
-                                       pf->gtpu_hash_ctx.ipv4.symm);
-                               ICE_HASH_CFG_ROTATE_STOP(&pf->gtpu_hash_ctx.ipv4);
-                       }
-               } else if ((hdr & ICE_FLOW_SEG_HDR_IPV6) &&
-                          (hdr & ICE_FLOW_SEG_HDR_TCP)) {
-                       if (ICE_HASH_CFG_IS_ROTATING(&pf->gtpu_hash_ctx.ipv6)) {
-                               ice_add_rss_cfg(hw, vsi->idx,
-                                       pf->gtpu_hash_ctx.ipv6.hash_fld,
-                                       pf->gtpu_hash_ctx.ipv6.pkt_hdr,
-                                       pf->gtpu_hash_ctx.ipv6.symm);
-                               ICE_HASH_CFG_ROTATE_STOP(&pf->gtpu_hash_ctx.ipv6);
-                       }
-               }
+       status = ice_rem_rss_cfg(hw, vsi->idx, cfg);
+       if (status && status != ICE_ERR_DOES_NOT_EXIST) {
+               PMD_DRV_LOG(ERR,
+                           "ice_rem_rss_cfg failed for VSI:%d, error:%d\n",
+                           vsi->idx, status);
+               return -EBUSY;
        }
 
        return 0;
 }
 
 static int
-ice_add_rss_cfg_pre(struct ice_pf *pf, uint32_t hdr)
+ice_hash_moveback(struct ice_pf *pf, struct ice_rss_hash_cfg *cfg)
 {
+       enum ice_status status = ICE_SUCCESS;
        struct ice_hw *hw = ICE_PF_TO_HW(pf);
        struct ice_vsi *vsi = pf->main_vsi;
 
-       if (hdr & (ICE_FLOW_SEG_HDR_GTPU_DWN |
-           ICE_FLOW_SEG_HDR_GTPU_UP)) {
-               if ((hdr & ICE_FLOW_SEG_HDR_IPV4) &&
-                   (hdr & ICE_FLOW_SEG_HDR_UDP)) {
-                       if (ICE_HASH_CFG_VALID(&pf->gtpu_hash_ctx.ipv4_udp)) {
-                               ice_rem_rss_cfg(hw, vsi->idx,
-                                       pf->gtpu_hash_ctx.ipv4_udp.hash_fld,
-                                       pf->gtpu_hash_ctx.ipv4_udp.pkt_hdr);
-                               ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv4_udp);
-                       }
+       if (!is_hash_cfg_valid(cfg))
+               return -ENOENT;
 
-                       if (ICE_HASH_CFG_VALID(&pf->gtpu_hash_ctx.ipv4)) {
-                               ice_rem_rss_cfg(hw, vsi->idx,
-                                       pf->gtpu_hash_ctx.ipv4.hash_fld,
-                                       pf->gtpu_hash_ctx.ipv4.pkt_hdr);
-                               ICE_HASH_CFG_ROTATE_START(&pf->gtpu_hash_ctx.ipv4);
-                       }
-               } else if ((hdr & ICE_FLOW_SEG_HDR_IPV6) &&
-                          (hdr & ICE_FLOW_SEG_HDR_UDP)) {
-                       if (ICE_HASH_CFG_VALID(&pf->gtpu_hash_ctx.ipv6_udp)) {
-                               ice_rem_rss_cfg(hw, vsi->idx,
-                                       pf->gtpu_hash_ctx.ipv6_udp.hash_fld,
-                                       pf->gtpu_hash_ctx.ipv6_udp.pkt_hdr);
-                               ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv6_udp);
-                       }
+       status = ice_add_rss_cfg(hw, vsi->idx, cfg);
+       if (status) {
+               PMD_DRV_LOG(ERR,
+                           "ice_add_rss_cfg failed for VSI:%d, error:%d\n",
+                           vsi->idx, status);
+               return -EBUSY;
+       }
 
-                       if (ICE_HASH_CFG_VALID(&pf->gtpu_hash_ctx.ipv6)) {
-                               ice_rem_rss_cfg(hw, vsi->idx,
-                                       pf->gtpu_hash_ctx.ipv6.hash_fld,
-                                       pf->gtpu_hash_ctx.ipv6.pkt_hdr);
-                               ICE_HASH_CFG_ROTATE_START(&pf->gtpu_hash_ctx.ipv6);
-                       }
-               } else if ((hdr & ICE_FLOW_SEG_HDR_IPV4) &&
-                          (hdr & ICE_FLOW_SEG_HDR_TCP)) {
-                       if (ICE_HASH_CFG_VALID(&pf->gtpu_hash_ctx.ipv4_tcp)) {
-                               ice_rem_rss_cfg(hw, vsi->idx,
-                                       pf->gtpu_hash_ctx.ipv4_tcp.hash_fld,
-                                       pf->gtpu_hash_ctx.ipv4_tcp.pkt_hdr);
-                               ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv4_tcp);
-                       }
+       return 0;
+}
 
-                       if (ICE_HASH_CFG_VALID(&pf->gtpu_hash_ctx.ipv4)) {
-                               ice_rem_rss_cfg(hw, vsi->idx,
-                                       pf->gtpu_hash_ctx.ipv4.hash_fld,
-                                       pf->gtpu_hash_ctx.ipv4.pkt_hdr);
-                               ICE_HASH_CFG_ROTATE_START(&pf->gtpu_hash_ctx.ipv4);
-                       }
-               } else if ((hdr & ICE_FLOW_SEG_HDR_IPV6) &&
-                          (hdr & ICE_FLOW_SEG_HDR_TCP)) {
-                       if (ICE_HASH_CFG_VALID(&pf->gtpu_hash_ctx.ipv6_tcp)) {
-                               ice_rem_rss_cfg(hw, vsi->idx,
-                                       pf->gtpu_hash_ctx.ipv6_tcp.hash_fld,
-                                       pf->gtpu_hash_ctx.ipv6_tcp.pkt_hdr);
-                               ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv6_tcp);
-                       }
+static int
+ice_hash_remove(struct ice_pf *pf, struct ice_rss_hash_cfg *cfg)
+{
+       int ret;
 
-                       if (ICE_HASH_CFG_VALID(&pf->gtpu_hash_ctx.ipv6)) {
-                               ice_rem_rss_cfg(hw, vsi->idx,
-                                       pf->gtpu_hash_ctx.ipv6.hash_fld,
-                                       pf->gtpu_hash_ctx.ipv6.pkt_hdr);
-                               ICE_HASH_CFG_ROTATE_START(&pf->gtpu_hash_ctx.ipv6);
-                       }
-               } else if (hdr & ICE_FLOW_SEG_HDR_IPV4) {
-                       if (ICE_HASH_CFG_VALID(&pf->gtpu_hash_ctx.ipv4)) {
-                               ice_rem_rss_cfg(hw, vsi->idx,
-                                       pf->gtpu_hash_ctx.ipv4.hash_fld,
-                                       pf->gtpu_hash_ctx.ipv4.pkt_hdr);
-                               ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv4);
-                       }
+       ret = ice_hash_moveout(pf, cfg);
+       if (ret && (ret != -ENOENT))
+               return ret;
 
-                       if (ICE_HASH_CFG_VALID(&pf->gtpu_hash_ctx.ipv4_udp)) {
-                               ice_rem_rss_cfg(hw, vsi->idx,
-                                       pf->gtpu_hash_ctx.ipv4_udp.hash_fld,
-                                       pf->gtpu_hash_ctx.ipv4_udp.pkt_hdr);
-                               ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv4_udp);
-                       }
+       hash_cfg_reset(cfg);
 
-                       if (ICE_HASH_CFG_VALID(&pf->gtpu_hash_ctx.ipv4_tcp)) {
-                               ice_rem_rss_cfg(hw, vsi->idx,
-                                       pf->gtpu_hash_ctx.ipv4_tcp.hash_fld,
-                                       pf->gtpu_hash_ctx.ipv4_tcp.pkt_hdr);
-                               ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv4_tcp);
-                       }
-               } else if (hdr & ICE_FLOW_SEG_HDR_IPV6) {
-                       if (ICE_HASH_CFG_VALID(&pf->gtpu_hash_ctx.ipv6)) {
-                               ice_rem_rss_cfg(hw, vsi->idx,
-                                       pf->gtpu_hash_ctx.ipv6.hash_fld,
-                                       pf->gtpu_hash_ctx.ipv6.pkt_hdr);
-                               ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv6);
-                       }
+       return 0;
+}
 
-                       if (ICE_HASH_CFG_VALID(&pf->gtpu_hash_ctx.ipv6_udp)) {
-                               ice_rem_rss_cfg(hw, vsi->idx,
-                                       pf->gtpu_hash_ctx.ipv6_udp.hash_fld,
-                                       pf->gtpu_hash_ctx.ipv6_udp.pkt_hdr);
-                               ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv6_udp);
-                       }
+static int
+ice_add_rss_cfg_pre_gtpu(struct ice_pf *pf, struct ice_hash_gtpu_ctx *ctx,
+                        u8 ctx_idx)
+{
+       int ret;
 
-                       if (ICE_HASH_CFG_VALID(&pf->gtpu_hash_ctx.ipv6_tcp)) {
-                               ice_rem_rss_cfg(hw, vsi->idx,
-                                       pf->gtpu_hash_ctx.ipv6_tcp.hash_fld,
-                                       pf->gtpu_hash_ctx.ipv6_tcp.pkt_hdr);
-                               ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv6_tcp);
-                       }
-               }
+       switch (ctx_idx) {
+       case ICE_HASH_GTPU_CTX_EH_IP:
+               ret = ice_hash_remove(pf,
+                                     &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_UDP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_remove(pf,
+                                     &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_TCP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_remove(pf,
+                                     &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_remove(pf,
+                                     &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_UDP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_remove(pf,
+                                     &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_TCP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_remove(pf,
+                                     &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_remove(pf,
+                                     &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_UDP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_remove(pf,
+                                     &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_TCP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               break;
+       case ICE_HASH_GTPU_CTX_EH_IP_UDP:
+               ret = ice_hash_remove(pf,
+                                     &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_UDP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_remove(pf,
+                                     &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_UDP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_TCP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_TCP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               break;
+       case ICE_HASH_GTPU_CTX_EH_IP_TCP:
+               ret = ice_hash_remove(pf,
+                                     &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_TCP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_remove(pf,
+                                     &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_TCP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_UDP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_UDP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               break;
+       case ICE_HASH_GTPU_CTX_UP_IP:
+               ret = ice_hash_remove(pf,
+                                     &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_UDP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_remove(pf,
+                                     &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_TCP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_UDP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_TCP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               break;
+       case ICE_HASH_GTPU_CTX_UP_IP_UDP:
+       case ICE_HASH_GTPU_CTX_UP_IP_TCP:
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_UDP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_TCP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               break;
+       case ICE_HASH_GTPU_CTX_DW_IP:
+               ret = ice_hash_remove(pf,
+                                     &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_UDP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_remove(pf,
+                                     &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_TCP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_UDP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_TCP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               break;
+       case ICE_HASH_GTPU_CTX_DW_IP_UDP:
+       case ICE_HASH_GTPU_CTX_DW_IP_TCP:
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_UDP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveout(pf,
+                                      &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_TCP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               break;
+       default:
+               break;
        }
 
        return 0;
 }
 
+static u8 calc_gtpu_ctx_idx(uint32_t hdr)
+{
+       u8 eh_idx, ip_idx;
+
+       if (hdr & ICE_FLOW_SEG_HDR_GTPU_EH)
+               eh_idx = 0;
+       else if (hdr & ICE_FLOW_SEG_HDR_GTPU_UP)
+               eh_idx = 1;
+       else if (hdr & ICE_FLOW_SEG_HDR_GTPU_DWN)
+               eh_idx = 2;
+       else
+               return ICE_HASH_GTPU_CTX_MAX;
+
+       ip_idx = 0;
+       if (hdr & ICE_FLOW_SEG_HDR_UDP)
+               ip_idx = 1;
+       else if (hdr & ICE_FLOW_SEG_HDR_TCP)
+               ip_idx = 2;
+
+       if (hdr & (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6))
+               return eh_idx * 3 + ip_idx;
+       else
+               return ICE_HASH_GTPU_CTX_MAX;
+}
+
 static int
-ice_rem_rss_cfg_post(struct ice_pf *pf, uint32_t hdr)
+ice_add_rss_cfg_pre(struct ice_pf *pf, uint32_t hdr)
 {
-       if (hdr & ICE_FLOW_SEG_HDR_GTPU_EH) {
-               if ((hdr & ICE_FLOW_SEG_HDR_IPV4) &&
-                   (hdr & ICE_FLOW_SEG_HDR_UDP)) {
-                       ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv4_udp);
-               } else if ((hdr & ICE_FLOW_SEG_HDR_IPV6) &&
-                          (hdr & ICE_FLOW_SEG_HDR_UDP)) {
-                       ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv6_udp);
-               } else if ((hdr & ICE_FLOW_SEG_HDR_IPV4) &&
-                          (hdr & ICE_FLOW_SEG_HDR_TCP)) {
-                       ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv4_tcp);
-               } else if ((hdr & ICE_FLOW_SEG_HDR_IPV6) &&
-                          (hdr & ICE_FLOW_SEG_HDR_TCP)) {
-                       ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv6_tcp);
-               } else if (hdr & ICE_FLOW_SEG_HDR_IPV4) {
-                       ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv4);
-               } else if (hdr & ICE_FLOW_SEG_HDR_IPV6) {
-                       ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv6);
-               }
+       u8 gtpu_ctx_idx = calc_gtpu_ctx_idx(hdr);
+
+       if (hdr & ICE_FLOW_SEG_HDR_IPV4)
+               return ice_add_rss_cfg_pre_gtpu(pf, &pf->hash_ctx.gtpu4,
+                                               gtpu_ctx_idx);
+       else if (hdr & ICE_FLOW_SEG_HDR_IPV6)
+               return ice_add_rss_cfg_pre_gtpu(pf, &pf->hash_ctx.gtpu6,
+                                               gtpu_ctx_idx);
+
+       return 0;
+}
+
+static int
+ice_add_rss_cfg_post_gtpu(struct ice_pf *pf, struct ice_hash_gtpu_ctx *ctx,
+                         u8 ctx_idx, struct ice_rss_hash_cfg *cfg)
+{
+       int ret;
+
+       if (ctx_idx < ICE_HASH_GTPU_CTX_MAX)
+               ctx->ctx[ctx_idx] = *cfg;
+
+       switch (ctx_idx) {
+       case ICE_HASH_GTPU_CTX_EH_IP:
+               break;
+       case ICE_HASH_GTPU_CTX_EH_IP_UDP:
+               ret = ice_hash_moveback(pf,
+                                       &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveback(pf,
+                                       &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_TCP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveback(pf,
+                                       &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveback(pf,
+                                       &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_TCP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               break;
+       case ICE_HASH_GTPU_CTX_EH_IP_TCP:
+               ret = ice_hash_moveback(pf,
+                                       &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveback(pf,
+                                       &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_UDP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveback(pf,
+                                       &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveback(pf,
+                                       &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_UDP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               break;
+       case ICE_HASH_GTPU_CTX_UP_IP:
+       case ICE_HASH_GTPU_CTX_UP_IP_UDP:
+       case ICE_HASH_GTPU_CTX_UP_IP_TCP:
+       case ICE_HASH_GTPU_CTX_DW_IP:
+       case ICE_HASH_GTPU_CTX_DW_IP_UDP:
+       case ICE_HASH_GTPU_CTX_DW_IP_TCP:
+               ret = ice_hash_moveback(pf,
+                                       &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveback(pf,
+                                       &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_UDP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               ret = ice_hash_moveback(pf,
+                                       &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_TCP]);
+               if (ret && (ret != -ENOENT))
+                       return ret;
+
+               break;
+       default:
+               break;
        }
 
        return 0;
 }
 
+static int
+ice_add_rss_cfg_post(struct ice_pf *pf, struct ice_rss_hash_cfg *cfg)
+{
+       u8 gtpu_ctx_idx = calc_gtpu_ctx_idx(cfg->addl_hdrs);
+
+       if (cfg->addl_hdrs & ICE_FLOW_SEG_HDR_IPV4)
+               return ice_add_rss_cfg_post_gtpu(pf, &pf->hash_ctx.gtpu4,
+                                                gtpu_ctx_idx, cfg);
+       else if (cfg->addl_hdrs & ICE_FLOW_SEG_HDR_IPV6)
+               return ice_add_rss_cfg_post_gtpu(pf, &pf->hash_ctx.gtpu6,
+                                                gtpu_ctx_idx, cfg);
+
+       return 0;
+}
+
+static void
+ice_rem_rss_cfg_post(struct ice_pf *pf, uint32_t hdr)
+{
+       u8 gtpu_ctx_idx = calc_gtpu_ctx_idx(hdr);
+
+       if (gtpu_ctx_idx >= ICE_HASH_GTPU_CTX_MAX)
+               return;
+
+       if (hdr & ICE_FLOW_SEG_HDR_IPV4)
+               hash_cfg_reset(&pf->hash_ctx.gtpu4.ctx[gtpu_ctx_idx]);
+       else if (hdr & ICE_FLOW_SEG_HDR_IPV6)
+               hash_cfg_reset(&pf->hash_ctx.gtpu6.ctx[gtpu_ctx_idx]);
+}
+
 int
 ice_rem_rss_cfg_wrap(struct ice_pf *pf, uint16_t vsi_id,
-               uint64_t fld, uint32_t hdr)
+                    struct ice_rss_hash_cfg *cfg)
 {
        struct ice_hw *hw = ICE_PF_TO_HW(pf);
        int ret;
 
-       ret = ice_rem_rss_cfg(hw, vsi_id, fld, hdr);
+       ret = ice_rem_rss_cfg(hw, vsi_id, cfg);
        if (ret && ret != ICE_ERR_DOES_NOT_EXIST)
                PMD_DRV_LOG(ERR, "remove rss cfg failed\n");
 
-       ret = ice_rem_rss_cfg_post(pf, hdr);
-       if (ret)
-               PMD_DRV_LOG(ERR, "remove rss cfg post failed\n");
+       ice_rem_rss_cfg_post(pf, cfg->addl_hdrs);
 
        return 0;
 }
 
 int
 ice_add_rss_cfg_wrap(struct ice_pf *pf, uint16_t vsi_id,
-               uint64_t fld, uint32_t hdr, bool symm)
+                    struct ice_rss_hash_cfg *cfg)
 {
        struct ice_hw *hw = ICE_PF_TO_HW(pf);
        int ret;
 
-       ret = ice_add_rss_cfg_pre(pf, hdr);
+       ret = ice_add_rss_cfg_pre(pf, cfg->addl_hdrs);
        if (ret)
                PMD_DRV_LOG(ERR, "add rss cfg pre failed\n");
 
-       ret = ice_add_rss_cfg(hw, vsi_id, fld, hdr, symm);
+       ret = ice_add_rss_cfg(hw, vsi_id, cfg);
        if (ret)
                PMD_DRV_LOG(ERR, "add rss cfg failed\n");
 
-       ret = ice_add_rss_cfg_post(pf, hdr, fld, symm);
+       ret = ice_add_rss_cfg_post(pf, cfg);
        if (ret)
                PMD_DRV_LOG(ERR, "add rss cfg post failed\n");
 
@@ -2759,14 +2810,33 @@ ice_add_rss_cfg_wrap(struct ice_pf *pf, uint16_t vsi_id,
 static void
 ice_rss_hash_set(struct ice_pf *pf, uint64_t rss_hf)
 {
+       struct ice_hw *hw = ICE_PF_TO_HW(pf);
        struct ice_vsi *vsi = pf->main_vsi;
+       struct ice_rss_hash_cfg cfg;
        int ret;
 
+#define ICE_RSS_HF_ALL ( \
+       ETH_RSS_IPV4 | \
+       ETH_RSS_IPV6 | \
+       ETH_RSS_NONFRAG_IPV4_UDP | \
+       ETH_RSS_NONFRAG_IPV6_UDP | \
+       ETH_RSS_NONFRAG_IPV4_TCP | \
+       ETH_RSS_NONFRAG_IPV6_TCP | \
+       ETH_RSS_NONFRAG_IPV4_SCTP | \
+       ETH_RSS_NONFRAG_IPV6_SCTP)
+
+       ret = ice_rem_vsi_rss_cfg(hw, vsi->idx);
+       if (ret)
+               PMD_DRV_LOG(ERR, "%s Remove rss vsi fail %d",
+                           __func__, ret);
+
+       cfg.symm = 0;
+       cfg.hdr_type = ICE_RSS_OUTER_HEADERS;
        /* Configure RSS for IPv4 with src/dst addr as input set */
        if (rss_hf & ETH_RSS_IPV4) {
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_FLOW_HASH_IPV4,
-                                     ICE_FLOW_SEG_HDR_IPV4 |
-                                     ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_FLOW_HASH_IPV4;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s IPV4 rss flow fail %d",
                                    __func__, ret);
@@ -2774,9 +2844,9 @@ ice_rss_hash_set(struct ice_pf *pf, uint64_t rss_hf)
 
        /* Configure RSS for IPv6 with src/dst addr as input set */
        if (rss_hf & ETH_RSS_IPV6) {
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_FLOW_HASH_IPV6,
-                                     ICE_FLOW_SEG_HDR_IPV6 |
-                                     ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_FLOW_HASH_IPV6;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s IPV6 rss flow fail %d",
                                    __func__, ret);
@@ -2784,10 +2854,10 @@ ice_rss_hash_set(struct ice_pf *pf, uint64_t rss_hf)
 
        /* Configure RSS for udp4 with src/dst addr and port as input set */
        if (rss_hf & ETH_RSS_NONFRAG_IPV4_UDP) {
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_UDP_IPV4,
-                                     ICE_FLOW_SEG_HDR_UDP |
-                                     ICE_FLOW_SEG_HDR_IPV4 |
-                                     ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV4 |
+                               ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_HASH_UDP_IPV4;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s UDP_IPV4 rss flow fail %d",
                                    __func__, ret);
@@ -2795,10 +2865,10 @@ ice_rss_hash_set(struct ice_pf *pf, uint64_t rss_hf)
 
        /* Configure RSS for udp6 with src/dst addr and port as input set */
        if (rss_hf & ETH_RSS_NONFRAG_IPV6_UDP) {
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_UDP_IPV6,
-                                     ICE_FLOW_SEG_HDR_UDP |
-                                     ICE_FLOW_SEG_HDR_IPV6 |
-                                     ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV6 |
+                               ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_HASH_UDP_IPV6;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s UDP_IPV6 rss flow fail %d",
                                    __func__, ret);
@@ -2806,10 +2876,10 @@ ice_rss_hash_set(struct ice_pf *pf, uint64_t rss_hf)
 
        /* Configure RSS for tcp4 with src/dst addr and port as input set */
        if (rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) {
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_TCP_IPV4,
-                                     ICE_FLOW_SEG_HDR_TCP |
-                                     ICE_FLOW_SEG_HDR_IPV4 |
-                                     ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_IPV4 |
+                               ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_HASH_TCP_IPV4;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s TCP_IPV4 rss flow fail %d",
                                    __func__, ret);
@@ -2817,10 +2887,10 @@ ice_rss_hash_set(struct ice_pf *pf, uint64_t rss_hf)
 
        /* Configure RSS for tcp6 with src/dst addr and port as input set */
        if (rss_hf & ETH_RSS_NONFRAG_IPV6_TCP) {
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_TCP_IPV6,
-                                     ICE_FLOW_SEG_HDR_TCP |
-                                     ICE_FLOW_SEG_HDR_IPV6 |
-                                     ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_IPV6 |
+                               ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_HASH_TCP_IPV6;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s TCP_IPV6 rss flow fail %d",
                                    __func__, ret);
@@ -2828,10 +2898,10 @@ ice_rss_hash_set(struct ice_pf *pf, uint64_t rss_hf)
 
        /* Configure RSS for sctp4 with src/dst addr and port as input set */
        if (rss_hf & ETH_RSS_NONFRAG_IPV4_SCTP) {
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_FLOW_HASH_IPV4,
-                                     ICE_FLOW_SEG_HDR_SCTP |
-                                     ICE_FLOW_SEG_HDR_IPV4 |
-                                     ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_IPV4 |
+                               ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_HASH_SCTP_IPV4;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s SCTP_IPV4 rss flow fail %d",
                                    __func__, ret);
@@ -2839,222 +2909,160 @@ ice_rss_hash_set(struct ice_pf *pf, uint64_t rss_hf)
 
        /* Configure RSS for sctp6 with src/dst addr and port as input set */
        if (rss_hf & ETH_RSS_NONFRAG_IPV6_SCTP) {
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_FLOW_HASH_IPV6,
-                                     ICE_FLOW_SEG_HDR_SCTP |
-                                     ICE_FLOW_SEG_HDR_IPV6 |
-                                     ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_IPV6 |
+                               ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_HASH_SCTP_IPV6;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s SCTP_IPV6 rss flow fail %d",
                                    __func__, ret);
        }
 
        if (rss_hf & ETH_RSS_IPV4) {
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_FLOW_HASH_IPV4,
-                               ICE_FLOW_SEG_HDR_GTPU_IP |
-                               ICE_FLOW_SEG_HDR_IPV4 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_IP | ICE_FLOW_SEG_HDR_IPV4 |
+                               ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_FLOW_HASH_IPV4;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s GTPU_IPV4 rss flow fail %d",
                                    __func__, ret);
 
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_FLOW_HASH_IPV4,
-                               ICE_FLOW_SEG_HDR_GTPU_EH |
-                               ICE_FLOW_SEG_HDR_IPV4 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_EH | ICE_FLOW_SEG_HDR_IPV4 |
+                               ICE_FLOW_SEG_HDR_IPV_OTHER;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV4 rss flow fail %d",
                                    __func__, ret);
 
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_FLOW_HASH_IPV4,
-                               ICE_FLOW_SEG_HDR_PPPOE |
-                               ICE_FLOW_SEG_HDR_IPV4 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_IPV4 |
+                               ICE_FLOW_SEG_HDR_IPV_OTHER;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s PPPoE_IPV4 rss flow fail %d",
                                    __func__, ret);
        }
 
        if (rss_hf & ETH_RSS_IPV6) {
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_FLOW_HASH_IPV6,
-                               ICE_FLOW_SEG_HDR_GTPU_IP |
-                               ICE_FLOW_SEG_HDR_IPV6 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_IP | ICE_FLOW_SEG_HDR_IPV6 |
+                               ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_FLOW_HASH_IPV6;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s GTPU_IPV6 rss flow fail %d",
                                    __func__, ret);
 
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_FLOW_HASH_IPV6,
-                               ICE_FLOW_SEG_HDR_GTPU_EH |
-                               ICE_FLOW_SEG_HDR_IPV6 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_EH | ICE_FLOW_SEG_HDR_IPV6 |
+                               ICE_FLOW_SEG_HDR_IPV_OTHER;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV6 rss flow fail %d",
                                    __func__, ret);
 
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_FLOW_HASH_IPV6,
-                               ICE_FLOW_SEG_HDR_PPPOE |
-                               ICE_FLOW_SEG_HDR_IPV6 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_IPV6 |
+                               ICE_FLOW_SEG_HDR_IPV_OTHER;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s PPPoE_IPV6 rss flow fail %d",
                                    __func__, ret);
        }
 
        if (rss_hf & ETH_RSS_NONFRAG_IPV4_UDP) {
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_UDP_IPV4,
-                               ICE_FLOW_SEG_HDR_GTPU_IP |
-                               ICE_FLOW_SEG_HDR_UDP |
-                               ICE_FLOW_SEG_HDR_IPV4 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_IP | ICE_FLOW_SEG_HDR_UDP |
+                               ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_HASH_UDP_IPV4;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s GTPU_IPV4_UDP rss flow fail %d",
                                    __func__, ret);
 
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_UDP_IPV4,
-                               ICE_FLOW_SEG_HDR_GTPU_EH |
-                               ICE_FLOW_SEG_HDR_UDP |
-                               ICE_FLOW_SEG_HDR_IPV4 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_EH | ICE_FLOW_SEG_HDR_UDP |
+                               ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV4_UDP rss flow fail %d",
                                    __func__, ret);
 
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_UDP_IPV4,
-                               ICE_FLOW_SEG_HDR_PPPOE |
-                               ICE_FLOW_SEG_HDR_UDP |
-                               ICE_FLOW_SEG_HDR_IPV4 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_UDP |
+                               ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s PPPoE_IPV4_UDP rss flow fail %d",
                                    __func__, ret);
        }
 
        if (rss_hf & ETH_RSS_NONFRAG_IPV6_UDP) {
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_UDP_IPV6,
-                               ICE_FLOW_SEG_HDR_GTPU_IP |
-                               ICE_FLOW_SEG_HDR_UDP |
-                               ICE_FLOW_SEG_HDR_IPV6 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_IP | ICE_FLOW_SEG_HDR_UDP |
+                               ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_HASH_UDP_IPV6;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s GTPU_IPV6_UDP rss flow fail %d",
                                    __func__, ret);
 
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_UDP_IPV6,
-                               ICE_FLOW_SEG_HDR_GTPU_EH |
-                               ICE_FLOW_SEG_HDR_UDP |
-                               ICE_FLOW_SEG_HDR_IPV6 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_EH | ICE_FLOW_SEG_HDR_UDP |
+                               ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV6_UDP rss flow fail %d",
                                    __func__, ret);
 
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_UDP_IPV6,
-                               ICE_FLOW_SEG_HDR_PPPOE |
-                               ICE_FLOW_SEG_HDR_UDP |
-                               ICE_FLOW_SEG_HDR_IPV6 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_UDP |
+                               ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s PPPoE_IPV6_UDP rss flow fail %d",
                                    __func__, ret);
        }
 
        if (rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) {
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_TCP_IPV4,
-                               ICE_FLOW_SEG_HDR_GTPU_IP |
-                               ICE_FLOW_SEG_HDR_TCP |
-                               ICE_FLOW_SEG_HDR_IPV4 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_IP | ICE_FLOW_SEG_HDR_TCP |
+                               ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_HASH_TCP_IPV4;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s GTPU_IPV4_TCP rss flow fail %d",
                                    __func__, ret);
 
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_TCP_IPV4,
-                               ICE_FLOW_SEG_HDR_GTPU_EH |
-                               ICE_FLOW_SEG_HDR_TCP |
-                               ICE_FLOW_SEG_HDR_IPV4 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_EH | ICE_FLOW_SEG_HDR_TCP |
+                               ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV4_TCP rss flow fail %d",
                                    __func__, ret);
 
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_TCP_IPV4,
-                               ICE_FLOW_SEG_HDR_PPPOE |
-                               ICE_FLOW_SEG_HDR_TCP |
-                               ICE_FLOW_SEG_HDR_IPV4 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_TCP |
+                               ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s PPPoE_IPV4_TCP rss flow fail %d",
                                    __func__, ret);
        }
 
        if (rss_hf & ETH_RSS_NONFRAG_IPV6_TCP) {
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_TCP_IPV6,
-                               ICE_FLOW_SEG_HDR_GTPU_IP |
-                               ICE_FLOW_SEG_HDR_TCP |
-                               ICE_FLOW_SEG_HDR_IPV6 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_IP | ICE_FLOW_SEG_HDR_TCP |
+                               ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_HASH_TCP_IPV6;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s GTPU_IPV6_TCP rss flow fail %d",
                                    __func__, ret);
 
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_TCP_IPV6,
-                               ICE_FLOW_SEG_HDR_GTPU_EH |
-                               ICE_FLOW_SEG_HDR_TCP |
-                               ICE_FLOW_SEG_HDR_IPV6 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_EH | ICE_FLOW_SEG_HDR_TCP |
+                               ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV6_TCP rss flow fail %d",
                                    __func__, ret);
 
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_TCP_IPV6,
-                               ICE_FLOW_SEG_HDR_PPPOE |
-                               ICE_FLOW_SEG_HDR_TCP |
-                               ICE_FLOW_SEG_HDR_IPV6 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_TCP |
+                               ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER;
+               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s PPPoE_IPV6_TCP rss flow fail %d",
                                    __func__, ret);
        }
 
-       if (rss_hf & ETH_RSS_NONFRAG_IPV4_SCTP) {
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_SCTP_IPV4,
-                               ICE_FLOW_SEG_HDR_GTPU_IP |
-                               ICE_FLOW_SEG_HDR_SCTP |
-                               ICE_FLOW_SEG_HDR_IPV4 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
-               if (ret)
-                       PMD_DRV_LOG(ERR, "%s GTPU_IPV4_SCTP rss flow fail %d",
-                                   __func__, ret);
-
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_SCTP_IPV4,
-                               ICE_FLOW_SEG_HDR_GTPU_EH |
-                               ICE_FLOW_SEG_HDR_SCTP |
-                               ICE_FLOW_SEG_HDR_IPV4 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
-               if (ret)
-                       PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV4_SCTP rss flow fail %d",
-                                   __func__, ret);
-       }
-
-       if (rss_hf & ETH_RSS_NONFRAG_IPV6_SCTP) {
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_SCTP_IPV6,
-                               ICE_FLOW_SEG_HDR_GTPU_IP |
-                               ICE_FLOW_SEG_HDR_SCTP |
-                               ICE_FLOW_SEG_HDR_IPV6 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
-               if (ret)
-                       PMD_DRV_LOG(ERR, "%s GTPU_IPV6_SCTP rss flow fail %d",
-                                   __func__, ret);
-
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, ICE_HASH_SCTP_IPV6,
-                               ICE_FLOW_SEG_HDR_GTPU_EH |
-                               ICE_FLOW_SEG_HDR_SCTP |
-                               ICE_FLOW_SEG_HDR_IPV6 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
-               if (ret)
-                       PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV6_SCTP rss flow fail %d",
-                                   __func__, ret);
-       }
+       pf->rss_hf = rss_hf & ICE_RSS_HF_ALL;
 }
 
 static int ice_init_rss(struct ice_pf *pf)
@@ -3062,6 +3070,7 @@ static int ice_init_rss(struct ice_pf *pf)
        struct ice_hw *hw = ICE_PF_TO_HW(pf);
        struct ice_vsi *vsi = pf->main_vsi;
        struct rte_eth_dev *dev = pf->adapter->eth_dev;
+       struct ice_aq_get_set_rss_lut_params lut_params;
        struct rte_eth_rss_conf *rss_conf;
        struct ice_aqc_get_set_rss_keys key;
        uint16_t i, nb_q;
@@ -3074,6 +3083,12 @@ static int ice_init_rss(struct ice_pf *pf)
        vsi->rss_key_size = ICE_AQC_GET_SET_RSS_KEY_DATA_RSS_KEY_SIZE;
        vsi->rss_lut_size = pf->hash_lut_size;
 
+       if (nb_q == 0) {
+               PMD_DRV_LOG(WARNING,
+                       "RSS is not supported as rx queues number is zero\n");
+               return 0;
+       }
+
        if (is_safe_mode) {
                PMD_DRV_LOG(WARNING, "RSS is not supported in safe mode\n");
                return 0;
@@ -3116,9 +3131,12 @@ static int ice_init_rss(struct ice_pf *pf)
        for (i = 0; i < vsi->rss_lut_size; i++)
                vsi->rss_lut[i] = i % nb_q;
 
-       ret = ice_aq_set_rss_lut(hw, vsi->idx,
-                                ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF,
-                                vsi->rss_lut, vsi->rss_lut_size);
+       lut_params.vsi_handle = vsi->idx;
+       lut_params.lut_size = vsi->rss_lut_size;
+       lut_params.lut_type = ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF;
+       lut_params.lut = vsi->rss_lut;
+       lut_params.global_lut_id = 0;
+       ret = ice_aq_set_rss_lut(hw, &lut_params);
        if (ret)
                goto out;
 
@@ -3157,10 +3175,12 @@ ice_dev_configure(struct rte_eth_dev *dev)
        if (dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG)
                dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_RSS_HASH;
 
-       ret = ice_init_rss(pf);
-       if (ret) {
-               PMD_DRV_LOG(ERR, "Failed to enable rss for PF");
-               return ret;
+       if (dev->data->nb_rx_queues) {
+               ret = ice_init_rss(pf);
+               if (ret) {
+                       PMD_DRV_LOG(ERR, "Failed to enable rss for PF");
+                       return ret;
+               }
        }
 
        return 0;
@@ -3184,7 +3204,7 @@ __vsi_queues_bind_intr(struct ice_vsi *vsi, uint16_t msix_vect,
                PMD_DRV_LOG(INFO, "queue %d is binding to vect %d",
                            base_queue + i, msix_vect);
                /* set ITR0 value */
-               ICE_WRITE_REG(hw, GLINT_ITR(0, msix_vect), 0x10);
+               ICE_WRITE_REG(hw, GLINT_ITR(0, msix_vect), 0x2);
                ICE_WRITE_REG(hw, QINT_RQCTL(base_queue + i), val);
                ICE_WRITE_REG(hw, QINT_TQCTL(base_queue + i), val_tx);
        }
@@ -3729,8 +3749,8 @@ ice_force_phys_link_state(struct ice_hw *hw, bool link_up)
        if (!pcaps)
                return ICE_ERR_NO_MEMORY;
 
-       status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_SW_CFG, pcaps,
-                                    NULL);
+       status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_ACTIVE_CFG,
+                                    pcaps, NULL);
        if (status)
                goto out;
 
@@ -3793,7 +3813,7 @@ ice_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
                return -EBUSY;
        }
 
-       if (frame_size > RTE_ETHER_MAX_LEN)
+       if (frame_size > ICE_ETH_MAX_LEN)
                dev_data->dev_conf.rxmode.offloads |=
                        DEV_RX_OFFLOAD_JUMBO_FRAME;
        else
@@ -3892,19 +3912,27 @@ static int
 ice_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 {
        struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+       struct ice_vlan vlan = ICE_VLAN(RTE_ETHER_TYPE_VLAN, vlan_id);
        struct ice_vsi *vsi = pf->main_vsi;
        int ret;
 
        PMD_INIT_FUNC_TRACE();
 
+       /**
+        * Vlan 0 is the generic filter for untagged packets
+        * and can't be removed or added by user.
+        */
+       if (vlan_id == 0)
+               return 0;
+
        if (on) {
-               ret = ice_add_vlan_filter(vsi, vlan_id);
+               ret = ice_add_vlan_filter(vsi, &vlan);
                if (ret < 0) {
                        PMD_DRV_LOG(ERR, "Failed to add vlan filter");
                        return -EINVAL;
                }
        } else {
-               ret = ice_remove_vlan_filter(vsi, vlan_id);
+               ret = ice_remove_vlan_filter(vsi, &vlan);
                if (ret < 0) {
                        PMD_DRV_LOG(ERR, "Failed to remove vlan filter");
                        return -EINVAL;
@@ -3914,26 +3942,93 @@ ice_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
        return 0;
 }
 
+/* In Single VLAN Mode (SVM), single VLAN filters via ICE_SW_LKUP_VLAN are
+ * based on the inner VLAN ID, so the VLAN TPID (i.e. 0x8100 or 0x888a8)
+ * doesn't matter. In Double VLAN Mode (DVM), outer/single VLAN filters via
+ * ICE_SW_LKUP_VLAN are based on the outer/single VLAN ID + VLAN TPID.
+ *
+ * For both modes add a VLAN 0 + no VLAN TPID filter to handle untagged traffic
+ * when VLAN pruning is enabled. Also, this handles VLAN 0 priority tagged
+ * traffic in SVM, since the VLAN TPID isn't part of filtering.
+ *
+ * If DVM is enabled then an explicit VLAN 0 + VLAN TPID filter needs to be
+ * added to allow VLAN 0 priority tagged traffic in DVM, since the VLAN TPID is
+ * part of filtering.
+ */
+static int
+ice_vsi_add_vlan_zero(struct ice_vsi *vsi)
+{
+       struct ice_vlan vlan;
+       int err;
+
+       vlan = ICE_VLAN(0, 0);
+       err = ice_add_vlan_filter(vsi, &vlan);
+       if (err) {
+               PMD_DRV_LOG(DEBUG, "Failed to add VLAN ID 0");
+               return err;
+       }
+
+       /* in SVM both VLAN 0 filters are identical */
+       if (!ice_is_dvm_ena(&vsi->adapter->hw))
+               return 0;
+
+       vlan = ICE_VLAN(RTE_ETHER_TYPE_VLAN, 0);
+       err = ice_add_vlan_filter(vsi, &vlan);
+       if (err) {
+               PMD_DRV_LOG(DEBUG, "Failed to add VLAN ID 0 in double VLAN mode");
+               return err;
+       }
+
+       return 0;
+}
+
+/*
+ * Delete the VLAN 0 filters in the same manner that they were added in
+ * ice_vsi_add_vlan_zero.
+ */
+static int
+ice_vsi_del_vlan_zero(struct ice_vsi *vsi)
+{
+       struct ice_vlan vlan;
+       int err;
+
+       vlan = ICE_VLAN(0, 0);
+       err = ice_remove_vlan_filter(vsi, &vlan);
+       if (err) {
+               PMD_DRV_LOG(DEBUG, "Failed to remove VLAN ID 0");
+               return err;
+       }
+
+       /* in SVM both VLAN 0 filters are identical */
+       if (!ice_is_dvm_ena(&vsi->adapter->hw))
+               return 0;
+
+       vlan = ICE_VLAN(RTE_ETHER_TYPE_VLAN, 0);
+       err = ice_remove_vlan_filter(vsi, &vlan);
+       if (err) {
+               PMD_DRV_LOG(DEBUG, "Failed to remove VLAN ID 0 in double VLAN mode");
+               return err;
+       }
+
+       return 0;
+}
+
 /* Configure vlan filter on or off */
 static int
 ice_vsi_config_vlan_filter(struct ice_vsi *vsi, bool on)
 {
        struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
        struct ice_vsi_ctx ctxt;
-       uint8_t sec_flags, sw_flags2;
+       uint8_t sw_flags2;
        int ret = 0;
 
-       sec_flags = ICE_AQ_VSI_SEC_TX_VLAN_PRUNE_ENA <<
-                   ICE_AQ_VSI_SEC_TX_PRUNE_ENA_S;
        sw_flags2 = ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA;
 
-       if (on) {
-               vsi->info.sec_flags |= sec_flags;
+       if (on)
                vsi->info.sw_flags2 |= sw_flags2;
-       } else {
-               vsi->info.sec_flags &= ~sec_flags;
+       else
                vsi->info.sw_flags2 &= ~sw_flags2;
-       }
+
        vsi->info.sw_id = hw->port_info->sw_id;
        (void)rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
        ctxt.info.valid_sections =
@@ -3954,56 +4049,154 @@ ice_vsi_config_vlan_filter(struct ice_vsi *vsi, bool on)
 
        /* consist with other drivers, allow untagged packet when vlan filter on */
        if (on)
-               ret = ice_add_vlan_filter(vsi, 0);
+               ret = ice_vsi_add_vlan_zero(vsi);
        else
-               ret = ice_remove_vlan_filter(vsi, 0);
+               ret = ice_vsi_del_vlan_zero(vsi);
 
        return 0;
 }
 
+/* Manage VLAN stripping for the VSI for Rx */
 static int
-ice_vsi_config_vlan_stripping(struct ice_vsi *vsi, bool on)
+ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena)
 {
        struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
        struct ice_vsi_ctx ctxt;
-       uint8_t vlan_flags;
-       int ret = 0;
+       enum ice_status status;
+       int err = 0;
 
-       /* Check if it has been already on or off */
-       if (vsi->info.valid_sections &
-               rte_cpu_to_le_16(ICE_AQ_VSI_PROP_VLAN_VALID)) {
-               if (on) {
-                       if ((vsi->info.vlan_flags &
-                            ICE_AQ_VSI_VLAN_EMOD_M) ==
-                           ICE_AQ_VSI_VLAN_EMOD_STR_BOTH)
-                               return 0; /* already on */
-               } else {
-                       if ((vsi->info.vlan_flags &
-                            ICE_AQ_VSI_VLAN_EMOD_M) ==
-                           ICE_AQ_VSI_VLAN_EMOD_NOTHING)
-                               return 0; /* already off */
-               }
-       }
+       /* do not allow modifying VLAN stripping when a port VLAN is configured
+        * on this VSI
+        */
+       if (vsi->info.port_based_inner_vlan)
+               return 0;
 
-       if (on)
-               vlan_flags = ICE_AQ_VSI_VLAN_EMOD_STR_BOTH;
+       memset(&ctxt, 0, sizeof(ctxt));
+
+       if (ena)
+               /* Strip VLAN tag from Rx packet and put it in the desc */
+               ctxt.info.inner_vlan_flags =
+                                       ICE_AQ_VSI_INNER_VLAN_EMODE_STR_BOTH;
        else
-               vlan_flags = ICE_AQ_VSI_VLAN_EMOD_NOTHING;
-       vsi->info.vlan_flags &= ~(ICE_AQ_VSI_VLAN_EMOD_M);
-       vsi->info.vlan_flags |= vlan_flags;
-       (void)rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
+               /* Disable stripping. Leave tag in packet */
+               ctxt.info.inner_vlan_flags =
+                                       ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING;
+
+       /* Allow all packets untagged/tagged */
+       ctxt.info.inner_vlan_flags |= ICE_AQ_VSI_INNER_VLAN_TX_MODE_ALL;
+
+       ctxt.info.valid_sections = rte_cpu_to_le_16(ICE_AQ_VSI_PROP_VLAN_VALID);
+
+       status = ice_update_vsi(hw, vsi->idx, &ctxt, NULL);
+       if (status) {
+               PMD_DRV_LOG(ERR, "Update VSI failed to %s vlan stripping",
+                           ena ? "enable" : "disable");
+               err = -EIO;
+       } else {
+               vsi->info.inner_vlan_flags = ctxt.info.inner_vlan_flags;
+       }
+
+       return err;
+}
+
+static int
+ice_vsi_ena_inner_stripping(struct ice_vsi *vsi)
+{
+       return ice_vsi_manage_vlan_stripping(vsi, true);
+}
+
+static int
+ice_vsi_dis_inner_stripping(struct ice_vsi *vsi)
+{
+       return ice_vsi_manage_vlan_stripping(vsi, false);
+}
+
+static int ice_vsi_ena_outer_stripping(struct ice_vsi *vsi)
+{
+       struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
+       struct ice_vsi_ctx ctxt;
+       enum ice_status status;
+       int err = 0;
+
+       /* do not allow modifying VLAN stripping when a port VLAN is configured
+        * on this VSI
+        */
+       if (vsi->info.port_based_outer_vlan)
+               return 0;
+
+       memset(&ctxt, 0, sizeof(ctxt));
+
        ctxt.info.valid_sections =
-               rte_cpu_to_le_16(ICE_AQ_VSI_PROP_VLAN_VALID);
-       ctxt.vsi_num = vsi->vsi_id;
-       ret = ice_update_vsi(hw, vsi->idx, &ctxt, NULL);
-       if (ret) {
-               PMD_DRV_LOG(INFO, "Update VSI failed to %s vlan stripping",
-                           on ? "enable" : "disable");
-               return -EINVAL;
+               rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID);
+       /* clear current outer VLAN strip settings */
+       ctxt.info.outer_vlan_flags = vsi->info.outer_vlan_flags &
+               ~(ICE_AQ_VSI_OUTER_VLAN_EMODE_M | ICE_AQ_VSI_OUTER_TAG_TYPE_M);
+       ctxt.info.outer_vlan_flags |=
+               (ICE_AQ_VSI_OUTER_VLAN_EMODE_SHOW_BOTH <<
+                ICE_AQ_VSI_OUTER_VLAN_EMODE_S) |
+               (ICE_AQ_VSI_OUTER_TAG_VLAN_8100 <<
+                ICE_AQ_VSI_OUTER_TAG_TYPE_S);
+
+       status = ice_update_vsi(hw, vsi->idx, &ctxt, NULL);
+       if (status) {
+               PMD_DRV_LOG(ERR, "Update VSI failed to enable outer VLAN stripping");
+               err = -EIO;
+       } else {
+               vsi->info.outer_vlan_flags = ctxt.info.outer_vlan_flags;
        }
 
-       vsi->info.valid_sections |=
-               rte_cpu_to_le_16(ICE_AQ_VSI_PROP_VLAN_VALID);
+       return err;
+}
+
+static int
+ice_vsi_dis_outer_stripping(struct ice_vsi *vsi)
+{
+       struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
+       struct ice_vsi_ctx ctxt;
+       enum ice_status status;
+       int err = 0;
+
+       if (vsi->info.port_based_outer_vlan)
+               return 0;
+
+       memset(&ctxt, 0, sizeof(ctxt));
+
+       ctxt.info.valid_sections =
+               rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID);
+       /* clear current outer VLAN strip settings */
+       ctxt.info.outer_vlan_flags = vsi->info.outer_vlan_flags &
+               ~ICE_AQ_VSI_OUTER_VLAN_EMODE_M;
+       ctxt.info.outer_vlan_flags |= ICE_AQ_VSI_OUTER_VLAN_EMODE_NOTHING <<
+               ICE_AQ_VSI_OUTER_VLAN_EMODE_S;
+
+       status = ice_update_vsi(hw, vsi->idx, &ctxt, NULL);
+       if (status) {
+               PMD_DRV_LOG(ERR, "Update VSI failed to disable outer VLAN stripping");
+               err = -EIO;
+       } else {
+               vsi->info.outer_vlan_flags = ctxt.info.outer_vlan_flags;
+       }
+
+       return err;
+}
+
+static int
+ice_vsi_config_vlan_stripping(struct ice_vsi *vsi, bool ena)
+{
+       struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
+       int ret;
+
+       if (ice_is_dvm_ena(hw)) {
+               if (ena)
+                       ret = ice_vsi_ena_outer_stripping(vsi);
+               else
+                       ret = ice_vsi_dis_outer_stripping(vsi);
+       } else {
+               if (ena)
+                       ret = ice_vsi_ena_inner_stripping(vsi);
+               else
+                       ret = ice_vsi_dis_inner_stripping(vsi);
+       }
 
        return ret;
 }
@@ -4030,19 +4223,13 @@ ice_vlan_offload_set(struct rte_eth_dev *dev, int mask)
                        ice_vsi_config_vlan_stripping(vsi, false);
        }
 
-       if (mask & ETH_VLAN_EXTEND_MASK) {
-               if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_EXTEND)
-                       ice_vsi_config_double_vlan(vsi, true);
-               else
-                       ice_vsi_config_double_vlan(vsi, false);
-       }
-
        return 0;
 }
 
 static int
 ice_get_rss_lut(struct ice_vsi *vsi, uint8_t *lut, uint16_t lut_size)
 {
+       struct ice_aq_get_set_rss_lut_params lut_params;
        struct ice_pf *pf = ICE_VSI_TO_PF(vsi);
        struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
        int ret;
@@ -4051,8 +4238,12 @@ ice_get_rss_lut(struct ice_vsi *vsi, uint8_t *lut, uint16_t lut_size)
                return -EINVAL;
 
        if (pf->flags & ICE_FLAG_RSS_AQ_CAPABLE) {
-               ret = ice_aq_get_rss_lut(hw, vsi->idx,
-                       ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF, lut, lut_size);
+               lut_params.vsi_handle = vsi->idx;
+               lut_params.lut_size = lut_size;
+               lut_params.lut_type = ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF;
+               lut_params.lut = lut;
+               lut_params.global_lut_id = 0;
+               ret = ice_aq_get_rss_lut(hw, &lut_params);
                if (ret) {
                        PMD_DRV_LOG(ERR, "Failed to get RSS lookup table");
                        return -EINVAL;
@@ -4071,6 +4262,7 @@ ice_get_rss_lut(struct ice_vsi *vsi, uint8_t *lut, uint16_t lut_size)
 static int
 ice_set_rss_lut(struct ice_vsi *vsi, uint8_t *lut, uint16_t lut_size)
 {
+       struct ice_aq_get_set_rss_lut_params lut_params;
        struct ice_pf *pf;
        struct ice_hw *hw;
        int ret;
@@ -4082,8 +4274,12 @@ ice_set_rss_lut(struct ice_vsi *vsi, uint8_t *lut, uint16_t lut_size)
        hw = ICE_VSI_TO_HW(vsi);
 
        if (pf->flags & ICE_FLAG_RSS_AQ_CAPABLE) {
-               ret = ice_aq_set_rss_lut(hw, vsi->idx,
-                       ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF, lut, lut_size);
+               lut_params.vsi_handle = vsi->idx;
+               lut_params.lut_size = lut_size;
+               lut_params.lut_type = ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF;
+               lut_params.lut = lut;
+               lut_params.global_lut_id = 0;
+               ret = ice_aq_set_rss_lut(hw, &lut_params);
                if (ret) {
                        PMD_DRV_LOG(ERR, "Failed to set RSS lookup table");
                        return -EINVAL;
@@ -4259,8 +4455,10 @@ ice_rss_hash_update(struct rte_eth_dev *dev,
        if (status)
                return status;
 
-       if (rss_conf->rss_hf == 0)
+       if (rss_conf->rss_hf == 0) {
+               pf->rss_hf = 0;
                return 0;
+       }
 
        /* RSS hash configuration */
        ice_rss_hash_set(pf, rss_conf->rss_hf);
@@ -4278,8 +4476,7 @@ ice_rss_hash_conf_get(struct rte_eth_dev *dev,
        ice_get_rss_key(vsi, rss_conf->rss_key,
                        &rss_conf->rss_key_len);
 
-       /* TODO: default set to 0 as hf config is not supported now */
-       rss_conf->rss_hf = 0;
+       rss_conf->rss_hf = pf->rss_hf;
        return 0;
 }
 
@@ -4460,24 +4657,24 @@ ice_vsi_vlan_pvid_set(struct ice_vsi *vsi, struct ice_vsi_vlan_pvid_info *info)
        }
 
        if (info->on) {
-               vsi->info.pvid = info->config.pvid;
+               vsi->info.port_based_inner_vlan = info->config.pvid;
                /**
                 * If insert pvid is enabled, only tagged pkts are
                 * allowed to be sent out.
                 */
-               vlan_flags = ICE_AQ_VSI_PVLAN_INSERT_PVID |
-                            ICE_AQ_VSI_VLAN_MODE_UNTAGGED;
+               vlan_flags = ICE_AQ_VSI_INNER_VLAN_INSERT_PVID |
+                            ICE_AQ_VSI_INNER_VLAN_TX_MODE_ACCEPTUNTAGGED;
        } else {
-               vsi->info.pvid = 0;
+               vsi->info.port_based_inner_vlan = 0;
                if (info->config.reject.tagged == 0)
-                       vlan_flags |= ICE_AQ_VSI_VLAN_MODE_TAGGED;
+                       vlan_flags |= ICE_AQ_VSI_INNER_VLAN_TX_MODE_ACCEPTTAGGED;
 
                if (info->config.reject.untagged == 0)
-                       vlan_flags |= ICE_AQ_VSI_VLAN_MODE_UNTAGGED;
+                       vlan_flags |= ICE_AQ_VSI_INNER_VLAN_TX_MODE_ACCEPTUNTAGGED;
        }
-       vsi->info.vlan_flags &= ~(ICE_AQ_VSI_PVLAN_INSERT_PVID |
-                                 ICE_AQ_VSI_VLAN_MODE_M);
-       vsi->info.vlan_flags |= vlan_flags;
+       vsi->info.inner_vlan_flags &= ~(ICE_AQ_VSI_INNER_VLAN_INSERT_PVID |
+                                 ICE_AQ_VSI_INNER_VLAN_EMODE_M);
+       vsi->info.inner_vlan_flags |= vlan_flags;
        memset(&ctxt, 0, sizeof(ctxt));
        rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
        ctxt.info.valid_sections =
@@ -5068,30 +5265,14 @@ static int ice_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
 }
 
 static int
-ice_dev_filter_ctrl(struct rte_eth_dev *dev,
-                    enum rte_filter_type filter_type,
-                    enum rte_filter_op filter_op,
-                    void *arg)
+ice_dev_flow_ops_get(struct rte_eth_dev *dev,
+                    const struct rte_flow_ops **ops)
 {
-       int ret = 0;
-
        if (!dev)
                return -EINVAL;
 
-       switch (filter_type) {
-       case RTE_ETH_FILTER_GENERIC:
-               if (filter_op != RTE_ETH_FILTER_GET)
-                       return -EINVAL;
-               *(const void **)arg = &ice_flow_ops;
-               break;
-       default:
-               PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
-                                       filter_type);
-               ret = -EINVAL;
-               break;
-       }
-
-       return ret;
+       *ops = &ice_flow_ops;
+       return 0;
 }
 
 /* Add UDP tunneling port */
@@ -5179,12 +5360,9 @@ RTE_PMD_REGISTER_PARAM_STRING(net_ice,
 
 RTE_LOG_REGISTER(ice_logtype_init, pmd.net.ice.init, NOTICE);
 RTE_LOG_REGISTER(ice_logtype_driver, pmd.net.ice.driver, NOTICE);
-#ifdef RTE_LIBRTE_ICE_DEBUG_RX
+#ifdef RTE_ETHDEV_DEBUG_RX
 RTE_LOG_REGISTER(ice_logtype_rx, pmd.net.ice.rx, DEBUG);
 #endif
-#ifdef RTE_LIBRTE_ICE_DEBUG_TX
+#ifdef RTE_ETHDEV_DEBUG_TX
 RTE_LOG_REGISTER(ice_logtype_tx, pmd.net.ice.tx, DEBUG);
 #endif
-#ifdef RTE_LIBRTE_ICE_DEBUG_TX_FREE
-RTE_LOG_REGISTER(ice_logtype_tx_free, pmd.net.ice.tx_free, DEBUG);
-#endif