Skip to content

Commit

Permalink
raw/cnxk_rvu_lf: add self test
Browse files Browse the repository at this point in the history
Added raw device selftest for cnxk_rvu_lf to verify
various PMD APIs.

Signed-off-by: Akhil Goyal <gakhil@marvell.com>
  • Loading branch information
Akhil Goyal authored and jerinjacobk committed Nov 4, 2024
1 parent 79c469d commit aeb8615
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 1 deletion.
22 changes: 22 additions & 0 deletions doc/guides/rawdevs/cnxk_rvu_lf.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,31 @@ and provides an opaque pointer for a response and its length.
PF and VF out-of-tree driver can define its own request and response
based on the message id of the mailbox.

For sample usage of the API, refer ``rvu_lf_rawdev_selftest()``.

Get BAR addresses
-----------------

Out-of-tree drivers can retrieve PCI BAR addresses of the device
using the API function ``rte_pmd_rvu_lf_bar_get()``.
This helps PF/VF drivers 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.
2 changes: 1 addition & 1 deletion drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,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
Expand Down
2 changes: 2 additions & 0 deletions drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_ */
166 changes: 166 additions & 0 deletions drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf_selftest.c
Original file line number Diff line number Diff line change
@@ -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;
}


1 change: 1 addition & 0 deletions drivers/raw/cnxk_rvu_lf/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit aeb8615

Please sign in to comment.