raw/cnxk_bphy: support CGX self test

Add support for performing selftest operation.

Signed-off-by: Tomasz Duszynski <tduszynski@marvell.com>
Signed-off-by: Jakub Palider <jpalider@marvell.com>
Reviewed-by: Jerin Jacob <jerinj@marvell.com>
This commit is contained in:
Tomasz Duszynski 2021-06-21 17:04:31 +02:00 committed by Thomas Monjalon
parent ee9978857f
commit 4d2b226726
5 changed files with 237 additions and 1 deletions

View File

@ -38,7 +38,8 @@ To perform data transfer use standard ``rte_rawdev_enqueue_buffers()`` and
responses hence dequeueing is not always necessary.
BPHY CGX/RPM PMD accepts ``struct cnxk_bphy_cgx_msg`` messages which differ by type and payload.
Message types along with description are listed below.
Message types along with description are listed below. As for the usage examples please refer to
``cnxk_bphy_cgx_dev_selftest()``.
Get link information
~~~~~~~~~~~~~~~~~~~~
@ -93,3 +94,19 @@ Message is used to start or stop accepting traffic.
Message must have type set to ``CNXK_BPHY_CGX_MSG_TYPE_START_RXTX`` or
``CNXK_BPHY_CGX_MSG_TYPE_STOP_RXTX``. Former will enable traffic while the latter will
do the opposite.
Self test
---------
On EAL initialization, BPHY CGX/RPM 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 "BPHY_CGX" for
RFOE module,
- x is the device's bus id specified in "bus:device.func" (BDF) format.
Use this identifier for further rawdev function calls.
The driver's selftest rawdev API can be used to verify the BPHY CGX/RPM
functionality.

View File

