[PATCH v2] common/cnxk: add NPA diagnostic and performance counter apis
Nawal Kishor
nkishor at marvell.com
Mon Mar 16 07:27:17 CET 2026
Add DPC (Diagnostic and Performance Counter) support for NPA pool
operations on CN20K. This allows allocating and attaching hardware
counters to pool/aura for monitoring alloc/free, outstanding buffers,
and high-watermark.
Signed-off-by: Nawal Kishor <nkishor at marvell.com>
---
v2:
* Fixed commit message.
drivers/common/cnxk/hw/npa.h | 10 +
drivers/common/cnxk/roc_features.h | 6 +
drivers/common/cnxk/roc_mbox.h | 19 ++
drivers/common/cnxk/roc_npa.c | 235 ++++++++++++++++++
drivers/common/cnxk/roc_npa.h | 45 ++++
drivers/common/cnxk/roc_npa_priv.h | 2 +
.../common/cnxk/roc_platform_base_symbols.c | 4 +
7 files changed, 321 insertions(+)
diff --git a/drivers/common/cnxk/hw/npa.h b/drivers/common/cnxk/hw/npa.h
index e421c70e01..8d6b6bbe8b 100644
--- a/drivers/common/cnxk/hw/npa.h
+++ b/drivers/common/cnxk/hw/npa.h
@@ -48,6 +48,8 @@
#define NPA_AF_BATCH_ACCEPT_CTL (0x6a8ull) /* [CN10K, .) */
#define NPA_AF_BATCH_ERR_DATA0 (0x6c0ull) /* [CN10K, .) */
#define NPA_AF_BATCH_ERR_DATA1 (0x6c8ull) /* [CN10K, .) */
+#define NPA_AF_DPCX_CFG(a) (0x800ull | (uint64_t)(a) << 6) /* [CN20K, .) */
+#define NPA_AF_DPC_PERMITX(a) (0x1000ull | (uint64_t)(a) << 3) /* [CN20K, .) */
#define NPA_AF_LFX_AURAS_CFG(a) (0x4000ull | (uint64_t)(a) << 18)
#define NPA_AF_LFX_LOC_AURAS_BASE(a) (0x4010ull | (uint64_t)(a) << 18)
#define NPA_AF_LFX_QINTS_CFG(a) (0x4100ull | (uint64_t)(a) << 18)
@@ -89,6 +91,14 @@
#define NPA_LF_AURA_BATCH_FREE0 (0x400ull) /* [CN10K, .) */
#define NPA_LF_AURA_BATCH_FREEX(a) \
(0x400ull | (uint64_t)(a) << 3) /* [CN10K, .) */
+#define NPA_LF_DPCX_ALLOC_CNT(a) \
+ (0x808ull | (uint64_t)(a) << 6) /* [CN20K, .) */
+#define NPA_LF_DPCX_FREE_CNT(a) \
+ (0x810ull | (uint64_t)(a) << 6) /* [CN20K, .) */
+#define NPA_LF_DPCX_OUTST_BUF_CNT(a) \
+ (0x818ull | (uint64_t)(a) << 6) /* [CN20K, .) */
+#define NPA_LF_DPCX_CNT_HI_WM(a) \
+ (0x820ull | (uint64_t)(a) << 6) /* [CN20K, .) */
/* Enum offsets */
diff --git a/drivers/common/cnxk/roc_features.h b/drivers/common/cnxk/roc_features.h
index 3c34041d76..2d8bad5b0c 100644
--- a/drivers/common/cnxk/roc_features.h
+++ b/drivers/common/cnxk/roc_features.h
@@ -132,6 +132,12 @@ roc_feature_nix_has_sq_cnt_update(void)
return roc_model_is_cn20k();
}
+static inline bool
+roc_feature_npa_has_dpc(void)
+{
+ return roc_model_is_cn20k();
+}
+
static inline bool
roc_feature_nix_has_16b_align(void)
{
diff --git a/drivers/common/cnxk/roc_mbox.h b/drivers/common/cnxk/roc_mbox.h
index 3176c87382..e86446c339 100644
--- a/drivers/common/cnxk/roc_mbox.h
+++ b/drivers/common/cnxk/roc_mbox.h
@@ -123,6 +123,10 @@ struct mbox_msghdr {
msg_rsp) \
M(NPA_CN20K_AQ_ENQ, 0x404, npa_cn20k_aq_enq, npa_cn20k_aq_enq_req, \
npa_cn20k_aq_enq_rsp) \
+ M(NPA_CN20K_DPC_ALLOC, 0x405, npa_cn20k_dpc_alloc, \
+ npa_cn20k_dpc_alloc_req, npa_cn20k_dpc_alloc_rsp) \
+ M(NPA_CN20K_DPC_FREE, 0x406, npa_cn20k_dpc_free, \
+ npa_cn20k_dpc_free_req, msg_rsp) \
/* SSO/SSOW mbox IDs (range 0x600 - 0x7FF) */ \
M(SSO_LF_ALLOC, 0x600, sso_lf_alloc, sso_lf_alloc_req, \
sso_lf_alloc_rsp) \
@@ -1423,6 +1427,21 @@ struct npa_cn20k_aq_enq_rsp {
};
};
+struct npa_cn20k_dpc_alloc_req {
+ struct mbox_msghdr hdr;
+ uint16_t __io dpc_conf;
+};
+
+struct npa_cn20k_dpc_alloc_rsp {
+ struct mbox_msghdr hdr;
+ uint8_t __io cntr_id;
+};
+
+struct npa_cn20k_dpc_free_req {
+ struct mbox_msghdr hdr;
+ uint8_t __io cntr_id;
+};
+
/* Disable all contexts of type 'ctype' */
struct hwctx_disable_req {
struct mbox_msghdr hdr;
diff --git a/drivers/common/cnxk/roc_npa.c b/drivers/common/cnxk/roc_npa.c
index 10087e19ef..88e328105a 100644
--- a/drivers/common/cnxk/roc_npa.c
+++ b/drivers/common/cnxk/roc_npa.c
@@ -1803,3 +1803,238 @@ roc_npa_dev_unlock(void)
if (idev != NULL)
plt_spinlock_unlock(&idev->npa_dev_lock);
}
+
+int
+roc_npa_dpc_alloc(uint8_t *counter_id, uint16_t conf)
+{
+ struct npa_cn20k_dpc_alloc_req *req;
+ struct npa_cn20k_dpc_alloc_rsp *rsp;
+ int rc = NPA_ERR_DPC_ALLOC, off;
+ struct mbox_dev *mdev;
+ struct mbox *mbox;
+ struct npa_lf *lf;
+
+ lf = idev_npa_obj_get();
+ if (lf == NULL) {
+ rc = NPA_ERR_DEVICE_NOT_BOUNDED;
+ return rc;
+ }
+ mdev = &lf->mbox->dev[0];
+
+ mbox = mbox_get(lf->mbox);
+ req = mbox_alloc_msg_npa_cn20k_dpc_alloc(mbox);
+ if (req == NULL)
+ goto exit;
+
+ req->dpc_conf = conf;
+ rc = mbox_process(mbox);
+ if (rc < 0)
+ goto exit;
+
+ off = mbox->rx_start +
+ PLT_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
+ rsp = (struct npa_cn20k_dpc_alloc_rsp *)((uintptr_t)mdev->mbase + off);
+
+ if (rsp->hdr.rc != 0)
+ goto exit;
+
+ *counter_id = rsp->cntr_id;
+ rc = 0;
+exit:
+ mbox_put(mbox);
+ return rc;
+}
+
+int
+roc_npa_dpc_free(uint8_t counter_id)
+{
+ struct npa_cn20k_dpc_free_req *free_req;
+ int rc = NPA_ERR_DPC_FREE, off;
+ struct mbox_dev *mdev;
+ struct msg_rsp *rsp;
+ struct mbox *mbox;
+ struct npa_lf *lf;
+
+ lf = idev_npa_obj_get();
+ if (lf == NULL) {
+ rc = NPA_ERR_DEVICE_NOT_BOUNDED;
+ return rc;
+ }
+ mdev = &lf->mbox->dev[0];
+ mbox = mbox_get(lf->mbox);
+ free_req = mbox_alloc_msg_npa_cn20k_dpc_free(mbox);
+ if (free_req == NULL)
+ goto exit;
+
+ free_req->cntr_id = counter_id;
+ rc = mbox_process(mbox);
+ if (rc < 0)
+ goto exit;
+
+ off = mbox->rx_start +
+ PLT_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
+ rsp = (struct msg_rsp *)((uintptr_t)mdev->mbase + off);
+ if (rsp->hdr.rc != 0)
+ goto exit;
+
+ rc = 0;
+exit:
+ mbox_put(mbox);
+ return rc;
+}
+
+int
+roc_npa_pool_dpc_enable(uint64_t aura_handle, uint8_t counter_id, uint32_t flags)
+{
+ struct npa_cn20k_aq_enq_req *req;
+ struct npa_cn20k_aq_enq_rsp *rsp;
+ int rc = -ENOSPC, off;
+ struct mbox_dev *mdev;
+ struct mbox *mbox;
+ struct npa_lf *lf;
+
+ lf = idev_npa_obj_get();
+ if (lf == NULL) {
+ rc = NPA_ERR_DEVICE_NOT_BOUNDED;
+ return rc;
+ }
+ mdev = &lf->mbox->dev[0];
+ mbox = mbox_get(lf->mbox);
+ req = mbox_alloc_msg_npa_cn20k_aq_enq(mbox);
+ if (req == NULL)
+ goto exit;
+
+ req->aura_id = roc_npa_aura_handle_to_aura(aura_handle);
+ req->op = NPA_AQ_INSTOP_WRITE;
+ if (!(flags & ROC_NPA_HALO_F)) {
+ /* Enable DPC in Pool */
+ req->ctype = NPA_AQ_CTYPE_POOL;
+ req->pool.op_dpc_ena = 1;
+ req->pool.op_dpc_set = counter_id;
+ req->pool_mask.op_dpc_ena = 1;
+ req->pool_mask.op_dpc_set = 0;
+ req->pool_mask.op_dpc_set = ~req->pool_mask.op_dpc_set;
+ } else {
+ /* Enable DPC in Halo */
+ req->ctype = NPA_AQ_CTYPE_HALO;
+ req->halo.op_dpc_ena = 1;
+ req->halo.op_dpc_set = counter_id;
+ req->halo_mask.op_dpc_ena = 1;
+ req->halo_mask.op_dpc_set = 0;
+ req->halo_mask.op_dpc_set = ~req->halo_mask.op_dpc_set;
+ }
+
+ rc = mbox_process(mbox);
+ if (rc < 0)
+ goto exit;
+
+ off = mbox->rx_start +
+ PLT_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
+ rsp = (struct npa_cn20k_aq_enq_rsp *)((uintptr_t)mdev->mbase + off);
+ if (rsp->hdr.rc != 0)
+ goto exit;
+
+ if (!(flags & ROC_NPA_HALO_F)) {
+ req = mbox_alloc_msg_npa_cn20k_aq_enq(mbox);
+ if (req == NULL)
+ goto disable;
+
+ /* Enable DPC in Aura */
+ req->aura_id = roc_npa_aura_handle_to_aura(aura_handle);
+ req->op = NPA_AQ_INSTOP_WRITE;
+ req->ctype = NPA_AQ_CTYPE_AURA;
+ req->aura.op_dpc_ena = 1;
+ req->aura.op_dpc_set = counter_id;
+ req->aura_mask.op_dpc_ena = 1;
+ req->aura_mask.op_dpc_set = 0;
+ req->aura_mask.op_dpc_set = ~req->aura_mask.op_dpc_set;
+
+ rc = mbox_process(mbox);
+ if (rc < 0)
+ goto disable;
+
+ off = mbox->rx_start +
+ PLT_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
+ rsp = (struct npa_cn20k_aq_enq_rsp *)((uintptr_t)mdev->mbase + off);
+ if (rsp->hdr.rc != 0)
+ goto disable;
+ }
+ rc = 0;
+ goto exit;
+
+disable:
+ roc_npa_pool_dpc_disable(aura_handle, flags);
+exit:
+ mbox_put(mbox);
+ return rc;
+}
+
+int
+roc_npa_pool_dpc_disable(uint64_t aura_handle, uint32_t flags)
+{
+ struct npa_cn20k_aq_enq_req *req;
+ struct npa_cn20k_aq_enq_rsp *rsp;
+ int rc = -ENOSPC, off;
+ struct mbox_dev *mdev;
+ struct mbox *mbox;
+ struct npa_lf *lf;
+
+ lf = idev_npa_obj_get();
+ if (lf == NULL) {
+ rc = NPA_ERR_DEVICE_NOT_BOUNDED;
+ return rc;
+ }
+ mdev = &lf->mbox->dev[0];
+ mbox = mbox_get(lf->mbox);
+ req = mbox_alloc_msg_npa_cn20k_aq_enq(mbox);
+ if (req == NULL)
+ goto exit;
+
+ req->aura_id = roc_npa_aura_handle_to_aura(aura_handle);
+ req->op = NPA_AQ_INSTOP_WRITE;
+ if (!(flags & ROC_NPA_HALO_F)) {
+ req->ctype = NPA_AQ_CTYPE_POOL;
+ req->pool.op_dpc_ena = 0;
+ req->pool_mask.op_dpc_ena = 1;
+ } else {
+ req->ctype = NPA_AQ_CTYPE_HALO;
+ req->halo.op_dpc_ena = 0;
+ req->halo_mask.op_dpc_ena = 1;
+ }
+
+ rc = mbox_process(mbox);
+ if (rc < 0)
+ goto exit;
+
+ off = mbox->rx_start +
+ PLT_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
+ rsp = (struct npa_cn20k_aq_enq_rsp *)((uintptr_t)mdev->mbase + off);
+ if (rsp->hdr.rc != 0)
+ goto exit;
+
+ if (!(flags & ROC_NPA_HALO_F)) {
+ req = mbox_alloc_msg_npa_cn20k_aq_enq(mbox);
+ if (req == NULL)
+ goto exit;
+
+ req->aura_id = roc_npa_aura_handle_to_aura(aura_handle);
+ req->op = NPA_AQ_INSTOP_WRITE;
+ req->ctype = NPA_AQ_CTYPE_AURA;
+ req->aura.op_dpc_ena = 0;
+ req->aura_mask.op_dpc_ena = 1;
+ rc = mbox_process(mbox);
+ if (rc < 0)
+ goto exit;
+
+ off = mbox->rx_start + PLT_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
+ rsp = (struct npa_cn20k_aq_enq_rsp *)((uintptr_t)mdev->mbase + off);
+ if (rsp->hdr.rc != 0)
+ goto exit;
+ }
+
+ rc = 0;
+
+exit:
+ mbox_put(mbox);
+ return rc;
+}
diff --git a/drivers/common/cnxk/roc_npa.h b/drivers/common/cnxk/roc_npa.h
index 18808e5873..db610cbd2c 100644
--- a/drivers/common/cnxk/roc_npa.h
+++ b/drivers/common/cnxk/roc_npa.h
@@ -191,6 +191,47 @@ roc_npa_aura_op_available_wait(uint64_t aura_handle, uint32_t count,
return op_avail;
}
+static inline void
+roc_npa_pool_op_dpc_reset(uint64_t aura_handle, uint8_t counter_id)
+{
+ plt_write64(0, roc_npa_aura_handle_to_base(aura_handle) +
+ NPA_LF_DPCX_ALLOC_CNT(counter_id));
+ plt_write64(0, roc_npa_aura_handle_to_base(aura_handle) +
+ NPA_LF_DPCX_FREE_CNT(counter_id));
+ plt_write64(0, roc_npa_aura_handle_to_base(aura_handle) +
+ NPA_LF_DPCX_OUTST_BUF_CNT(counter_id));
+ plt_write64(0, roc_npa_aura_handle_to_base(aura_handle) +
+ NPA_LF_DPCX_CNT_HI_WM(counter_id));
+}
+
+static inline uint64_t
+roc_npa_pool_op_dpc_alloc_count(uint64_t aura_handle, uint8_t counter_id)
+{
+ return plt_read64(roc_npa_aura_handle_to_base(aura_handle) +
+ NPA_LF_DPCX_ALLOC_CNT(counter_id));
+}
+
+static inline uint64_t
+roc_npa_pool_op_dpc_free_count(uint64_t aura_handle, uint8_t counter_id)
+{
+ return plt_read64(roc_npa_aura_handle_to_base(aura_handle) +
+ NPA_LF_DPCX_FREE_CNT(counter_id));
+}
+
+static inline uint64_t
+roc_npa_pool_op_dpc_outst_buf_count(uint64_t aura_handle, uint8_t counter_id)
+{
+ return plt_read64(roc_npa_aura_handle_to_base(aura_handle) +
+ NPA_LF_DPCX_OUTST_BUF_CNT(counter_id));
+}
+
+static inline uint64_t
+roc_npa_pool_op_dpc_high_wm_count(uint64_t aura_handle, uint8_t counter_id)
+{
+ return plt_read64(roc_npa_aura_handle_to_base(aura_handle) +
+ NPA_LF_DPCX_CNT_HI_WM(counter_id));
+}
+
static inline uint64_t
roc_npa_pool_op_performance_counter(uint64_t aura_handle, const int drop)
{
@@ -852,5 +893,9 @@ int __roc_api roc_npa_aura_drop_set(uint64_t aura_handle, uint64_t limit,
void __roc_api roc_npa_dev_lock(void);
void __roc_api roc_npa_dev_unlock(void);
+int __roc_api roc_npa_dpc_alloc(uint8_t *counter_id, uint16_t conf);
+int __roc_api roc_npa_dpc_free(uint8_t counter_id);
+int __roc_api roc_npa_pool_dpc_enable(uint64_t aura_handle, uint8_t counter_id, uint32_t flags);
+int __roc_api roc_npa_pool_dpc_disable(uint64_t aura_handle, uint32_t flags);
#endif /* _ROC_NPA_H_ */
diff --git a/drivers/common/cnxk/roc_npa_priv.h b/drivers/common/cnxk/roc_npa_priv.h
index e437fe831a..a3bda39f73 100644
--- a/drivers/common/cnxk/roc_npa_priv.h
+++ b/drivers/common/cnxk/roc_npa_priv.h
@@ -16,6 +16,8 @@ enum npa_error_status {
NPA_ERR_DEVICE_NOT_BOUNDED = -519,
NPA_ERR_HALO_INIT = -520,
NPA_ERR_HALO_FINI = -521,
+ NPA_ERR_DPC_ALLOC = -522,
+ NPA_ERR_DPC_FREE = -523,
};
struct npa_lf {
diff --git a/drivers/common/cnxk/roc_platform_base_symbols.c b/drivers/common/cnxk/roc_platform_base_symbols.c
index 79dd18fbd7..65db0c77bd 100644
--- a/drivers/common/cnxk/roc_platform_base_symbols.c
+++ b/drivers/common/cnxk/roc_platform_base_symbols.c
@@ -452,6 +452,10 @@ RTE_EXPORT_INTERNAL_SYMBOL(roc_npa_dump)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npa_buf_type_update)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npa_buf_type_mask)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npa_buf_type_limit_get)
+RTE_EXPORT_INTERNAL_SYMBOL(roc_npa_dpc_alloc)
+RTE_EXPORT_INTERNAL_SYMBOL(roc_npa_dpc_free)
+RTE_EXPORT_INTERNAL_SYMBOL(roc_npa_pool_dpc_enable)
+RTE_EXPORT_INTERNAL_SYMBOL(roc_npa_pool_dpc_disable)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_mark_actions_get)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_mark_actions_sub_return)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_vtag_actions_get)
--
2.48.1
More information about the dev
mailing list