Add support for performing selftest operation.

Signed-off-by: Tomasz Duszynski <tduszyn...@marvell.com>
Signed-off-by: Jakub Palider <jpali...@marvell.com>
---
 drivers/raw/cnxk_bphy/cnxk_bphy_cgx.c      |   2 +
 drivers/raw/cnxk_bphy/cnxk_bphy_cgx.h      |  10 +
 drivers/raw/cnxk_bphy/cnxk_bphy_cgx_test.c | 206 +++++++++++++++++++++
 drivers/raw/cnxk_bphy/meson.build          |   1 +
 4 files changed, 219 insertions(+)
 create mode 100644 drivers/raw/cnxk_bphy/cnxk_bphy_cgx.h
 create mode 100644 drivers/raw/cnxk_bphy/cnxk_bphy_cgx_test.c

diff --git a/drivers/raw/cnxk_bphy/cnxk_bphy_cgx.c 
b/drivers/raw/cnxk_bphy/cnxk_bphy_cgx.c
index a8eafae1b..3da224414 100644
--- a/drivers/raw/cnxk_bphy/cnxk_bphy_cgx.c
+++ b/drivers/raw/cnxk_bphy/cnxk_bphy_cgx.c
@@ -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
diff --git a/drivers/raw/cnxk_bphy/cnxk_bphy_cgx.h 
b/drivers/raw/cnxk_bphy/cnxk_bphy_cgx.h
new file mode 100644
index 000000000..cd14a3850
--- /dev/null
+++ b/drivers/raw/cnxk_bphy/cnxk_bphy_cgx.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell International Ltd.
+ */
+
+#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_ */
diff --git a/drivers/raw/cnxk_bphy/cnxk_bphy_cgx_test.c 
b/drivers/raw/cnxk_bphy/cnxk_bphy_cgx_test.c
new file mode 100644
index 000000000..cb4dd4b22
--- /dev/null
+++ b/drivers/raw/cnxk_bphy/cnxk_bphy_cgx_test.c
@@ -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;
+}
diff --git a/drivers/raw/cnxk_bphy/meson.build 
b/drivers/raw/cnxk_bphy/meson.build
index c47ba2449..2fab7c0ec 100644
--- a/drivers/raw/cnxk_bphy/meson.build
+++ b/drivers/raw/cnxk_bphy/meson.build
@@ -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')
-- 
2.25.1

Reply via email to