From 77393f561030c86c2b80dbe720aa81a981900aa9 Mon Sep 17 00:00:00 2001 From: Sachin Saxena Date: Thu, 24 Sep 2020 09:32:07 +0530 Subject: [PATCH] bus/dpaa: enable Rx/Tx error queues Enables a debugging queue to fetch error (Rx/Tx) packets to user space. Earlier all packets with L3/L4 checksum errors were getting dropped by the hardware. Setting CONFIG_RTE_LIBRTE_DPAA_DEBUG_DRIVER=y is required which enables following enhancements. 1) Enable TX/RX error queues to check the errors packet. 2) Display error frame information(payload, status, paresr result). 3) Send error packets to application Signed-off-by: Jun Yang Signed-off-by: Rohit Raj Signed-off-by: Nipun Gupta Signed-off-by: Sachin Saxena --- drivers/bus/dpaa/base/fman/fman_hw.c | 19 ++++ drivers/bus/dpaa/include/fman.h | 2 + drivers/bus/dpaa/include/fsl_fman.h | 5 + drivers/bus/dpaa/rte_bus_dpaa_version.map | 2 + drivers/net/dpaa/dpaa_ethdev.c | 22 ++++- drivers/net/dpaa/dpaa_rxtx.c | 109 ++++++++++++++++++---- 6 files changed, 139 insertions(+), 20 deletions(-) diff --git a/drivers/bus/dpaa/base/fman/fman_hw.c b/drivers/bus/dpaa/base/fman/fman_hw.c index 9ab8e835dc..4ab49f7853 100644 --- a/drivers/bus/dpaa/base/fman/fman_hw.c +++ b/drivers/bus/dpaa/base/fman/fman_hw.c @@ -609,3 +609,22 @@ fman_if_discard_rx_errors(struct fman_if *fm_if) fmbm_rfsdm = &((struct rx_bmi_regs *)__if->bmi_map)->fmbm_rfsdm; out_be32(fmbm_rfsdm, 0x010EE3F0); } + +void +fman_if_receive_rx_errors(struct fman_if *fm_if, + unsigned int err_eq) +{ + struct __fman_if *__if = container_of(fm_if, struct __fman_if, __if); + unsigned int *fmbm_rcfg, *fmbm_rfsdm, *fmbm_rfsem; + unsigned int val; + + fmbm_rcfg = &((struct rx_bmi_regs *)__if->bmi_map)->fmbm_rcfg; + fmbm_rfsdm = &((struct rx_bmi_regs *)__if->bmi_map)->fmbm_rfsdm; + fmbm_rfsem = &((struct rx_bmi_regs *)__if->bmi_map)->fmbm_rfsem; + + val = in_be32(fmbm_rcfg); + out_be32(fmbm_rcfg, val | BMI_PORT_CFG_FDOVR); + + out_be32(fmbm_rfsdm, 0); + out_be32(fmbm_rfsem, err_eq); +} diff --git a/drivers/bus/dpaa/include/fman.h b/drivers/bus/dpaa/include/fman.h index dcf408372a..f2b0bf91e7 100644 --- a/drivers/bus/dpaa/include/fman.h +++ b/drivers/bus/dpaa/include/fman.h @@ -226,6 +226,8 @@ struct memac_regs { uint32_t thm; /**< 0x37C tx messages counter */ }; +#define BMI_PORT_CFG_FDOVR 0x02000000 + struct rx_bmi_regs { uint32_t fmbm_rcfg; /**< Rx Configuration */ uint32_t fmbm_rst; /**< Rx Status */ diff --git a/drivers/bus/dpaa/include/fsl_fman.h b/drivers/bus/dpaa/include/fsl_fman.h index 6c87c8db0d..a3cf77f0e3 100644 --- a/drivers/bus/dpaa/include/fsl_fman.h +++ b/drivers/bus/dpaa/include/fsl_fman.h @@ -111,6 +111,7 @@ __rte_internal int fman_if_set_fc_quanta(struct fman_if *fm_if, u16 pause_quanta); /* Set default error fqid on specific interface */ +__rte_internal void fman_if_set_err_fqid(struct fman_if *fm_if, uint32_t err_fqid); /* Get IC transfer params */ @@ -151,6 +152,10 @@ void fman_if_set_dnia(struct fman_if *fm_if, uint32_t nia); __rte_internal void fman_if_discard_rx_errors(struct fman_if *fm_if); +__rte_internal +void fman_if_receive_rx_errors(struct fman_if *fm_if, + unsigned int err_eq); + __rte_internal void fman_if_set_mcast_filter_table(struct fman_if *p); diff --git a/drivers/bus/dpaa/rte_bus_dpaa_version.map b/drivers/bus/dpaa/rte_bus_dpaa_version.map index f47922c6a0..f6028b82de 100644 --- a/drivers/bus/dpaa/rte_bus_dpaa_version.map +++ b/drivers/bus/dpaa/rte_bus_dpaa_version.map @@ -33,6 +33,7 @@ INTERNAL { fman_if_promiscuous_enable; fman_if_reset_mcast_filter_table; fman_if_set_bp; + fman_if_set_err_fqid; fman_if_set_fc_quanta; fman_if_set_fc_threshold; fman_if_set_fdoff; @@ -44,6 +45,7 @@ INTERNAL { fman_if_stats_get_all; fman_if_stats_reset; fman_ip_rev; + fman_if_receive_rx_errors; fsl_qman_fq_portal_create; netcfg_acquire; netcfg_release; diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c index a01c8f3fc6..cc20f28c89 100644 --- a/drivers/net/dpaa/dpaa_ethdev.c +++ b/drivers/net/dpaa/dpaa_ethdev.c @@ -47,6 +47,7 @@ #include #include #include +#include /* Supported Rx offloads */ static uint64_t dev_rx_offloads_sup = @@ -1949,11 +1950,19 @@ dpaa_dev_init(struct rte_eth_dev *eth_dev) dpaa_intf->nb_tx_queues = MAX_DPAA_CORES; #ifdef RTE_LIBRTE_DPAA_DEBUG_DRIVER - dpaa_debug_queue_init(&dpaa_intf->debug_queues[ - DPAA_DEBUG_FQ_RX_ERROR], fman_intf->fqid_rx_err); + ret = dpaa_debug_queue_init(&dpaa_intf->debug_queues + [DPAA_DEBUG_FQ_RX_ERROR], fman_intf->fqid_rx_err); + if (ret) { + DPAA_PMD_ERR("DPAA RX ERROR queue init failed!"); + goto free_tx; + } dpaa_intf->debug_queues[DPAA_DEBUG_FQ_RX_ERROR].dpaa_intf = dpaa_intf; - dpaa_debug_queue_init(&dpaa_intf->debug_queues[ - DPAA_DEBUG_FQ_TX_ERROR], fman_intf->fqid_tx_err); + ret = dpaa_debug_queue_init(&dpaa_intf->debug_queues + [DPAA_DEBUG_FQ_TX_ERROR], fman_intf->fqid_tx_err); + if (ret) { + DPAA_PMD_ERR("DPAA TX ERROR queue init failed!"); + goto free_tx; + } dpaa_intf->debug_queues[DPAA_DEBUG_FQ_TX_ERROR].dpaa_intf = dpaa_intf; #endif @@ -1999,7 +2008,12 @@ dpaa_dev_init(struct rte_eth_dev *eth_dev) if (!fman_intf->is_shared_mac) { /* Disable RX mode */ +#ifdef RTE_LIBRTE_DPAA_DEBUG_DRIVER + fman_if_receive_rx_errors(fman_intf, + FM_FD_RX_STATUS_ERR_MASK); +#else fman_if_discard_rx_errors(fman_intf); +#endif fman_if_disable_rx(fman_intf); /* Disable promiscuous mode */ fman_if_promiscuous_disable(fman_intf); diff --git a/drivers/net/dpaa/dpaa_rxtx.c b/drivers/net/dpaa/dpaa_rxtx.c index 5303c9b769..6eadbfa143 100644 --- a/drivers/net/dpaa/dpaa_rxtx.c +++ b/drivers/net/dpaa/dpaa_rxtx.c @@ -58,29 +58,57 @@ (_fd)->bpid = _bpid; \ } while (0) -#if (defined RTE_LIBRTE_DPAA_DEBUG_DRIVER) -static void dpaa_display_frame(const struct qm_fd *fd) +#ifdef RTE_LIBRTE_DPAA_DEBUG_DRIVER +#define DISPLAY_PRINT printf +static void dpaa_display_frame_info(const struct qm_fd *fd, + uint32_t fqid, bool rx) { int ii; char *ptr; + struct annotations_t *annot = rte_dpaa_mem_ptov(fd->addr); + uint8_t format; + + if (!fd->status) { + /* Do not display correct packets.*/ + return; + } + + format = (fd->opaque & DPAA_FD_FORMAT_MASK) >> + DPAA_FD_FORMAT_SHIFT; + + DISPLAY_PRINT("fqid %d bpid %d addr 0x%lx, format %d\r\n", + fqid, fd->bpid, (unsigned long)fd->addr, fd->format); + DISPLAY_PRINT("off %d, len %d stat 0x%x\r\n", + fd->offset, fd->length20, fd->status); + if (rx) { + ptr = (char *)&annot->parse; + DISPLAY_PRINT("RX parser result:\r\n"); + for (ii = 0; ii < (int)sizeof(struct dpaa_eth_parse_results_t); + ii++) { + DISPLAY_PRINT("%02x ", ptr[ii]); + if (((ii + 1) % 16) == 0) + DISPLAY_PRINT("\n"); + } + DISPLAY_PRINT("\n"); + } - printf("%s::bpid %x addr %08x%08x, format %d off %d, len %d stat %x\n", - __func__, fd->bpid, fd->addr_hi, fd->addr_lo, fd->format, - fd->offset, fd->length20, fd->status); + if (unlikely(format == qm_fd_sg)) { + /*TBD:S/G display: to be implemented*/ + return; + } - ptr = (char *)rte_dpaa_mem_ptov(fd->addr); + DISPLAY_PRINT("Frame payload:\r\n"); + ptr = (char *)annot; ptr += fd->offset; - printf("%02x ", *ptr); - for (ii = 1; ii < fd->length20; ii++) { - printf("%02x ", *ptr); - if ((ii % 16) == 0) + for (ii = 0; ii < fd->length20; ii++) { + DISPLAY_PRINT("%02x ", ptr[ii]); + if (((ii + 1) % 16) == 0) printf("\n"); - ptr++; } - printf("\n"); + DISPLAY_PRINT("\n"); } #else -#define dpaa_display_frame(a) +#define dpaa_display_frame_info(a, b, c) #endif static inline void dpaa_slow_parsing(struct rte_mbuf *m __rte_unused, @@ -377,7 +405,6 @@ dpaa_eth_fd_to_mbuf(const struct qm_fd *fd, uint32_t ifid) DPAA_DP_LOG(DEBUG, " FD--->MBUF off %d len = %d", offset, length); /* Ignoring case when format != qm_fd_contig */ - dpaa_display_frame(fd); ptr = DPAA_MEMPOOL_PTOV(bp_info, qm_fd_addr(fd)); mbuf = (struct rte_mbuf *)((char *)ptr - bp_info->meta_data_size); @@ -492,7 +519,6 @@ dpaa_rx_cb_no_prefetch(struct qman_fq **fq, struct qm_dqrr_entry **dqrr, fd = &dqrr[i]->fd; dpaa_intf = fq[0]->dpaa_intf; - format = (fd->opaque & DPAA_FD_FORMAT_MASK) >> DPAA_FD_FORMAT_SHIFT; if (unlikely(format == qm_fd_sg)) { @@ -515,6 +541,7 @@ dpaa_rx_cb_no_prefetch(struct qman_fq **fq, struct qm_dqrr_entry **dqrr, mbuf->next = NULL; rte_mbuf_refcnt_set(mbuf, 1); dpaa_eth_packet_info(mbuf, mbuf->buf_addr); + dpaa_display_frame_info(fd, fq[0]->fqid, true); } } @@ -532,7 +559,6 @@ dpaa_rx_cb(struct qman_fq **fq, struct qm_dqrr_entry **dqrr, for (i = 0; i < num_bufs; i++) { fd = &dqrr[i]->fd; dpaa_intf = fq[0]->dpaa_intf; - format = (fd->opaque & DPAA_FD_FORMAT_MASK) >> DPAA_FD_FORMAT_SHIFT; if (unlikely(format == qm_fd_sg)) { @@ -555,6 +581,7 @@ dpaa_rx_cb(struct qman_fq **fq, struct qm_dqrr_entry **dqrr, mbuf->next = NULL; rte_mbuf_refcnt_set(mbuf, 1); dpaa_eth_packet_info(mbuf, mbuf->buf_addr); + dpaa_display_frame_info(fd, fq[0]->fqid, true); } } @@ -653,6 +680,50 @@ dpaa_rx_cb_atomic(void *event, return qman_cb_dqrr_defer; } +#ifdef RTE_LIBRTE_DPAA_DEBUG_DRIVER +static inline void dpaa_eth_err_queue(struct dpaa_if *dpaa_intf) +{ + struct rte_mbuf *mbuf; + struct qman_fq *debug_fq; + int ret, i; + struct qm_dqrr_entry *dq; + struct qm_fd *fd; + + if (unlikely(!RTE_PER_LCORE(dpaa_io))) { + ret = rte_dpaa_portal_init((void *)0); + if (ret) { + DPAA_PMD_ERR("Failure in affining portal"); + return; + } + } + for (i = 0; i <= DPAA_DEBUG_FQ_TX_ERROR; i++) { + debug_fq = &dpaa_intf->debug_queues[i]; + ret = qman_set_vdq(debug_fq, 4, QM_VDQCR_EXACT); + if (ret) + return; + + do { + dq = qman_dequeue(debug_fq); + if (!dq) + continue; + fd = &dq->fd; + if (i == DPAA_DEBUG_FQ_RX_ERROR) + DPAA_PMD_ERR("RX ERROR status: 0x%08x", + fd->status); + else + DPAA_PMD_ERR("TX ERROR status: 0x%08x", + fd->status); + dpaa_display_frame_info(fd, debug_fq->fqid, + i == DPAA_DEBUG_FQ_RX_ERROR); + + mbuf = dpaa_eth_fd_to_mbuf(fd, dpaa_intf->ifid); + rte_pktmbuf_free(mbuf); + qman_dqrr_consume(debug_fq, dq); + } while (debug_fq->flags & QMAN_FQ_STATE_VDQCR); + } +} +#endif + uint16_t dpaa_eth_queue_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs) @@ -667,6 +738,11 @@ uint16_t dpaa_eth_queue_rx(void *q, rte_eal_process_type() == RTE_PROC_SECONDARY)) rte_dpaa_bpid_info = fq->bp_array; +#ifdef RTE_LIBRTE_DPAA_DEBUG_DRIVER + if (fq->fqid == ((struct dpaa_if *)fq->dpaa_intf)->rx_queues[0].fqid) + dpaa_eth_err_queue((struct dpaa_if *)fq->dpaa_intf); +#endif + if (likely(fq->is_static)) return dpaa_eth_queue_portal_rx(fq, bufs, nb_bufs); @@ -699,6 +775,7 @@ uint16_t dpaa_eth_queue_rx(void *q, if (!dq) continue; bufs[num_rx++] = dpaa_eth_fd_to_mbuf(&dq->fd, ifid); + dpaa_display_frame_info(&dq->fd, fq->fqid, true); qman_dqrr_consume(fq, dq); } while (fq->flags & QMAN_FQ_STATE_VDQCR); -- 2.20.1