i40e: split some code in i40e_reset_vf into helpers
authorJacob Keller <jacob.e.keller@intel.com>
Thu, 13 Apr 2017 08:45:51 +0000 (04:45 -0400)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Thu, 20 Apr 2017 00:42:21 +0000 (17:42 -0700)
A future patch is going to want to re-use some of the code in
i40e_reset_vf, so lets break up the beginning and ending parts into
their own helper functions. The first function will be used to
initialize the reset on a VF, while the second function will be used to
finalize the reset and restore functionality.

Change-ID: I48df808b8bf09de3c2ed8c521f57b3f0ab9e5907
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c

index 65c95ffc15ec9c1e97ed3a0ffbc5dc9d15f3f1ef..9a75ce3f15644808a82b8cf50bdd3a04a3f5b6b9 100644 (file)
@@ -923,22 +923,19 @@ static int i40e_quiesce_vf_pci(struct i40e_vf *vf)
 }
 
 /**
- * i40e_reset_vf
+ * i40e_trigger_vf_reset
  * @vf: pointer to the VF structure
  * @flr: VFLR was issued or not
  *
- * reset the VF
+ * Trigger hardware to start a reset for a particular VF. Expects the caller
+ * to wait the proper amount of time to allow hardware to reset the VF before
+ * it cleans up and restores VF functionality.
  **/
-void i40e_reset_vf(struct i40e_vf *vf, bool flr)
+static void i40e_trigger_vf_reset(struct i40e_vf *vf, bool flr)
 {
        struct i40e_pf *pf = vf->pf;
        struct i40e_hw *hw = &pf->hw;
        u32 reg, reg_idx, bit_idx;
-       bool rsd = false;
-       int i;
-
-       if (test_and_set_bit(__I40E_VF_DISABLE, &pf->state))
-               return;
 
        /* warn the VF */
        clear_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states);
@@ -970,37 +967,22 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr)
        if (i40e_quiesce_vf_pci(vf))
                dev_err(&pf->pdev->dev, "VF %d PCI transactions stuck\n",
                        vf->vf_id);
+}
 
-       /* poll VPGEN_VFRSTAT reg to make sure
-        * that reset is complete
-        */
-       for (i = 0; i < 10; i++) {
-               /* VF reset requires driver to first reset the VF and then
-                * poll the status register to make sure that the reset
-                * completed successfully. Due to internal HW FIFO flushes,
-                * we must wait 10ms before the register will be valid.
-                */
-               usleep_range(10000, 20000);
-               reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id));
-               if (reg & I40E_VPGEN_VFRSTAT_VFRD_MASK) {
-                       rsd = true;
-                       break;
-               }
-       }
-
-       if (flr)
-               usleep_range(10000, 20000);
-
-       if (!rsd)
-               dev_err(&pf->pdev->dev, "VF reset check timeout on VF %d\n",
-                       vf->vf_id);
-
-       /* On initial reset, we won't have any queues */
-       if (vf->lan_vsi_idx == 0)
-               goto complete_reset;
+/**
+ * i40e_cleanup_reset_vf
+ * @vf: pointer to the VF structure
+ *
+ * Cleanup a VF after the hardware reset is finished. Expects the caller to
+ * have verified whether the reset is finished properly, and ensure the
+ * minimum amount of wait time has passed.
+ **/
+static void i40e_cleanup_reset_vf(struct i40e_vf *vf)
+{
+       struct i40e_pf *pf = vf->pf;
+       struct i40e_hw *hw = &pf->hw;
+       u32 reg;
 
-       i40e_vsi_stop_rings(pf->vsi[vf->lan_vsi_idx]);
-complete_reset:
        /* free VF resources to begin resetting the VSI state */
        i40e_free_vf_res(vf);
 
@@ -1035,6 +1017,59 @@ complete_reset:
         * request resources immediately after setting this flag.
         */
        wr32(hw, I40E_VFGEN_RSTAT1(vf->vf_id), I40E_VFR_VFACTIVE);
+}
+
+/**
+ * i40e_reset_vf
+ * @vf: pointer to the VF structure
+ * @flr: VFLR was issued or not
+ *
+ * reset the VF
+ **/
+void i40e_reset_vf(struct i40e_vf *vf, bool flr)
+{
+       struct i40e_pf *pf = vf->pf;
+       struct i40e_hw *hw = &pf->hw;
+       bool rsd = false;
+       u32 reg;
+       int i;
+
+       /* If VFs have been disabled, there is no need to reset */
+       if (test_and_set_bit(__I40E_VF_DISABLE, &pf->state))
+               return;
+
+       i40e_trigger_vf_reset(vf, flr);
+
+       /* poll VPGEN_VFRSTAT reg to make sure
+        * that reset is complete
+        */
+       for (i = 0; i < 10; i++) {
+               /* VF reset requires driver to first reset the VF and then
+                * poll the status register to make sure that the reset
+                * completed successfully. Due to internal HW FIFO flushes,
+                * we must wait 10ms before the register will be valid.
+                */
+               usleep_range(10000, 20000);
+               reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id));
+               if (reg & I40E_VPGEN_VFRSTAT_VFRD_MASK) {
+                       rsd = true;
+                       break;
+               }
+       }
+
+       if (flr)
+               usleep_range(10000, 20000);
+
+       if (!rsd)
+               dev_err(&pf->pdev->dev, "VF reset check timeout on VF %d\n",
+                       vf->vf_id);
+       usleep_range(10000, 20000);
+
+       /* On initial reset, we don't have any queues to disable */
+       if (vf->lan_vsi_idx != 0)
+               i40e_vsi_stop_rings(pf->vsi[vf->lan_vsi_idx]);
+
+       i40e_cleanup_reset_vf(vf);
 
        i40e_flush(hw);
        clear_bit(__I40E_VF_DISABLE, &pf->state);