1// SPDX-License-Identifier: GPL-2.0 AND MIT
2/*
3 * Copyright © 2023 Intel Corporation
4 */
5
6#include <kunit/static_stub.h>
7#include <kunit/test.h>
8#include <kunit/test-bug.h>
9
10#include "xe_device.h"
11#include "xe_kunit_helpers.h"
12#include "xe_pci_test.h"
13
14#define TEST_RID 1234
15#define TEST_VFID 5
16#define TEST_LEN 6
17#define TEST_ACTION 0xa
18#define TEST_DATA(n) (0xd0 + (n))
19
20static int replacement_relay_get_totalvfs(struct xe_guc_relay *relay)
21{
22 return TEST_VFID;
23}
24
25static int relay_test_init(struct kunit *test)
26{
27 struct xe_pci_fake_data fake = {
28 .sriov_mode = XE_SRIOV_MODE_PF,
29 .platform = XE_TIGERLAKE, /* some random platform */
30 .subplatform = XE_SUBPLATFORM_NONE,
31 };
32 struct xe_guc_relay *relay;
33 struct xe_device *xe;
34
35 test->priv = &fake;
36 xe_kunit_helper_xe_device_test_init(test);
37
38 xe = test->priv;
39 KUNIT_ASSERT_EQ(test, xe_sriov_init(xe), 0);
40
41 relay = &xe_device_get_gt(xe, gt_id: 0)->uc.guc.relay;
42 kunit_activate_static_stub(test, relay_get_totalvfs,
43 replacement_relay_get_totalvfs);
44
45 KUNIT_ASSERT_EQ(test, xe_guc_relay_init(relay), 0);
46 KUNIT_EXPECT_TRUE(test, relay_is_ready(relay));
47 relay->last_rid = TEST_RID - 1;
48
49 test->priv = relay;
50 return 0;
51}
52
53static const u32 TEST_MSG[TEST_LEN] = {
54 FIELD_PREP_CONST(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
55 FIELD_PREP_CONST(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_EVENT) |
56 FIELD_PREP_CONST(GUC_HXG_EVENT_MSG_0_ACTION, TEST_ACTION) |
57 FIELD_PREP_CONST(GUC_HXG_EVENT_MSG_0_DATA0, TEST_DATA(0)),
58 TEST_DATA(1), TEST_DATA(2), TEST_DATA(3), TEST_DATA(4),
59};
60
61static int replacement_xe_guc_ct_send_recv_always_fails(struct xe_guc_ct *ct,
62 const u32 *msg, u32 len,
63 u32 *response_buffer)
64{
65 struct kunit *test = kunit_get_current_test();
66
67 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ct);
68 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, msg);
69 KUNIT_ASSERT_GE(test, len, GUC_HXG_MSG_MIN_LEN);
70
71 return -ECOMM;
72}
73
74static int replacement_xe_guc_ct_send_recv_expects_pf2guc_relay(struct xe_guc_ct *ct,
75 const u32 *msg, u32 len,
76 u32 *response_buffer)
77{
78 struct kunit *test = kunit_get_current_test();
79
80 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ct);
81 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, msg);
82 KUNIT_ASSERT_GE(test, len, PF2GUC_RELAY_TO_VF_REQUEST_MSG_MIN_LEN);
83 KUNIT_ASSERT_EQ(test, len, PF2GUC_RELAY_TO_VF_REQUEST_MSG_MIN_LEN + TEST_LEN);
84 KUNIT_EXPECT_EQ(test, GUC_HXG_ORIGIN_HOST, FIELD_GET(GUC_HXG_MSG_0_ORIGIN, msg[0]));
85 KUNIT_EXPECT_EQ(test, GUC_HXG_TYPE_REQUEST, FIELD_GET(GUC_HXG_MSG_0_TYPE, msg[0]));
86 KUNIT_EXPECT_EQ(test, XE_GUC_ACTION_PF2GUC_RELAY_TO_VF,
87 FIELD_GET(GUC_HXG_REQUEST_MSG_0_ACTION, msg[0]));
88 KUNIT_EXPECT_EQ(test, TEST_VFID,
89 FIELD_GET(PF2GUC_RELAY_TO_VF_REQUEST_MSG_1_VFID, msg[1]));
90 KUNIT_EXPECT_EQ(test, TEST_RID,
91 FIELD_GET(PF2GUC_RELAY_TO_VF_REQUEST_MSG_2_RELAY_ID, msg[2]));
92 KUNIT_EXPECT_MEMEQ(test, TEST_MSG, msg + PF2GUC_RELAY_TO_VF_REQUEST_MSG_MIN_LEN,
93 sizeof(u32) * TEST_LEN);
94 return 0;
95}
96
97static const u32 test_guc2pf[GUC2PF_RELAY_FROM_VF_EVENT_MSG_MAX_LEN] = {
98 /* transport */
99 FIELD_PREP_CONST(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_GUC) |
100 FIELD_PREP_CONST(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_EVENT) |
101 FIELD_PREP_CONST(GUC_HXG_EVENT_MSG_0_ACTION, XE_GUC_ACTION_GUC2PF_RELAY_FROM_VF),
102 FIELD_PREP_CONST(GUC2PF_RELAY_FROM_VF_EVENT_MSG_1_VFID, TEST_VFID),
103 FIELD_PREP_CONST(GUC2PF_RELAY_FROM_VF_EVENT_MSG_2_RELAY_ID, TEST_RID),
104 /* payload */
105 FIELD_PREP_CONST(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
106 FIELD_PREP_CONST(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_RESPONSE_SUCCESS),
107};
108
109static const u32 test_guc2vf[GUC2VF_RELAY_FROM_PF_EVENT_MSG_MAX_LEN] = {
110 /* transport */
111 FIELD_PREP_CONST(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_GUC) |
112 FIELD_PREP_CONST(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_EVENT) |
113 FIELD_PREP_CONST(GUC_HXG_EVENT_MSG_0_ACTION, XE_GUC_ACTION_GUC2VF_RELAY_FROM_PF),
114 FIELD_PREP_CONST(GUC2VF_RELAY_FROM_PF_EVENT_MSG_1_RELAY_ID, TEST_RID),
115 /* payload */
116 FIELD_PREP_CONST(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
117 FIELD_PREP_CONST(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_RESPONSE_SUCCESS),
118};
119
120static void pf_rejects_guc2pf_too_short(struct kunit *test)
121{
122 const u32 len = GUC2PF_RELAY_FROM_VF_EVENT_MSG_MIN_LEN - 1;
123 struct xe_guc_relay *relay = test->priv;
124 const u32 *msg = test_guc2pf;
125
126 KUNIT_ASSERT_EQ(test, -EPROTO, xe_guc_relay_process_guc2pf(relay, msg, len));
127}
128
129static void pf_rejects_guc2pf_too_long(struct kunit *test)
130{
131 const u32 len = GUC2PF_RELAY_FROM_VF_EVENT_MSG_MAX_LEN + 1;
132 struct xe_guc_relay *relay = test->priv;
133 const u32 *msg = test_guc2pf;
134
135 KUNIT_ASSERT_EQ(test, -EMSGSIZE, xe_guc_relay_process_guc2pf(relay, msg, len));
136}
137
138static void pf_rejects_guc2pf_no_payload(struct kunit *test)
139{
140 const u32 len = GUC2PF_RELAY_FROM_VF_EVENT_MSG_MIN_LEN;
141 struct xe_guc_relay *relay = test->priv;
142 const u32 *msg = test_guc2pf;
143
144 KUNIT_ASSERT_EQ(test, -EPROTO, xe_guc_relay_process_guc2pf(relay, msg, len));
145}
146
147static void pf_fails_no_payload(struct kunit *test)
148{
149 struct xe_guc_relay *relay = test->priv;
150 const u32 msg = 0;
151
152 KUNIT_ASSERT_EQ(test, -EPROTO, relay_process_msg(relay, TEST_VFID, TEST_RID, &msg, 0));
153}
154
155static void pf_fails_bad_origin(struct kunit *test)
156{
157 struct xe_guc_relay *relay = test->priv;
158 static const u32 msg[] = {
159 FIELD_PREP_CONST(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_GUC) |
160 FIELD_PREP_CONST(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_RESPONSE_SUCCESS),
161 };
162 u32 len = ARRAY_SIZE(msg);
163
164 KUNIT_ASSERT_EQ(test, -EPROTO, relay_process_msg(relay, TEST_VFID, TEST_RID, msg, len));
165}
166
167static void pf_fails_bad_type(struct kunit *test)
168{
169 struct xe_guc_relay *relay = test->priv;
170 const u32 msg[] = {
171 FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
172 FIELD_PREP(GUC_HXG_MSG_0_TYPE, 4), /* only 4 is undefined */
173 };
174 u32 len = ARRAY_SIZE(msg);
175
176 KUNIT_ASSERT_EQ(test, -EBADRQC, relay_process_msg(relay, TEST_VFID, TEST_RID, msg, len));
177}
178
179static void pf_txn_reports_error(struct kunit *test)
180{
181 struct xe_guc_relay *relay = test->priv;
182 struct relay_transaction *txn;
183
184 txn = __relay_get_transaction(relay, false, TEST_VFID, TEST_RID,
185 TEST_MSG, TEST_LEN, NULL, 0);
186 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, txn);
187
188 kunit_activate_static_stub(test, xe_guc_ct_send_recv,
189 replacement_xe_guc_ct_send_recv_always_fails);
190 KUNIT_EXPECT_EQ(test, -ECOMM, relay_send_transaction(relay, txn));
191
192 relay_release_transaction(relay, txn);
193}
194
195static void pf_txn_sends_pf2guc(struct kunit *test)
196{
197 struct xe_guc_relay *relay = test->priv;
198 struct relay_transaction *txn;
199
200 txn = __relay_get_transaction(relay, false, TEST_VFID, TEST_RID,
201 TEST_MSG, TEST_LEN, NULL, 0);
202 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, txn);
203
204 kunit_activate_static_stub(test, xe_guc_ct_send_recv,
205 replacement_xe_guc_ct_send_recv_expects_pf2guc_relay);
206 KUNIT_ASSERT_EQ(test, 0, relay_send_transaction(relay, txn));
207
208 relay_release_transaction(relay, txn);
209}
210
211static void pf_sends_pf2guc(struct kunit *test)
212{
213 struct xe_guc_relay *relay = test->priv;
214
215 kunit_activate_static_stub(test, xe_guc_ct_send_recv,
216 replacement_xe_guc_ct_send_recv_expects_pf2guc_relay);
217 KUNIT_ASSERT_EQ(test, 0,
218 xe_guc_relay_send_to_vf(relay, TEST_VFID,
219 TEST_MSG, TEST_LEN, NULL, 0));
220}
221
222static int replacement_xe_guc_ct_send_recv_loopback_relay(struct xe_guc_ct *ct,
223 const u32 *msg, u32 len,
224 u32 *response_buffer)
225{
226 struct kunit *test = kunit_get_current_test();
227 struct xe_guc_relay *relay = test->priv;
228 u32 *reply = kunit_kzalloc(test, size: len * sizeof(u32), GFP_KERNEL);
229 int (*guc2relay)(struct xe_guc_relay *, const u32 *, u32);
230 u32 action;
231 int err;
232
233 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ct);
234 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, msg);
235 KUNIT_ASSERT_GE(test, len, GUC_HXG_MSG_MIN_LEN);
236 KUNIT_ASSERT_EQ(test, GUC_HXG_TYPE_REQUEST,
237 FIELD_GET(GUC_HXG_MSG_0_TYPE, msg[0]));
238 KUNIT_ASSERT_GE(test, len, GUC_HXG_REQUEST_MSG_MIN_LEN);
239 KUNIT_ASSERT_NOT_NULL(test, reply);
240
241 switch (FIELD_GET(GUC_HXG_REQUEST_MSG_0_ACTION, msg[0])) {
242 case XE_GUC_ACTION_PF2GUC_RELAY_TO_VF:
243 KUNIT_ASSERT_GE(test, len, PF2GUC_RELAY_TO_VF_REQUEST_MSG_MIN_LEN);
244 action = XE_GUC_ACTION_GUC2PF_RELAY_FROM_VF;
245 guc2relay = xe_guc_relay_process_guc2pf;
246 break;
247 case XE_GUC_ACTION_VF2GUC_RELAY_TO_PF:
248 KUNIT_ASSERT_GE(test, len, VF2GUC_RELAY_TO_PF_REQUEST_MSG_MIN_LEN);
249 action = XE_GUC_ACTION_GUC2VF_RELAY_FROM_PF;
250 guc2relay = xe_guc_relay_process_guc2vf;
251 break;
252 default:
253 KUNIT_FAIL(test, "bad RELAY action %#x", msg[0]);
254 return -EINVAL;
255 }
256
257 reply[0] = FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_GUC) |
258 FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_EVENT) |
259 FIELD_PREP(GUC_HXG_EVENT_MSG_0_ACTION, action);
260 memcpy(reply + 1, msg + 1, sizeof(u32) * (len - 1));
261
262 err = guc2relay(relay, reply, len);
263 KUNIT_EXPECT_EQ(test, err, 0);
264
265 return err;
266}
267
268static void test_requires_relay_testloop(struct kunit *test)
269{
270 /*
271 * The debug relay action GUC_RELAY_ACTION_VFXPF_TESTLOOP is available
272 * only on builds with CONFIG_DRM_XE_DEBUG_SRIOV enabled.
273 * See "kunit.py --kconfig_add" option if it's missing.
274 */
275 if (!IS_ENABLED(CONFIG_DRM_XE_DEBUG_SRIOV))
276 kunit_skip(test, "requires %s\n", __stringify(CONFIG_DRM_XE_DEBUG_SRIOV));
277}
278
279static void pf_loopback_nop(struct kunit *test)
280{
281 struct xe_guc_relay *relay = test->priv;
282 u32 request[] = {
283 FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
284 FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
285 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_RELAY_ACTION_VFXPF_TESTLOOP) |
286 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_DATA0, VFXPF_TESTLOOP_OPCODE_NOP),
287 };
288 u32 response[GUC_HXG_RESPONSE_MSG_MIN_LEN];
289 int ret;
290
291 test_requires_relay_testloop(test);
292
293 kunit_activate_static_stub(test, relay_kick_worker, relay_process_incoming_action);
294 kunit_activate_static_stub(test, xe_guc_ct_send_recv,
295 replacement_xe_guc_ct_send_recv_loopback_relay);
296 ret = xe_guc_relay_send_to_vf(relay, TEST_VFID,
297 request, ARRAY_SIZE(request),
298 response, ARRAY_SIZE(response));
299 KUNIT_ASSERT_EQ(test, ret, GUC_HXG_RESPONSE_MSG_MIN_LEN);
300 KUNIT_EXPECT_EQ(test, FIELD_GET(GUC_HXG_MSG_0_ORIGIN, response[0]),
301 GUC_HXG_ORIGIN_HOST);
302 KUNIT_EXPECT_EQ(test, FIELD_GET(GUC_HXG_MSG_0_TYPE, response[0]),
303 GUC_HXG_TYPE_RESPONSE_SUCCESS);
304 KUNIT_EXPECT_EQ(test, FIELD_GET(GUC_HXG_RESPONSE_MSG_0_DATA0, response[0]), 0);
305}
306
307static void pf_loopback_echo(struct kunit *test)
308{
309 struct xe_guc_relay *relay = test->priv;
310 u32 request[] = {
311 FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
312 FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
313 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_RELAY_ACTION_VFXPF_TESTLOOP) |
314 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_DATA0, VFXPF_TESTLOOP_OPCODE_ECHO),
315 TEST_DATA(1), TEST_DATA(2), TEST_DATA(3), TEST_DATA(4),
316 };
317 u32 response[ARRAY_SIZE(request)];
318 unsigned int n;
319 int ret;
320
321 test_requires_relay_testloop(test);
322
323 kunit_activate_static_stub(test, relay_kick_worker, relay_process_incoming_action);
324 kunit_activate_static_stub(test, xe_guc_ct_send_recv,
325 replacement_xe_guc_ct_send_recv_loopback_relay);
326 ret = xe_guc_relay_send_to_vf(relay, TEST_VFID,
327 request, ARRAY_SIZE(request),
328 response, ARRAY_SIZE(response));
329 KUNIT_ASSERT_EQ(test, ret, ARRAY_SIZE(response));
330 KUNIT_EXPECT_EQ(test, FIELD_GET(GUC_HXG_MSG_0_ORIGIN, response[0]),
331 GUC_HXG_ORIGIN_HOST);
332 KUNIT_EXPECT_EQ(test, FIELD_GET(GUC_HXG_MSG_0_TYPE, response[0]),
333 GUC_HXG_TYPE_RESPONSE_SUCCESS);
334 KUNIT_EXPECT_EQ(test, FIELD_GET(GUC_HXG_RESPONSE_MSG_0_DATA0, response[0]),
335 ARRAY_SIZE(response));
336 for (n = GUC_HXG_RESPONSE_MSG_MIN_LEN; n < ret; n++)
337 KUNIT_EXPECT_EQ(test, request[n], response[n]);
338}
339
340static void pf_loopback_fail(struct kunit *test)
341{
342 struct xe_guc_relay *relay = test->priv;
343 u32 request[] = {
344 FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
345 FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
346 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_RELAY_ACTION_VFXPF_TESTLOOP) |
347 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_DATA0, VFXPF_TESTLOOP_OPCODE_FAIL),
348 };
349 u32 response[GUC_HXG_RESPONSE_MSG_MIN_LEN];
350 int ret;
351
352 test_requires_relay_testloop(test);
353
354 kunit_activate_static_stub(test, relay_kick_worker, relay_process_incoming_action);
355 kunit_activate_static_stub(test, xe_guc_ct_send_recv,
356 replacement_xe_guc_ct_send_recv_loopback_relay);
357 ret = xe_guc_relay_send_to_vf(relay, TEST_VFID,
358 request, ARRAY_SIZE(request),
359 response, ARRAY_SIZE(response));
360 KUNIT_ASSERT_EQ(test, ret, -EREMOTEIO);
361}
362
363static void pf_loopback_busy(struct kunit *test)
364{
365 struct xe_guc_relay *relay = test->priv;
366 u32 request[] = {
367 FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
368 FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
369 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_RELAY_ACTION_VFXPF_TESTLOOP) |
370 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_DATA0, VFXPF_TESTLOOP_OPCODE_BUSY),
371 TEST_DATA(0xb),
372 };
373 u32 response[GUC_HXG_RESPONSE_MSG_MIN_LEN];
374 int ret;
375
376 test_requires_relay_testloop(test);
377
378 kunit_activate_static_stub(test, relay_testonly_nop, relay_process_incoming_action);
379 kunit_activate_static_stub(test, relay_kick_worker, relay_process_incoming_action);
380 kunit_activate_static_stub(test, xe_guc_ct_send_recv,
381 replacement_xe_guc_ct_send_recv_loopback_relay);
382 ret = xe_guc_relay_send_to_vf(relay, TEST_VFID,
383 request, ARRAY_SIZE(request),
384 response, ARRAY_SIZE(response));
385 KUNIT_ASSERT_EQ(test, ret, GUC_HXG_RESPONSE_MSG_MIN_LEN);
386}
387
388static void pf_loopback_retry(struct kunit *test)
389{
390 struct xe_guc_relay *relay = test->priv;
391 u32 request[] = {
392 FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
393 FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
394 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_RELAY_ACTION_VFXPF_TESTLOOP) |
395 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_DATA0, VFXPF_TESTLOOP_OPCODE_RETRY),
396 TEST_DATA(0xd), TEST_DATA(0xd),
397 };
398 u32 response[GUC_HXG_RESPONSE_MSG_MIN_LEN];
399 int ret;
400
401 test_requires_relay_testloop(test);
402
403 kunit_activate_static_stub(test, relay_kick_worker, relay_process_incoming_action);
404 kunit_activate_static_stub(test, xe_guc_ct_send_recv,
405 replacement_xe_guc_ct_send_recv_loopback_relay);
406 ret = xe_guc_relay_send_to_vf(relay, TEST_VFID,
407 request, ARRAY_SIZE(request),
408 response, ARRAY_SIZE(response));
409 KUNIT_ASSERT_EQ(test, ret, GUC_HXG_RESPONSE_MSG_MIN_LEN);
410}
411
412static struct kunit_case pf_relay_test_cases[] = {
413 KUNIT_CASE(pf_rejects_guc2pf_too_short),
414 KUNIT_CASE(pf_rejects_guc2pf_too_long),
415 KUNIT_CASE(pf_rejects_guc2pf_no_payload),
416 KUNIT_CASE(pf_fails_no_payload),
417 KUNIT_CASE(pf_fails_bad_origin),
418 KUNIT_CASE(pf_fails_bad_type),
419 KUNIT_CASE(pf_txn_reports_error),
420 KUNIT_CASE(pf_txn_sends_pf2guc),
421 KUNIT_CASE(pf_sends_pf2guc),
422 KUNIT_CASE(pf_loopback_nop),
423 KUNIT_CASE(pf_loopback_echo),
424 KUNIT_CASE(pf_loopback_fail),
425 KUNIT_CASE_SLOW(pf_loopback_busy),
426 KUNIT_CASE_SLOW(pf_loopback_retry),
427 {}
428};
429
430static struct kunit_suite pf_relay_suite = {
431 .name = "pf_relay",
432 .test_cases = pf_relay_test_cases,
433 .init = relay_test_init,
434};
435
436static void vf_rejects_guc2vf_too_short(struct kunit *test)
437{
438 const u32 len = GUC2VF_RELAY_FROM_PF_EVENT_MSG_MIN_LEN - 1;
439 struct xe_guc_relay *relay = test->priv;
440 const u32 *msg = test_guc2vf;
441
442 KUNIT_ASSERT_EQ(test, -EPROTO, xe_guc_relay_process_guc2vf(relay, msg, len));
443}
444
445static void vf_rejects_guc2vf_too_long(struct kunit *test)
446{
447 const u32 len = GUC2VF_RELAY_FROM_PF_EVENT_MSG_MAX_LEN + 1;
448 struct xe_guc_relay *relay = test->priv;
449 const u32 *msg = test_guc2vf;
450
451 KUNIT_ASSERT_EQ(test, -EMSGSIZE, xe_guc_relay_process_guc2vf(relay, msg, len));
452}
453
454static void vf_rejects_guc2vf_no_payload(struct kunit *test)
455{
456 const u32 len = GUC2VF_RELAY_FROM_PF_EVENT_MSG_MIN_LEN;
457 struct xe_guc_relay *relay = test->priv;
458 const u32 *msg = test_guc2vf;
459
460 KUNIT_ASSERT_EQ(test, -EPROTO, xe_guc_relay_process_guc2vf(relay, msg, len));
461}
462
463static struct kunit_case vf_relay_test_cases[] = {
464 KUNIT_CASE(vf_rejects_guc2vf_too_short),
465 KUNIT_CASE(vf_rejects_guc2vf_too_long),
466 KUNIT_CASE(vf_rejects_guc2vf_no_payload),
467 {}
468};
469
470static struct kunit_suite vf_relay_suite = {
471 .name = "vf_relay",
472 .test_cases = vf_relay_test_cases,
473 .init = relay_test_init,
474};
475
476static void xe_drops_guc2pf_if_not_ready(struct kunit *test)
477{
478 struct xe_device *xe = test->priv;
479 struct xe_guc_relay *relay = &xe_device_get_gt(xe, gt_id: 0)->uc.guc.relay;
480 const u32 *msg = test_guc2pf;
481 u32 len = GUC2PF_RELAY_FROM_VF_EVENT_MSG_MIN_LEN + GUC_RELAY_MSG_MIN_LEN;
482
483 KUNIT_ASSERT_EQ(test, -ENODEV, xe_guc_relay_process_guc2pf(relay, msg, len));
484}
485
486static void xe_drops_guc2vf_if_not_ready(struct kunit *test)
487{
488 struct xe_device *xe = test->priv;
489 struct xe_guc_relay *relay = &xe_device_get_gt(xe, gt_id: 0)->uc.guc.relay;
490 const u32 *msg = test_guc2vf;
491 u32 len = GUC2VF_RELAY_FROM_PF_EVENT_MSG_MIN_LEN + GUC_RELAY_MSG_MIN_LEN;
492
493 KUNIT_ASSERT_EQ(test, -ENODEV, xe_guc_relay_process_guc2vf(relay, msg, len));
494}
495
496static void xe_rejects_send_if_not_ready(struct kunit *test)
497{
498 struct xe_device *xe = test->priv;
499 struct xe_guc_relay *relay = &xe_device_get_gt(xe, gt_id: 0)->uc.guc.relay;
500 u32 msg[GUC_RELAY_MSG_MIN_LEN];
501 u32 len = ARRAY_SIZE(msg);
502
503 KUNIT_ASSERT_EQ(test, -ENODEV, xe_guc_relay_send_to_pf(relay, msg, len, NULL, 0));
504 KUNIT_ASSERT_EQ(test, -ENODEV, relay_send_to(relay, TEST_VFID, msg, len, NULL, 0));
505}
506
507static struct kunit_case no_relay_test_cases[] = {
508 KUNIT_CASE(xe_drops_guc2pf_if_not_ready),
509 KUNIT_CASE(xe_drops_guc2vf_if_not_ready),
510 KUNIT_CASE(xe_rejects_send_if_not_ready),
511 {}
512};
513
514static struct kunit_suite no_relay_suite = {
515 .name = "no_relay",
516 .test_cases = no_relay_test_cases,
517 .init = xe_kunit_helper_xe_device_test_init,
518};
519
520kunit_test_suites(&no_relay_suite,
521 &pf_relay_suite,
522 &vf_relay_suite);
523

source code of linux/drivers/gpu/drm/xe/tests/xe_guc_relay_test.c