|
@@ -156,12 +156,28 @@ void i40e_vc_notify_vf_reset(struct i40e_vf *vf)
|
|
|
* i40e_vc_disable_vf
|
|
|
* @vf: pointer to the VF info
|
|
|
*
|
|
|
- * Disable the VF through a SW reset
|
|
|
+ * Disable the VF through a SW reset.
|
|
|
**/
|
|
|
static inline void i40e_vc_disable_vf(struct i40e_vf *vf)
|
|
|
{
|
|
|
+ int i;
|
|
|
+
|
|
|
i40e_vc_notify_vf_reset(vf);
|
|
|
- i40e_reset_vf(vf, false);
|
|
|
+
|
|
|
+ /* We want to ensure that an actual reset occurs initiated after this
|
|
|
+ * function was called. However, we do not want to wait forever, so
|
|
|
+ * we'll give a reasonable time and print a message if we failed to
|
|
|
+ * ensure a reset.
|
|
|
+ */
|
|
|
+ for (i = 0; i < 20; i++) {
|
|
|
+ if (i40e_reset_vf(vf, false))
|
|
|
+ return;
|
|
|
+ usleep_range(10000, 20000);
|
|
|
+ }
|
|
|
+
|
|
|
+ dev_warn(&vf->pf->pdev->dev,
|
|
|
+ "Failed to initiate reset for VF %d after 200 milliseconds\n",
|
|
|
+ vf->vf_id);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1051,9 +1067,9 @@ static void i40e_cleanup_reset_vf(struct i40e_vf *vf)
|
|
|
* @vf: pointer to the VF structure
|
|
|
* @flr: VFLR was issued or not
|
|
|
*
|
|
|
- * reset the VF
|
|
|
+ * Returns true if the VF is reset, false otherwise.
|
|
|
**/
|
|
|
-void i40e_reset_vf(struct i40e_vf *vf, bool flr)
|
|
|
+bool i40e_reset_vf(struct i40e_vf *vf, bool flr)
|
|
|
{
|
|
|
struct i40e_pf *pf = vf->pf;
|
|
|
struct i40e_hw *hw = &pf->hw;
|
|
@@ -1061,9 +1077,11 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr)
|
|
|
u32 reg;
|
|
|
int i;
|
|
|
|
|
|
- /* If VFs have been disabled, there is no need to reset */
|
|
|
+ /* If the VFs have been disabled, this means something else is
|
|
|
+ * resetting the VF, so we shouldn't continue.
|
|
|
+ */
|
|
|
if (test_and_set_bit(__I40E_VF_DISABLE, pf->state))
|
|
|
- return;
|
|
|
+ return false;
|
|
|
|
|
|
i40e_trigger_vf_reset(vf, flr);
|
|
|
|
|
@@ -1100,6 +1118,8 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr)
|
|
|
|
|
|
i40e_flush(hw);
|
|
|
clear_bit(__I40E_VF_DISABLE, pf->state);
|
|
|
+
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1111,8 +1131,10 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr)
|
|
|
* VF, then do all the waiting in one chunk, and finally finish restoring each
|
|
|
* VF after the wait. This is useful during PF routines which need to reset
|
|
|
* all VFs, as otherwise it must perform these resets in a serialized fashion.
|
|
|
+ *
|
|
|
+ * Returns true if any VFs were reset, and false otherwise.
|
|
|
**/
|
|
|
-void i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
|
|
|
+bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
|
|
|
{
|
|
|
struct i40e_hw *hw = &pf->hw;
|
|
|
struct i40e_vf *vf;
|
|
@@ -1121,11 +1143,11 @@ void i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
|
|
|
|
|
|
/* If we don't have any VFs, then there is nothing to reset */
|
|
|
if (!pf->num_alloc_vfs)
|
|
|
- return;
|
|
|
+ return false;
|
|
|
|
|
|
/* If VFs have been disabled, there is no need to reset */
|
|
|
if (test_and_set_bit(__I40E_VF_DISABLE, pf->state))
|
|
|
- return;
|
|
|
+ return false;
|
|
|
|
|
|
/* Begin reset on all VFs at once */
|
|
|
for (v = 0; v < pf->num_alloc_vfs; v++)
|
|
@@ -1200,6 +1222,8 @@ void i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
|
|
|
|
|
|
i40e_flush(hw);
|
|
|
clear_bit(__I40E_VF_DISABLE, pf->state);
|
|
|
+
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
/**
|