Commit 1a8c7778 authored by Brett Creeley's avatar Brett Creeley Committed by Tony Nguyen

ice: Fix VF true promiscuous mode

When a VF requests promiscuous mode and it's trusted and true promiscuous
mode is enabled the PF driver attempts to enable unicast and/or
multicast promiscuous mode filters based on the request. This is fine,
but there are a couple issues with the current code.

[1] The define to configure the unicast promiscuous mode mask also
    includes bits to configure the multicast promiscuous mode mask, which
    causes multicast to be set/cleared unintentionally.
[2] All 4 cases for enable/disable unicast/multicast mode are not
    handled in the promiscuous mode message handler, which causes
    unexpected results regarding the current promiscuous mode settings.

To fix [1] make sure any promiscuous mask defines include the correct
bits for each of the promiscuous modes.

To fix [2] make sure that all 4 cases are handled since there are 2 bits
(FLAG_VF_UNICAST_PROMISC and FLAG_VF_MULTICAST_PROMISC) that can be
either set or cleared. Also, since either unicast and/or multicast
promiscuous configuration can fail, introduce two separate error values
to handle each of these cases.

Fixes: 01b5e89a ("ice: Add VF promiscuous support")
Signed-off-by: default avatarBrett Creeley <brett.creeley@intel.com>
Tested-by: default avatarTony Brelinski <tony.brelinski@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 92f62485
...@@ -165,13 +165,10 @@ ...@@ -165,13 +165,10 @@
#define ice_for_each_chnl_tc(i) \ #define ice_for_each_chnl_tc(i) \
for ((i) = ICE_CHNL_START_TC; (i) < ICE_CHNL_MAX_TC; (i)++) for ((i) = ICE_CHNL_START_TC; (i) < ICE_CHNL_MAX_TC; (i)++)
#define ICE_UCAST_PROMISC_BITS (ICE_PROMISC_UCAST_TX | ICE_PROMISC_MCAST_TX | \ #define ICE_UCAST_PROMISC_BITS (ICE_PROMISC_UCAST_TX | ICE_PROMISC_UCAST_RX)
ICE_PROMISC_UCAST_RX | ICE_PROMISC_MCAST_RX)
#define ICE_UCAST_VLAN_PROMISC_BITS (ICE_PROMISC_UCAST_TX | \ #define ICE_UCAST_VLAN_PROMISC_BITS (ICE_PROMISC_UCAST_TX | \
ICE_PROMISC_MCAST_TX | \
ICE_PROMISC_UCAST_RX | \ ICE_PROMISC_UCAST_RX | \
ICE_PROMISC_MCAST_RX | \
ICE_PROMISC_VLAN_TX | \ ICE_PROMISC_VLAN_TX | \
ICE_PROMISC_VLAN_RX) ICE_PROMISC_VLAN_RX)
......
...@@ -3013,6 +3013,7 @@ bool ice_is_any_vf_in_promisc(struct ice_pf *pf) ...@@ -3013,6 +3013,7 @@ 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) static int ice_vc_cfg_promiscuous_mode_msg(struct ice_vf *vf, u8 *msg)
{ {
enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; 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; bool rm_promisc, alluni = false, allmulti = false;
struct virtchnl_promisc_info *info = struct virtchnl_promisc_info *info =
(struct virtchnl_promisc_info *)msg; (struct virtchnl_promisc_info *)msg;
...@@ -3105,52 +3106,51 @@ static int ice_vc_cfg_promiscuous_mode_msg(struct ice_vf *vf, u8 *msg) ...@@ -3105,52 +3106,51 @@ static int ice_vc_cfg_promiscuous_mode_msg(struct ice_vf *vf, u8 *msg)
goto error_param; goto error_param;
} }
} else { } else {
enum ice_status status; u8 mcast_m, ucast_m;
u8 promisc_m;
if (vf->port_vlan_info || vsi->num_vlan > 1) {
if (alluni) { mcast_m = ICE_MCAST_VLAN_PROMISC_BITS;
if (vf->port_vlan_info || vsi->num_vlan) ucast_m = ICE_UCAST_VLAN_PROMISC_BITS;
promisc_m = ICE_UCAST_VLAN_PROMISC_BITS;
else
promisc_m = ICE_UCAST_PROMISC_BITS;
} else if (allmulti) {
if (vf->port_vlan_info || vsi->num_vlan)
promisc_m = ICE_MCAST_VLAN_PROMISC_BITS;
else
promisc_m = ICE_MCAST_PROMISC_BITS;
} else { } else {
if (vf->port_vlan_info || vsi->num_vlan) mcast_m = ICE_MCAST_PROMISC_BITS;
promisc_m = ICE_UCAST_VLAN_PROMISC_BITS; ucast_m = ICE_UCAST_PROMISC_BITS;
else
promisc_m = ICE_UCAST_PROMISC_BITS;
} }
/* Configure multicast/unicast with or without VLAN promiscuous ucast_status = ice_vf_set_vsi_promisc(vf, vsi, ucast_m,
* mode !alluni);
*/ if (ucast_status) {
status = ice_vf_set_vsi_promisc(vf, vsi, promisc_m, rm_promisc); dev_err(dev, "%sable Tx/Rx filter promiscuous mode on VF-%d failed\n",
if (status) { alluni ? "en" : "dis", vf->vf_id);
dev_err(dev, "%sable Tx/Rx filter promiscuous mode on VF-%d failed, error: %s\n", v_ret = ice_err_to_virt_err(ucast_status);
rm_promisc ? "dis" : "en", vf->vf_id, }
ice_stat_str(status));
v_ret = ice_err_to_virt_err(status); mcast_status = ice_vf_set_vsi_promisc(vf, vsi, mcast_m,
goto error_param; !allmulti);
} else { if (mcast_status) {
dev_dbg(dev, "%sable Tx/Rx filter promiscuous mode on VF-%d succeeded\n", dev_err(dev, "%sable Tx/Rx filter promiscuous mode on VF-%d failed\n",
rm_promisc ? "dis" : "en", vf->vf_id); allmulti ? "en" : "dis", vf->vf_id);
v_ret = ice_err_to_virt_err(mcast_status);
} }
} }
if (allmulti && if (!mcast_status) {
!test_and_set_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states)) if (allmulti &&
dev_info(dev, "VF %u successfully set multicast promiscuous mode\n", vf->vf_id); !test_and_set_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states))
else if (!allmulti && test_and_clear_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states)) dev_info(dev, "VF %u successfully set multicast promiscuous mode\n",
dev_info(dev, "VF %u successfully unset multicast promiscuous mode\n", vf->vf_id); vf->vf_id);
else if (!allmulti && test_and_clear_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states))
dev_info(dev, "VF %u successfully unset multicast promiscuous mode\n",
vf->vf_id);
}
if (alluni && !test_and_set_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states)) if (!ucast_status) {
dev_info(dev, "VF %u successfully set unicast promiscuous mode\n", vf->vf_id); if (alluni && !test_and_set_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states))
else if (!alluni && test_and_clear_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states)) dev_info(dev, "VF %u successfully set unicast promiscuous mode\n",
dev_info(dev, "VF %u successfully unset unicast promiscuous mode\n", vf->vf_id); vf->vf_id);
else if (!alluni && test_and_clear_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states))
dev_info(dev, "VF %u successfully unset unicast promiscuous mode\n",
vf->vf_id);
}
error_param: error_param:
return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE, return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment