Merge 5.17-rc6 into char-misc-next
[linux-2.6-microblaze.git] / drivers / net / ethernet / intel / ice / ice_virtchnl_pf.c
index 6427e7e..408f78e 100644 (file)
@@ -9,6 +9,7 @@
 #include "ice_flow.h"
 #include "ice_eswitch.h"
 #include "ice_virtchnl_allowlist.h"
+#include "ice_flex_pipe.h"
 
 #define FIELD_SELECTOR(proto_hdr_field) \
                BIT((proto_hdr_field) & PROTO_HDR_FIELD_MASK)
@@ -18,18 +19,7 @@ struct ice_vc_hdr_match_type {
        u32 ice_hdr;    /* ice headers (ICE_FLOW_SEG_HDR_XXX) */
 };
 
-static const struct ice_vc_hdr_match_type ice_vc_hdr_list_os[] = {
-       {VIRTCHNL_PROTO_HDR_NONE,       ICE_FLOW_SEG_HDR_NONE},
-       {VIRTCHNL_PROTO_HDR_IPV4,       ICE_FLOW_SEG_HDR_IPV4 |
-                                       ICE_FLOW_SEG_HDR_IPV_OTHER},
-       {VIRTCHNL_PROTO_HDR_IPV6,       ICE_FLOW_SEG_HDR_IPV6 |
-                                       ICE_FLOW_SEG_HDR_IPV_OTHER},
-       {VIRTCHNL_PROTO_HDR_TCP,        ICE_FLOW_SEG_HDR_TCP},
-       {VIRTCHNL_PROTO_HDR_UDP,        ICE_FLOW_SEG_HDR_UDP},
-       {VIRTCHNL_PROTO_HDR_SCTP,       ICE_FLOW_SEG_HDR_SCTP},
-};
-
-static const struct ice_vc_hdr_match_type ice_vc_hdr_list_comms[] = {
+static const struct ice_vc_hdr_match_type ice_vc_hdr_list[] = {
        {VIRTCHNL_PROTO_HDR_NONE,       ICE_FLOW_SEG_HDR_NONE},
        {VIRTCHNL_PROTO_HDR_ETH,        ICE_FLOW_SEG_HDR_ETH},
        {VIRTCHNL_PROTO_HDR_S_VLAN,     ICE_FLOW_SEG_HDR_VLAN},
@@ -67,83 +57,7 @@ struct ice_vc_hash_field_match_type {
 };
 
 static const struct
-ice_vc_hash_field_match_type ice_vc_hash_field_list_os[] = {
-       {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC),
-               BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)},
-       {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST),
-               BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)},
-       {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) |
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST),
-               ICE_FLOW_HASH_IPV4},
-       {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) |
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
-               BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) |
-               BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
-       {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) |
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
-               BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) |
-               BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
-       {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) |
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) |
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
-               ICE_FLOW_HASH_IPV4 | BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
-       {VIRTCHNL_PROTO_HDR_IPV4, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT),
-               BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)},
-       {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC),
-               BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)},
-       {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST),
-               BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)},
-       {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) |
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST),
-               ICE_FLOW_HASH_IPV6},
-       {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) |
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
-               BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) |
-               BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
-       {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) |
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
-               BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) |
-               BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
-       {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) |
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) |
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
-               ICE_FLOW_HASH_IPV6 | BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
-       {VIRTCHNL_PROTO_HDR_IPV6, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT),
-               BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)},
-       {VIRTCHNL_PROTO_HDR_TCP,
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT),
-               BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)},
-       {VIRTCHNL_PROTO_HDR_TCP,
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT),
-               BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)},
-       {VIRTCHNL_PROTO_HDR_TCP,
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT) |
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT),
-               ICE_FLOW_HASH_TCP_PORT},
-       {VIRTCHNL_PROTO_HDR_UDP,
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT),
-               BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)},
-       {VIRTCHNL_PROTO_HDR_UDP,
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT),
-               BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)},
-       {VIRTCHNL_PROTO_HDR_UDP,
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT) |
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT),
-               ICE_FLOW_HASH_UDP_PORT},
-       {VIRTCHNL_PROTO_HDR_SCTP,
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT),
-               BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)},
-       {VIRTCHNL_PROTO_HDR_SCTP,
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT),
-               BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)},
-       {VIRTCHNL_PROTO_HDR_SCTP,
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT) |
-               FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT),
-               ICE_FLOW_HASH_SCTP_PORT},
-};
-
-static const struct
-ice_vc_hash_field_match_type ice_vc_hash_field_list_comms[] = {
+ice_vc_hash_field_match_type ice_vc_hash_field_list[] = {
        {VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_SRC),
                BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_SA)},
        {VIRTCHNL_PROTO_HDR_ETH, FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_DST),
@@ -288,37 +202,6 @@ static int ice_check_vf_init(struct ice_pf *pf, struct ice_vf *vf)
        return 0;
 }
 
