case XE_GT_SRIOV_STATE_##_X: return #_X
CASE2STR(WIP);
CASE2STR(FLR_WIP);
+ CASE2STR(FLR_PREPARE);
CASE2STR(FLR_SEND_START);
CASE2STR(FLR_WAIT_GUC);
CASE2STR(FLR_GUC_DONE);
* The VF FLR state machine looks like::
*
* (READY,PAUSED,STOPPED)<------------<--------------o
- * | \
- * flr \
- * | \
- * ....V..........................FLR_WIP........... \
- * : \ : \
+ * | | \
+ * flr prepare \
+ * | | \
+ * ....V.............V............FLR_WIP........... \
+ * : | | : \
+ * : | FLR_PREPARE : |
+ * : | / : |
+ * : \ flr : |
+ * : \ / : |
* : \ o----<----busy : |
* : \ / / : |
* : FLR_SEND_START---failed----->-----------o--->(FLR_FAILED)<---o
pf_queue_vf(gt, vfid);
}
-static void pf_enter_vf_flr_wip(struct xe_gt *gt, unsigned int vfid)
+static bool pf_exit_vf_flr_prepare(struct xe_gt *gt, unsigned int vfid)
{
- if (!pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_WIP)) {
- xe_gt_sriov_dbg(gt, "VF%u FLR is already in progress\n", vfid);
- return;
- }
+ if (!pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_PREPARE))
+ return false;
- pf_enter_vf_wip(gt, vfid);
pf_enter_vf_flr_send_start(gt, vfid);
+ return true;
+}
+
+static bool pf_enter_vf_flr_wip(struct xe_gt *gt, unsigned int vfid)
+{
+ if (!pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_WIP))
+ return false;
+
+ pf_enter_vf_wip(gt, vfid);
+ return true;
}
static void pf_exit_vf_flr_wip(struct xe_gt *gt, unsigned int vfid)
{
if (pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_WIP)) {
+ pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_PREPARE);
pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_SEND_FINISH);
pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_RESET_MMIO);
pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_RESET_DATA);
}
/**
- * xe_gt_sriov_pf_control_trigger_flr - Start a VF FLR sequence.
+ * xe_gt_sriov_pf_control_prepare_flr() - Notify PF that VF FLR request was issued.
* @gt: the &xe_gt
* @vfid: the VF identifier
*
+ * This is an optional early notification path used to mark pending FLR before
+ * the GuC notifies the PF with a FLR event.
+ *
* This function is for PF only.
*
* Return: 0 on success or a negative error code on failure.
*/
-int xe_gt_sriov_pf_control_trigger_flr(struct xe_gt *gt, unsigned int vfid)
+int xe_gt_sriov_pf_control_prepare_flr(struct xe_gt *gt, unsigned int vfid)
{
- pf_enter_vf_flr_wip(gt, vfid);
+ if (!pf_enter_vf_flr_wip(gt, vfid))
+ return -EALREADY;
+ pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_PREPARE);
return 0;
}
+static int pf_begin_vf_flr(struct xe_gt *gt, unsigned int vfid)
+{
+ if (pf_enter_vf_flr_wip(gt, vfid)) {
+ pf_enter_vf_flr_send_start(gt, vfid);
+ return 0;
+ }
+
+ if (pf_exit_vf_flr_prepare(gt, vfid))
+ return 0;
+
+ xe_gt_sriov_dbg(gt, "VF%u FLR is already in progress\n", vfid);
+ return -EALREADY;
+}
+
+/**
+ * xe_gt_sriov_pf_control_trigger_flr - Start a VF FLR sequence.
+ * @gt: the &xe_gt
+ * @vfid: the VF identifier
+ *
+ * This function is for PF only.
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int xe_gt_sriov_pf_control_trigger_flr(struct xe_gt *gt, unsigned int vfid)
+{
+ return pf_begin_vf_flr(gt, vfid);
+}
+
/**
* xe_gt_sriov_pf_control_sync_flr() - Synchronize on the VF FLR checkpoint.
* @gt: the &xe_gt
if (needs_dispatch_flr(xe)) {
for_each_gt(gtit, xe, gtid)
- pf_enter_vf_flr_wip(gtit, vfid);
+ pf_begin_vf_flr(gtit, vfid);
} else {
- pf_enter_vf_flr_wip(gt, vfid);
+ pf_begin_vf_flr(gt, vfid);
}
}
*
* @XE_GT_SRIOV_STATE_WIP: indicates that some operations are in progress.
* @XE_GT_SRIOV_STATE_FLR_WIP: indicates that a VF FLR is in progress.
+ * @XE_GT_SRIOV_STATE_FLR_PREPARE: indicates that the PF received early VF FLR prepare notification.
* @XE_GT_SRIOV_STATE_FLR_SEND_START: indicates that the PF wants to send a FLR START command.
* @XE_GT_SRIOV_STATE_FLR_WAIT_GUC: indicates that the PF awaits for a response from the GuC.
* @XE_GT_SRIOV_STATE_FLR_GUC_DONE: indicates that the PF has received a response from the GuC.
XE_GT_SRIOV_STATE_WIP = 1,
XE_GT_SRIOV_STATE_FLR_WIP,
+ XE_GT_SRIOV_STATE_FLR_PREPARE,
XE_GT_SRIOV_STATE_FLR_SEND_START,
XE_GT_SRIOV_STATE_FLR_WAIT_GUC,
XE_GT_SRIOV_STATE_FLR_GUC_DONE,