Add rte_pmd_mcdma_qcsr_read() and rte_pmd_mcdma_qcsr_dump() to snapshot and print queue control/status registers together with driver software indices. Document the QCSR helpers in mcdma.rst.
Co-developed-by: Cheryl Bansal <[email protected]> Signed-off-by: Cheryl Bansal <[email protected]> Signed-off-by: Subhransu S. Prusty <[email protected]> --- doc/guides/nics/mcdma.rst | 10 +- drivers/net/altera/mcdma/rte_pmd_mcdma.c | 178 +++++++++++++++++++++++ drivers/net/altera/mcdma/rte_pmd_mcdma.h | 79 ++++++++++ 3 files changed, 265 insertions(+), 2 deletions(-) diff --git a/doc/guides/nics/mcdma.rst b/doc/guides/nics/mcdma.rst index 3bbd345d575c..a41997f1618d 100644 --- a/doc/guides/nics/mcdma.rst +++ b/doc/guides/nics/mcdma.rst @@ -107,8 +107,14 @@ defined by the FPGA application connected to the MCDMA IP. Experimental driver API ----------------------- -The header ``rte_pmd_mcdma.h`` provides experimental helpers to access - the PIO BAR: +The header ``rte_pmd_mcdma.h`` provides experimental helpers to inspect queue +state and access the PIO BAR: + +rte_pmd_mcdma_qcsr_read() + Read QCSR registers and software queue indices for one queue. + +rte_pmd_mcdma_qcsr_dump() + Dump decoded QCSR state to a ``FILE`` stream. rte_pmd_mcdma_pio_read64() / rte_pmd_mcdma_pio_write64() Read or write 64-bit registers in the mapped PIO BAR. ``pio_read64`` returns diff --git a/drivers/net/altera/mcdma/rte_pmd_mcdma.c b/drivers/net/altera/mcdma/rte_pmd_mcdma.c index 49d7d97b90bc..3736c7b45913 100644 --- a/drivers/net/altera/mcdma/rte_pmd_mcdma.c +++ b/drivers/net/altera/mcdma/rte_pmd_mcdma.c @@ -38,6 +38,82 @@ mcdma_pmd_port_get(uint16_t port_id, struct rte_eth_dev **eth_dev) return 0; } +static struct mcdma_queue * +mcdma_pmd_queue_get(struct rte_eth_dev *dev, uint16_t queue_id, + enum rte_pmd_mcdma_queue_dir dir) +{ + if (dir == RTE_PMD_MCDMA_QUEUE_TX) { + if (queue_id >= dev->data->nb_tx_queues) + return NULL; + return dev->data->tx_queues[queue_id]; + } + + if (queue_id >= dev->data->nb_rx_queues) + return NULL; + + return dev->data->rx_queues[queue_id]; +} + +static void +mcdma_qcsr_regs_read(struct mcdma_queue *q, struct rte_pmd_mcdma_qcsr *regs) +{ + regs->q_ctrl = mcdma_qcsr_reg_readl(q->qcsr, MCDMA_QCSR_Q_CTRL); + regs->q_start_addr_l = mcdma_qcsr_reg_readl(q->qcsr, + MCDMA_QCSR_Q_START_ADDR_L); + regs->q_start_addr_h = mcdma_qcsr_reg_readl(q->qcsr, + MCDMA_QCSR_Q_START_ADDR_H); + regs->q_size = mcdma_qcsr_reg_readl(q->qcsr, MCDMA_QCSR_Q_SIZE); + regs->q_tail_pointer = mcdma_qcsr_reg_readl(q->qcsr, + MCDMA_QCSR_Q_TAIL_POINTER); + regs->q_head_pointer = mcdma_qcsr_reg_readl(q->qcsr, + MCDMA_QCSR_Q_HEAD_POINTER); + regs->q_completed_pointer = mcdma_qcsr_reg_readl(q->qcsr, + MCDMA_QCSR_Q_COMPLETED_POINTER); + regs->q_consumed_head_addr_l = mcdma_qcsr_reg_readl(q->qcsr, + MCDMA_QCSR_Q_CONSUMED_HEAD_ADDR_L); + regs->q_consumed_head_addr_h = mcdma_qcsr_reg_readl(q->qcsr, + MCDMA_QCSR_Q_CONSUMED_HEAD_ADDR_H); + regs->q_batch_delay = mcdma_qcsr_reg_readl(q->qcsr, + MCDMA_QCSR_Q_BATCH_DELAY); + regs->q_debug_status_1 = mcdma_qcsr_reg_readl(q->qcsr, + MCDMA_QCSR_Q_DEBUG_STATUS_1); + regs->q_debug_status_2 = mcdma_qcsr_reg_readl(q->qcsr, + MCDMA_QCSR_Q_DEBUG_STATUS_2); + regs->q_data_drp_err_ctr = mcdma_qcsr_reg_readl(q->qcsr, + MCDMA_QCSR_Q_DATA_DRP_ERR_CTR); + regs->q_payload_count = mcdma_qcsr_reg_readl(q->qcsr, + MCDMA_QCSR_Q_PAYLOAD_COUNT); + regs->q_reset = mcdma_qcsr_reg_readl(q->qcsr, MCDMA_QCSR_Q_RESET); + regs->q_cpl_timeout = mcdma_qcsr_reg_readl(q->qcsr, + MCDMA_QCSR_Q_CPL_TIMEOUT); + + rte_rmb(); + regs->prod_didx = q->prod_didx; + regs->cons_didx = q->cons_didx; + regs->freed_cons_didx = q->freed_cons_didx; + regs->submitted_didx = q->submitted_didx; + regs->num_descs = q->num_descs; +} + +static void +mcdma_qcsr_dump_decoded(FILE *f, const struct rte_pmd_mcdma_qcsr *regs) +{ + mcdma_qcsr_q_ctrl_t q_ctrl; + + q_ctrl.val = regs->q_ctrl; + fprintf(f, " Q_CTRL decoded: q_en=%u q_wb_en=%u q_intr_en=%u\n", + q_ctrl.field.q_en, q_ctrl.field.q_wb_en, q_ctrl.field.q_intr_en); + + if (regs->q_head_pointer & MCDMA_QCSR_PTR_ERR_MASK) + fprintf(f, " Q_HEAD_POINTER error bit set\n"); + if (regs->q_completed_pointer & MCDMA_QCSR_PTR_ERR_MASK) + fprintf(f, " Q_COMPLETED_POINTER error bit set\n"); + if (regs->q_data_drp_err_ctr & MCDMA_QCSR_DRP_CTR_VALID) { + fprintf(f, " Q_DATA_DRP_ERR_CTR drop_count=%u\n", + regs->q_data_drp_err_ctr & MCDMA_QCSR_DRP_CTR_CNT_MASK); + } +} + static int mcdma_pio_offset_check(const struct mcdma_pci_device *priv, uint64_t offset) { @@ -104,3 +180,105 @@ rte_pmd_mcdma_pio_write64(uint16_t port_id, uint64_t offset, uint64_t val) mcdma_pio_reg_write64(priv->pio, offset, val); return 0; } + +RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_mcdma_qcsr_read, 26.11) +int +rte_pmd_mcdma_qcsr_read(uint16_t port_id, uint16_t queue_id, + enum rte_pmd_mcdma_queue_dir dir, + struct rte_pmd_mcdma_qcsr *regs) +{ + struct rte_eth_dev *dev; + struct mcdma_queue *q; + int ret; + + if (regs == NULL) + return -EINVAL; + + if (dir != RTE_PMD_MCDMA_QUEUE_RX && dir != RTE_PMD_MCDMA_QUEUE_TX) + return -EINVAL; + + ret = mcdma_pmd_port_get(port_id, &dev); + if (ret != 0) + return ret; + + q = mcdma_pmd_queue_get(dev, queue_id, dir); + if (q == NULL || q->qcsr == NULL) + return -EINVAL; + + memset(regs, 0, sizeof(*regs)); + mcdma_qcsr_regs_read(q, regs); + return 0; +} + +static void +mcdma_qcsr_dump_reg(FILE *f, const char *name, uint32_t offset, uint32_t val) +{ + fprintf(f, " %s @ 0x%03x = 0x%08x (%u)\n", name, offset, val, val); +} + +RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_mcdma_qcsr_dump, 26.11) +int +rte_pmd_mcdma_qcsr_dump(uint16_t port_id, uint16_t queue_id, + enum rte_pmd_mcdma_queue_dir dir, FILE *f) +{ + struct rte_pmd_mcdma_qcsr regs; + uint64_t qbuf_dma; + int ret; + + if (f == NULL) + f = stdout; + + ret = rte_pmd_mcdma_qcsr_read(port_id, queue_id, dir, ®s); + if (ret != 0) + return ret; + + qbuf_dma = ((uint64_t)regs.q_start_addr_h << 32) | regs.q_start_addr_l; + + fprintf(f, "MCDMA QCSR dump port %u queue %u %s\n", + port_id, queue_id, + dir == RTE_PMD_MCDMA_QUEUE_TX ? "TX" : "RX"); + fprintf(f, " ring_dma=0x%016llx ring_size_log2=%u\n", + (unsigned long long)qbuf_dma, regs.q_size); + + mcdma_qcsr_dump_reg(f, "Q_CTRL", MCDMA_QCSR_Q_CTRL, regs.q_ctrl); + mcdma_qcsr_dump_reg(f, "Q_START_ADDR_L", MCDMA_QCSR_Q_START_ADDR_L, + regs.q_start_addr_l); + mcdma_qcsr_dump_reg(f, "Q_START_ADDR_H", MCDMA_QCSR_Q_START_ADDR_H, + regs.q_start_addr_h); + mcdma_qcsr_dump_reg(f, "Q_SIZE", MCDMA_QCSR_Q_SIZE, regs.q_size); + mcdma_qcsr_dump_reg(f, "Q_TAIL_POINTER", MCDMA_QCSR_Q_TAIL_POINTER, + regs.q_tail_pointer); + mcdma_qcsr_dump_reg(f, "Q_HEAD_POINTER", MCDMA_QCSR_Q_HEAD_POINTER, + regs.q_head_pointer); + mcdma_qcsr_dump_reg(f, "Q_COMPLETED_POINTER", + MCDMA_QCSR_Q_COMPLETED_POINTER, + regs.q_completed_pointer); + mcdma_qcsr_dump_reg(f, "Q_CONSUMED_HEAD_ADDR_L", + MCDMA_QCSR_Q_CONSUMED_HEAD_ADDR_L, + regs.q_consumed_head_addr_l); + mcdma_qcsr_dump_reg(f, "Q_CONSUMED_HEAD_ADDR_H", + MCDMA_QCSR_Q_CONSUMED_HEAD_ADDR_H, + regs.q_consumed_head_addr_h); + mcdma_qcsr_dump_reg(f, "Q_BATCH_DELAY", MCDMA_QCSR_Q_BATCH_DELAY, + regs.q_batch_delay); + mcdma_qcsr_dump_reg(f, "Q_DEBUG_STATUS_1", MCDMA_QCSR_Q_DEBUG_STATUS_1, + regs.q_debug_status_1); + mcdma_qcsr_dump_reg(f, "Q_DEBUG_STATUS_2", MCDMA_QCSR_Q_DEBUG_STATUS_2, + regs.q_debug_status_2); + mcdma_qcsr_dump_reg(f, "Q_DATA_DRP_ERR_CTR", + MCDMA_QCSR_Q_DATA_DRP_ERR_CTR, + regs.q_data_drp_err_ctr); + mcdma_qcsr_dump_reg(f, "Q_PAYLOAD_COUNT", MCDMA_QCSR_Q_PAYLOAD_COUNT, + regs.q_payload_count); + mcdma_qcsr_dump_reg(f, "Q_RESET", MCDMA_QCSR_Q_RESET, regs.q_reset); + mcdma_qcsr_dump_reg(f, "Q_CPL_TIMEOUT", MCDMA_QCSR_Q_CPL_TIMEOUT, + regs.q_cpl_timeout); + + fprintf(f, " SW prod_didx=%u cons_didx=%u freed_cons_didx=%u " + "submitted_didx=%u num_descs=%u\n", + regs.prod_didx, regs.cons_didx, regs.freed_cons_didx, + regs.submitted_didx, regs.num_descs); + + mcdma_qcsr_dump_decoded(f, ®s); + return 0; +} diff --git a/drivers/net/altera/mcdma/rte_pmd_mcdma.h b/drivers/net/altera/mcdma/rte_pmd_mcdma.h index d76babbdf7e0..7b4ad83c07a2 100644 --- a/drivers/net/altera/mcdma/rte_pmd_mcdma.h +++ b/drivers/net/altera/mcdma/rte_pmd_mcdma.h @@ -16,6 +16,85 @@ #include <rte_compat.h> +/** MCDMA queue direction for PMD APIs. */ +enum rte_pmd_mcdma_queue_dir { + RTE_PMD_MCDMA_QUEUE_RX = 0, /**< Device-to-host (RX). */ + RTE_PMD_MCDMA_QUEUE_TX = 1, /**< Host-to-device (TX). */ +}; + +/** Snapshot of one queue's QCSR registers and driver state. */ +struct rte_pmd_mcdma_qcsr { + uint32_t q_ctrl; + uint32_t q_start_addr_l; + uint32_t q_start_addr_h; + uint32_t q_size; + uint32_t q_tail_pointer; + uint32_t q_head_pointer; + uint32_t q_completed_pointer; + uint32_t q_consumed_head_addr_l; + uint32_t q_consumed_head_addr_h; + uint32_t q_batch_delay; + uint32_t q_debug_status_1; + uint32_t q_debug_status_2; + uint32_t q_data_drp_err_ctr; + uint32_t q_payload_count; + uint32_t q_reset; + uint32_t q_cpl_timeout; + + uint16_t prod_didx; + uint16_t cons_didx; + uint16_t freed_cons_didx; + uint16_t submitted_didx; + uint32_t num_descs; +}; + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Read QCSR registers and software queue state for one queue. + * + * @param port_id + * Port identifier. + * @param queue_id + * Queue identifier. + * @param dir + * Queue direction (RX or TX). + * @param regs + * Output register snapshot. + * + * @return + * 0 on success, negative errno on failure. + */ +__rte_experimental +int +rte_pmd_mcdma_qcsr_read(uint16_t port_id, uint16_t queue_id, + enum rte_pmd_mcdma_queue_dir dir, + struct rte_pmd_mcdma_qcsr *regs); + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Dump QCSR registers and software queue state to a stream. + * + * @param port_id + * Port identifier. + * @param queue_id + * Queue identifier. + * @param dir + * Queue direction (RX or TX). + * @param f + * Output stream. Uses stdout if NULL. + * + * @return + * 0 on success, negative errno on failure. + */ +__rte_experimental +int +rte_pmd_mcdma_qcsr_dump(uint16_t port_id, uint16_t queue_id, + enum rte_pmd_mcdma_queue_dir dir, FILE *f); + /** * @warning * @b EXPERIMENTAL: this API may change, or be removed, without prior notice -- 2.34.1