-/**
- * ice_err_to_virt_err - translate errors for VF return code
- * @ice_err: error return code
- */
-static enum virtchnl_status_code ice_err_to_virt_err(enum ice_status ice_err)
-{
-       switch (ice_err) {
-       case ICE_SUCCESS:
-               return VIRTCHNL_STATUS_SUCCESS;
-       case ICE_ERR_BAD_PTR:
-       case ICE_ERR_INVAL_SIZE:
-       case ICE_ERR_DEVICE_NOT_SUPPORTED:
-       case ICE_ERR_PARAM:
-       case ICE_ERR_CFG:
-               return VIRTCHNL_STATUS_ERR_PARAM;
-       case ICE_ERR_NO_MEMORY:
-               return VIRTCHNL_STATUS_ERR_NO_MEMORY;
-       case ICE_ERR_NOT_READY:
-       case ICE_ERR_RESET_FAILED:
-       case ICE_ERR_FW_API_VER:
-       case ICE_ERR_AQ_ERROR:
-       case ICE_ERR_AQ_TIMEOUT:
-       case ICE_ERR_AQ_FULL:
-       case ICE_ERR_AQ_NO_WORK:
-       case ICE_ERR_AQ_EMPTY:
-               return VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR;
-       default:
-               return VIRTCHNL_STATUS_ERR_NOT_SUPPORTED;
-       }
-}
-
 /**
  * ice_vc_vf_broadcast - Broadcast a message to all VFs on PF
  * @pf: pointer to the PF structure
@@ -617,8 +500,6 @@ void ice_free_vfs(struct ice_pf *pf)
        struct ice_hw *hw = &pf->hw;
        unsigned int tmp, i;
 
-       set_bit(ICE_VF_DEINIT_IN_PROGRESS, pf->state);
-
        if (!pf->vf)
                return;
 
@@ -636,22 +517,26 @@ void ice_free_vfs(struct ice_pf *pf)
        else
                dev_warn(dev, "VFs are assigned - not disabling SR-IOV\n");
 
-       /* Avoid wait time by stopping all VFs at the same time */
-       ice_for_each_vf(pf, i)
-               ice_dis_vf_qs(&pf->vf[i]);
-
        tmp = pf->num_alloc_vfs;
        pf->num_qps_per_vf = 0;
        pf->num_alloc_vfs = 0;
        for (i = 0; i < tmp; i++) {
-               if (test_bit(ICE_VF_STATE_INIT, pf->vf[i].vf_states)) {
+               struct ice_vf *vf = &pf->vf[i];
+
+               mutex_lock(&vf->cfg_lock);
+
+               ice_dis_vf_qs(vf);
+
+               if (test_bit(ICE_VF_STATE_INIT, vf->vf_states)) {
                        /* disable VF qp mappings and set VF disable state */
-                       ice_dis_vf_mappings(&pf->vf[i]);
-                       set_bit(ICE_VF_STATE_DIS, pf->vf[i].vf_states);
-                       ice_free_vf_res(&pf->vf[i]);
+                       ice_dis_vf_mappings(vf);
+                       set_bit(ICE_VF_STATE_DIS, vf->vf_states);
+                       ice_free_vf_res(vf);
                }
 
-               mutex_destroy(&pf->vf[i].cfg_lock);
+               mutex_unlock(&vf->cfg_lock);
+
+               mutex_destroy(&vf->cfg_lock);
        }
 
        if (ice_sriov_free_msix_res(pf))
@@ -687,7 +572,6 @@ void ice_free_vfs(struct ice_pf *pf)
                                i);
 
        clear_bit(ICE_VF_DIS, pf->state);
-       clear_bit(ICE_VF_DEINIT_IN_PROGRESS, pf->state);
        clear_bit(ICE_FLAG_SRIOV_ENA, pf->flags);
 }
 
@@ -770,8 +654,7 @@ static int ice_vsi_manage_pvid(struct ice_vsi *vsi, u16 pvid_info, bool enable)
        struct ice_hw *hw = &vsi->back->hw;
        struct ice_aqc_vsi_props *info;
        struct ice_vsi_ctx *ctxt;
-       enum ice_status status;
-       int ret = 0;
+       int ret;
 
        ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);
        if (!ctxt)
@@ -794,12 +677,10 @@ static int ice_vsi_manage_pvid(struct ice_vsi *vsi, u16 pvid_info, bool enable)
        info->valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID |
                                           ICE_AQ_VSI_PROP_SW_VALID);
 
