xref: /linux/drivers/gpu/drm/xe/xe_sriov_pf_control.c (revision d30c1683aaecb93d2ab95685dc4300a33d3cea7a)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2025 Intel Corporation
4  */
5 
6 #include "xe_device.h"
7 #include "xe_gt_sriov_pf_control.h"
8 #include "xe_gt_sriov_pf_migration.h"
9 #include "xe_sriov_packet.h"
10 #include "xe_sriov_pf_control.h"
11 #include "xe_sriov_printk.h"
12 
13 /**
14  * xe_sriov_pf_control_pause_vf() - Pause a VF on all GTs.
15  * @xe: the &xe_device
16  * @vfid: the VF identifier (can't be 0 == PFID)
17  *
18  * This function is for PF only.
19  *
20  * Return: 0 on success or a negative error code on failure.
21  */
22 int xe_sriov_pf_control_pause_vf(struct xe_device *xe, unsigned int vfid)
23 {
24 	struct xe_gt *gt;
25 	unsigned int id;
26 	int result = 0;
27 	int err;
28 
29 	for_each_gt(gt, xe, id) {
30 		err = xe_gt_sriov_pf_control_pause_vf(gt, vfid);
31 		result = result ? -EUCLEAN : err;
32 	}
33 
34 	if (result)
35 		return result;
36 
37 	xe_sriov_info(xe, "VF%u paused!\n", vfid);
38 	return 0;
39 }
40 
41 /**
42  * xe_sriov_pf_control_resume_vf() - Resume a VF on all GTs.
43  * @xe: the &xe_device
44  * @vfid: the VF identifier
45  *
46  * This function is for PF only.
47  *
48  * Return: 0 on success or a negative error code on failure.
49  */
50 int xe_sriov_pf_control_resume_vf(struct xe_device *xe, unsigned int vfid)
51 {
52 	struct xe_gt *gt;
53 	unsigned int id;
54 	int result = 0;
55 	int err;
56 
57 	for_each_gt(gt, xe, id) {
58 		err = xe_gt_sriov_pf_control_resume_vf(gt, vfid);
59 		result = result ? -EUCLEAN : err;
60 	}
61 
62 	if (result)
63 		return result;
64 
65 	xe_sriov_info(xe, "VF%u resumed!\n", vfid);
66 	return 0;
67 }
68 
69 /**
70  * xe_sriov_pf_control_stop_vf - Stop a VF on all GTs.
71  * @xe: the &xe_device
72  * @vfid: the VF identifier
73  *
74  * This function is for PF only.
75  *
76  * Return: 0 on success or a negative error code on failure.
77  */
78 int xe_sriov_pf_control_stop_vf(struct xe_device *xe, unsigned int vfid)
79 {
80 	struct xe_gt *gt;
81 	unsigned int id;
82 	int result = 0;
83 	int err;
84 
85 	for_each_gt(gt, xe, id) {
86 		err = xe_gt_sriov_pf_control_stop_vf(gt, vfid);
87 		result = result ? -EUCLEAN : err;
88 	}
89 
90 	if (result)
91 		return result;
92 
93 	xe_sriov_info(xe, "VF%u stopped!\n", vfid);
94 	return 0;
95 }
96 
97 /**
98  * xe_sriov_pf_control_reset_vf() - Perform a VF reset (FLR).
99  * @xe: the &xe_device
100  * @vfid: the VF identifier
101  *
102  * This function is for PF only.
103  *
104  * Return: 0 on success or a negative error code on failure.
105  */
106 int xe_sriov_pf_control_reset_vf(struct xe_device *xe, unsigned int vfid)
107 {
108 	struct xe_gt *gt;
109 	unsigned int id;
110 	int result = 0;
111 	int err;
112 
113 	for_each_gt(gt, xe, id) {
114 		err = xe_gt_sriov_pf_control_trigger_flr(gt, vfid);
115 		result = result ? -EUCLEAN : err;
116 	}
117 
118 	for_each_gt(gt, xe, id) {
119 		err = xe_gt_sriov_pf_control_wait_flr(gt, vfid);
120 		result = result ? -EUCLEAN : err;
121 	}
122 
123 	return result;
124 }
125 
126 /**
127  * xe_sriov_pf_control_wait_flr() - Wait for a VF reset (FLR) to complete.
128  * @xe: the &xe_device
129  * @vfid: the VF identifier
130  *
131  * This function is for PF only.
132  *
133  * Return: 0 on success or a negative error code on failure.
134  */
135 int xe_sriov_pf_control_wait_flr(struct xe_device *xe, unsigned int vfid)
136 {
137 	struct xe_gt *gt;
138 	unsigned int id;
139 	int result = 0;
140 	int err;
141 
142 	for_each_gt(gt, xe, id) {
143 		err = xe_gt_sriov_pf_control_wait_flr(gt, vfid);
144 		result = result ? -EUCLEAN : err;
145 	}
146 
147 	return result;
148 }
149 
150 /**
151  * xe_sriov_pf_control_sync_flr() - Synchronize a VF FLR between all GTs.
152  * @xe: the &xe_device
153  * @vfid: the VF identifier
154  *
155  * This function is for PF only.
156  *
157  * Return: 0 on success or a negative error code on failure.
158  */
159 int xe_sriov_pf_control_sync_flr(struct xe_device *xe, unsigned int vfid)
160 {
161 	struct xe_gt *gt;
162 	unsigned int id;
163 	int ret;
164 
165 	for_each_gt(gt, xe, id) {
166 		ret = xe_gt_sriov_pf_control_sync_flr(gt, vfid, false);
167 		if (ret < 0)
168 			return ret;
169 	}
170 	for_each_gt(gt, xe, id) {
171 		ret = xe_gt_sriov_pf_control_sync_flr(gt, vfid, true);
172 		if (ret < 0)
173 			return ret;
174 	}
175 
176 	return 0;
177 }
178 
179 /**
180  * xe_sriov_pf_control_trigger_save_vf() - Start VF migration data SAVE sequence on all GTs.
181  * @xe: the &xe_device
182  * @vfid: the VF identifier
183  *
184  * This function is for PF only.
185  *
186  * Return: 0 on success or a negative error code on failure.
187  */
188 int xe_sriov_pf_control_trigger_save_vf(struct xe_device *xe, unsigned int vfid)
189 {
190 	struct xe_gt *gt;
191 	unsigned int id;
192 	int ret;
193 
194 	ret = xe_sriov_packet_save_init(xe, vfid);
195 	if (ret)
196 		return ret;
197 
198 	for_each_gt(gt, xe, id) {
199 		xe_gt_sriov_pf_migration_save_init(gt, vfid);
200 
201 		ret = xe_gt_sriov_pf_control_trigger_save_vf(gt, vfid);
202 		if (ret)
203 			return ret;
204 	}
205 
206 	return 0;
207 }
208 
209 /**
210  * xe_sriov_pf_control_finish_save_vf() - Complete VF migration data SAVE sequence on all GTs.
211  * @xe: the &xe_device
212  * @vfid: the VF identifier
213  *
214  * This function is for PF only.
215  *
216  * Return: 0 on success or a negative error code on failure.
217  */
218 int xe_sriov_pf_control_finish_save_vf(struct xe_device *xe, unsigned int vfid)
219 {
220 	struct xe_gt *gt;
221 	unsigned int id;
222 	int ret;
223 
224 	for_each_gt(gt, xe, id) {
225 		ret = xe_gt_sriov_pf_control_finish_save_vf(gt, vfid);
226 		if (ret)
227 			break;
228 	}
229 
230 	return ret;
231 }
232 
233 /**
234  * xe_sriov_pf_control_trigger_restore_vf() - Start VF migration data RESTORE sequence on all GTs.
235  * @xe: the &xe_device
236  * @vfid: the VF identifier
237  *
238  * This function is for PF only.
239  *
240  * Return: 0 on success or a negative error code on failure.
241  */
242 int xe_sriov_pf_control_trigger_restore_vf(struct xe_device *xe, unsigned int vfid)
243 {
244 	struct xe_gt *gt;
245 	unsigned int id;
246 	int ret;
247 
248 	for_each_gt(gt, xe, id) {
249 		ret = xe_gt_sriov_pf_control_trigger_restore_vf(gt, vfid);
250 		if (ret)
251 			return ret;
252 	}
253 
254 	return ret;
255 }
256 
257 /**
258  * xe_sriov_pf_control_finish_restore_vf() - Complete VF migration data RESTORE sequence on all GTs.
259  * @xe: the &xe_device
260  * @vfid: the VF identifier
261  *
262  * This function is for PF only.
263  *
264  * Return: 0 on success or a negative error code on failure.
265  */
266 int xe_sriov_pf_control_finish_restore_vf(struct xe_device *xe, unsigned int vfid)
267 {
268 	struct xe_gt *gt;
269 	unsigned int id;
270 	int ret;
271 
272 	for_each_gt(gt, xe, id) {
273 		ret = xe_gt_sriov_pf_control_finish_restore_vf(gt, vfid);
274 		if (ret)
275 			break;
276 	}
277 
278 	return ret;
279 }
280