bus/dpaa: enable Rx/Tx error queues
authorSachin Saxena <sachin.saxena@oss.nxp.com>
Thu, 24 Sep 2020 04:02:07 +0000 (09:32 +0530)
committerThomas Monjalon <thomas@monjalon.net>
Tue, 6 Oct 2020 12:43:40 +0000 (14:43 +0200)
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 <jun.yang@nxp.com>
Signed-off-by: Rohit Raj <rohit.raj@nxp.com>
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Signed-off-by: Sachin Saxena <sachin.saxena@oss.nxp.com>
drivers/bus/dpaa/base/fman/fman_hw.c
drivers/bus/dpaa/include/fman.h
drivers/bus/dpaa/include/fsl_fman.h
drivers/bus/dpaa/rte_bus_dpaa_version.map
drivers/net/dpaa/dpaa_ethdev.c
drivers/net/dpaa/dpaa_rxtx.c

index 9ab8e83..4ab49f7 100644 (file)
@@ -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);
+}
index dcf4083..f2b0bf9 100644 (file)
@@ -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 */
index 6c87c8d..a3cf77f 100644 (file)
@@ -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);
 
index f47922c..f6028b8 100644 (file)
@@ -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;
index a01c8f3..cc20f28 100644 (file)
@@ -47,6 +47,7 @@
 #include <fsl_bman.h>
 #include <fsl_fman.h>
 #include <process.h>
+#include <fmlib/fm_ext.h>
 
 /* 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);
index 5303c9b..6eadbfa 100644 (file)
                (_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);