-       status = ice_update_vsi(hw, vsi->idx, ctxt, NULL);
-       if (status) {
-               dev_info(ice_hw_to_dev(hw), "update VSI for port VLAN failed, err %s aq_err %s\n",
-                        ice_stat_str(status),
-                        ice_aq_str(hw->adminq.sq_last_status));
-               ret = -EIO;
+       ret = ice_update_vsi(hw, vsi->idx, ctxt, NULL);
+       if (ret) {
+               dev_info(ice_hw_to_dev(hw), "update VSI for port VLAN failed, err %d aq_err %s\n",
+                        ret, ice_aq_str(hw->adminq.sq_last_status));
                goto out;
        }
 
@@ -968,8 +849,8 @@ static int ice_vf_rebuild_host_mac_cfg(struct ice_vf *vf)
 {
        struct device *dev = ice_pf_to_dev(vf->pf);
        struct ice_vsi *vsi = ice_get_vf_vsi(vf);
-       enum ice_status status;
        u8 broadcast[ETH_ALEN];
+       int status;
 
        if (ice_is_eswitch_mode_switchdev(vf->pf))
                return 0;
@@ -977,9 +858,9 @@ static int ice_vf_rebuild_host_mac_cfg(struct ice_vf *vf)
        eth_broadcast_addr(broadcast);
        status = ice_fltr_add_mac(vsi, broadcast, ICE_FWD_TO_VSI);
        if (status) {
-               dev_err(dev, "failed to add broadcast MAC filter for VF %u, error %s\n",
-                       vf->vf_id, ice_stat_str(status));
-               return ice_status_to_errno(status);
+               dev_err(dev, "failed to add broadcast MAC filter for VF %u, error %d\n",
+                       vf->vf_id, status);
+               return status;
        }
 
        vf->num_mac++;
@@ -988,10 +869,10 @@ static int ice_vf_rebuild_host_mac_cfg(struct ice_vf *vf)
                status = ice_fltr_add_mac(vsi, vf->hw_lan_addr.addr,
                                          ICE_FWD_TO_VSI);
                if (status) {
-                       dev_err(dev, "failed to add default unicast MAC filter %pM for VF %u, error %s\n",
+                       dev_err(dev, "failed to add default unicast MAC filter %pM for VF %u, error %d\n",
                                &vf->hw_lan_addr.addr[0], vf->vf_id,
-                               ice_stat_str(status));
-                       return ice_status_to_errno(status);
+                               status);
+                       return status;
                }
                vf->num_mac++;
 
@@ -1341,45 +1222,50 @@ static void ice_clear_vf_reset_trigger(struct ice_vf *vf)
        ice_flush(hw);
 }
 
-/**
- * ice_vf_set_vsi_promisc - set given VF VSI to given promiscuous mode(s)
- * @vf: pointer to the VF info
- * @vsi: the VSI being configured
- * @promisc_m: mask of promiscuous config bits
- * @rm_promisc: promisc flag request from the VF to remove or add filter
- *
- * This function configures VF VSI promiscuous mode, based on the VF requests,
- * for Unicast, Multicast and VLAN
- */
-static enum ice_status
-ice_vf_set_vsi_promisc(struct ice_vf *vf, struct ice_vsi *vsi, u8 promisc_m,
-                      bool rm_promisc)
+static int
+ice_vf_set_vsi_promisc(struct ice_vf *vf, struct ice_vsi *vsi, u8 promisc_m)
 {
-       struct ice_pf *pf = vf->pf;
-       enum ice_status status = 0;
-       struct ice_hw *hw;
+       struct ice_hw *hw = &vsi->back->hw;
+       int status;
 
-       hw = &pf->hw;
-       if (vsi->num_vlan) {
-               status = ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_m,
-                                                 rm_promisc);
-       } else if (vf->port_vlan_info) {
-               if (rm_promisc)
-                       status = ice_clear_vsi_promisc(hw, vsi->idx, promisc_m,
-                                                      vf->port_vlan_info);
-               else
-                       status = ice_set_vsi_promisc(hw, vsi->idx, promisc_m,
-                                                    vf->port_vlan_info);
-       } else {
-               if (rm_promisc)
-                       status = ice_clear_vsi_promisc(hw, vsi->idx, promisc_m,
-                                                      0);
-               else
-                       status = ice_set_vsi_promisc(hw, vsi->idx, promisc_m,
-                                                    0);
+       if (vf->port_vlan_info)
+               status = ice_fltr_set_vsi_promisc(hw, vsi->idx, promisc_m,
+                                                 vf->port_vlan_info & VLAN_VID_MASK);
+       else if (vsi->num_vlan > 1)
+               status = ice_fltr_set_vlan_vsi_promisc(hw, vsi, promisc_m);
+       else
+               status = ice_fltr_set_vsi_promisc(hw, vsi->idx, promisc_m, 0);
+
+       if (status && status != -EEXIST) {
+               dev_err(ice_pf_to_dev(vsi->back), "enable Tx/Rx filter promiscuous mode on VF-%u failed, error: %d\n",
+                       vf->vf_id, status);
+               return status;
+       }
+
+       return 0;
+}
+
+static int
+ice_vf_clear_vsi_promisc(struct ice_vf *vf, struct ice_vsi *vsi, u8 promisc_m)
+{
+       struct ice_hw *hw = &vsi->back->hw;
+       int status;
+
+       if (vf->port_vlan_info)
+               status = ice_fltr_clear_vsi_promisc(hw, vsi->idx, promisc_m,
+                                                   vf->port_vlan_info & VLAN_VID_MASK);
+       else if (vsi->num_vlan > 1)
+               status = ice_fltr_clear_vlan_vsi_promisc(hw, vsi, promisc_m);
+       else
+               status = ice_fltr_clear_vsi_promisc(hw, vsi->idx, promisc_m, 0);
+
+       if (status && status != -ENOENT) {
+               dev_err(ice_pf_to_dev(vsi->back), "disable Tx/Rx filter promiscuous mode on VF-%u failed, error: %d\n",
+                       vf->vf_id, status);
+               return status;
        }
 
-       return status;
+       return 0;
 }
 
 static void ice_vf_clear_counters(struct ice_vf *vf)
@@ -1415,8 +1301,8 @@ static void ice_vf_pre_vsi_rebuild(struct ice_vf *vf)
 static void ice_vf_rebuild_aggregator_node_cfg(struct ice_vsi *vsi)
 {
        struct ice_pf *pf = vsi->back;
-       enum ice_status status;
        struct device *dev;
+       int status;
 
        if (!vsi->agg_node)
                return;
@@ -1613,6 +1499,8 @@ bool ice_reset_all_vfs(struct ice_pf *pf, bool is_vflr)
        ice_for_each_vf(pf, v) {
                vf = &pf->vf[v];
 
+               mutex_lock(&vf->cfg_lock);
+
                vf->driver_caps = 0;
                ice_vc_set_default_allowlist(vf);
 
@@ -1627,6 +1515,8 @@ bool ice_reset_all_vfs(struct ice_pf *pf, bool is_vflr)
                ice_vf_pre_vsi_rebuild(vf);
                ice_vf_rebuild_vsi(vf);
                ice_vf_post_vsi_rebuild(vf);
+
+               mutex_unlock(&vf->cfg_lock);
        }
 
        if (ice_is_eswitch_mode_switchdev(pf))
@@ -1677,6 +1567,8 @@ bool ice_reset_vf(struct ice_vf *vf, bool is_vflr)
        u32 reg;
        int i;
 
+       lockdep_assert_held(&vf->cfg_lock);
+
        dev = ice_pf_to_dev(pf);
 
        if (test_bit(ICE_VF_RESETS_DISABLED, pf->state)) {
@@ -1743,10 +1635,12 @@ bool ice_reset_vf(struct ice_vf *vf, bool is_vflr)
                else
                        promisc_m = ICE_UCAST_PROMISC_BITS;
 
-               if (ice_vf_set_vsi_promisc(vf, vsi, promisc_m, true))
+               if (ice_vf_clear_vsi_promisc(vf, vsi, promisc_m))
                        dev_err(dev, "disabling promiscuous mode failed\n");
        }
 
+       ice_eswitch_del_vf_mac_rule(vf);
+
        ice_vf_fdir_exit(vf);
        ice_vf_fdir_init(vf);
        /* clean VF control VSI when resetting VF since it should be setup
@@ -1765,6 +1659,7 @@ bool ice_reset_vf(struct ice_vf *vf, bool is_vflr)
        ice_vf_post_vsi_rebuild(vf);
        vsi = ice_get_vf_vsi(vf);
        ice_eswitch_update_repr(vsi);
+       ice_eswitch_replay_vf_mac_rule(vf);
 
        /* if the VF has been reset allow it to come up again */
        if (ice_mbx_clear_malvf(&hw->mbx_snapshot, pf->malvfs, ICE_MAX_VF_COUNT, vf->vf_id))
@@ -1846,7 +1741,6 @@ static int ice_init_vf_vsi_res(struct ice_vf *vf)
 {
        struct ice_pf *pf = vf->pf;
        u8 broadcast[ETH_ALEN];
-       enum ice_status status;
        struct ice_vsi *vsi;
        struct device *dev;
        int err;
@@ -1866,11 +1760,10 @@ static int ice_init_vf_vsi_res(struct ice_vf *vf)
        }
 
        eth_broadcast_addr(broadcast);
-       status = ice_fltr_add_mac(vsi, broadcast, ICE_FWD_TO_VSI);
-       if (status) {
-               dev_err(dev, "Failed to add broadcast MAC filter for VF %d, status %s\n",
-                       vf->vf_id, ice_stat_str(status));
-               err = ice_status_to_errno(status);
+       err = ice_fltr_add_mac(vsi, broadcast, ICE_FWD_TO_VSI);
+       if (err) {
+               dev_err(dev, "Failed to add broadcast MAC filter for VF %d, error %d\n",
+                       vf->vf_id, err);
                goto release_vsi;
        }
 
@@ -2116,7 +2009,6 @@ int ice_sriov_configure(struct pci_dev *pdev, int num_vfs)
 {
        struct ice_pf *pf = pci_get_drvdata(pdev);
        struct device *dev = ice_pf_to_dev(pf);
-       enum ice_status status;
        int err;
 
        err = ice_check_sriov_allowed(pf);
@@ -2136,9 +2028,9 @@ int ice_sriov_configure(struct pci_dev *pdev, int num_vfs)
                return -EBUSY;
        }
 
-       status = ice_mbx_init_snapshot(&pf->hw, num_vfs);
-       if (status)
-               return ice_status_to_errno(status);
+       err = ice_mbx_init_snapshot(&pf->hw, num_vfs);
+       if (err)
+               return err;
 
        err = ice_pci_sriov_ena(pf, num_vfs);
        if (err) {
@@ -2176,9 +2068,12 @@ void ice_process_vflr_event(struct ice_pf *pf)
                bit_idx = (hw->func_caps.vf_base_id + vf_id) % 32;
                /* read GLGEN_VFLRSTAT register to find out the flr VFs */
                reg = rd32(hw, GLGEN_VFLRSTAT(reg_idx));
-               if (reg & BIT(bit_idx))
+               if (reg & BIT(bit_idx)) {
                        /* GLGEN_VFLRSTAT bit will be cleared in ice_reset_vf */
+                       mutex_lock(&vf->cfg_lock);
                        ice_reset_vf(vf, true);
+                       mutex_unlock(&vf->cfg_lock);
+               }
        }
 }
 
@@ -2255,7 +2150,9 @@ ice_vf_lan_overflow_event(struct ice_pf *pf, struct ice_rq_event_info *event)
        if (!vf)
                return;
 
+       mutex_lock(&vf->cfg_lock);
        ice_vc_reset_vf(vf);
+       mutex_unlock(&vf->cfg_lock);
 }
 
 /**
@@ -2272,9 +2169,9 @@ int
 ice_vc_send_msg_to_vf(struct ice_vf *vf, u32 v_opcode,
                      enum virtchnl_status_code v_retval, u8 *msg, u16 msglen)
 {
-       enum ice_status aq_ret;
        struct device *dev;
        struct ice_pf *pf;
+       int aq_ret;
 
        if (!vf)
                return -EINVAL;
@@ -2306,8 +2203,8 @@ ice_vc_send_msg_to_vf(struct ice_vf *vf, u32 v_opcode,
        aq_ret = ice_aq_send_msg_to_vf(&pf->hw, vf->vf_id, v_opcode, v_retval,
                                       msg, msglen, NULL);
        if (aq_ret && pf->hw.mailboxq.sq_last_status != ICE_AQ_RC_ENOSYS) {
-               dev_info(dev, "Unable to send the message to VF %d ret %s aq_err %s\n",
-                        vf->vf_id, ice_stat_str(aq_ret),
+               dev_info(dev, "Unable to send the message to VF %d ret %d aq_err %s\n",
+                        vf->vf_id, aq_ret,
                         ice_aq_str(pf->hw.mailboxq.sq_last_status));
                return -EIO;
        }
@@ -2555,6 +2452,100 @@ static bool ice_vc_isvalid_ring_len(u16 ring_len)
                !(ring_len % ICE_REQ_DESC_MULTIPLE));
 }
 
+/**
+ * ice_vc_validate_pattern
+ * @vf: pointer to the VF info
+ * @proto: virtchnl protocol headers
+ *
+ * validate the pattern is supported or not.
+ *
+ * Return: true on success, false on error.
+ */
+bool
+ice_vc_validate_pattern(struct ice_vf *vf, struct virtchnl_proto_hdrs *proto)
+{
+       bool is_ipv4 = false;
+       bool is_ipv6 = false;
+       bool is_udp = false;
+       u16 ptype = -1;
+       int i = 0;
+
+       while (i < proto->count &&
+              proto->proto_hdr[i].type != VIRTCHNL_PROTO_HDR_NONE) {
+               switch (proto->proto_hdr[i].type) {
+               case VIRTCHNL_PROTO_HDR_ETH:
+                       ptype = ICE_PTYPE_MAC_PAY;
+                       break;
+               case VIRTCHNL_PROTO_HDR_IPV4:
+                       ptype = ICE_PTYPE_IPV4_PAY;
+                       is_ipv4 = true;
+                       break;
+               case VIRTCHNL_PROTO_HDR_IPV6:
+                       ptype = ICE_PTYPE_IPV6_PAY;
+                       is_ipv6 = true;
+                       break;
+               case VIRTCHNL_PROTO_HDR_UDP:
+                       if (is_ipv4)
+                               ptype = ICE_PTYPE_IPV4_UDP_PAY;
+                       else if (is_ipv6)
+                               ptype = ICE_PTYPE_IPV6_UDP_PAY;
+                       is_udp = true;
+                       break;
+               case VIRTCHNL_PROTO_HDR_TCP:
+                       if (is_ipv4)
+                               ptype = ICE_PTYPE_IPV4_TCP_PAY;
+                       else if (is_ipv6)
+                               ptype = ICE_PTYPE_IPV6_TCP_PAY;
+                       break;
+               case VIRTCHNL_PROTO_HDR_SCTP:
+                       if (is_ipv4)
+                               ptype = ICE_PTYPE_IPV4_SCTP_PAY;
+                       else if (is_ipv6)
+                               ptype = ICE_PTYPE_IPV6_SCTP_PAY;
+                       break;
+               case VIRTCHNL_PROTO_HDR_GTPU_IP:
+               case VIRTCHNL_PROTO_HDR_GTPU_EH:
+                       if (is_ipv4)
+                               ptype = ICE_MAC_IPV4_GTPU;
+                       else if (is_ipv6)
+                               ptype = ICE_MAC_IPV6_GTPU;
+                       goto out;
+               case VIRTCHNL_PROTO_HDR_L2TPV3:
+                       if (is_ipv4)
+                               ptype = ICE_MAC_IPV4_L2TPV3;
+                       else if (is_ipv6)
+                               ptype = ICE_MAC_IPV6_L2TPV3;
+                       goto out;
+               case VIRTCHNL_PROTO_HDR_ESP:
+                       if (is_ipv4)
+                               ptype = is_udp ? ICE_MAC_IPV4_NAT_T_ESP :
+                                               ICE_MAC_IPV4_ESP;
+                       else if (is_ipv6)
+                               ptype = is_udp ? ICE_MAC_IPV6_NAT_T_ESP :
+                                               ICE_MAC_IPV6_ESP;
+                       goto out;
+               case VIRTCHNL_PROTO_HDR_AH:
+                       if (is_ipv4)
+                               ptype = ICE_MAC_IPV4_AH;
+                       else if (is_ipv6)
+                               ptype = ICE_MAC_IPV6_AH;
+                       goto out;
+               case VIRTCHNL_PROTO_HDR_PFCP:
+                       if (is_ipv4)
+                               ptype = ICE_MAC_IPV4_PFCP_SESSION;
+                       else if (is_ipv6)
+                               ptype = ICE_MAC_IPV6_PFCP_SESSION;
+                       goto out;
+               default:
+                       break;
+               }
+               i++;
+       }
+
+out:
+       return ice_hw_ptype_ena(&vf->pf->hw, ptype);
+}
+
 /**
  * ice_vc_parse_rss_cfg - parses hash fields and headers from
  * a specific virtchnl RSS cfg
@@ -2578,18 +2569,10 @@ ice_vc_parse_rss_cfg(struct ice_hw *hw, struct virtchnl_rss_cfg *rss_cfg,
        const struct ice_vc_hdr_match_type *hdr_list;
        int i, hf_list_len, hdr_list_len;
 
-       if (!strncmp(hw->active_pkg_name, "ICE COMMS Package",
-                    sizeof(hw->active_pkg_name))) {
-               hf_list = ice_vc_hash_field_list_comms;
-               hf_list_len = ARRAY_SIZE(ice_vc_hash_field_list_comms);
-               hdr_list = ice_vc_hdr_list_comms;
-               hdr_list_len = ARRAY_SIZE(ice_vc_hdr_list_comms);
-       } else {
-               hf_list = ice_vc_hash_field_list_os;
-               hf_list_len = ARRAY_SIZE(ice_vc_hash_field_list_os);
-               hdr_list = ice_vc_hdr_list_os;
-               hdr_list_len = ARRAY_SIZE(ice_vc_hdr_list_os);
-       }
+       hf_list = ice_vc_hash_field_list;
+       hf_list_len = ARRAY_SIZE(ice_vc_hash_field_list);
+       hdr_list = ice_vc_hdr_list;
+       hdr_list_len = ARRAY_SIZE(ice_vc_hdr_list);
 
        for (i = 0; i < rss_cfg->proto_hdrs.count; i++) {
                struct virtchnl_proto_hdr *proto_hdr =
@@ -2691,10 +2674,15 @@ static int ice_vc_handle_rss_cfg(struct ice_vf *vf, u8 *msg, bool add)
                goto error_param;
        }
 
+       if (!ice_vc_validate_pattern(vf, &rss_cfg->proto_hdrs)) {
+               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+               goto error_param;
+       }
+
        if (rss_cfg->rss_algorithm == VIRTCHNL_RSS_ALG_R_ASYMMETRIC) {
                struct ice_vsi_ctx *ctx;
-               enum ice_status status;
                u8 lut_type, hash_type;
+               int status;
 
                lut_type = ICE_AQ_VSI_Q_OPT_RSS_LUT_VSI;
                hash_type = add ? ICE_AQ_VSI_Q_OPT_RSS_XOR :
@@ -2723,9 +2711,8 @@ static int ice_vc_handle_rss_cfg(struct ice_vf *vf, u8 *msg, bool add)
 
                status = ice_update_vsi(hw, vsi->idx, ctx, NULL);
                if (status) {
-                       dev_err(dev, "update VSI for RSS failed, err %s aq_err %s\n",
-                               ice_stat_str(status),
-                               ice_aq_str(hw->adminq.sq_last_status));
+                       dev_err(dev, "update VSI for RSS failed, err %d aq_err %s\n",
+                               status, ice_aq_str(hw->adminq.sq_last_status));
                        v_ret = VIRTCHNL_STATUS_ERR_PARAM;
                } else {
                        vsi->info.q_opt_rss = ctx->info.q_opt_rss;
@@ -2750,19 +2737,18 @@ static int ice_vc_handle_rss_cfg(struct ice_vf *vf, u8 *msg, bool add)
                                        vsi->vsi_num, v_ret);
                        }
                } else {
-                       enum ice_status status;
+                       int status;
 
                        status = ice_rem_rss_cfg(hw, vsi->idx, hash_flds,
                                                 addl_hdrs);
-                       /* We just ignore ICE_ERR_DOES_NOT_EXIST, because
-                        * if two configurations share the same profile remove
-                        * one of them actually removes both, since the
-                        * profile is deleted.
+                       /* We just ignore -ENOENT, because if two configurations
+                        * share the same profile remove one of them actually
+                        * removes both, since the profile is deleted.
                         */
-                       if (status && status != ICE_ERR_DOES_NOT_EXIST) {
+                       if (status && status != -ENOENT) {
                                v_ret = VIRTCHNL_STATUS_ERR_PARAM;
-                               dev_err(dev, "ice_rem_rss_cfg failed for VF ID:%d, error:%s\n",
-                                       vf->vf_id, ice_stat_str(status));
+                               dev_err(dev, "ice_rem_rss_cfg failed for VF ID:%d, error:%d\n",
+                                       vf->vf_id, status);
                        }
                }
        }
