Added raw device selftest for cnxk_rvu_lf to verify various PMD APIs. Signed-off-by: Akhil Goyal <gak...@marvell.com> --- doc/guides/rawdevs/cnxk_rvu_lf.rst | 18 ++ drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.c | 4 +- drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.h | 2 + .../raw/cnxk_rvu_lf/cnxk_rvu_lf_selftest.c | 166 ++++++++++++++++++ drivers/raw/cnxk_rvu_lf/meson.build | 1 + 5 files changed, 188 insertions(+), 3 deletions(-) create mode 100644 drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf_selftest.c
diff --git a/doc/guides/rawdevs/cnxk_rvu_lf.rst b/doc/guides/rawdevs/cnxk_rvu_lf.rst index a972654f82..41fd2d1b42 100644 --- a/doc/guides/rawdevs/cnxk_rvu_lf.rst +++ b/doc/guides/rawdevs/cnxk_rvu_lf.rst @@ -80,3 +80,21 @@ Get BAR addresses Application can retrieve PCI BAR addresses of the device using the API ``rte_pmd_rvu_lf_bar_get()``. This helps application to configure the registers of the hardware device. + +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 3a3971ecd3..516fc896b9 100644 --- a/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.c +++ b/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.c @@ -5,8 +5,6 @@ #include <bus_pci_driver.h> #include <rte_common.h> #include <dev_driver.h> -#include <rte_eal.h> -#include <rte_lcore.h> #include <rte_pci.h> #include <rte_rawdev.h> #include <rte_rawdev_pmd.h> @@ -155,7 +153,7 @@ rte_pmd_rvu_lf_pf_func_get(uint8_t dev_id) } static const struct rte_rawdev_ops rvu_lf_rawdev_ops = { - .dev_selftest = NULL, + .dev_selftest = rvu_lf_rawdev_selftest, }; static void diff --git a/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.h b/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.h index 65cc1bb64d..e64643dcee 100644 --- a/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.h +++ b/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.h @@ -21,4 +21,6 @@ extern int cnxk_logtype_rvu_lf; #define CNXK_RVU_LF_LOG(level, ...) \ RTE_LOG_LINE_PREFIX(level, CNXK_RVU_LF, "%s(): ", __func__, __VA_ARGS__) +int rvu_lf_rawdev_selftest(uint16_t dev_id); + #endif /* _CNXK_RVU_LF_H_ */ diff --git a/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf_selftest.c b/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf_selftest.c new file mode 100644 index 0000000000..e33973f24b --- /dev/null +++ b/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf_selftest.c @@ -0,0 +1,166 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2024 Marvell. + */ + +#include <stdlib.h> +#include <inttypes.h> + +#include <rte_common.h> +#include <rte_hexdump.h> +#include <rte_eal.h> +#include <rte_lcore.h> + +#include <rte_rawdev.h> +#include <rte_cycles.h> + +#include "cnxk_rvu_lf.h" +#include "cnxk_rvu_lf_driver.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 +#define MAX_BAR 6 + +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; +} + +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}; + size_t bar_mask = 0; + size_t bar_va = 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"); + + pf_func = rte_pmd_rvu_lf_pf_func_get(dev_id); + if (pf_func == 0) + CNXK_RVU_LF_LOG(WARNING, "RVU-LF pf_func is invalid"); + + for (i = 0; i < MAX_BAR; i++) { + if (!rte_pmd_rvu_lf_bar_get(dev_id, i, &bar_va, &bar_mask)) + printf("\n BAR[%d]: addr: 0x%" PRIx64 ", mask: 0x%" PRIx64 "\n", + i, bar_va, bar_mask); + } + + 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; +} + + diff --git a/drivers/raw/cnxk_rvu_lf/meson.build b/drivers/raw/cnxk_rvu_lf/meson.build index 7ea1c3916c..c960989bb7 100644 --- a/drivers/raw/cnxk_rvu_lf/meson.build +++ b/drivers/raw/cnxk_rvu_lf/meson.build @@ -5,6 +5,7 @@ deps += ['bus_pci', 'common_cnxk', 'rawdev'] sources = files( 'cnxk_rvu_lf.c', + 'cnxk_rvu_lf_selftest.c', ) driver_sdk_headers += files('cnxk_rvu_lf_driver.h') require_iova_in_mbuf = false -- 2.25.1