File Index
Files and directories
Sign in
FILE

xe_guc_relay_test.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/xe/tests/xe_guc_relay_test.c C
  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, 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, 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, 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, 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, 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);
~/ Read-only file preview.