@@ -2920,7 +2906,6 @@ int ice_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool ena)
        struct ice_pf *pf = np->vsi->back;
        struct ice_vsi_ctx *ctx;
        struct ice_vsi *vf_vsi;
-       enum ice_status status;
        struct device *dev;
        struct ice_vf *vf;
        int ret;
@@ -2970,12 +2955,10 @@ int ice_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool ena)
                           ICE_AQ_VSI_SEC_TX_PRUNE_ENA_S));
        }
 
-       status = ice_update_vsi(&pf->hw, vf_vsi->idx, ctx, NULL);
-       if (status) {
-               dev_err(dev, "Failed to %sable spoofchk on VF %d VSI %d\n error %s\n",
-                       ena ? "en" : "dis", vf->vf_id, vf_vsi->vsi_num,
-                       ice_stat_str(status));
-               ret = -EIO;
+       ret = ice_update_vsi(&pf->hw, vf_vsi->idx, ctx, NULL);
+       if (ret) {
+               dev_err(dev, "Failed to %sable spoofchk on VF %d VSI %d\n error %d\n",
+                       ena ? "en" : "dis", vf->vf_id, vf_vsi->vsi_num, ret);
                goto out;
        }
 
@@ -3021,10 +3004,10 @@ bool ice_is_any_vf_in_promisc(struct ice_pf *pf)
 static int ice_vc_cfg_promiscuous_mode_msg(struct ice_vf *vf, u8 *msg)
 {
        enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
-       enum ice_status mcast_status = 0, ucast_status = 0;
        bool rm_promisc, alluni = false, allmulti = false;
        struct virtchnl_promisc_info *info =
            (struct virtchnl_promisc_info *)msg;
+       int mcast_err = 0, ucast_err = 0;
        struct ice_pf *pf = vf->pf;
        struct ice_vsi *vsi;
        struct device *dev;
@@ -3106,24 +3089,21 @@ static int ice_vc_cfg_promiscuous_mode_msg(struct ice_vf *vf, u8 *msg)
                        ucast_m = ICE_UCAST_PROMISC_BITS;
                }
 
-               ucast_status = ice_vf_set_vsi_promisc(vf, vsi, ucast_m,
-                                                     !alluni);
-               if (ucast_status) {
-                       dev_err(dev, "%sable Tx/Rx filter promiscuous mode on VF-%d failed\n",
-                               alluni ? "en" : "dis", vf->vf_id);
-                       v_ret = ice_err_to_virt_err(ucast_status);
-               }
+               if (alluni)
+                       ucast_err = ice_vf_set_vsi_promisc(vf, vsi, ucast_m);
+               else
+                       ucast_err = ice_vf_clear_vsi_promisc(vf, vsi, ucast_m);
 
-               mcast_status = ice_vf_set_vsi_promisc(vf, vsi, mcast_m,
-                                                     !allmulti);
-               if (mcast_status) {
-                       dev_err(dev, "%sable Tx/Rx filter promiscuous mode on VF-%d failed\n",
-                               allmulti ? "en" : "dis", vf->vf_id);
-                       v_ret = ice_err_to_virt_err(mcast_status);
-               }
+               if (allmulti)
+                       mcast_err = ice_vf_set_vsi_promisc(vf, vsi, mcast_m);
+               else
+                       mcast_err = ice_vf_clear_vsi_promisc(vf, vsi, mcast_m);
+
+               if (ucast_err || mcast_err)
+                       v_ret = VIRTCHNL_STATUS_ERR_PARAM;
        }
 
