From: Keegan Freyhof <[email protected]>
Restructure CQ and NQ arming in NQ processing to be more readable.
Fix incorrect completion validation being used for NQEs and RX
completions in NQ processing.
Fixed the issue of excess interrupts by properly tracking the valid
bit for NQs and using the correct RX completion validation code.
Fixes: 683e5cf79249 ("net/bnxt: use common NQ ring")
Cc: [email protected]
Signed-off-by: Keegan Freyhof <[email protected]>
Signed-off-by: Mohammad Shuab Siddique <[email protected]>
---
drivers/net/bnxt/bnxt.h | 2 +
drivers/net/bnxt/bnxt_cpr.c | 99 +++++++++++++++++++++++++++++++++++++
drivers/net/bnxt/bnxt_cpr.h | 34 ++++++++++++-
drivers/net/bnxt/bnxt_rxq.c | 47 +++++++++++++++++-
4 files changed, 179 insertions(+), 3 deletions(-)
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 03df28e64a..f21753e40c 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -433,8 +433,10 @@ struct bnxt_coal {
#define DBR_TYPE_SQ (0x0ULL << 60)
#define DBR_TYPE_SRQ (0x2ULL << 60)
#define DBR_TYPE_CQ (0x4ULL << 60)
+#define DBR_TYPE_CQ_ARMALL (0x6ULL << 60)
#define DBR_TYPE_NQ (0xaULL << 60)
#define DBR_TYPE_NQ_ARM (0xbULL << 60)
+#define DBR_TYPE_NQ_MASK (0xeULL << 60)
#define DB_PF_OFFSET 0x10000
#define DB_VF_OFFSET 0x4000
diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index c6606e19a8..60d1ec0b4a 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -13,6 +13,104 @@
#include "hsi_struct_def_dpdk.h"
#include "tfc_vf2pf_msg.h"
+void bnxt_process_async_msg(struct bnxt *bp, struct tx_cmpl *cmpl)
+{
+ uint16_t type = cmpl->flags_type & TX_CMPL_TYPE_MASK;
+
+ switch (type) {
+ case HWRM_CMPL_TYPE_HWRM_DONE:
+ break;
+ case HWRM_ASYNC_EVENT_CMPL_TYPE_HWRM_ASYNC_EVENT:
+ bnxt_handle_async_event(bp, (struct cmpl_base *)cmpl);
+ break;
+ default:
+ printf("Port:%d Unhandled async message %x\n",
bp->eth_dev->data->port_id, type);
+ break;
+ }
+}
+
+void bnxt_process_nq(struct bnxt *bp, struct bnxt_cp_ring_info *nqr,
+ struct bnxt_cp_ring_info *rx_cpr)
+{
+ struct nqe_cn *nqcmps = (struct nqe_cn *)nqr->cp_desc_ring;
+ uint32_t ring_mask = nqr->cp_ring_struct->ring_mask;
+ uint32_t raw_cons = nqr->cp_raw_cons;
+ uint16_t nq_type, nqe_cnt = 0;
+ bool v_bit = nqr->valid;
+ uint32_t cons = RING_CMPL(ring_mask, raw_cons);
+
+ while (1) {
+ if (!CMPL_VALID(&nqcmps[cons], v_bit)) {
+ if (nqe_cnt) {
+ nqr->cp_raw_cons = raw_cons;
+ nqr->valid = v_bit;
+ }
+ return;
+ }
+
+ nq_type = NQ_CN_TYPE_MASK & nqcmps[cons].type;
+
+ if (CMP_TYPE((struct cmpl_base *)&nqcmps[cons]) !=
NQ_CN_TYPE_CQ_NOTIFICATION)
+ bnxt_process_async_msg(bp, (struct tx_cmpl
*)&nqcmps[cons]);
+ else
+ rx_cpr->toggle =
NQE_CN_TOGGLE((uint64_t)nqcmps[cons].type);
+
+ NEXT_CMPL(nqr, cons, v_bit, 1);
+ raw_cons++;
+ if (nq_type)
+ nqe_cnt++;
+ }
+}
+
+/* Arms/disarms the given NQ for Thor/Thor2, with P5+ represening the ASIC
family */
+void bnxt_arm_nq_p5p(struct bnxt_cp_ring_info *nqr, bool enable_irq)
+{
+ uint32_t raw_cons = nqr->cp_raw_cons;
+ uint64_t db_msg = 0;
+ uint32_t toggle = 0;
+
+ if (enable_irq == 1)
+ toggle = nqr->toggle;
+
+ db_msg = nqr->cp_db.db_key64 | (raw_cons & nqr->cp_db.db_ring_mask)
+ | DB_EPOCH(&nqr->cp_db, raw_cons) | DB_TOGGLE(toggle);
+
+ if (enable_irq)
+ db_msg |= DBR_TYPE_NQ_ARM;
+ else
+ db_msg |= DBR_TYPE_NQ_MASK;
+
+ rte_compiler_barrier();
+ rte_write64(db_msg, nqr->cp_db.doorbell);
+ rte_compiler_barrier();
+}
+
+/* Arms/disarms the given CQ for Thor/Thor2, with P5+ represening the ASIC
family */
+void bnxt_arm_rx_cq_p5p(struct bnxt_cp_ring_info *cpr, bool enable_irq)
+{
+ uint32_t raw_cons = cpr->cp_raw_cons;
+ uint64_t db_msg = 0;
+ uint32_t toggle = 0;
+
+ if (raw_cons == UINT32_MAX)
+ raw_cons = 0;
+
+ if (enable_irq == 1)
+ toggle = cpr->toggle;
+
+ db_msg = cpr->cp_db.db_key64 | (raw_cons & cpr->cp_db.db_ring_mask)
+ | DB_EPOCH(&cpr->cp_db, raw_cons) | DB_TOGGLE(toggle);
+
+ if (enable_irq)
+ db_msg |= DBR_TYPE_CQ_ARMALL;
+ else
+ db_msg |= DBR_TYPE_CQ;
+
+ rte_compiler_barrier();
+ rte_write64(db_msg, cpr->cp_db.doorbell);
+ rte_compiler_barrier();
+}
+
void bnxt_wait_for_device_shutdown(struct bnxt *bp)
{
uint32_t val, timeout;
diff --git a/drivers/net/bnxt/bnxt_cpr.h b/drivers/net/bnxt/bnxt_cpr.h
index 858ee15c47..e097f1034f 100644
--- a/drivers/net/bnxt/bnxt_cpr.h
+++ b/drivers/net/bnxt/bnxt_cpr.h
@@ -30,6 +30,14 @@ struct bnxt_db_info;
#define RING_CMPL(ring_mask, idx) ((idx) & (ring_mask))
#define NEXT_CMP(idx) RING_CMP(ADV_RAW_CMP(idx, 1))
+#define DBR_TOGGLE_SFT 25
+#define DB_TOGGLE(tgl) ((tgl) << DBR_TOGGLE_SFT)
+
+#define NQ_CN_TOGGLE_MASK 0xc0UL
+#define NQ_CN_TOGGLE_SFT 6
+#define NQE_CN_TOGGLE(type) (((type) & NQ_CN_TOGGLE_MASK) >>
\
+ NQ_CN_TOGGLE_SFT)
+
#define DB_CP_REARM_FLAGS (DB_KEY_CP | DB_IDX_VALID)
#define DB_CP_FLAGS (DB_KEY_CP | DB_IDX_VALID | DB_IRQ_DIS)
@@ -73,6 +81,21 @@ struct bnxt_db_info {
#define DB_RING_IDX(db, idx) (((idx) & (db)->db_ring_mask) | \
DB_EPOCH(db, idx))
+struct nqe_cn {
+ rte_le16_t type;
+ #define NQ_CN_TYPE_MASK 0x3fUL
+ #define NQ_CN_TYPE_SFT 0
+ #define NQ_CN_TYPE_CQ_NOTIFICATION 0x30UL
+ #define NQ_CN_TYPE_LAST NQ_CN_TYPE_CQ_NOTIFICATION
+ #define NQ_CN_TOGGLE_MASK 0xc0UL
+ #define NQ_CN_TOGGLE_SFT 6
+ rte_le16_t reserved16;
+ rte_le32_t cq_handle_low;
+ rte_le32_t v;
+ #define NQ_CN_V 0x1UL
+ rte_le32_t cq_handle_high;
+};
+
struct bnxt_ring;
struct bnxt_cp_ring_info {
uint32_t cp_raw_cons;
@@ -89,7 +112,9 @@ struct bnxt_cp_ring_info {
struct bnxt_ring *cp_ring_struct;
bool valid;
uint32_t epoch;
- uint8_t dpi;
+ uint32_t toggle;
+ uint8_t dpi; /* Doorbell page index for multi-doorbell
support */
+
};
#define RX_CMP_L2_ERRORS \
@@ -101,6 +126,11 @@ void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base
*cmp);
int bnxt_event_hwrm_resp_handler(struct bnxt *bp, struct cmpl_base *cmp);
void bnxt_dev_reset_and_resume(void *arg);
void bnxt_wait_for_device_shutdown(struct bnxt *bp);
+void bnxt_arm_nq_p5p(struct bnxt_cp_ring_info *nqr, bool enable_irq);
+void bnxt_arm_rx_cq_p5p(struct bnxt_cp_ring_info *cpr, bool enable_irq);
+void bnxt_process_async_msg(struct bnxt *bp, struct tx_cmpl *cmpl);
+void bnxt_process_nq(struct bnxt *bp, struct bnxt_cp_ring_info *nqr,
+ struct bnxt_cp_ring_info *rx_cpr);
#define EVENT_DATA1_REASON_CODE_FW_EXCEPTION_FATAL \
HWRM_ASYNC_EVENT_CMPL_RESET_NOTIFY_EVENT_DATA1_REASON_CODE_FW_EXCEPTION_FATAL
@@ -152,4 +182,6 @@ bnxt_cpr_cmp_valid(const void *cmpl, uint32_t raw_cons,
uint32_t ring_size)
}
return false;
}
+
#endif
+
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index 91b3555df6..b93f5043de 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -461,7 +461,14 @@ bnxt_rx_queue_intr_enable_op(struct rte_eth_dev *eth_dev,
uint16_t queue_id)
return -EINVAL;
cpr = rxq->cp_ring;
- B_CP_DB_REARM(cpr, cpr->cp_raw_cons);
+ if (BNXT_CHIP_P5_P7(bp)) {
+ struct bnxt_cp_ring_info *nqr = bp->rxtx_nq_ring;
+
+ bnxt_arm_nq_p5p(nqr, 1);
+ bnxt_arm_rx_cq_p5p(rxq->cp_ring, 1);
+ } else {
+ B_CP_DB_ARM(cpr);
+ }
}
return rc;
}
@@ -484,7 +491,43 @@ bnxt_rx_queue_intr_disable_op(struct rte_eth_dev *eth_dev,
uint16_t queue_id)
return -EINVAL;
cpr = rxq->cp_ring;
- B_CP_DB_DISARM(cpr);
+ if (BNXT_CHIP_P5_P7(bp)) {
+ struct bnxt_cp_ring_info *nqr = bp->rxtx_nq_ring;
+ struct bnxt_cp_ring_info *rx_cpr;
+
+ bnxt_arm_nq_p5p(nqr, 0);
+ /* Loops through all RXQs and finds the one that
+ * received a packet if any
+ */
+ uint32_t cons =
RING_CMPL(nqr->cp_ring_struct->ring_mask,
+ nqr->cp_raw_cons);
+ struct cmpl_base *cmpl = &((nqr->cp_desc_ring)[cons]);
+
+ if (CMPL_VALID(cmpl, nqr->valid)) {
+ unsigned int rxid = 0;
+
+ rx_cpr = rxq->cp_ring;
+ for (; rxid < bp->rx_nr_rings; rxid++) {
+ rxq = bp->rx_queues[rxid];
+ rx_cpr = rxq->cp_ring;
+ cons =
RING_CMPL(rx_cpr->cp_ring_struct->ring_mask,
+ rx_cpr->cp_raw_cons);
+ cmpl = &((rx_cpr->cp_desc_ring)[cons]);
+ /* Because the valid bit in the rx
+ * completion queue is not updated the
+ * cmp valid using raw cons is used
+ */
+ if (bnxt_cpr_cmp_valid(cmpl,
+
rx_cpr->cp_raw_cons,
+
rx_cpr->cp_ring_struct->ring_size)) {
+ break;
+ }
+ }
+ bnxt_process_nq(bp, nqr, rx_cpr);
+ }
+ } else {
+ B_CP_DB_DISARM(cpr);
+ }
}
return rc;
}
--
2.47.3