[9/9] raw/cnxk_rvu_lf: add selftest

Message ID 20240907193311.1342310-10-gakhil@marvell.com (mailing list archive)
State Changes Requested
Delegated to: Jerin Jacob
Headers
Series drivers/raw: introduce cnxk rvu lf device driver |

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/loongarch-compilation success Compilation OK
ci/loongarch-unit-testing success Unit Testing PASS
ci/Intel-compilation success Compilation OK
ci/intel-Testing success Testing PASS
ci/github-robot: build success github build: passed
ci/intel-Functional success Functional PASS
ci/iol-unit-amd64-testing success Testing PASS
ci/iol-unit-arm64-testing success Testing PASS
ci/iol-compile-amd64-testing success Testing PASS
ci/iol-broadcom-Performance success Performance Testing PASS
ci/iol-broadcom-Functional success Functional Testing PASS
ci/iol-compile-arm64-testing success Testing PASS
ci/iol-sample-apps-testing success Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-marvell-Functional success Functional Testing PASS

Commit Message

Akhil Goyal Sept. 7, 2024, 7:33 p.m. UTC
Added raw device selftest for cnxk_rvu_lf to verify
various PMD APIs.

Signed-off-by: Akhil Goyal <gakhil@marvell.com>
---
 doc/guides/rawdevs/cnxk_rvu_lf.rst    |  18 ++++
 drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.c | 137 +++++++++++++++++++++++++-
 2 files changed, 154 insertions(+), 1 deletion(-)
  

Patch

diff --git a/doc/guides/rawdevs/cnxk_rvu_lf.rst b/doc/guides/rawdevs/cnxk_rvu_lf.rst
index 7b321abd38..59f6506ebb 100644
--- a/doc/guides/rawdevs/cnxk_rvu_lf.rst
+++ b/doc/guides/rawdevs/cnxk_rvu_lf.rst
@@ -80,3 +80,21 @@  and provides an opaque pointer for a response and its length.
 PF and VF application can define its own request and response based on the message id
 of the mailbox.
 For sample usage of the APIs, please refer to ``rvu_lf_rawdev_selftest()``.
+
+Self test
+---------
+
+On EAL initialization RVU_LF devices will be probed and populated into
+the raw devices. The rawdev ID of the device can be obtained using invocation
+of ``rte_rawdev_get_dev_id("NAME:x")`` from the test application, where:
+
+- NAME is the desired subsystem: use "RVU_LF".
+- x is the device's bus id specified in "bus:device.func" (BDF) format. BDF follows convention
+  used by lspci i.e bus, device and func are specified using respectively two, two and one hex
+  digit(s).
+
+Use this identifier for further rawdev function calls.
+
+Selftest rawdev API can be used to verify the mailbox communication between
+PF and VF devices based applications. There can be multiple VFs for a particular PF.
+Each VF can send mailboxes to PF and PF can broadcast message to all VFs.
diff --git a/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.c b/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.c
index 66c8e241db..0c3dbdee9a 100644
--- a/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.c
+++ b/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.c
@@ -10,11 +10,146 @@ 
 #include <rte_pci.h>
 #include <rte_rawdev.h>
 #include <rte_rawdev_pmd.h>
+#include <rte_hexdump.h>
 
 #include <roc_api.h>
 
 #include "rte_pmd_rvu_lf.h"
 