-       if (!mcast_status) {
+       if (!mcast_err) {
                if (allmulti &&
                    !test_and_set_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states))
                        dev_info(dev, "VF %u successfully set multicast promiscuous mode\n",
@@ -3133,7 +3113,7 @@ static int ice_vc_cfg_promiscuous_mode_msg(struct ice_vf *vf, u8 *msg)
                                 vf->vf_id);
        }
 
-       if (!ucast_status) {
+       if (!ucast_err) {
                if (alluni && !test_and_set_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states))
                        dev_info(dev, "VF %u successfully set unicast promiscuous mode\n",
                                 vf->vf_id);
@@ -3813,8 +3793,7 @@ ice_vc_add_mac_addr(struct ice_vf *vf, struct ice_vsi *vsi,
 {
        struct device *dev = ice_pf_to_dev(vf->pf);
        u8 *mac_addr = vc_ether_addr->addr;
-       enum ice_status status;
-       int ret = 0;
+       int ret;
 
        /* device MAC already added */
        if (ether_addr_equal(mac_addr, vf->dev_lan_addr.addr))
@@ -3825,18 +3804,17 @@ ice_vc_add_mac_addr(struct ice_vf *vf, struct ice_vsi *vsi,
                return -EPERM;
        }
 
-       status = ice_fltr_add_mac(vsi, mac_addr, ICE_FWD_TO_VSI);
-       if (status == ICE_ERR_ALREADY_EXISTS) {
+       ret = ice_fltr_add_mac(vsi, mac_addr, ICE_FWD_TO_VSI);
+       if (ret == -EEXIST) {
                dev_dbg(dev, "MAC %pM already exists for VF %d\n", mac_addr,
                        vf->vf_id);
                /* don't return since we might need to update
                 * the primary MAC in ice_vfhw_mac_add() below
                 */
-               ret = -EEXIST;
-       } else if (status) {
-               dev_err(dev, "Failed to add MAC %pM for VF %d\n, error %s\n",
-                       mac_addr, vf->vf_id, ice_stat_str(status));
-               return -EIO;
+       } else if (ret) {
+               dev_err(dev, "Failed to add MAC %pM for VF %d\n, error %d\n",
+                       mac_addr, vf->vf_id, ret);
+               return ret;
        } else {
                vf->num_mac++;
        }
@@ -3913,20 +3891,20 @@ ice_vc_del_mac_addr(struct ice_vf *vf, struct ice_vsi *vsi,
 {
        struct device *dev = ice_pf_to_dev(vf->pf);
        u8 *mac_addr = vc_ether_addr->addr;
-       enum ice_status status;
+       int status;
 
        if (!ice_can_vf_change_mac(vf) &&
            ether_addr_equal(vf->dev_lan_addr.addr, mac_addr))
                return 0;
 
        status = ice_fltr_remove_mac(vsi, mac_addr, ICE_FWD_TO_VSI);
-       if (status == ICE_ERR_DOES_NOT_EXIST) {
+       if (status == -ENOENT) {
                dev_err(dev, "MAC %pM does not exist for VF %d\n", mac_addr,
                        vf->vf_id);
                return -ENOENT;
        } else if (status) {
-               dev_err(dev, "Failed to delete MAC %pM for VF %d, error %s\n",
-                       mac_addr, vf->vf_id, ice_stat_str(status));
+               dev_err(dev, "Failed to delete MAC %pM for VF %d, error %d\n",
+                       mac_addr, vf->vf_id, status);
                return -EIO;
        }
 
@@ -4533,6 +4511,7 @@ static int ice_vc_repr_add_mac(struct ice_vf *vf, u8 *msg)
 
        for (i = 0; i < al->num_elements; i++) {
                u8 *mac_addr = al->list[i].addr;
+               int result;
 
                if (!is_unicast_ether_addr(mac_addr) ||
                    ether_addr_equal(mac_addr, vf->hw_lan_addr.addr))
@@ -4544,6 +4523,13 @@ static int ice_vc_repr_add_mac(struct ice_vf *vf, u8 *msg)
                        goto handle_mac_exit;
                }
 
+               result = ice_eswitch_add_vf_mac_rule(pf, vf, mac_addr);
+               if (result) {
+                       dev_err(ice_pf_to_dev(pf), "Failed to add MAC %pM for VF %d\n, error %d\n",
+                               mac_addr, vf->vf_id, result);
+                       goto handle_mac_exit;
+               }
+
                ice_vfhw_mac_add(vf, &al->list[i]);
                vf->num_mac++;
                break;
@@ -4651,10 +4637,6 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event)
        struct device *dev;
        int err = 0;
 
-       /* if de-init is underway, don't process messages from VF */
-       if (test_bit(ICE_VF_DEINIT_IN_PROGRESS, pf->state))
-               return;
-
        dev = ice_pf_to_dev(pf);
        if (ice_validate_vf_id(pf, vf_id)) {
                err = -EINVAL;
@@ -5289,9 +5271,9 @@ ice_is_malicious_vf(struct ice_pf *pf, struct ice_rq_event_info *event,
        s16 vf_id = le16_to_cpu(event->desc.retval);
        struct device *dev = ice_pf_to_dev(pf);
        struct ice_mbx_data mbxdata;
-       enum ice_status status;
        bool malvf = false;
        struct ice_vf *vf;
+       int status;
 
        if (ice_validate_vf_id(pf, vf_id))
                return false;