mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 10:00:17 +00:00
i40e: Fix VF disable behavior to block all traffic
[ Upstream commit 31deb12e85 ]
Currently, if a VF is disabled using the
'ip link set dev $ETHX vf $VF_NUM state disable' command, the VF is still
able to receive traffic.
Fix the behavior of the 'ip link set dev $ETHX vf $VF_NUM state disable'
to completely shutdown the VF's queues making it entirely disabled and
not able to receive or send any traffic.
Modify the behavior of the 'ip link set $ETHX vf $VF_NUM state enable'
command to make a VF do reinitialization bringing the queues back up.
Co-developed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Jan Sokolowski <jan.sokolowski@intel.com>
Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Signed-off-by: Andrii Staikov <andrii.staikov@intel.com>
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
9f5fd537d3
commit
087ef07c32
@@ -2607,6 +2607,14 @@ static int i40e_vc_enable_queues_msg(struct i40e_vf *vf, u8 *msg)
|
|||||||
int aq_ret = 0;
|
int aq_ret = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (vf->is_disabled_from_host) {
|
||||||
|
aq_ret = -EPERM;
|
||||||
|
dev_info(&pf->pdev->dev,
|
||||||
|
"Admin has disabled VF %d, will not enable queues\n",
|
||||||
|
vf->vf_id);
|
||||||
|
goto error_param;
|
||||||
|
}
|
||||||
|
|
||||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
|
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
|
||||||
aq_ret = -EINVAL;
|
aq_ret = -EINVAL;
|
||||||
goto error_param;
|
goto error_param;
|
||||||
@@ -4734,9 +4742,12 @@ int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link)
|
|||||||
struct i40e_link_status *ls = &pf->hw.phy.link_info;
|
struct i40e_link_status *ls = &pf->hw.phy.link_info;
|
||||||
struct virtchnl_pf_event pfe;
|
struct virtchnl_pf_event pfe;
|
||||||
struct i40e_hw *hw = &pf->hw;
|
struct i40e_hw *hw = &pf->hw;
|
||||||
|
struct i40e_vsi *vsi;
|
||||||
|
unsigned long q_map;
|
||||||
struct i40e_vf *vf;
|
struct i40e_vf *vf;
|
||||||
int abs_vf_id;
|
int abs_vf_id;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
int tmp;
|
||||||
|
|
||||||
if (test_and_set_bit(__I40E_VIRTCHNL_OP_PENDING, pf->state)) {
|
if (test_and_set_bit(__I40E_VIRTCHNL_OP_PENDING, pf->state)) {
|
||||||
dev_warn(&pf->pdev->dev, "Unable to configure VFs, other operation is pending.\n");
|
dev_warn(&pf->pdev->dev, "Unable to configure VFs, other operation is pending.\n");
|
||||||
@@ -4759,17 +4770,38 @@ int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link)
|
|||||||
switch (link) {
|
switch (link) {
|
||||||
case IFLA_VF_LINK_STATE_AUTO:
|
case IFLA_VF_LINK_STATE_AUTO:
|
||||||
vf->link_forced = false;
|
vf->link_forced = false;
|
||||||
|
vf->is_disabled_from_host = false;
|
||||||
|
/* reset needed to reinit VF resources */
|
||||||
|
i40e_vc_reset_vf(vf, true);
|
||||||
i40e_set_vf_link_state(vf, &pfe, ls);
|
i40e_set_vf_link_state(vf, &pfe, ls);
|
||||||
break;
|
break;
|
||||||
case IFLA_VF_LINK_STATE_ENABLE:
|
case IFLA_VF_LINK_STATE_ENABLE:
|
||||||
vf->link_forced = true;
|
vf->link_forced = true;
|
||||||
vf->link_up = true;
|
vf->link_up = true;
|
||||||
|
vf->is_disabled_from_host = false;
|
||||||
|
/* reset needed to reinit VF resources */
|
||||||
|
i40e_vc_reset_vf(vf, true);
|
||||||
i40e_set_vf_link_state(vf, &pfe, ls);
|
i40e_set_vf_link_state(vf, &pfe, ls);
|
||||||
break;
|
break;
|
||||||
case IFLA_VF_LINK_STATE_DISABLE:
|
case IFLA_VF_LINK_STATE_DISABLE:
|
||||||
vf->link_forced = true;
|
vf->link_forced = true;
|
||||||
vf->link_up = false;
|
vf->link_up = false;
|
||||||
i40e_set_vf_link_state(vf, &pfe, ls);
|
i40e_set_vf_link_state(vf, &pfe, ls);
|
||||||
|
|
||||||
|
vsi = pf->vsi[vf->lan_vsi_idx];
|
||||||
|
q_map = BIT(vsi->num_queue_pairs) - 1;
|
||||||
|
|
||||||
|
vf->is_disabled_from_host = true;
|
||||||
|
|
||||||
|
/* Try to stop both Tx&Rx rings even if one of the calls fails
|
||||||
|
* to ensure we stop the rings even in case of errors.
|
||||||
|
* If any of them returns with an error then the first
|
||||||
|
* error that occurred will be returned.
|
||||||
|
*/
|
||||||
|
tmp = i40e_ctrl_vf_tx_rings(vsi, q_map, false);
|
||||||
|
ret = i40e_ctrl_vf_rx_rings(vsi, q_map, false);
|
||||||
|
|
||||||
|
ret = tmp ? tmp : ret;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ struct i40e_vf {
|
|||||||
bool link_forced;
|
bool link_forced;
|
||||||
bool link_up; /* only valid if VF link is forced */
|
bool link_up; /* only valid if VF link is forced */
|
||||||
bool spoofchk;
|
bool spoofchk;
|
||||||
|
bool is_disabled_from_host; /* PF ctrl of VF enable/disable */
|
||||||
u16 num_vlan;
|
u16 num_vlan;
|
||||||
|
|
||||||
/* ADq related variables */
|
/* ADq related variables */
|
||||||
|
|||||||
Reference in New Issue
Block a user