xref: /linux/drivers/gpu/drm/xe/xe_sriov_pf_control.c (revision 53597deca0e38c30e6cd4ba2114fa42d2bcd85bb)
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_prepare_flr() - Notify PF that VF FLR prepare has started.
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_prepare_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_prepare_flr(gt, vfid);
144 		result = result ? -EUCLEAN : err;
145 	}
146 
147 	return result;
148 }
149 
150 /**
151  * xe_sriov_pf_control_wait_flr() - Wait for a VF reset (FLR) to complete.
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_wait_flr(struct xe_device *xe, unsigned int vfid)
160 {
161 	struct xe_gt *gt;
162 	unsigned int id;
163 	int result = 0;
164 	int err;
165 
166 	for_each_gt(gt, xe, id) {
167 		err = xe_gt_sriov_pf_control_wait_flr(gt, vfid);
168 		result = result ? -EUCLEAN : err;
169 	}
170 
171 	return result;
172 }
173 
174 /**
175  * xe_sriov_pf_control_sync_flr() - Synchronize a VF FLR between all GTs.
176  * @xe: the &xe_device
177  * @vfid: the VF identifier
178  *
179  * This function is for PF only.
180  *
181  * Return: 0 on success or a negative error code on failure.
182  */
183 int xe_sriov_pf_control_sync_flr(struct xe_device *xe, unsigned int vfid)
184 {
185 	struct xe_gt *gt;
186 	unsigned int id;
187 	int ret;
188 
189 	for_each_gt(gt, xe, id) {
190 		ret = xe_gt_sriov_pf_control_sync_flr(gt, vfid, false);
191 		if (ret < 0)
192 			return ret;
193 	}
194 	for_each_gt(gt, xe, id) {
195 		ret = xe_gt_sriov_pf_control_sync_flr(gt, vfid, true);
196 		if (ret < 0)
197 			return ret;
198 	}
199 
200 	return 0;
201 }
202 
203 /**
204  * xe_sriov_pf_control_trigger_save_vf() - Start VF migration data SAVE sequence on all GTs.
205  * @xe: the &xe_device
206  * @vfid: the VF identifier
207  *
208  * This function is for PF only.
209  *
210  * Return: 0 on success or a negative error code on failure.
211  */
212 int xe_sriov_pf_control_trigger_save_vf(struct xe_device *xe, unsigned int vfid)
213 {
214 	struct xe_gt *gt;
215 	unsigned int id;
216 	int ret;
217 
218 	ret = xe_sriov_packet_save_init(xe, vfid);
219 	if (ret)
220 		return ret;
221 
222 	for_each_gt(gt, xe, id) {
223 		xe_gt_sriov_pf_migration_save_init(gt, vfid);
224 
225 		ret = xe_gt_sriov_pf_control_trigger_save_vf(gt, vfid);
226 		if (ret)
227 			return ret;
228 	}
229 
230 	return 0;
231 }
232 
233 /**
234  * xe_sriov_pf_control_finish_save_vf() - Complete VF migration data SAVE 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_finish_save_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_finish_save_vf(gt, vfid);
250 		if (ret)
251 			break;
252 	}
253 
254 	return ret;
255 }
256 
257 /**
258  * xe_sriov_pf_control_trigger_restore_vf() - Start 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_trigger_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_trigger_restore_vf(gt, vfid);
274 		if (ret)
275 			return ret;
276 	}
277 
278 	return ret;
279 }
280 
281 /**
282  * xe_sriov_pf_control_finish_restore_vf() - Complete VF migration data RESTORE sequence on all GTs.
283  * @xe: the &xe_device
284  * @vfid: the VF identifier
285  *
286  * This function is for PF only.
287  *
288  * Return: 0 on success or a negative error code on failure.
289  */
290 int xe_sriov_pf_control_finish_restore_vf(struct xe_device *xe, unsigned int vfid)
291 {
292 	struct xe_gt *gt;
293 	unsigned int id;
294 	int ret;
295 
296 	for_each_gt(gt, xe, id) {
297 		ret = xe_gt_sriov_pf_control_finish_restore_vf(gt, vfid);
298 		if (ret)
299 			break;
300 	}
301 
302 	return ret;
303 }
304