[2/2] net/bnxt: fix epoch bit calculation
Checks
Commit Message
The epoch bit is a binary value which needs to be toggled with
every pass of the ring in the hardware.
The code was doing this prematurely in vector path.
Improve the ring wrap identification and fix epoch bit calculation
in the vector path.
Fixes: 30656a1cace8 ("net/bnxt: refactor epoch setting")
Cc: stable@dpdk.org
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Reviewed-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
drivers/net/bnxt/bnxt_ring.h | 19 +++++++++++++++++++
drivers/net/bnxt/bnxt_rxq.c | 1 +
drivers/net/bnxt/bnxt_rxq.h | 1 +
drivers/net/bnxt/bnxt_rxr.c | 4 ++++
drivers/net/bnxt/bnxt_rxtx_vec_common.h | 11 +++++------
5 files changed, 30 insertions(+), 6 deletions(-)
@@ -108,6 +108,25 @@ static inline void bnxt_db_write(struct bnxt_db_info *db, uint32_t idx)
}
}
+static inline void bnxt_db_epoch_write(struct bnxt_db_info *db, uint32_t idx, uint32_t epoch)
+{
+ uint32_t db_idx = DB_RING_IDX(db, idx);
+ void *doorbell = db->doorbell;
+
+ if (db->db_64) {
+ uint64_t key_idx = db->db_key64 | db_idx;
+
+ key_idx |= epoch << DBR_EPOCH_SFT;
+
+ rte_compiler_barrier();
+ rte_write64_relaxed(key_idx, doorbell);
+ } else {
+ uint32_t key_idx = db->db_key32 | db_idx;
+
+ rte_write32(key_idx, doorbell);
+ }
+}
+
static inline void bnxt_db_mpc_write(struct bnxt_db_info *db, uint32_t idx, uint32_t epoch)
{
uint32_t db_idx = DB_RING_IDX(db, idx);
@@ -425,6 +425,7 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
goto err;
}
rxq->rx_mbuf_alloc_fail = 0;
+ rxq->epoch = 0;
/* rxq 0 must not be stopped when used as async CPR */
if (!BNXT_NUM_ASYNC_CPR(bp) && queue_idx == 0)
@@ -30,6 +30,7 @@ struct bnxt_rx_queue {
uint16_t rxrearm_nb; /* number of descs to reinit. */
uint16_t rxrearm_start; /* next desc index to reinit. */
#endif
+ uint32_t epoch;
uint16_t port_id; /* Device port identifier */
uint8_t crc_len; /* 0 if CRC stripped, 4 otherwise */
uint8_t rx_deferred_start; /* not in global dev start */
@@ -1366,6 +1366,10 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
bnxt_db_write(&rxr->rx_db, rxr->rx_raw_prod);
rxq->rxrearm_start++;
rxq->rxrearm_nb--;
+ if (rxq->rxrearm_start >= rxq->nb_rx_desc) {
+ rxq->rxrearm_start = 0;
+ rxq->epoch = rxq->epoch == 0 ? 1 : 0;
+ }
} else {
/* Retry allocation on next call. */
break;
@@ -50,6 +50,7 @@ bnxt_rxq_vec_setup_common(struct bnxt_rx_queue *rxq)
rxq->mbuf_initializer = *(uint64_t *)p;
rxq->rxrearm_nb = 0;
rxq->rxrearm_start = 0;
+ rxq->epoch = 1;
return 0;
}
@@ -88,13 +89,11 @@ bnxt_rxq_rearm(struct bnxt_rx_queue *rxq, struct bnxt_rx_ring_info *rxr)
}
rxq->rxrearm_start += nb;
- /*
- * We can pass rxq->rxrearm_star - 1 as well, but then the epoch
- * bit calculation is messed up.
- */
- bnxt_db_write(&rxr->rx_db, rxr->rx_raw_prod);
- if (rxq->rxrearm_start >= rxq->nb_rx_desc)
+ bnxt_db_epoch_write(&rxr->rx_db, rxq->rxrearm_start - 1, rxq->epoch);
+ if (rxq->rxrearm_start >= rxq->nb_rx_desc) {
rxq->rxrearm_start = 0;
+ rxq->epoch = rxq->epoch == 0 ? 1 : 0;
+ }
rxq->rxrearm_nb -= nb;
}