*/
 static void ice_trigger_vf_reset(struct ice_vf *vf, bool is_vflr, bool is_pfr)
 {
-       struct ice_pf *pf = vf->pf;
-       u32 reg, reg_idx, bit_idx;
-       unsigned int vf_abs_id, i;
-       struct device *dev;
-       struct ice_hw *hw;
-
-       dev = ice_pf_to_dev(pf);
-       hw = &pf->hw;
-       vf_abs_id = vf->vf_id + hw->func_caps.vf_base_id;
-
        /* Inform VF that it is no longer active, as a warning */
        clear_bit(ICE_VF_STATE_ACTIVE, vf->vf_states);
 
         * PFR, it can mess up VF resets because the VF driver may already
         * have started cleanup by the time we get here.
         */
-       if (!is_pfr) {
-               wr32(hw, VF_MBX_ARQLEN(vf->vf_id), 0);
-               wr32(hw, VF_MBX_ATQLEN(vf->vf_id), 0);
-       }
-
-       /* In the case of a VFLR, the HW has already reset the VF and we
-        * just need to clean up, so don't hit the VFRTRIG register.
-        */
-       if (!is_vflr) {
-               /* reset VF using VPGEN_VFRTRIG reg */
-               reg = rd32(hw, VPGEN_VFRTRIG(vf->vf_id));
-               reg |= VPGEN_VFRTRIG_VFSWR_M;
-               wr32(hw, VPGEN_VFRTRIG(vf->vf_id), reg);
-       }
-       /* clear the VFLR bit in GLGEN_VFLRSTAT */
-       reg_idx = (vf_abs_id) / 32;
-       bit_idx = (vf_abs_id) % 32;
-       wr32(hw, GLGEN_VFLRSTAT(reg_idx), BIT(bit_idx));
-       ice_flush(hw);
+       if (!is_pfr)
+               vf->vf_ops->clear_mbx_register(vf);
 
-       wr32(hw, PF_PCI_CIAA,
-            VF_DEVICE_STATUS | (vf_abs_id << PF_PCI_CIAA_VF_NUM_S));
-       for (i = 0; i < ICE_PCI_CIAD_WAIT_COUNT; i++) {
-               reg = rd32(hw, PF_PCI_CIAD);
-               /* no transactions pending so stop polling */
-               if ((reg & VF_TRANS_PENDING_M) == 0)
-                       break;
-
-               dev_err(dev, "VF %u PCI transactions stuck\n", vf->vf_id);
-               udelay(ICE_PCI_CIAD_WAIT_DELAY_US);
-       }
+       vf->vf_ops->trigger_reset_register(vf, is_vflr);
 }
 
 /**
        return 0;
 }
 
-/**
- * ice_clear_vf_reset_trigger - enable VF to access hardware
- * @vf: VF to enabled hardware access for
- */
-static void ice_clear_vf_reset_trigger(struct ice_vf *vf)
-{
-       struct ice_hw *hw = &vf->pf->hw;
-       u32 reg;
-
-       reg = rd32(hw, VPGEN_VFRTRIG(vf->vf_id));
-       reg &= ~VPGEN_VFRTRIG_VFSWR_M;
-       wr32(hw, VPGEN_VFRTRIG(vf->vf_id), reg);
-       ice_flush(hw);
-}
-
 static void ice_vf_clear_counters(struct ice_vf *vf)
 {
        struct ice_vsi *vsi = ice_get_vf_vsi(vf);
 static void ice_vf_pre_vsi_rebuild(struct ice_vf *vf)
 {
        ice_vf_clear_counters(vf);
-       ice_clear_vf_reset_trigger(vf);
+       vf->vf_ops->clear_reset_trigger(vf);
 }
 
 /**
        ice_vf_rebuild_aggregator_node_cfg(vsi);
 }
 
-/**
- * ice_vf_rebuild_vsi_with_release - release and setup the VF's VSI
- * @vf: VF to release and setup the VSI for
- *
- * This is only called when a single VF is being reset (i.e. VFR, VFLR, host VF
- * configuration change, etc.).
- */
-static int ice_vf_rebuild_vsi_with_release(struct ice_vf *vf)
-{
-       ice_vf_vsi_release(vf);
-       if (!ice_vf_vsi_setup(vf))
-               return -ENOMEM;
-
-       return 0;
-}
-
 /**
  * ice_vf_rebuild_vsi - rebuild the VF's VSI
  * @vf: VF to rebuild the VSI for
        return 0;
 }
 
-/**
- * ice_vf_post_vsi_rebuild - tasks to do after the VF's VSI have been rebuilt
- * @vf: VF to perform tasks on
- */
-static void ice_vf_post_vsi_rebuild(struct ice_vf *vf)
-{
-       struct ice_pf *pf = vf->pf;
-       struct ice_hw *hw;
-
-       hw = &pf->hw;
-
-       ice_vf_rebuild_host_cfg(vf);
-
-       ice_vf_set_initialized(vf);
-       ice_ena_vf_mappings(vf);
-       wr32(hw, VFGEN_RSTAT(vf->vf_id), VIRTCHNL_VFR_VFACTIVE);
-}
-
 /**
  * ice_reset_all_vfs - reset all allocated VFs in one go
  * @pf: pointer to the PF structure
                ice_trigger_vf_reset(vf, is_vflr, true);
 
        /* HW requires some time to make sure it can flush the FIFO for a VF
-        * when it resets it. Poll the VPGEN_VFRSTAT register for each VF in
-        * sequence to make sure that it has completed. We'll keep track of
-        * the VFs using a simple iterator that increments once that VF has
-        * finished resetting.
+        * when it resets it. Now that we've triggered all of the VFs, iterate
+        * the table again and wait for each VF to complete.
         */
        ice_for_each_vf(pf, bkt, vf) {
-               bool done = false;
-               unsigned int i;
-               u32 reg;
-
-               for (i = 0; i < 10; i++) {
-                       reg = rd32(&pf->hw, VPGEN_VFRSTAT(vf->vf_id));
-                       if (reg & VPGEN_VFRSTAT_VFRD_M) {
-                               done = true;
-                               break;
-                       }
-
-                       /* only delay if check failed */
-                       usleep_range(10, 20);
-               }
-
-               if (!done) {
+               if (!vf->vf_ops->poll_reset_status(vf)) {
                        /* Display a warning if at least one VF didn't manage
                         * to reset in time, but continue on with the
                         * operation.
 
                ice_vf_pre_vsi_rebuild(vf);
                ice_vf_rebuild_vsi(vf);
-               ice_vf_post_vsi_rebuild(vf);
+               vf->vf_ops->post_vsi_rebuild(vf);
 
                mutex_unlock(&vf->cfg_lock);
        }
        struct ice_vsi *vsi;
        struct device *dev;
        struct ice_hw *hw;
-       bool rsd = false;
        u8 promisc_m;
-       u32 reg;
-       int i;
+       bool rsd;
 
        lockdep_assert_held(&vf->cfg_lock);
 
        dev = ice_pf_to_dev(pf);
+       hw = &pf->hw;
 
        if (test_bit(ICE_VF_RESETS_DISABLED, pf->state)) {
                dev_dbg(dev, "Trying to reset VF %d, but all VF resets are disabled\n",
         * enabled. This is needed for successful completion of VFR.
         */
        ice_dis_vsi_txq(vsi->port_info, vsi->idx, 0, 0, NULL, NULL,
-                       NULL, ICE_VF_RESET, vf->vf_id, NULL);
+                       NULL, vf->vf_ops->reset_type, vf->vf_id, NULL);
 
-       hw = &pf->hw;
        /* 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.
-                */
-               reg = rd32(hw, VPGEN_VFRSTAT(vf->vf_id));
-               if (reg & VPGEN_VFRSTAT_VFRD_M) {
-                       rsd = true;
-                       break;
-               }
-
-               /* only sleep if the reset is not done */
-               usleep_range(10, 20);
-       }
-
-       vf->driver_caps = 0;
-       ice_vc_set_default_allowlist(vf);
+       rsd = vf->vf_ops->poll_reset_status(vf);
 
        /* Display a warning if VF didn't manage to reset in time, but need to
         * continue on with the operation.
        if (!rsd)
                dev_warn(dev, "VF reset check timeout on VF %d\n", vf->vf_id);
 
+       vf->driver_caps = 0;
+       ice_vc_set_default_allowlist(vf);
+
        /* disable promiscuous modes in case they were enabled
         * ignore any error if disabling process failed
         */
 
        ice_vf_pre_vsi_rebuild(vf);
 
-       if (ice_vf_rebuild_vsi_with_release(vf)) {
+       if (vf->vf_ops->vsi_rebuild(vf)) {
                dev_err(dev, "Failed to release and setup the VF%u's VSI\n", vf->vf_id);
                return false;
        }
 
-       ice_vf_post_vsi_rebuild(vf);
+       vf->vf_ops->post_vsi_rebuild(vf);
        vsi = ice_get_vf_vsi(vf);
        ice_eswitch_update_repr(vsi);
        ice_eswitch_replay_vf_mac_rule(vf);
 
        it_cnt = 0;
        ice_for_each_vf(pf, bkt, vf) {
-               ice_clear_vf_reset_trigger(vf);
+               vf->vf_ops->clear_reset_trigger(vf);
 
                retval = ice_init_vf_vsi_res(vf);
                if (retval) {
        return retval;
 }
 
+/**
+ * ice_sriov_free_vf - Free VF memory after all references are dropped
+ * @vf: pointer to VF to free
+ *
+ * Called by ice_put_vf through ice_release_vf once the last reference to a VF
+ * structure has been dropped.
+ */
+static void ice_sriov_free_vf(struct ice_vf *vf)
+{
+       mutex_destroy(&vf->cfg_lock);
+
+       kfree_rcu(vf, rcu);
+}
+
+/**
+ * ice_sriov_clear_mbx_register - clears SRIOV VF's mailbox registers
+ * @vf: the vf to configure
+ */
+static void ice_sriov_clear_mbx_register(struct ice_vf *vf)
+{
+       struct ice_pf *pf = vf->pf;
+
+       wr32(&pf->hw, VF_MBX_ARQLEN(vf->vf_id), 0);
+       wr32(&pf->hw, VF_MBX_ATQLEN(vf->vf_id), 0);
+}
+
+/**
+ * ice_sriov_trigger_reset_register - trigger VF reset for SRIOV VF
+ * @vf: pointer to VF structure
+ * @is_vflr: true if reset occurred due to VFLR
+ *
+ * Trigger and cleanup after a VF reset for a SR-IOV VF.
+ */
+static void ice_sriov_trigger_reset_register(struct ice_vf *vf, bool is_vflr)
+{
+       struct ice_pf *pf = vf->pf;
+       u32 reg, reg_idx, bit_idx;
+       unsigned int vf_abs_id, i;
+       struct device *dev;
+       struct ice_hw *hw;
+
+       dev = ice_pf_to_dev(pf);
+       hw = &pf->hw;
+       vf_abs_id = vf->vf_id + hw->func_caps.vf_base_id;
+
+       /* In the case of a VFLR, HW has already reset the VF and we just need
+        * to clean up. Otherwise we must first trigger the reset using the
+        * VFRTRIG register.
+        */
+       if (!is_vflr) {
+               reg = rd32(hw, VPGEN_VFRTRIG(vf->vf_id));
+               reg |= VPGEN_VFRTRIG_VFSWR_M;
+               wr32(hw, VPGEN_VFRTRIG(vf->vf_id), reg);
+       }
+
+       /* clear the VFLR bit in GLGEN_VFLRSTAT */
+       reg_idx = (vf_abs_id) / 32;
+       bit_idx = (vf_abs_id) % 32;
+       wr32(hw, GLGEN_VFLRSTAT(reg_idx), BIT(bit_idx));
+       ice_flush(hw);
+
+       wr32(hw, PF_PCI_CIAA,
+            VF_DEVICE_STATUS | (vf_abs_id << PF_PCI_CIAA_VF_NUM_S));
+       for (i = 0; i < ICE_PCI_CIAD_WAIT_COUNT; i++) {
+               reg = rd32(hw, PF_PCI_CIAD);
+               /* no transactions pending so stop polling */
+               if ((reg & VF_TRANS_PENDING_M) == 0)
+                       break;
+
+               dev_err(dev, "VF %u PCI transactions stuck\n", vf->vf_id);
+               udelay(ICE_PCI_CIAD_WAIT_DELAY_US);
+       }
+}
+
+/**
+ * ice_sriov_poll_reset_status - poll SRIOV VF reset status
+ * @vf: pointer to VF structure
+ *
+ * Returns true when reset is successful, else returns false
+ */
+static bool ice_sriov_poll_reset_status(struct ice_vf *vf)
+{
+       struct ice_pf *pf = vf->pf;
+       unsigned int i;
+       u32 reg;
+
+       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.
+                */
+               reg = rd32(&pf->hw, VPGEN_VFRSTAT(vf->vf_id));
+               if (reg & VPGEN_VFRSTAT_VFRD_M)
+                       return true;
+
+               /* only sleep if the reset is not done */
+               usleep_range(10, 20);
+       }
+       return false;
+}
+
+/**
+ * ice_sriov_clear_reset_trigger - enable VF to access hardware
+ * @vf: VF to enabled hardware access for
+ */
+static void ice_sriov_clear_reset_trigger(struct ice_vf *vf)
+{
+       struct ice_hw *hw = &vf->pf->hw;
+       u32 reg;
+
+       reg = rd32(hw, VPGEN_VFRTRIG(vf->vf_id));
+       reg &= ~VPGEN_VFRTRIG_VFSWR_M;
+       wr32(hw, VPGEN_VFRTRIG(vf->vf_id), reg);
+       ice_flush(hw);
+}
+
+/**
+ * ice_sriov_vsi_rebuild - release and rebuild VF's VSI
+ * @vf: VF to release and setup the VSI for
+ *
+ * This is only called when a single VF is being reset (i.e. VFR, VFLR, host VF
+ * configuration change, etc.).
+ */
+static int ice_sriov_vsi_rebuild(struct ice_vf *vf)
+{
+       struct ice_pf *pf = vf->pf;
+
+       ice_vf_vsi_release(vf);
+       if (!ice_vf_vsi_setup(vf)) {
+               dev_err(ice_pf_to_dev(pf),
+                       "Failed to release and setup the VF%u's VSI\n",
+                       vf->vf_id);
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+/**
+ * ice_sriov_post_vsi_rebuild - tasks to do after the VF's VSI have been rebuilt
+ * @vf: VF to perform tasks on
+ */
+static void ice_sriov_post_vsi_rebuild(struct ice_vf *vf)
+{
+       ice_vf_rebuild_host_cfg(vf);
+       ice_vf_set_initialized(vf);
+       ice_ena_vf_mappings(vf);
+       wr32(&vf->pf->hw, VFGEN_RSTAT(vf->vf_id), VIRTCHNL_VFR_VFACTIVE);
+}
+
+static const struct ice_vf_ops ice_sriov_vf_ops = {
+       .reset_type = ICE_VF_RESET,
+       .free = ice_sriov_free_vf,
+       .clear_mbx_register = ice_sriov_clear_mbx_register,
+       .trigger_reset_register = ice_sriov_trigger_reset_register,
+       .poll_reset_status = ice_sriov_poll_reset_status,
+       .clear_reset_trigger = ice_sriov_clear_reset_trigger,
+       .vsi_rebuild = ice_sriov_vsi_rebuild,
+       .post_vsi_rebuild = ice_sriov_post_vsi_rebuild,
+};
+
 /**
  * ice_create_vf_entries - Allocate and insert VF entries
  * @pf: pointer to the PF structure
                vf->pf = pf;
                vf->vf_id = vf_id;
 
+               /* set sriov vf ops for VFs created during SRIOV flow */
+               vf->vf_ops = &ice_sriov_vf_ops;
+
                vf->vf_sw_id = pf->first_sw;
                /* assign default capabilities */
                vf->spoofchk = true;