[PATCH v13 10/25] drivers: add BMI Tx statistics
Hemant Agrawal
hemant.agrawal at nxp.com
Wed Aug 19 12:49:49 CEST 2026
From: Jun Yang <jun.yang at nxp.com>
Add support for BMI (Buffer Manager Interface) Tx statistics
counters. Extend fman to read Tx BMI registers and expose
them through the xstats interface.
Signed-off-by: Jun Yang <jun.yang at nxp.com>
---
drivers/bus/dpaa/base/fman/fman_hw.c | 96 +++++++++++++++++++++-------
drivers/bus/dpaa/include/fman.h | 16 +++++
drivers/net/dpaa/dpaa_ethdev.c | 26 ++++++--
drivers/net/dpaa/dpaa_ethdev.h | 11 +++-
4 files changed, 121 insertions(+), 28 deletions(-)
diff --git a/drivers/bus/dpaa/base/fman/fman_hw.c b/drivers/bus/dpaa/base/fman/fman_hw.c
index 731ba6aa25..ee885eb958 100644
--- a/drivers/bus/dpaa/base/fman/fman_hw.c
+++ b/drivers/bus/dpaa/base/fman/fman_hw.c
@@ -296,13 +296,24 @@ fman_if_bmi_stats_enable(struct fman_if *p)
{
struct __fman_if *m = container_of(p, struct __fman_if, __if);
struct rx_bmi_regs *regs = (struct rx_bmi_regs *)m->rx_bmi_map;
+ struct tx_bmi_regs *tx_regs = (struct tx_bmi_regs *)m->tx_bmi_map;
uint32_t tmp;
- tmp = in_be32(®s->fmbm_rstc);
+ if (regs) {
+ tmp = in_be32(®s->fmbm_rstc);
- tmp |= FMAN_BMI_COUNTERS_EN;
+ tmp |= FMAN_BMI_COUNTERS_EN;
- out_be32(®s->fmbm_rstc, tmp);
+ out_be32(®s->fmbm_rstc, tmp);
+ }
+
+ if (tx_regs) {
+ tmp = in_be32(&tx_regs->fmbm_tstc);
+
+ tmp |= FMAN_BMI_COUNTERS_EN;
+
+ out_be32(&tx_regs->fmbm_tstc, tmp);
+ }
}
void
@@ -310,13 +321,24 @@ fman_if_bmi_stats_disable(struct fman_if *p)
{
struct __fman_if *m = container_of(p, struct __fman_if, __if);
struct rx_bmi_regs *regs = (struct rx_bmi_regs *)m->rx_bmi_map;
+ struct tx_bmi_regs *tx_regs = (struct tx_bmi_regs *)m->tx_bmi_map;
uint32_t tmp;
- tmp = in_be32(®s->fmbm_rstc);
+ if (regs) {
+ tmp = in_be32(®s->fmbm_rstc);
- tmp &= ~FMAN_BMI_COUNTERS_EN;
+ tmp &= ~FMAN_BMI_COUNTERS_EN;
- out_be32(®s->fmbm_rstc, tmp);
+ out_be32(®s->fmbm_rstc, tmp);
+ }
+
+ if (tx_regs) {
+ tmp = in_be32(&tx_regs->fmbm_tstc);
+
+ tmp &= ~FMAN_BMI_COUNTERS_EN;
+
+ out_be32(&tx_regs->fmbm_tstc, tmp);
+ }
}
void
@@ -324,16 +346,36 @@ fman_if_bmi_stats_get_all(struct fman_if *p, uint64_t *value)
{
struct __fman_if *m = container_of(p, struct __fman_if, __if);
struct rx_bmi_regs *regs = (struct rx_bmi_regs *)m->rx_bmi_map;
+ struct tx_bmi_regs *tx_regs = (struct tx_bmi_regs *)m->tx_bmi_map;
+
int i = 0;
- value[i++] = (u32)in_be32(®s->fmbm_rfrc);
- value[i++] = (u32)in_be32(®s->fmbm_rfbc);
- value[i++] = (u32)in_be32(®s->fmbm_rlfc);
- value[i++] = (u32)in_be32(®s->fmbm_rffc);
- value[i++] = (u32)in_be32(®s->fmbm_rfdc);
- value[i++] = (u32)in_be32(®s->fmbm_rfldec);
- value[i++] = (u32)in_be32(®s->fmbm_rodc);
- value[i++] = (u32)in_be32(®s->fmbm_rbdc);
+ /* Report zero for register blocks that are not mapped for this port
+ * type, the caller expects a fixed number of values in a fixed order.
+ */
+ if (regs) {
+ value[i++] = (u32)in_be32(®s->fmbm_rfrc);
+ value[i++] = (u32)in_be32(®s->fmbm_rfbc);
+ value[i++] = (u32)in_be32(®s->fmbm_rlfc);
+ value[i++] = (u32)in_be32(®s->fmbm_rffc);
+ value[i++] = (u32)in_be32(®s->fmbm_rfdc);
+ value[i++] = (u32)in_be32(®s->fmbm_rfldec);
+ value[i++] = (u32)in_be32(®s->fmbm_rodc);
+ value[i++] = (u32)in_be32(®s->fmbm_rbdc);
+ } else {
+ while (i < 8)
+ value[i++] = 0;
+ }
+
+ if (tx_regs) {
+ value[i++] = (u32)in_be32(&tx_regs->fmbm_tfdc);
+ value[i++] = (u32)in_be32(&tx_regs->fmbm_tfledc);
+ value[i++] = (u32)in_be32(&tx_regs->fmbm_tfufdc);
+ value[i++] = (u32)in_be32(&tx_regs->fmbm_tbdc);
+ } else {
+ while (i < 12)
+ value[i++] = 0;
+ }
}
void
@@ -341,15 +383,25 @@ fman_if_bmi_stats_reset(struct fman_if *p)
{
struct __fman_if *m = container_of(p, struct __fman_if, __if);
struct rx_bmi_regs *regs = (struct rx_bmi_regs *)m->rx_bmi_map;
+ struct tx_bmi_regs *tx_regs = (struct tx_bmi_regs *)m->tx_bmi_map;
+
+ if (regs) {
+ out_be32(®s->fmbm_rfrc, 0);
+ out_be32(®s->fmbm_rfbc, 0);
+ out_be32(®s->fmbm_rlfc, 0);
+ out_be32(®s->fmbm_rffc, 0);
+ out_be32(®s->fmbm_rfdc, 0);
+ out_be32(®s->fmbm_rfldec, 0);
+ out_be32(®s->fmbm_rodc, 0);
+ out_be32(®s->fmbm_rbdc, 0);
+ }
- out_be32(®s->fmbm_rfrc, 0);
- out_be32(®s->fmbm_rfbc, 0);
- out_be32(®s->fmbm_rlfc, 0);
- out_be32(®s->fmbm_rffc, 0);
- out_be32(®s->fmbm_rfdc, 0);
- out_be32(®s->fmbm_rfldec, 0);
- out_be32(®s->fmbm_rodc, 0);
- out_be32(®s->fmbm_rbdc, 0);
+ if (tx_regs) {
+ out_be32(&tx_regs->fmbm_tfdc, 0);
+ out_be32(&tx_regs->fmbm_tfledc, 0);
+ out_be32(&tx_regs->fmbm_tfufdc, 0);
+ out_be32(&tx_regs->fmbm_tbdc, 0);
+ }
}
void
diff --git a/drivers/bus/dpaa/include/fman.h b/drivers/bus/dpaa/include/fman.h
index d949b38b8d..d34cced049 100644
--- a/drivers/bus/dpaa/include/fman.h
+++ b/drivers/bus/dpaa/include/fman.h
@@ -306,6 +306,13 @@ struct tx_bmi_regs {
uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine*/
uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale*/
uint32_t fmbm_trlmt; /**< Tx Rate Limiter*/
+ uint32_t reserved0034[0x73]; /**< (0x034 - 0x1FF) */
+ uint32_t fmbm_tstc; /**< Tx Statistics Counters*/
+ uint32_t fmbm_tfrc; /**< Tx Frame Counter*/
+ uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter*/
+ uint32_t fmbm_tfledc; /**< Tx Frames Length Error Discard Counter*/
+ uint32_t fmbm_tfufdc; /**< Tx Frames Unsupported Format Discard Counter*/
+ uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter*/
};
/* Description FM RTC timer alarm */
@@ -468,6 +475,15 @@ struct __fman_if {
void *qmi_map;
};
+#define MEMMAC_REG_OFFSET(reg) offsetof(struct memac_regs, reg)
+#define BMI_RX_REG_OFFSET(reg) offsetof(struct rx_bmi_regs, reg)
+#define BMI_TX_REG_OFFSET(reg) offsetof(struct tx_bmi_regs, reg)
+
+#define FMAN_IF_BMI_RX_STAT_OFFSET_START BMI_RX_REG_OFFSET(fmbm_rfrc)
+#define FMAN_IF_BMI_RX_STAT_OFFSET_END BMI_RX_REG_OFFSET(fmbm_rbdc)
+#define FMAN_IF_BMI_TX_STAT_OFFSET_START BMI_TX_REG_OFFSET(fmbm_tfrc)
+#define FMAN_IF_BMI_TX_STAT_OFFSET_END BMI_TX_REG_OFFSET(fmbm_tbdc)
+
/* And this is the base list node that the interfaces are added to. (See
* fman_if_enable_all_rx() below for an example of its use.)
*/
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 0425288ca1..2f31ff5150 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -143,8 +143,26 @@ static const struct rte_dpaa_xstats_name_off dpaa_xstats_strings[] = {
offsetof(struct dpaa_if_rx_bmi_stats, fmbm_rodc)},
{"rx_buf_deallocate",
offsetof(struct dpaa_if_rx_bmi_stats, fmbm_rbdc)},
+ {"tx_bad_frames_count",
+ offsetof(struct dpaa_if_tx_bmi_stats, fmbm_tfdc)},
+ {"tx_frame_length_discard",
+ offsetof(struct dpaa_if_tx_bmi_stats, fmbm_tfledc)},
+ {"tx_frames_unsupported_format",
+ offsetof(struct dpaa_if_tx_bmi_stats, fmbm_tfufdc)},
+ {"tx_buf_deallocate",
+ offsetof(struct dpaa_if_tx_bmi_stats, fmbm_tbdc)},
};
+/* Number of BMI entries at the tail of dpaa_xstats_strings[].
+ * Must equal RTE_DIM(dpaa_xstats_strings) - number_of_non_bmi_entries.
+ */
+#define DPAA_MAC_XSTATS_COUNT 13
+#define DPAA_BMI_XSTATS_COUNT (RTE_DIM(dpaa_xstats_strings) - DPAA_MAC_XSTATS_COUNT)
+static_assert(sizeof(struct dpaa_if_rx_bmi_stats) / sizeof(uint32_t)
+ + sizeof(struct dpaa_if_tx_bmi_stats) / sizeof(uint32_t) - 1
+ == DPAA_BMI_XSTATS_COUNT,
+ "DPAA_BMI_XSTATS_COUNT out of sync with BMI stats structs");
+
static struct rte_dpaa_driver rte_dpaa_pmd;
int dpaa_valid_dev;
struct rte_mempool *dpaa_tx_sg_pool;
@@ -906,7 +924,7 @@ dpaa_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
{
unsigned int i = 0, j, num = RTE_DIM(dpaa_xstats_strings);
uint64_t values[sizeof(struct dpaa_if_stats) / 8];
- unsigned int bmi_count = sizeof(struct dpaa_if_rx_bmi_stats) / 4;
+ unsigned int bmi_count = DPAA_BMI_XSTATS_COUNT;
if (n < num)
return num;
@@ -917,7 +935,7 @@ dpaa_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
fman_if_stats_get_all(dev->process_private, values,
sizeof(struct dpaa_if_stats) / 8);
- for (i = 0; i < num - (bmi_count - 1); i++) {
+ for (i = 0; i < num - bmi_count; i++) {
xstats[i].id = i;
xstats[i].value = values[dpaa_xstats_strings[i].offset / 8];
}
@@ -955,7 +973,7 @@ dpaa_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
{
unsigned int i, j, stat_cnt = RTE_DIM(dpaa_xstats_strings);
uint64_t values_copy[sizeof(struct dpaa_if_stats) / 8];
- unsigned int bmi_count = sizeof(struct dpaa_if_rx_bmi_stats) / 4;
+ unsigned int bmi_count = DPAA_BMI_XSTATS_COUNT;
if (!ids) {
if (n < stat_cnt)
@@ -967,7 +985,7 @@ dpaa_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
fman_if_stats_get_all(dev->process_private, values_copy,
sizeof(struct dpaa_if_stats) / 8);
- for (i = 0; i < stat_cnt - (bmi_count - 1); i++)
+ for (i = 0; i < stat_cnt - bmi_count; i++)
values[i] =
values_copy[dpaa_xstats_strings[i].offset / 8];
diff --git a/drivers/net/dpaa/dpaa_ethdev.h b/drivers/net/dpaa/dpaa_ethdev.h
index f400030a5c..d342d98f23 100644
--- a/drivers/net/dpaa/dpaa_ethdev.h
+++ b/drivers/net/dpaa/dpaa_ethdev.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2014-2016 Freescale Semiconductor, Inc. All rights reserved.
- * Copyright 2017-2024 NXP
+ * Copyright 2017-2026 NXP
*
*/
#ifndef __DPAA_ETHDEV_H__
@@ -234,7 +234,6 @@ dpaa_rx_cb_atomic(void *event,
void **bufs);
struct dpaa_if_rx_bmi_stats {
- uint32_t fmbm_rstc; /**< Rx Statistics Counters*/
uint32_t fmbm_rfrc; /**< Rx Frame Counter*/
uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/
uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/
@@ -245,6 +244,14 @@ struct dpaa_if_rx_bmi_stats {
uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter*/
};
+struct dpaa_if_tx_bmi_stats {
+ uint32_t fmbm_tfrc; /**< Tx Frame Counter*/
+ uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter*/
+ uint32_t fmbm_tfledc; /**< Tx Frames Length Error Discard*/
+ uint32_t fmbm_tfufdc; /**< Tx Frames Unsupported Format*/
+ uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
+};
+
int
dpaa_tx_conf_queue_init(struct qman_fq *fq);
--
2.25.1
More information about the dev
mailing list