diff mbox series

[RFC,28/29] net/qdma: add additional debug APIs

Message ID 20220706075219.517046-29-aman.kumar@vvdntech.in (mailing list archive)
State New
Delegated to: Thomas Monjalon
Headers show
Series cover letter for net/qdma PMD | expand

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Aman Kumar July 6, 2022, 7:52 a.m. UTC
this patch implements function to debug and dump
PMD/QDMA specific data.

Signed-off-by: Aman Kumar <aman.kumar@vvdntech.in>
---
 drivers/net/qdma/meson.build   |    1 +
 drivers/net/qdma/qdma_xdebug.c | 1072 ++++++++++++++++++++++++++++++++
 2 files changed, 1073 insertions(+)
 create mode 100644 drivers/net/qdma/qdma_xdebug.c
diff mbox series

Patch

diff --git a/drivers/net/qdma/meson.build b/drivers/net/qdma/meson.build
index 1dc4392666..7ba2c89442 100644
--- a/drivers/net/qdma/meson.build
+++ b/drivers/net/qdma/meson.build
@@ -29,6 +29,7 @@  sources = files(
         'qdma_user.c',
         'qdma_rxtx.c',
         'qdma_vf_ethdev.c',
+        'qdma_xdebug.c',
         'qdma_access/eqdma_soft_access/eqdma_soft_access.c',
         'qdma_access/eqdma_soft_access/eqdma_soft_reg_dump.c',
         'qdma_access/qdma_s80_hard_access/qdma_s80_hard_access.c',
diff --git a/drivers/net/qdma/qdma_xdebug.c b/drivers/net/qdma/qdma_xdebug.c
new file mode 100644
index 0000000000..43f8380465
--- /dev/null
+++ b/drivers/net/qdma/qdma_xdebug.c
@@ -0,0 +1,1072 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017-2022 Xilinx, Inc. All rights reserved.
+ * Copyright(c) 2022 VVDN Technologies Private Limited. All rights reserved.
+ */
+
+#include <stdint.h>
+#include <sys/mman.h>
+#include <sys/fcntl.h>
+#include <rte_memzone.h>
+#include <rte_string_fns.h>
+#include <ethdev_pci.h>
+#include <rte_malloc.h>
+#include <rte_dev.h>
+#include <rte_pci.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_cycles.h>
+#include <unistd.h>
+#include <string.h>
+#include <rte_hexdump.h>
+
+#include "qdma.h"
+#include "rte_pmd_qdma.h"
+#include "qdma_access_common.h"
+#include "qdma_reg_dump.h"
+#include "qdma_mbox_protocol.h"
+#include "qdma_mbox.h"
+
+#define xdebug_info(args...) rte_log(RTE_LOG_INFO, RTE_LOGTYPE_USER1,\
+					## args)
+#define xdebug_error(args...) rte_log(RTE_LOG_ERR, RTE_LOGTYPE_USER1,\
+					## args)
+
+struct xdebug_desc_param {
+	uint16_t queue;
+	int start;
+	int end;
+	enum rte_pmd_qdma_xdebug_desc_type type;
+};
+
+const char *qdma_desc_eng_mode_info[QDMA_DESC_ENG_MODE_MAX] = {
+	"Internal and Bypass mode",
+	"Bypass only mode",
+	"Internal only mode"
+};
+
+static void print_header(const char *str)
+{
+	xdebug_info("\n\n%s\n\n", str);
+}
+
+static int qdma_h2c_struct_dump(uint8_t port_id, uint16_t queue)
+{
+	struct rte_eth_dev *dev;
+	struct qdma_tx_queue *tx_q;
+
+	if (port_id >= rte_eth_dev_count_avail()) {
+		xdebug_error("Wrong port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	dev = &rte_eth_devices[port_id];
+	tx_q = (struct qdma_tx_queue *)dev->data->tx_queues[queue];
+
+	if (queue >= dev->data->nb_tx_queues) {
+		xdebug_info("TX queue_id=%d not configured\n", queue);
+		return -EINVAL;
+	}
+
+	if (tx_q) {
+		print_header("***********TX Queue struct************");
+		xdebug_info("\t\t wb_pidx             :%x\n",
+				tx_q->wb_status->pidx);
+		xdebug_info("\t\t wb_cidx             :%x\n",
+				tx_q->wb_status->cidx);
+		xdebug_info("\t\t h2c_pidx            :%x\n",
+				tx_q->q_pidx_info.pidx);
+		xdebug_info("\t\t tx_fl_tail          :%x\n",
+				tx_q->tx_fl_tail);
+		xdebug_info("\t\t tx_desc_pend        :%x\n",
+				tx_q->tx_desc_pend);
+		xdebug_info("\t\t nb_tx_desc          :%x\n",
+				tx_q->nb_tx_desc);
+		xdebug_info("\t\t st_mode             :%x\n",
+				tx_q->st_mode);
+		xdebug_info("\t\t tx_deferred_start   :%x\n",
+				tx_q->tx_deferred_start);
+		xdebug_info("\t\t en_bypass           :%x\n",
+				tx_q->en_bypass);
+		xdebug_info("\t\t bypass_desc_sz      :%x\n",
+				tx_q->bypass_desc_sz);
+		xdebug_info("\t\t func_id             :%x\n",
+				tx_q->func_id);
+		xdebug_info("\t\t port_id             :%x\n",
+				tx_q->port_id);
+		xdebug_info("\t\t ringszidx           :%x\n",
+				tx_q->ringszidx);
+	}
+
+	return 0;
+}
+
+static int qdma_c2h_struct_dump(uint8_t port_id, uint16_t queue)
+{
+	struct rte_eth_dev *dev;
+	struct qdma_pci_dev *qdma_dev;
+	struct qdma_rx_queue *rx_q;
+	enum qdma_ip_type ip_type;
+
+	if (port_id >= rte_eth_dev_count_avail()) {
+		xdebug_error("Wrong port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	dev = &rte_eth_devices[port_id];
+	qdma_dev = dev->data->dev_private;
+	ip_type = (enum qdma_ip_type)qdma_dev->ip_type;
+	rx_q = (struct qdma_rx_queue *)dev->data->rx_queues[queue];
+
+	if (queue >= dev->data->nb_rx_queues) {
+		xdebug_info("RX queue_id=%d not configured\n", queue);
+		return -EINVAL;
+	}
+
+	if (rx_q) {
+		print_header(" ***********RX Queue struct********** ");
+		xdebug_info("\t\t wb_pidx             :%x\n",
+				rx_q->wb_status->pidx);
+		xdebug_info("\t\t wb_cidx             :%x\n",
+				rx_q->wb_status->cidx);
+		xdebug_info("\t\t rx_tail (ST)        :%x\n",
+				rx_q->rx_tail);
+		xdebug_info("\t\t c2h_pidx            :%x\n",
+				rx_q->q_pidx_info.pidx);
+		xdebug_info("\t\t rx_cmpt_cidx        :%x\n",
+				rx_q->cmpt_cidx_info.wrb_cidx);
+		xdebug_info("\t\t cmpt_desc_len       :%x\n",
+				rx_q->cmpt_desc_len);
+		xdebug_info("\t\t rx_buff_size        :%x\n",
+				rx_q->rx_buff_size);
+		xdebug_info("\t\t nb_rx_desc          :%x\n",
+				rx_q->nb_rx_desc);
+		xdebug_info("\t\t nb_rx_cmpt_desc     :%x\n",
+				rx_q->nb_rx_cmpt_desc);
+		xdebug_info("\t\t ep_addr             :%x\n",
+				rx_q->ep_addr);
+		xdebug_info("\t\t st_mode             :%x\n",
+				rx_q->st_mode);
+		xdebug_info("\t\t rx_deferred_start   :%x\n",
+				rx_q->rx_deferred_start);
+		xdebug_info("\t\t en_prefetch         :%x\n",
+				rx_q->en_prefetch);
+		xdebug_info("\t\t en_bypass           :%x\n",
+				rx_q->en_bypass);
+		xdebug_info("\t\t dump_immediate_data :%x\n",
+				rx_q->dump_immediate_data);
+		xdebug_info("\t\t en_bypass_prefetch  :%x\n",
+				rx_q->en_bypass_prefetch);
+
+		if (!(ip_type == QDMA_VERSAL_HARD_IP))
+			xdebug_info("\t\t dis_overflow_check  :%x\n",
+				rx_q->dis_overflow_check);
+
+		xdebug_info("\t\t bypass_desc_sz      :%x\n",
+				rx_q->bypass_desc_sz);
+		xdebug_info("\t\t ringszidx           :%x\n",
+				rx_q->ringszidx);
+		xdebug_info("\t\t cmpt_ringszidx      :%x\n",
+				rx_q->cmpt_ringszidx);
+		xdebug_info("\t\t buffszidx           :%x\n",
+				rx_q->buffszidx);
+		xdebug_info("\t\t threshidx           :%x\n",
+				rx_q->threshidx);
+		xdebug_info("\t\t timeridx            :%x\n",
+				rx_q->timeridx);
+		xdebug_info("\t\t triggermode         :%x\n",
+				rx_q->triggermode);
+	}
+
+	return 0;
+}
+
+static int qdma_config_read_reg_list(struct rte_eth_dev *dev,
+			uint16_t group_num,
+			uint16_t *num_regs, struct qdma_reg_data *reg_list)
+{
+	struct qdma_pci_dev *qdma_dev = dev->data->dev_private;
+	struct qdma_mbox_msg *m = qdma_mbox_msg_alloc();
+	int rv;
+
+	if (!m)
+		return -ENOMEM;
+
+	qdma_mbox_compose_reg_read(qdma_dev->func_id, group_num, m->raw_data);
+
+	rv = qdma_mbox_msg_send(dev, m, MBOX_OP_RSP_TIMEOUT);
+	if (rv < 0) {
+		if (rv != -ENODEV)
+			xdebug_error("reg read mbox failed with error = %d\n",
+				rv);
+		goto err_out;
+	}
+
+	rv = qdma_mbox_vf_reg_list_get(m->raw_data, num_regs, reg_list);
+	if (rv < 0) {
+		xdebug_error("qdma_mbox_vf_reg_list_get failed with error = %d\n",
+			rv);
+		goto err_out;
+	}
+
+err_out:
+	qdma_mbox_msg_free(m);
+	return rv;
+}
+
+static int qdma_config_reg_dump(uint8_t port_id)
+{
+	struct rte_eth_dev *dev;
+	struct qdma_pci_dev *qdma_dev;
+	enum qdma_ip_type ip_type;
+	char *buf = NULL;
+	int buflen;
+	int ret;
+	struct qdma_reg_data *reg_list;
+	uint16_t num_regs = 0, group_num = 0;
+	int len = 0, rcv_len = 0, reg_len = 0;
+
+	if (port_id >= rte_eth_dev_count_avail()) {
+		xdebug_error("Wrong port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	dev = &rte_eth_devices[port_id];
+	qdma_dev = dev->data->dev_private;
+	ip_type = (enum qdma_ip_type)qdma_dev->ip_type;
+
+	if (qdma_dev->is_vf) {
+		reg_len = (QDMA_MAX_REGISTER_DUMP *
+						sizeof(struct qdma_reg_data));
+		reg_list = (struct qdma_reg_data *)rte_zmalloc("QDMA_DUMP_REG_VF",
+				reg_len, RTE_CACHE_LINE_SIZE);
+		if (!reg_list) {
+			xdebug_error("Unable to allocate memory for VF dump for reglist "
+					"size %d\n", reg_len);
+			return -ENOMEM;
+		}
+
+		ret = qdma_acc_reg_dump_buf_len(dev, ip_type, &buflen);
+		if (ret < 0) {
+			xdebug_error("Failed to get register dump buffer length\n");
+			return ret;
+		}
+		/* allocate memory for register dump */
+		buf = (char *)rte_zmalloc("QDMA_DUMP_BUF_VF", buflen,
+				RTE_CACHE_LINE_SIZE);
+		if (!buf) {
+			xdebug_error("Unable to allocate memory for reg dump "
+					"size %d\n", buflen);
+			rte_free(reg_list);
+			return -ENOMEM;
+		}
+		xdebug_info("FPGA Config Registers for port_id: %d\n--------\n",
+			port_id);
+		xdebug_info(" Offset       Name    "
+				"                                    Value(Hex) Value(Dec)\n");
+
+		for (group_num = 0; group_num < QDMA_REG_READ_GROUP_3;
+				group_num++) {
+			/* Reset the reg_list  with 0's */
+			memset(reg_list, 0, (QDMA_MAX_REGISTER_DUMP *
+					sizeof(struct qdma_reg_data)));
+			ret = qdma_config_read_reg_list(dev,
+						group_num, &num_regs, reg_list);
+			if (ret < 0) {
+				xdebug_error("Failed to read config registers "
+					"size %d, err = %d\n", buflen, ret);
+				rte_free(reg_list);
+				rte_free(buf);
+				return ret;
+			}
+
+			rcv_len = qdma_acc_dump_config_reg_list(dev,
+				ip_type, num_regs,
+				reg_list, buf + len, buflen - len);
+			if (len < 0) {
+				xdebug_error("Failed to dump config regs "
+					"size %d, err = %d\n", buflen, ret);
+				rte_free(reg_list);
+				rte_free(buf);
+				return ret;
+			}
+			len += rcv_len;
+		}
+		if (ret < 0) {
+			xdebug_error("Insufficient space to dump Config Bar register values\n");
+			rte_free(reg_list);
+			rte_free(buf);
+			return qdma_get_error_code(ret);
+		}
+		xdebug_info("%s\n", buf);
+		rte_free(reg_list);
+		rte_free(buf);
+	} else {
+		ret = qdma_acc_reg_dump_buf_len(dev,
+			ip_type, &buflen);
+		if (ret < 0) {
+			xdebug_error("Failed to get register dump buffer length\n");
+			return ret;
+		}
+
+		/* allocate memory for register dump */
+		buf = (char *)rte_zmalloc("QDMA_REG_DUMP", buflen,
+					RTE_CACHE_LINE_SIZE);
+		if (!buf) {
+			xdebug_error("Unable to allocate memory for reg dump "
+					"size %d\n", buflen);
+			return -ENOMEM;
+		}
+		xdebug_info("FPGA Config Registers for port_id: %d\n--------\n",
+			port_id);
+		xdebug_info(" Offset       Name    "
+				"                                    Value(Hex) Value(Dec)\n");
+
+		ret = qdma_acc_dump_config_regs(dev, qdma_dev->is_vf,
+			ip_type, buf, buflen);
+		if (ret < 0) {
+			xdebug_error
+			("Insufficient space to dump Config Bar register values\n");
+			rte_free(buf);
+			return qdma_get_error_code(ret);
+		}
+		xdebug_info("%s\n", buf);
+		rte_free(buf);
+	}
+
+	return 0;
+}
+
+static int qdma_device_dump(uint8_t port_id)
+{
+	struct rte_eth_dev *dev;
+	struct qdma_pci_dev *qdma_dev;
+
+	if (port_id >= rte_eth_dev_count_avail()) {
+		xdebug_error("Wrong port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	dev = &rte_eth_devices[port_id];
+	qdma_dev = dev->data->dev_private;
+
+	xdebug_info("\n*** QDMA Device struct for port_id: %d ***\n\n",
+		port_id);
+
+	xdebug_info("\t\t config BAR index         :%x\n",
+			qdma_dev->config_bar_idx);
+	xdebug_info("\t\t AXI Master Lite BAR index           :%x\n",
+			qdma_dev->user_bar_idx);
+	xdebug_info("\t\t AXI Bridge Master BAR index         :%x\n",
+			qdma_dev->bypass_bar_idx);
+	xdebug_info("\t\t qsets enable             :%x\n",
+			qdma_dev->qsets_en);
+	xdebug_info("\t\t queue base               :%x\n",
+			qdma_dev->queue_base);
+	xdebug_info("\t\t pf                       :%x\n",
+			qdma_dev->func_id);
+	xdebug_info("\t\t cmpt desc length         :%x\n",
+			qdma_dev->cmpt_desc_len);
+	xdebug_info("\t\t c2h bypass mode          :%x\n",
+			qdma_dev->c2h_bypass_mode);
+	xdebug_info("\t\t h2c bypass mode          :%x\n",
+			qdma_dev->h2c_bypass_mode);
+	xdebug_info("\t\t trigger mode             :%x\n",
+			qdma_dev->trigger_mode);
+	xdebug_info("\t\t timer count              :%x\n",
+			qdma_dev->timer_count);
+	xdebug_info("\t\t is vf                    :%x\n",
+			qdma_dev->is_vf);
+	xdebug_info("\t\t is master                :%x\n",
+			qdma_dev->is_master);
+	xdebug_info("\t\t enable desc prefetch     :%x\n",
+			qdma_dev->en_desc_prefetch);
+	xdebug_info("\t\t ip type                  :%x\n",
+			qdma_dev->ip_type);
+	xdebug_info("\t\t vivado release           :%x\n",
+			qdma_dev->vivado_rel);
+	xdebug_info("\t\t rtl version              :%x\n",
+			qdma_dev->rtl_version);
+	xdebug_info("\t\t is queue conigured       :%x\n",
+		qdma_dev->init_q_range);
+
+	xdebug_info("\n\t ***** Device Capabilities *****\n");
+	xdebug_info("\t\t number of PFs            :%x\n",
+			qdma_dev->dev_cap.num_pfs);
+	xdebug_info("\t\t number of Queues         :%x\n",
+			qdma_dev->dev_cap.num_qs);
+	xdebug_info("\t\t FLR present              :%x\n",
+			qdma_dev->dev_cap.flr_present);
+	xdebug_info("\t\t ST mode enable           :%x\n",
+			qdma_dev->dev_cap.st_en);
+	xdebug_info("\t\t MM mode enable           :%x\n",
+			qdma_dev->dev_cap.mm_en);
+	xdebug_info("\t\t MM with compt enable     :%x\n",
+			qdma_dev->dev_cap.mm_cmpt_en);
+	xdebug_info("\t\t Mailbox enable           :%x\n",
+			qdma_dev->dev_cap.mailbox_en);
+	xdebug_info("\t\t Num of MM channels       :%x\n",
+			qdma_dev->dev_cap.mm_channel_max);
+	xdebug_info("\t\t Descriptor engine mode   :%s\n",
+		qdma_desc_eng_mode_info[qdma_dev->dev_cap.desc_eng_mode]);
+	xdebug_info("\t\t Debug mode enable        :%x\n",
+			qdma_dev->dev_cap.debug_mode);
+
+	return 0;
+}
+
+static int qdma_descq_context_read_vf(struct rte_eth_dev *dev,
+	unsigned int qid_hw, bool st_mode,
+	enum qdma_dev_q_type q_type,
+	struct qdma_descq_context *context)
+{
+	struct qdma_pci_dev *qdma_dev = dev->data->dev_private;
+	struct qdma_mbox_msg *m = qdma_mbox_msg_alloc();
+	enum mbox_cmpt_ctxt_type cmpt_ctxt_type = QDMA_MBOX_CMPT_CTXT_NONE;
+	int rv;
+
+	if (!m)
+		return -ENOMEM;
+
+	if (!st_mode) {
+		if (q_type == QDMA_DEV_Q_TYPE_CMPT)
+			cmpt_ctxt_type = QDMA_MBOX_CMPT_CTXT_ONLY;
+		else
+			cmpt_ctxt_type = QDMA_MBOX_CMPT_CTXT_NONE;
+	} else {
+		if (q_type == QDMA_DEV_Q_TYPE_C2H)
+			cmpt_ctxt_type = QDMA_MBOX_CMPT_WITH_ST;
+	}
+
+	qdma_mbox_compose_vf_qctxt_read(qdma_dev->func_id,
+		qid_hw, st_mode, q_type, cmpt_ctxt_type, m->raw_data);
+
+	rv = qdma_mbox_msg_send(dev, m, MBOX_OP_RSP_TIMEOUT);
+	if (rv < 0) {
+		xdebug_error("%x, qid_hw 0x%x, mbox failed for vf q context %d.\n",
+			qdma_dev->func_id, qid_hw, rv);
+		goto free_msg;
+	}
+
+	rv = qdma_mbox_vf_context_get(m->raw_data, context);
+	if (rv < 0) {
+		xdebug_error("%x, failed to get vf queue context info %d.\n",
+				qdma_dev->func_id, rv);
+		goto free_msg;
+	}
+
+free_msg:
+	qdma_mbox_msg_free(m);
+	return rv;
+}
+
+static int qdma_c2h_context_dump(uint8_t port_id, uint16_t queue)
+{
+	struct rte_eth_dev *dev;
+	struct qdma_pci_dev *qdma_dev;
+	struct qdma_descq_context queue_context;
+	enum qdma_dev_q_type q_type;
+	enum qdma_ip_type ip_type;
+	uint16_t qid;
+	uint8_t st_mode;
+	char *buf = NULL;
+	uint32_t buflen = 0;
+	int ret = 0;
+
+	if (port_id >= rte_eth_dev_count_avail()) {
+		xdebug_error("Wrong port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	dev = &rte_eth_devices[port_id];
+	qdma_dev = dev->data->dev_private;
+	qid = qdma_dev->queue_base + queue;
+	ip_type = (enum qdma_ip_type)qdma_dev->ip_type;
+	st_mode = qdma_dev->q_info[qid].queue_mode;
+	q_type = QDMA_DEV_Q_TYPE_C2H;
+
+	if (queue >= dev->data->nb_rx_queues) {
+		xdebug_info("RX queue_id=%d not configured\n", queue);
+		return -EINVAL;
+	}
+
+	xdebug_info("\n ***** C2H Queue Contexts on port_id: %d for q_id: %d *****\n",
+		port_id, qid);
+
+	ret = qdma_acc_context_buf_len(dev, ip_type, st_mode,
+			q_type, &buflen);
+	if (ret < 0) {
+		xdebug_error("Failed to get context buffer length,\n");
+		return ret;
+	}
+
+	/* allocate memory for csr dump */
+	buf = (char *)rte_zmalloc("QDMA_C2H_CONTEXT_DUMP",
+				buflen, RTE_CACHE_LINE_SIZE);
+	if (!buf) {
+		xdebug_error("Unable to allocate memory for c2h context dump "
+				"size %d\n", buflen);
+		return -ENOMEM;
+	}
+
+	if (qdma_dev->is_vf) {
+		ret = qdma_descq_context_read_vf(dev, qid,
+				st_mode, q_type, &queue_context);
+		if (ret < 0) {
+			xdebug_error("Failed to read c2h queue context\n");
+			rte_free(buf);
+			return qdma_get_error_code(ret);
+		}
+
+		ret = qdma_acc_dump_queue_context(dev, ip_type,
+			st_mode, q_type, &queue_context, buf, buflen);
+		if (ret < 0) {
+			xdebug_error("Failed to dump c2h queue context\n");
+			rte_free(buf);
+			return qdma_get_error_code(ret);
+		}
+	} else {
+		ret = qdma_acc_read_dump_queue_context(dev, ip_type,
+			qid, st_mode, q_type, buf, buflen);
+		if (ret < 0) {
+			xdebug_error("Failed to read and dump c2h queue context\n");
+			rte_free(buf);
+			return qdma_get_error_code(ret);
+		}
+	}
+
+	xdebug_info("%s\n", buf);
+	rte_free(buf);
+
+	return 0;
+}
+
+static int qdma_h2c_context_dump(uint8_t port_id, uint16_t queue)
+{
+	struct rte_eth_dev *dev;
+	struct qdma_pci_dev *qdma_dev;
+	struct qdma_descq_context queue_context;
+	enum qdma_dev_q_type q_type;
+	enum qdma_ip_type ip_type;
+	uint32_t buflen = 0;
+	uint16_t qid;
+	uint8_t st_mode;
+	char *buf = NULL;
+	int ret = 0;
+
+	if (port_id >= rte_eth_dev_count_avail()) {
+		xdebug_error("Wrong port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	dev = &rte_eth_devices[port_id];
+	qdma_dev = dev->data->dev_private;
+	qid = qdma_dev->queue_base + queue;
+	ip_type = (enum qdma_ip_type)qdma_dev->ip_type;
+	st_mode = qdma_dev->q_info[qid].queue_mode;
+	q_type = QDMA_DEV_Q_TYPE_H2C;
+
+	if (queue >= dev->data->nb_tx_queues) {
+		xdebug_info("TX queue_id=%d not configured\n", queue);
+		return -EINVAL;
+	}
+
+	xdebug_info("\n ***** H2C Queue Contexts on port_id: %d for q_id: %d *****\n",
+		port_id, qid);
+
+	ret = qdma_acc_context_buf_len(dev, ip_type, st_mode,
+			q_type, &buflen);
+	if (ret < 0) {
+		xdebug_error("Failed to get context buffer length,\n");
+		return ret;
+	}
+
+	/* allocate memory for csr dump */
+	buf = (char *)rte_zmalloc("QDMA_H2C_CONTEXT_DUMP",
+			buflen, RTE_CACHE_LINE_SIZE);
+	if (!buf) {
+		xdebug_error("Unable to allocate memory for h2c context dump "
+				"size %d\n", buflen);
+		return -ENOMEM;
+	}
+
+	if (qdma_dev->is_vf) {
+		ret = qdma_descq_context_read_vf(dev, qid,
+				st_mode, q_type, &queue_context);
+		if (ret < 0) {
+			xdebug_error("Failed to read h2c queue context\n");
+			rte_free(buf);
+			return qdma_get_error_code(ret);
+		}
+
+		ret = qdma_acc_dump_queue_context(dev, ip_type,
+			st_mode, q_type, &queue_context, buf, buflen);
+		if (ret < 0) {
+			xdebug_error("Failed to dump h2c queue context\n");
+			rte_free(buf);
+			return qdma_get_error_code(ret);
+		}
+	} else {
+		ret = qdma_acc_read_dump_queue_context(dev, ip_type,
+				qid, st_mode, q_type, buf, buflen);
+		if (ret < 0) {
+			xdebug_error("Failed to read and dump h2c queue context\n");
+			rte_free(buf);
+			return qdma_get_error_code(ret);
+		}
+	}
+
+	xdebug_info("%s\n", buf);
+	rte_free(buf);
+
+	return 0;
+}
+
+static int qdma_cmpt_context_dump(uint8_t port_id, uint16_t queue)
+{
+	struct rte_eth_dev *dev;
+	struct qdma_pci_dev *qdma_dev;
+	struct qdma_descq_context queue_context;
+	enum qdma_dev_q_type q_type;
+	enum qdma_ip_type ip_type;
+	uint32_t buflen;
+	uint16_t qid;
+	uint8_t st_mode;
+	char *buf = NULL;
+	int ret = 0;
+
+	if (port_id >= rte_eth_dev_count_avail()) {
+		xdebug_error("Wrong port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	dev = &rte_eth_devices[port_id];
+	qdma_dev = dev->data->dev_private;
+	qid = qdma_dev->queue_base + queue;
+	ip_type = (enum qdma_ip_type)qdma_dev->ip_type;
+	st_mode = qdma_dev->q_info[qid].queue_mode;
+	q_type = QDMA_DEV_Q_TYPE_CMPT;
+
+	if (queue >= dev->data->nb_rx_queues) {
+		xdebug_info("RX queue_id=%d not configured\n", queue);
+		return -EINVAL;
+	}
+
+	xdebug_info("\n ***** CMPT Queue Contexts on port_id: %d for q_id: %d *****\n",
+		port_id, qid);
+
+	ret = qdma_acc_context_buf_len(dev, ip_type,
+			st_mode, q_type, &buflen);
+	if (ret < 0) {
+		xdebug_error("Failed to get context buffer length\n");
+		return ret;
+	}
+
+	/* allocate memory for csr dump */
+	buf = (char *)rte_zmalloc("QDMA_CMPT_CONTEXT_DUMP",
+			buflen, RTE_CACHE_LINE_SIZE);
+	if (!buf) {
+		xdebug_error("Unable to allocate memory for cmpt context dump "
+				"size %d\n", buflen);
+		return -ENOMEM;
+	}
+
+	if (qdma_dev->is_vf) {
+		ret = qdma_descq_context_read_vf(dev, qid,
+			st_mode, q_type, &queue_context);
+		if (ret < 0) {
+			xdebug_error("Failed to read cmpt queue context\n");
+			rte_free(buf);
+			return qdma_get_error_code(ret);
+		}
+
+		ret = qdma_acc_dump_queue_context(dev, ip_type,
+			st_mode, q_type,
+			&queue_context, buf, buflen);
+		if (ret < 0) {
+			xdebug_error("Failed to dump cmpt queue context\n");
+			rte_free(buf);
+			return qdma_get_error_code(ret);
+		}
+	} else {
+		ret = qdma_acc_read_dump_queue_context(dev,
+			ip_type, qid, st_mode,
+			q_type, buf, buflen);
+		if (ret < 0) {
+			xdebug_error("Failed to read and dump cmpt queue context\n");
+			rte_free(buf);
+			return qdma_get_error_code(ret);
+		}
+	}
+
+	xdebug_info("%s\n", buf);
+	rte_free(buf);
+
+	return 0;
+}
+
+static int qdma_queue_desc_dump(uint8_t port_id,
+		struct xdebug_desc_param *param)
+{
+	struct rte_eth_dev *dev;
+	struct qdma_rx_queue *rxq;
+	struct qdma_tx_queue *txq;
+	uint8_t *rx_ring_bypass = NULL;
+	uint8_t *tx_ring_bypass = NULL;
+	char str[50];
+	int x;
+
+	if (port_id >= rte_eth_dev_count_avail()) {
+		xdebug_error("Wrong port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	dev = &rte_eth_devices[port_id];
+
+	switch (param->type) {
+	case RTE_PMD_QDMA_XDEBUG_DESC_C2H:
+
+		if (param->queue >= dev->data->nb_rx_queues) {
+			xdebug_info("queue_id=%d not configured",
+					param->queue);
+			return -1;
+		}
+
+		rxq = (struct qdma_rx_queue *)
+			dev->data->rx_queues[param->queue];
+
+		if (rxq == NULL) {
+			xdebug_info("Caught NULL pointer for queue_id: %d\n",
+				param->queue);
+			return -1;
+		}
+
+		if (rxq->status != RTE_ETH_QUEUE_STATE_STARTED) {
+			xdebug_info("Queue_id %d is not yet started\n",
+				param->queue);
+			return -1;
+		}
+
+		if (param->start < 0 || param->start > rxq->nb_rx_desc)
+			param->start = 0;
+		if (param->end <= param->start ||
+				param->end > rxq->nb_rx_desc)
+			param->end = rxq->nb_rx_desc;
+
+		if (rxq->en_bypass && rxq->bypass_desc_sz != 0) {
+			rx_ring_bypass = (uint8_t *)rxq->rx_ring;
+
+			xdebug_info("\n===== C2H bypass descriptors=====\n");
+			for (x = param->start; x < param->end; x++) {
+				uint8_t *rx_bypass =
+						&rx_ring_bypass[x];
+				snprintf(str, sizeof(str),
+						"\nDescriptor ID %d\t", x);
+				rte_hexdump(stdout, str,
+					(const void *)rx_bypass,
+					rxq->bypass_desc_sz);
+			}
+		} else {
+			if (rxq->st_mode) {
+				struct qdma_ul_st_c2h_desc *rx_ring_st =
+				(struct qdma_ul_st_c2h_desc *)rxq->rx_ring;
+
+				xdebug_info("\n===== C2H ring descriptors=====\n");
+				for (x = param->start; x < param->end; x++) {
+					struct qdma_ul_st_c2h_desc *rx_st =
+						&rx_ring_st[x];
+					snprintf(str, sizeof(str),
+						"\nDescriptor ID %d\t", x);
+					rte_hexdump(stdout, str,
+					(const void *)rx_st,
+					sizeof(struct qdma_ul_st_c2h_desc));
+				}
+			} else {
+				struct qdma_ul_mm_desc *rx_ring_mm =
+					(struct qdma_ul_mm_desc *)rxq->rx_ring;
+				xdebug_info("\n====== C2H ring descriptors======\n");
+				for (x = param->start; x < param->end; x++) {
+					snprintf(str, sizeof(str),
+						"\nDescriptor ID %d\t", x);
+					rte_hexdump(stdout, str,
+						(const void *)&rx_ring_mm[x],
+						sizeof(struct qdma_ul_mm_desc));
+				}
+			}
+		}
+		break;
+	case RTE_PMD_QDMA_XDEBUG_DESC_CMPT:
+
+		if (param->queue >= dev->data->nb_rx_queues) {
+			xdebug_info("queue_id=%d not configured",
+					param->queue);
+			return -1;
+		}
+
+		rxq = (struct qdma_rx_queue *)
+			dev->data->rx_queues[param->queue];
+
+		if (rxq) {
+			if (rxq->status != RTE_ETH_QUEUE_STATE_STARTED) {
+				xdebug_info("Queue_id %d is not yet started\n",
+						param->queue);
+				return -1;
+			}
+
+			if (param->start < 0 ||
+					param->start > rxq->nb_rx_cmpt_desc)
+				param->start = 0;
+			if (param->end <= param->start ||
+					param->end > rxq->nb_rx_cmpt_desc)
+				param->end = rxq->nb_rx_cmpt_desc;
+
+			if (!rxq->st_mode) {
+				xdebug_info("Queue_id %d is not initialized "
+					"in Stream mode\n", param->queue);
+				return -1;
+			}
+
+			xdebug_info("\n===== CMPT ring descriptors=====\n");
+			for (x = param->start; x < param->end; x++) {
+				uint32_t *cmpt_ring = (uint32_t *)
+					((uint64_t)(rxq->cmpt_ring) +
+					((uint64_t)x * rxq->cmpt_desc_len));
+				snprintf(str, sizeof(str),
+						"\nDescriptor ID %d\t", x);
+				rte_hexdump(stdout, str,
+						(const void *)cmpt_ring,
+						rxq->cmpt_desc_len);
+			}
+		}
+		break;
+	case RTE_PMD_QDMA_XDEBUG_DESC_H2C:
+
+		if (param->queue >= dev->data->nb_tx_queues) {
+			xdebug_info("queue_id=%d not configured",
+				param->queue);
+			return -1;
+		}
+
+		txq = (struct qdma_tx_queue *)
+			dev->data->tx_queues[param->queue];
+
+		if (txq == NULL) {
+			xdebug_info("Caught NULL pointer for queue_id: %d\n",
+				param->queue);
+			return -1;
+		}
+
+		if (txq->status != RTE_ETH_QUEUE_STATE_STARTED) {
+			xdebug_info("Queue_id %d is not yet started\n",
+				param->queue);
+			return -1;
+		}
+
+		if (param->start < 0 || param->start > txq->nb_tx_desc)
+			param->start = 0;
+		if (param->end <= param->start ||
+				param->end > txq->nb_tx_desc)
+			param->end = txq->nb_tx_desc;
+
+		if (txq->en_bypass && txq->bypass_desc_sz != 0) {
+			tx_ring_bypass = (uint8_t *)txq->tx_ring;
+
+			xdebug_info("\n====== H2C bypass descriptors=====\n");
+			for (x = param->start; x < param->end; x++) {
+				uint8_t *tx_bypass =
+					&tx_ring_bypass[x];
+				snprintf(str, sizeof(str),
+						"\nDescriptor ID %d\t", x);
+				rte_hexdump(stdout, str,
+					(const void *)tx_bypass,
+					txq->bypass_desc_sz);
+			}
+		} else {
+			if (txq->st_mode) {
+				struct qdma_ul_st_h2c_desc *qdma_h2c_ring =
+				(struct qdma_ul_st_h2c_desc *)txq->tx_ring;
+				xdebug_info("\n====== H2C ring descriptors=====\n");
+				for (x = param->start; x < param->end; x++) {
+					snprintf(str, sizeof(str),
+						"\nDescriptor ID %d\t", x);
+					rte_hexdump(stdout, str,
+					(const void *)&qdma_h2c_ring[x],
+					sizeof(struct qdma_ul_st_h2c_desc));
+				}
+			} else {
+				struct qdma_ul_mm_desc *tx_ring_mm =
+					(struct qdma_ul_mm_desc *)txq->tx_ring;
+				xdebug_info("\n===== H2C ring descriptors=====\n");
+				for (x = param->start; x < param->end; x++) {
+					snprintf(str, sizeof(str),
+						"\nDescriptor ID %d\t", x);
+					rte_hexdump(stdout, str,
+						(const void *)&tx_ring_mm[x],
+						sizeof(struct qdma_ul_mm_desc));
+				}
+			}
+		}
+		break;
+	default:
+		xdebug_info("Invalid ring selected\n");
+		break;
+	}
+	return 0;
+}
+
+int rte_pmd_qdma_dbg_regdump(uint8_t port_id)
+{
+	int err;
+
+	if (port_id >= rte_eth_dev_count_avail()) {
+		xdebug_error("Wrong port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	err = qdma_config_reg_dump(port_id);
+	if (err) {
+		xdebug_error("Error dumping Global registers\n");
+		return err;
+	}
+	return 0;
+}
+
+int rte_pmd_qdma_dbg_reg_info_dump(uint8_t port_id,
+	uint32_t num_regs, uint32_t reg_addr)
+{
+	struct rte_eth_dev *dev;
+	struct qdma_pci_dev *qdma_dev;
+	enum qdma_ip_type ip_type;
+	char *buf = NULL;
+	int buflen = QDMA_MAX_BUFLEN;
+	int ret;
+
+	if (port_id >= rte_eth_dev_count_avail()) {
+		xdebug_error("Wrong port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	dev = &rte_eth_devices[port_id];
+	qdma_dev = dev->data->dev_private;
+	ip_type = (enum qdma_ip_type)qdma_dev->ip_type;
+
+	/* allocate memory for register dump */
+	buf = (char *)rte_zmalloc("QDMA_DUMP_BUF_REG_INFO", buflen,
+			RTE_CACHE_LINE_SIZE);
+	if (!buf) {
+		xdebug_error("Unable to allocate memory for reg info dump "
+				"size %d\n", buflen);
+		return -ENOMEM;
+	}
+
+	ret = qdma_acc_dump_reg_info(dev, ip_type,
+		reg_addr, num_regs, buf, buflen);
+	if (ret < 0) {
+		xdebug_error("Failed to dump reg field values\n");
+		rte_free(buf);
+		return qdma_get_error_code(ret);
+	}
+	xdebug_info("%s\n", buf);
+	rte_free(buf);
+
+	return 0;
+}
+
+int rte_pmd_qdma_dbg_qdevice(uint8_t port_id)
+{
+	int err;
+
+	if (port_id >= rte_eth_dev_count_avail()) {
+		xdebug_error("Wrong port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	err = qdma_device_dump(port_id);
+	if (err) {
+		xdebug_error("Error dumping QDMA device\n");
+		return err;
+	}
+	return 0;
+}
+
+int rte_pmd_qdma_dbg_qinfo(uint8_t port_id, uint16_t queue)
+{
+	struct rte_eth_dev *dev;
+	struct qdma_pci_dev *qdma_dev;
+	uint16_t qid;
+	uint8_t st_mode;
+	int err;
+
+	if (port_id >= rte_eth_dev_count_avail()) {
+		xdebug_error("Wrong port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	dev = &rte_eth_devices[port_id];
+	qdma_dev = dev->data->dev_private;
+	qid = qdma_dev->queue_base + queue;
+	st_mode = qdma_dev->q_info[qid].queue_mode;
+
+	err = qdma_h2c_context_dump(port_id, queue);
+	if (err) {
+		xdebug_error("Error dumping %d: %d\n",
+				queue, err);
+		return err;
+	}
+
+	err = qdma_c2h_context_dump(port_id, queue);
+	if (err) {
+		xdebug_error("Error dumping %d: %d\n",
+				queue, err);
+		return err;
+	}
+
+	if (!st_mode && qdma_dev->dev_cap.mm_cmpt_en) {
+		err = qdma_cmpt_context_dump(port_id, queue);
+		if (err) {
+			xdebug_error("Error dumping %d: %d\n",
+					queue, err);
+			return err;
+		}
+	}
+
+	err = qdma_h2c_struct_dump(port_id, queue);
+	if (err) {
+		xdebug_error("Error dumping %d: %d\n",
+				queue, err);
+		return err;
+	}
+
+	err = qdma_c2h_struct_dump(port_id, queue);
+	if (err) {
+		xdebug_error("Error dumping %d: %d\n",
+				queue, err);
+		return err;
+	}
+
+	return 0;
+}
+
+int rte_pmd_qdma_dbg_qdesc(uint8_t port_id, uint16_t queue, int start,
+		int end, enum rte_pmd_qdma_xdebug_desc_type type)
+{
+	struct xdebug_desc_param param;
+	int err;
+
+	if (port_id >= rte_eth_dev_count_avail()) {
+		xdebug_error("Wrong port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	param.queue = queue;
+	param.start = start;
+	param.end = end;
+	param.type = type;
+
+	err = qdma_queue_desc_dump(port_id, &param);
+	if (err) {
+		xdebug_error("Error dumping %d: %d\n",
+			queue, err);
+		return err;
+	}
+	return 0;
+}