// SPDX-License-Identifier: MIT /* * Copyright © 2023-2024 Intel Corporation */ #include "abi/guc_actions_sriov_abi.h" #include "xe_device.h" #include "xe_gt.h" #include "xe_gt_sriov_pf_control.h" #include "xe_gt_sriov_printk.h" #include "xe_guc_ct.h" #include "xe_sriov.h" static const char *control_cmd_to_string(u32 cmd) { … } static int guc_action_vf_control_cmd(struct xe_guc *guc, u32 vfid, u32 cmd) { … } static int pf_send_vf_control_cmd(struct xe_gt *gt, unsigned int vfid, u32 cmd) { … } static int pf_send_vf_pause(struct xe_gt *gt, unsigned int vfid) { … } static int pf_send_vf_resume(struct xe_gt *gt, unsigned int vfid) { … } static int pf_send_vf_stop(struct xe_gt *gt, unsigned int vfid) { … } static int pf_send_vf_flr_start(struct xe_gt *gt, unsigned int vfid) { … } static int pf_send_vf_flr_finish(struct xe_gt *gt, unsigned int vfid) { … } /** * xe_gt_sriov_pf_control_pause_vf - Pause a VF. * @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_pause_vf(struct xe_gt *gt, unsigned int vfid) { … } /** * xe_gt_sriov_pf_control_resume_vf - Resume a VF. * @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_resume_vf(struct xe_gt *gt, unsigned int vfid) { … } /** * xe_gt_sriov_pf_control_stop_vf - Stop a VF. * @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_stop_vf(struct xe_gt *gt, unsigned int vfid) { … } /** * 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) { … } /** * DOC: The VF FLR Flow with GuC * * PF GUC PCI * ======================================================== * | | | * (1) | [ ] <----- FLR --| * | [ ] : * (2) [ ] <-------- NOTIFY FLR --[ ] * [ ] | * (3) [ ] | * [ ] | * [ ]-- START FLR ---------> [ ] * | [ ] * (4) | [ ] * | [ ] * [ ] <--------- FLR DONE -- [ ] * [ ] | * (5) [ ] | * [ ] | * [ ]-- FINISH FLR --------> [ ] * | | * * Step 1: PCI HW generates interrupt to the GuC about VF FLR * Step 2: GuC FW sends G2H notification to the PF about VF FLR * Step 2a: on some platforms G2H is only received from root GuC * Step 3: PF sends H2G request to the GuC to start VF FLR sequence * Step 3a: on some platforms PF must send H2G to all other GuCs * Step 4: GuC FW performs VF FLR cleanups and notifies the PF when done * Step 5: PF performs VF FLR cleanups and notifies the GuC FW when finished */ static bool needs_dispatch_flr(struct xe_device *xe) { … } static void pf_handle_vf_flr(struct xe_gt *gt, u32 vfid) { … } static void pf_handle_vf_flr_done(struct xe_gt *gt, u32 vfid) { … } static int pf_handle_vf_event(struct xe_gt *gt, u32 vfid, u32 eventid) { … } static int pf_handle_pf_event(struct xe_gt *gt, u32 eventid) { … } /** * xe_gt_sriov_pf_control_process_guc2pf - Handle VF state notification from GuC. * @gt: the &xe_gt * @msg: the G2H message * @len: the length of the G2H message * * This function is for PF only. * * Return: 0 on success or a negative error code on failure. */ int xe_gt_sriov_pf_control_process_guc2pf(struct xe_gt *gt, const u32 *msg, u32 len) { … }