net/bnxt: fix Rx timestamp when FIFO pending bit is set
authorSomnath Kotur <somnath.kotur@broadcom.com>
Mon, 26 Apr 2021 06:07:55 +0000 (11:37 +0530)
committerAjit Khaparde <ajit.khaparde@broadcom.com>
Sun, 2 May 2021 22:15:19 +0000 (00:15 +0200)
Fix to clear the Rx FIFO while reading the timestamp.
If the Rx FIFO has pending bit set, keep reading to clear it
and return the last valid timestamp instead of unconditionally
returning an error.

Fixes: b11cceb83a34 ("net/bnxt: support timesync")
Cc: stable@dpdk.org
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
drivers/net/bnxt/bnxt.h
drivers/net/bnxt/bnxt_ethdev.c

index bd2dec4..72513fe 100644 (file)
@@ -306,6 +306,7 @@ struct rte_flow {
        struct bnxt_vnic_info   *vnic;
 };
 
+#define BNXT_PTP_RX_PND_CNT            10
 #define BNXT_PTP_FLAGS_PATH_TX         0x0
 #define BNXT_PTP_FLAGS_PATH_RX         0x1
 #define BNXT_PTP_FLAGS_CURRENT_TIME    0x2
index dba5b9f..748b766 100644 (file)
@@ -3390,6 +3390,38 @@ static int bnxt_get_tx_ts(struct bnxt *bp, uint64_t *ts)
        return 0;
 }
 
+static int bnxt_clr_rx_ts(struct bnxt *bp, uint64_t *last_ts)
+{
+       struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+       struct bnxt_pf_info *pf = bp->pf;
+       uint16_t port_id;
+       int i = 0;
+       uint32_t fifo;
+
+       if (!ptp || (bp->flags & BNXT_FLAG_CHIP_P5))
+               return -EINVAL;
+
+       port_id = pf->port_id;
+       fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
+                               ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO]));
+       while ((fifo & BNXT_PTP_RX_FIFO_PENDING) && (i < BNXT_PTP_RX_PND_CNT)) {
+               rte_write32(1 << port_id, (uint8_t *)bp->bar0 +
+                           ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO_ADV]);
+               fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
+                                       ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO]));
+               *last_ts = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
+                                       ptp->rx_mapped_regs[BNXT_PTP_RX_TS_L]));
+               *last_ts |= (uint64_t)rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
+                                       ptp->rx_mapped_regs[BNXT_PTP_RX_TS_H])) << 32;
+               i++;
+       }
+
+       if (i >= BNXT_PTP_RX_PND_CNT)
+               return -EBUSY;
+
+       return 0;
+}
+
 static int bnxt_get_rx_ts(struct bnxt *bp, uint64_t *ts)
 {
        struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
@@ -3408,10 +3440,8 @@ static int bnxt_get_rx_ts(struct bnxt *bp, uint64_t *ts)
 
        fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
                                   ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO]));
-       if (fifo & BNXT_PTP_RX_FIFO_PENDING) {
-/*             bnxt_clr_rx_ts(bp);       TBD  */
-               return -EBUSY;
-       }
+       if (fifo & BNXT_PTP_RX_FIFO_PENDING)
+               return bnxt_clr_rx_ts(bp, ts);
 
        *ts = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
                                ptp->rx_mapped_regs[BNXT_PTP_RX_TS_L]));