diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c index 9038d2687ba68..8fd7c3e37f5e3 100644 --- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c @@ -297,6 +297,73 @@ bool ice_is_any_vf_in_unicast_promisc(struct ice_pf *pf) return is_vf_promisc; } +/** + * ice_vf_get_promisc_masks - Calculate masks for promiscuous modes + * @vf: the VF pointer + * @vsi: the VSI to configure + * @ucast_m: promiscuous mask to apply to unicast + * @mcast_m: promiscuous mask to apply to multicast + * + * Decide which mask should be used for unicast and multicast filter, + * based on presence of VLANs + */ +void +ice_vf_get_promisc_masks(struct ice_vf *vf, struct ice_vsi *vsi, + u8 *ucast_m, u8 *mcast_m) +{ + if (ice_vf_is_port_vlan_ena(vf) || + ice_vsi_has_non_zero_vlans(vsi)) { + *mcast_m = ICE_MCAST_VLAN_PROMISC_BITS; + *ucast_m = ICE_UCAST_VLAN_PROMISC_BITS; + } else { + *mcast_m = ICE_MCAST_PROMISC_BITS; + *ucast_m = ICE_UCAST_PROMISC_BITS; + } +} + +/** + * ice_vf_clear_all_promisc_modes - Clear promisc/allmulticast on VF VSI + * @vf: the VF pointer + * @vsi: the VSI to configure + * + * Clear all promiscuous/allmulticast filters for a VF + */ +static int +ice_vf_clear_all_promisc_modes(struct ice_vf *vf, struct ice_vsi *vsi) +{ + struct ice_pf *pf = vf->pf; + u8 ucast_m, mcast_m; + int ret = 0; + + ice_vf_get_promisc_masks(vf, vsi, &ucast_m, &mcast_m); + if (test_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states)) { + if (!test_bit(ICE_FLAG_VF_TRUE_PROMISC_ENA, pf->flags)) { + if (ice_is_dflt_vsi_in_use(vsi->port_info)) + ret = ice_clear_dflt_vsi(vsi); + } else { + ret = ice_vf_clear_vsi_promisc(vf, vsi, ucast_m); + } + + if (ret) { + dev_err(ice_pf_to_dev(vf->pf), "Disabling promiscuous mode failed\n"); + } else { + clear_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states); + dev_info(ice_pf_to_dev(vf->pf), "Disabling promiscuous mode succeeded\n"); + } + } + + if (test_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states)) { + ret = ice_vf_clear_vsi_promisc(vf, vsi, mcast_m); + if (ret) { + dev_err(ice_pf_to_dev(vf->pf), "Disabling allmulticast mode failed\n"); + } else { + clear_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states); + dev_info(ice_pf_to_dev(vf->pf), "Disabling allmulticast mode succeeded\n"); + } + } + return ret; +} + /** * ice_vf_set_vsi_promisc - Enable promiscuous mode for a VF VSI * @vf: the VF to configure @@ -487,7 +554,6 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags) struct ice_vsi *vsi; struct device *dev; struct ice_hw *hw; - u8 promisc_m; int err = 0; bool rsd; @@ -554,16 +620,7 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags) /* disable promiscuous modes in case they were enabled * ignore any error if disabling process failed */ - if (test_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states) || - test_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states)) { - if (ice_vf_is_port_vlan_ena(vf) || vsi->num_vlan) - promisc_m = ICE_UCAST_VLAN_PROMISC_BITS; - else - promisc_m = ICE_UCAST_PROMISC_BITS; - - if (ice_vf_clear_vsi_promisc(vf, vsi, promisc_m)) - dev_err(dev, "disabling promiscuous mode failed\n"); - } + ice_vf_clear_all_promisc_modes(vf, vsi); ice_eswitch_del_vf_mac_rule(vf); diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.h b/drivers/net/ethernet/intel/ice/ice_vf_lib.h index 1acb35c9ff017..52bd9a3816bf2 100644 --- a/drivers/net/ethernet/intel/ice/ice_vf_lib.h +++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.h @@ -215,6 +215,9 @@ bool ice_is_vf_disabled(struct ice_vf *vf); int ice_check_vf_ready_for_cfg(struct ice_vf *vf); void ice_set_vf_state_qs_dis(struct ice_vf *vf); bool ice_is_any_vf_in_unicast_promisc(struct ice_pf *pf); +void +ice_vf_get_promisc_masks(struct ice_vf *vf, struct ice_vsi *vsi, + u8 *ucast_m, u8 *mcast_m); int ice_vf_set_vsi_promisc(struct ice_vf *vf, struct ice_vsi *vsi, u8 promisc_m); int diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c b/drivers/net/ethernet/intel/ice/ice_virtchnl.c index 47ce713274cf7..d46786cdc1621 100644 --- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c @@ -1046,14 +1046,7 @@ static int ice_vc_cfg_promiscuous_mode_msg(struct ice_vf *vf, u8 *msg) goto error_param; } - if (ice_vf_is_port_vlan_ena(vf) || - ice_vsi_has_non_zero_vlans(vsi)) { - mcast_m = ICE_MCAST_VLAN_PROMISC_BITS; - ucast_m = ICE_UCAST_VLAN_PROMISC_BITS; - } else { - mcast_m = ICE_MCAST_PROMISC_BITS; - ucast_m = ICE_UCAST_PROMISC_BITS; - } + ice_vf_get_promisc_masks(vf, vsi, &ucast_m, &mcast_m); if (!test_bit(ICE_FLAG_VF_TRUE_PROMISC_ENA, pf->flags)) { if (alluni) {