+#define PF		0
+#define VF		0
+#define RSP_LEN		64
+#define REQ_LEN		64
+#define MSG_ID_FROM	0x3000
+#define MSG_ID_TO	0x4000
+
+static int
+msg_process_notify_cb(uint16_t vf, uint16_t msg_id,
+		      void *req, uint16_t req_len, void **rsp, uint16_t *rsp_len)
+{
+	uint8_t *resp;
+	int i;
+
+	printf("\nReceived message(0x%x) from VF0x%x\n", msg_id, vf);
+	rte_hexdump(stdout, "req_data received", req, req_len);
+
+	resp = malloc(RSP_LEN);
+	if (resp == NULL)
+		return -ENOMEM;
+	for (i = 0; i < RSP_LEN; i++)
+		resp[i] = 0xB0;
+	*rsp = resp;
+	*rsp_len = RSP_LEN;
+	rte_hexdump(stdout, "rsp_data_filled", *rsp, RSP_LEN);
+
+	return 0;
+}
+
+static int
+rvu_lf_rawdev_selftest(uint16_t dev_id)
+{
+	char *dev_name = rte_rawdevs[dev_id].name;
+	uint8_t req[REQ_LEN] = {0};
+	uint8_t rsp[RSP_LEN] = {0};
+	unsigned int i, j;
+	uint16_t pf_func;
+	char *token[2];
+	int func, ret;
+
+	token[0] = strtok_r(dev_name, ".", &dev_name);
+	token[1] = strtok_r(dev_name, ".", &dev_name);
+	func = atoi(token[1]);
+
+	ret = rte_rawdev_start(dev_id);
+	if (ret)
+		return ret;
+
+	pf_func = rte_pmd_rvu_lf_npa_pf_func_get();
+	if (pf_func == 0)
+		CNXK_RVU_LF_LOG(WARNING, "NPA pf_func is invalid");
+
+	pf_func = rte_pmd_rvu_lf_sso_pf_func_get();
+	if (pf_func == 0)
+		CNXK_RVU_LF_LOG(WARNING, "SSO pf_func is invalid");
+
+	ret = rte_pmd_rvu_lf_msg_id_range_set(dev_id, MSG_ID_FROM, MSG_ID_TO);
+	if (ret) {
+		CNXK_RVU_LF_LOG(ERR, "RVU message ID range invalid");
+		goto out;
+	}
+
+	ret = rte_pmd_rvu_lf_msg_handler_register(dev_id, msg_process_notify_cb);
+	if (ret) {
+		CNXK_RVU_LF_LOG(ERR, "RVU message handler register failed, ret: %d", ret);
+		goto out;
+	}
+
+	if (func == 0) {
+		j = 50;
+		printf("\n");
+		while (j--) {
+		/* PF will wait for RVU message callbacks to be called */
+			rte_delay_ms(1000);
+			printf("PF waiting for VF messages for %d sec.\r", j);
+		}
+		/* PF will send the messages and receive responses. */
+		for (i = 0; i < REQ_LEN; i++)
+			req[i] = 0xC0;
+		/*
+		 * Range is set as between MSG_ID_FROM and MSG_ID_TO.
+		 * Messages sent with this id will be serviced by VF..
+		 */
+		ret = rte_pmd_rvu_lf_msg_process(dev_id,
+					     VF /* Send to VF0 */,
+					     MSG_ID_FROM + 0x2,
+					     req, REQ_LEN, rsp, RSP_LEN);
+		if (ret) {
+			CNXK_RVU_LF_LOG(ERR, "rvu lf PF->VF message send failed");
+			goto unregister;
+		}
+		CNXK_RVU_LF_LOG(INFO, "RVU PF->VF message processed");
+		rte_hexdump(stdout, "rsp_data received", rsp, RSP_LEN);
+		j = 50;
+		printf("\n");
+		while (j--) {
+			rte_delay_ms(1000);
+			printf("PF waiting for VF to exit for %d sec.\r", j);
+		}
+
+	} else {
+		/* VF will send the messages and receive responses. */
+		for (i = 0; i < REQ_LEN; i++)
+			req[i] = 0xA0;
+		/*
+		 * Range is set as between MSG_ID_FROM and MSG_ID_TO
+		 * Messages sent with this id will be serviced by PF and will
+		 * not be forwarded to AF.
+		 */
+		ret = rte_pmd_rvu_lf_msg_process(dev_id,
+					     PF /* Send to PF */,
+					     MSG_ID_FROM + 0x1,
+					     req, REQ_LEN, rsp, RSP_LEN);
+		if (ret) {
+			CNXK_RVU_LF_LOG(ERR, "rvu lf VF->PF message send failed");
+			goto unregister;
+		}
+		CNXK_RVU_LF_LOG(INFO, "RVU VF->PF message processed");
+		rte_hexdump(stdout, "rsp_data received", rsp, RSP_LEN);
+		j = 50;
+		printf("\n");
+		while (j--) {
+			rte_delay_ms(1000);
+			printf("VF waiting for PF to send msg for %d sec.\r", j);
+		}
+	}
+unregister:
+	rte_pmd_rvu_lf_msg_handler_unregister(dev_id);
+out:
+	rte_rawdev_stop(dev_id);
+
+	return ret;
+}
+
 int
 rte_pmd_rvu_lf_msg_id_range_set(uint8_t dev_id, uint16_t from, uint16_t to)
 {
@@ -138,7 +273,7 @@  rte_pmd_rvu_lf_sso_pf_func_get(void)
 }
 
 static const struct rte_rawdev_ops rvu_lf_rawdev_ops = {
-	.dev_selftest = NULL,
+	.dev_selftest = rvu_lf_rawdev_selftest,
 };
 
 static void