@ -9,6 +9,7 @@
#include <roc_api.h>
#include "cnxk_bphy_cgx.h"
#include "rte_pmd_bphy.h"
struct cnxk_bphy_cgx_queue {
@ -196,6 +197,7 @@ static const struct rte_rawdev_ops cnxk_bphy_cgx_rawdev_ops = {
.enqueue_bufs = cnxk_bphy_cgx_enqueue_bufs,
.dequeue_bufs = cnxk_bphy_cgx_dequeue_bufs,
.queue_count = cnxk_bphy_cgx_queue_count,
.dev_selftest = cnxk_bphy_cgx_dev_selftest,
};
static void

View File

@ -0,0 +1,10 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(C) 2021 Marvell.
*/
#ifndef _CNXK_BPHY_CGX_H_
#define _CNXK_BPHY_CGX_H_
int cnxk_bphy_cgx_dev_selftest(uint16_t dev_id);
#endif /* _CNXK_BPHY_CGX_H_ */

View File

@ -0,0 +1,206 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(C) 2021 Marvell.
*/
#include <stdint.h>
#include <rte_cycles.h>
#include <rte_log.h>
#include <rte_malloc.h>
#include <rte_rawdev.h>
#include "cnxk_bphy_cgx.h"
#include "rte_pmd_bphy.h"
static int
cnxk_bphy_cgx_enq_msg(uint16_t dev_id, unsigned int queue, void *msg)
{
struct rte_rawdev_buf *bufs[1];
struct rte_rawdev_buf buf;
void *q;
int ret;
q = (void *)(size_t)queue;
buf.buf_addr = msg;
bufs[0] = &buf;
ret = rte_rawdev_enqueue_buffers(dev_id, bufs, 1, q);
if (ret < 0)
return ret;
if (ret != 1)
return -EIO;
return 0;
}
static int
cnxk_bphy_cgx_deq_msg(uint16_t dev_id, unsigned int queue, void **msg)
{
struct rte_rawdev_buf *bufs[1];
struct rte_rawdev_buf buf;
void *q;
int ret;
q = (void *)(size_t)queue;
bufs[0] = &buf;
ret = rte_rawdev_dequeue_buffers(dev_id, bufs, 1, q);
if (ret < 0)
return ret;
if (ret != 1)
return -EIO;
*msg = buf.buf_addr;
return 0;
}
static int
cnxk_bphy_cgx_link_cond(uint16_t dev_id, unsigned int queue, int cond)
{
int tries = 10, ret;
do {
struct cnxk_bphy_cgx_msg_link_info *link_info = NULL;
struct cnxk_bphy_cgx_msg msg;
msg.type = CNXK_BPHY_CGX_MSG_TYPE_GET_LINKINFO;
ret = cnxk_bphy_cgx_enq_msg(dev_id, queue, &msg);
if (ret)
return ret;
ret = cnxk_bphy_cgx_deq_msg(dev_id, queue, (void **)&link_info);
if (ret)
return ret;
if (link_info->link_up == cond) {
rte_free(link_info);
break;
}
rte_free(link_info);
rte_delay_ms(500);
} while (--tries);
if (tries)
return !!cond;
return -ETIMEDOUT;
}
int
cnxk_bphy_cgx_dev_selftest(uint16_t dev_id)
{
unsigned int queues, i;
int ret;
queues = rte_rawdev_queue_count(dev_id);
if (queues == 0)
return -ENODEV;
ret = rte_rawdev_start(dev_id);
if (ret)
return ret;
for (i = 0; i < queues; i++) {
struct cnxk_bphy_cgx_msg_set_link_state link_state;
struct cnxk_bphy_cgx_msg msg;
unsigned int descs;
ret = rte_rawdev_queue_conf_get(dev_id, i, &descs,
sizeof(descs));
if (ret)
break;
if (descs != 1) {
RTE_LOG(ERR, PMD, "Wrong number of descs reported\n");
ret = -ENODEV;
break;
}
RTE_LOG(INFO, PMD, "Testing queue %d\n", i);
/* stop rx/tx */
msg.type = CNXK_BPHY_CGX_MSG_TYPE_STOP_RXTX;
ret = cnxk_bphy_cgx_enq_msg(dev_id, i, &msg);
if (ret) {
RTE_LOG(ERR, PMD, "Failed to stop rx/tx\n");
break;
}
/* start rx/tx */
msg.type = CNXK_BPHY_CGX_MSG_TYPE_START_RXTX;
ret = cnxk_bphy_cgx_enq_msg(dev_id, i, &msg);
if (ret) {
RTE_LOG(ERR, PMD, "Failed to start rx/tx\n");
break;
}
/* set link down */
link_state.state = false;
msg.type = CNXK_BPHY_CGX_MSG_TYPE_SET_LINK_STATE;
msg.data = &link_state;
ret = cnxk_bphy_cgx_enq_msg(dev_id, i, &msg);
if (ret) {
RTE_LOG(ERR, PMD, "Failed to set link down\n");
break;
}
ret = cnxk_bphy_cgx_link_cond(dev_id, i, 0);
if (ret != 0)
RTE_LOG(ERR, PMD,
"Timed out waiting for a link down\n");
/* set link up */
link_state.state = true;
msg.type = CNXK_BPHY_CGX_MSG_TYPE_SET_LINK_STATE;
msg.data = &link_state;
ret = cnxk_bphy_cgx_enq_msg(dev_id, i, &msg);
if (ret) {
RTE_LOG(ERR, PMD, "Failed to set link up\n");
break;
}
ret = cnxk_bphy_cgx_link_cond(dev_id, i, 1);
if (ret != 1)
RTE_LOG(ERR, PMD, "Timed out waiting for a link up\n");
/* enable internal loopback */
msg.type = CNXK_BPHY_CGX_MSG_TYPE_INTLBK_ENABLE;
ret = cnxk_bphy_cgx_enq_msg(dev_id, i, &msg);
if (ret) {
RTE_LOG(ERR, PMD, "Failed to enable internal lbk\n");
break;
}
/* disable internal loopback */
msg.type = CNXK_BPHY_CGX_MSG_TYPE_INTLBK_DISABLE;
ret = cnxk_bphy_cgx_enq_msg(dev_id, i, &msg);
if (ret) {
RTE_LOG(ERR, PMD, "Failed to disable internal lbk\n");
break;
}
/* enable ptp */
msg.type = CNXK_BPHY_CGX_MSG_TYPE_PTP_RX_ENABLE;
ret = cnxk_bphy_cgx_enq_msg(dev_id, i, &msg);
/* ptp not available on RPM */
if (ret < 0 && ret != -ENOTSUP) {
RTE_LOG(ERR, PMD, "Failed to enable ptp\n");
break;
}
ret = 0;
/* disable ptp */
msg.type = CNXK_BPHY_CGX_MSG_TYPE_PTP_RX_DISABLE;
ret = cnxk_bphy_cgx_enq_msg(dev_id, i, &msg);
/* ptp not available on RPM */
if (ret < 0 && ret != -ENOTSUP) {
RTE_LOG(ERR, PMD, "Failed to disable ptp\n");
break;
}
ret = 0;
}
rte_rawdev_stop(dev_id);
return ret;
}

View File

@ -5,5 +5,6 @@
deps += ['bus_pci', 'common_cnxk', 'rawdev']
sources = files(
'cnxk_bphy_cgx.c',
'cnxk_bphy_cgx_test.c',
)
headers = files('rte_pmd_bphy.h')