From: Kyo Liu <kyo.liu@nebula-matrix.com>
To: kyo.liu@nebula-matrix.com, dev@dpdk.org
Cc: Dimon Zhao <dimon.zhao@nebula-matrix.com>,
Leon Yu <leon.yu@nebula-matrix.com>,
Sam Chen <sam.chen@nebula-matrix.com>
Subject: [PATCH v1 16/17] net/nbl: add nbl device xstats and stats
Date: Thu, 12 Jun 2025 08:58:37 +0000 [thread overview]
Message-ID: <20250612085840.729830-17-kyo.liu@nebula-matrix.com> (raw)
In-Reply-To: <20250612085840.729830-1-kyo.liu@nebula-matrix.com>
Implement NBL device xstats and stats functions
Signed-off-by: Kyo Liu <kyo.liu@nebula-matrix.com>
---
drivers/net/nbl/nbl_dev/nbl_dev.c | 148 +++++++++++++++++-
drivers/net/nbl/nbl_dev/nbl_dev.h | 2 +
drivers/net/nbl/nbl_dispatch.c | 111 +++++++++++++
.../nbl/nbl_hw/nbl_hw_leonis/nbl_res_leonis.c | 113 +++++++++++++
drivers/net/nbl/nbl_hw/nbl_txrx.c | 112 ++++++++++++-
drivers/net/nbl/nbl_include/nbl_def_channel.h | 5 +
.../net/nbl/nbl_include/nbl_def_dispatch.h | 9 ++
.../net/nbl/nbl_include/nbl_def_resource.h | 12 +-
drivers/net/nbl/nbl_include/nbl_include.h | 4 +
9 files changed, 510 insertions(+), 6 deletions(-)
diff --git a/drivers/net/nbl/nbl_dev/nbl_dev.c b/drivers/net/nbl/nbl_dev/nbl_dev.c
index 949d42506d..4fa132ae1c 100644
--- a/drivers/net/nbl/nbl_dev/nbl_dev.c
+++ b/drivers/net/nbl/nbl_dev/nbl_dev.c
@@ -384,6 +384,129 @@ static int nbl_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_
return disp_ops->get_stats(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt), rte_stats);
}
+static int nbl_stats_reset(struct rte_eth_dev *eth_dev)
+{
+ struct nbl_adapter *adapter = ETH_DEV_TO_NBL_DEV_PF_PRIV(eth_dev);
+ struct nbl_dev_mgt *dev_mgt = NBL_ADAPTER_TO_DEV_MGT(adapter);
+ struct nbl_dispatch_ops *disp_ops = NBL_DEV_MGT_TO_DISP_OPS(dev_mgt);
+
+ return disp_ops->reset_stats(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt));
+}
+
+static int nbl_dev_update_hw_xstats(struct nbl_dev_mgt *dev_mgt, struct rte_eth_xstat *xstats,
+ u16 hw_xstats_cnt, u16 *xstats_cnt)
+{
+ struct nbl_common_info *common = NBL_DEV_MGT_TO_COMMON(dev_mgt);
+ struct nbl_dispatch_ops *disp_ops = NBL_DEV_MGT_TO_DISP_OPS(dev_mgt);
+ u64 *hw_stats;
+ int i;
+ u16 count = *xstats_cnt;
+
+ hw_stats = rte_zmalloc("nbl_xstats_cnt", hw_xstats_cnt * sizeof(u64), 0);
+ if (!hw_stats)
+ return -ENOMEM;
+
+ disp_ops->get_private_stat_data(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt),
+ common->eth_id, hw_stats, hw_xstats_cnt * sizeof(u64));
+ for (i = 0; i < hw_xstats_cnt; i++) {
+ xstats[count].value = hw_stats[i] - dev_mgt->net_dev->hw_xstats_offset[i];
+ xstats[count].id = count;
+ count++;
+ }
+
+ *xstats_cnt = count;
+ rte_free(hw_stats);
+ return 0;
+}
+
+static int nbl_xstats_get(struct rte_eth_dev *eth_dev,
+ struct rte_eth_xstat *xstats, unsigned int n)
+{
+ struct nbl_adapter *adapter = ETH_DEV_TO_NBL_DEV_PF_PRIV(eth_dev);
+ struct nbl_dev_mgt *dev_mgt = NBL_ADAPTER_TO_DEV_MGT(adapter);
+ struct nbl_common_info *common = NBL_DEV_MGT_TO_COMMON(dev_mgt);
+ struct nbl_dispatch_ops *disp_ops = NBL_DEV_MGT_TO_DISP_OPS(dev_mgt);
+ int ret = 0;
+ u16 txrx_xstats_cnt = 0, hw_xstats_cnt = 0, xstats_cnt = 0;
+
+ if (!xstats)
+ return 0;
+
+ ret = disp_ops->get_txrx_xstats_cnt(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt), &txrx_xstats_cnt);
+ if (!common->is_vf)
+ ret |= disp_ops->get_hw_xstats_cnt(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt),
+ &hw_xstats_cnt);
+ if (ret)
+ return -EIO;
+
+ if (n < (txrx_xstats_cnt + hw_xstats_cnt))
+ return txrx_xstats_cnt + hw_xstats_cnt;
+
+ if (txrx_xstats_cnt)
+ ret = disp_ops->get_txrx_xstats(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt),
+ xstats, &xstats_cnt);
+ if (hw_xstats_cnt)
+ ret |= nbl_dev_update_hw_xstats(dev_mgt, xstats, hw_xstats_cnt, &xstats_cnt);
+
+ if (ret)
+ return -EIO;
+
+ return xstats_cnt;
+}
+
+static int nbl_xstats_get_names(struct rte_eth_dev *eth_dev,
+ struct rte_eth_xstat_name *xstats_names,
+ __rte_unused unsigned int limit)
+{
+ struct nbl_adapter *adapter = ETH_DEV_TO_NBL_DEV_PF_PRIV(eth_dev);
+ struct nbl_dev_mgt *dev_mgt = NBL_ADAPTER_TO_DEV_MGT(adapter);
+ struct nbl_common_info *common = NBL_DEV_MGT_TO_COMMON(dev_mgt);
+ struct nbl_dispatch_ops *disp_ops = NBL_DEV_MGT_TO_DISP_OPS(dev_mgt);
+ u16 txrx_xstats_cnt = 0, hw_xstats_cnt = 0, xstats_cnt = 0;
+ int ret = 0;
+
+ ret = disp_ops->get_txrx_xstats_cnt(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt), &txrx_xstats_cnt);
+ if (!common->is_vf)
+ ret |= disp_ops->get_hw_xstats_cnt(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt),
+ &hw_xstats_cnt);
+ if (ret)
+ return -EIO;
+
+ if (!xstats_names)
+ return txrx_xstats_cnt + hw_xstats_cnt;
+
+ if (txrx_xstats_cnt)
+ ret = disp_ops->get_txrx_xstats_names(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt),
+ xstats_names, &xstats_cnt);
+ if (hw_xstats_cnt)
+ ret |= disp_ops->get_hw_xstats_names(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt),
+ xstats_names, &xstats_cnt);
+ if (ret)
+ return -EIO;
+
+ return xstats_cnt;
+}
+
+
+
+static int nbl_xstats_reset(struct rte_eth_dev *eth_dev)
+{
+ struct nbl_adapter *adapter = ETH_DEV_TO_NBL_DEV_PF_PRIV(eth_dev);
+ struct nbl_dev_mgt *dev_mgt = NBL_ADAPTER_TO_DEV_MGT(adapter);
+ struct nbl_common_info *common = NBL_DEV_MGT_TO_COMMON(dev_mgt);
+ struct nbl_dispatch_ops *disp_ops = NBL_DEV_MGT_TO_DISP_OPS(dev_mgt);
+ struct nbl_dev_net_mgt *net_dev = dev_mgt->net_dev;
+
+ if (!common->is_vf) {
+ disp_ops->get_private_stat_data(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt),
+ dev_mgt->common->eth_id,
+ net_dev->hw_xstats_offset, net_dev->hw_xstats_size);
+ }
+
+ nbl_stats_reset(eth_dev);
+ return 0;
+}
+
struct nbl_dev_ops dev_ops = {
.dev_configure = nbl_dev_configure,
.dev_start = nbl_dev_port_start,
@@ -396,6 +519,10 @@ struct nbl_dev_ops dev_ops = {
.dev_infos_get = nbl_dev_infos_get,
.link_update = nbl_link_update,
.stats_get = nbl_stats_get,
+ .stats_reset = nbl_stats_reset,
+ .xstats_get = nbl_xstats_get,
+ .xstats_get_names = nbl_xstats_get_names,
+ .xstats_reset = nbl_xstats_reset,
};
static int nbl_dev_setup_chan_queue(struct nbl_adapter *adapter)
@@ -438,6 +565,7 @@ static int nbl_dev_common_start(struct nbl_dev_mgt *dev_mgt)
struct nbl_board_port_info *board_info;
u8 *mac;
int ret;
+ u16 priv_cnt = 0;
board_info = &common->board_info;
disp_ops->get_board_info(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt), board_info);
@@ -456,8 +584,25 @@ static int nbl_dev_common_start(struct nbl_dev_mgt *dev_mgt)
goto add_multi_rule_failed;
}
- return 0;
+ net_dev->hw_xstats_offset = NULL;
+ if (!dev_mgt->common->is_vf)
+ disp_ops->get_hw_xstats_cnt(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt), &priv_cnt);
+ if (priv_cnt) {
+ net_dev->hw_xstats_offset = rte_zmalloc("nbl_xstats_cnt",
+ priv_cnt * sizeof(u64), 0);
+ net_dev->hw_xstats_size = priv_cnt * sizeof(u64);
+ if (!net_dev->hw_xstats_offset) {
+ ret = -ENOMEM;
+ goto alloc_xstats_offset_failed;
+ }
+
+ disp_ops->get_private_stat_data(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt),
+ dev_mgt->common->eth_id,
+ net_dev->hw_xstats_offset, net_dev->hw_xstats_size);
+ }
+ return 0;
+alloc_xstats_offset_failed:
add_multi_rule_failed:
disp_ops->del_macvlan(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt), mac, 0, net_dev->vsi_id);
@@ -719,6 +864,7 @@ int nbl_dev_init(void *p, struct rte_eth_dev *eth_dev)
eth_dev->data->mac_addrs[0].addr_bytes);
adapter->state = NBL_ETHDEV_INITIALIZED;
+ eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
disp_ops->get_resource_pt_ops(NBL_DEV_MGT_TO_DISP_PRIV(*dev_mgt),
&(*dev_mgt)->pt_ops, 0);
diff --git a/drivers/net/nbl/nbl_dev/nbl_dev.h b/drivers/net/nbl/nbl_dev/nbl_dev.h
index f58699a51e..1541aebba5 100644
--- a/drivers/net/nbl/nbl_dev/nbl_dev.h
+++ b/drivers/net/nbl/nbl_dev/nbl_dev.h
@@ -41,6 +41,8 @@ struct nbl_dev_net_mgt {
struct rte_eth_dev *eth_dev;
struct nbl_dev_ring_mgt ring_mgt;
struct nbl_eth_link_info eth_link_info;
+ u64 *hw_xstats_offset;
+ u32 hw_xstats_size;
u16 vsi_id;
u8 eth_mode;
u8 eth_id;
diff --git a/drivers/net/nbl/nbl_dispatch.c b/drivers/net/nbl/nbl_dispatch.c
index 33964641c4..e18b543ad6 100644
--- a/drivers/net/nbl/nbl_dispatch.c
+++ b/drivers/net/nbl/nbl_dispatch.c
@@ -724,9 +724,94 @@ static int nbl_disp_get_stats(void *priv, struct rte_eth_stats *rte_stats)
{
struct nbl_dispatch_mgt *disp_mgt = (struct nbl_dispatch_mgt *)priv;
struct nbl_resource_ops *res_ops = NBL_DISP_MGT_TO_RES_OPS(disp_mgt);
+
return res_ops->get_stats(NBL_DISP_MGT_TO_RES_PRIV(disp_mgt), rte_stats);
}
+static int nbl_disp_reset_stats(void *priv)
+{
+ struct nbl_dispatch_mgt *disp_mgt = (struct nbl_dispatch_mgt *)priv;
+ struct nbl_resource_ops *res_ops = NBL_DISP_MGT_TO_RES_OPS(disp_mgt);
+
+ return res_ops->reset_stats(NBL_DISP_MGT_TO_RES_PRIV(disp_mgt));
+}
+
+static int nbl_disp_get_txrx_xstats_cnt(void *priv, u16 *xstats_cnt)
+{
+ struct nbl_dispatch_mgt *disp_mgt = (struct nbl_dispatch_mgt *)priv;
+ struct nbl_resource_ops *res_ops;
+
+ res_ops = NBL_DISP_MGT_TO_RES_OPS(disp_mgt);
+ return res_ops->get_txrx_xstats_cnt(NBL_DISP_MGT_TO_RES_PRIV(disp_mgt), xstats_cnt);
+}
+
+static int nbl_disp_get_txrx_xstats(void *priv, struct rte_eth_xstat *xstats, u16 *xstats_cnt)
+{
+ struct nbl_dispatch_mgt *disp_mgt = (struct nbl_dispatch_mgt *)priv;
+ struct nbl_resource_ops *res_ops;
+
+ res_ops = NBL_DISP_MGT_TO_RES_OPS(disp_mgt);
+ return res_ops->get_txrx_xstats(NBL_DISP_MGT_TO_RES_PRIV(disp_mgt), xstats, xstats_cnt);
+}
+
+static int nbl_disp_get_txrx_xstats_names(void *priv, struct rte_eth_xstat_name *xstats_names,
+ u16 *xstats_cnt)
+{
+ struct nbl_dispatch_mgt *disp_mgt = (struct nbl_dispatch_mgt *)priv;
+ struct nbl_resource_ops *res_ops;
+
+ res_ops = NBL_DISP_MGT_TO_RES_OPS(disp_mgt);
+ return res_ops->get_txrx_xstats_names(NBL_DISP_MGT_TO_RES_PRIV(disp_mgt),
+ xstats_names, xstats_cnt);
+}
+
+static int nbl_disp_get_hw_xstats_cnt(void *priv, u16 *xstats_cnt)
+{
+ struct nbl_dispatch_mgt *disp_mgt = (struct nbl_dispatch_mgt *)priv;
+ struct nbl_resource_ops *res_ops;
+
+ res_ops = NBL_DISP_MGT_TO_RES_OPS(disp_mgt);
+ return res_ops->get_hw_xstats_cnt(NBL_DISP_MGT_TO_RES_PRIV(disp_mgt), xstats_cnt);
+}
+
+static int nbl_disp_get_hw_xstats_names(void *priv, struct rte_eth_xstat_name *xstats_names,
+ u16 *xstats_cnt)
+{
+ struct nbl_dispatch_mgt *disp_mgt = (struct nbl_dispatch_mgt *)priv;
+ struct nbl_resource_ops *res_ops;
+
+ res_ops = NBL_DISP_MGT_TO_RES_OPS(disp_mgt);
+ return res_ops->get_hw_xstats_names(NBL_DISP_MGT_TO_RES_PRIV(disp_mgt),
+ xstats_names, xstats_cnt);
+}
+
+static void nbl_disp_get_private_stat_data(void *priv, u32 eth_id, u64 *data,
+ __rte_unused u32 data_len)
+{
+ struct nbl_dispatch_mgt *disp_mgt = (struct nbl_dispatch_mgt *)priv;
+ struct nbl_resource_ops *res_ops;
+
+ res_ops = NBL_DISP_MGT_TO_RES_OPS(disp_mgt);
+ NBL_OPS_CALL(res_ops->get_private_stat_data,
+ (NBL_DISP_MGT_TO_RES_PRIV(disp_mgt), eth_id, data));
+}
+
+static void nbl_disp_get_private_stat_data_req(void *priv, u32 eth_id, u64 *data, u32 data_len)
+{
+ struct nbl_dispatch_mgt *disp_mgt = (struct nbl_dispatch_mgt *)priv;
+ struct nbl_channel_ops *chan_ops;
+ struct nbl_chan_send_info chan_send = {0};
+ struct nbl_chan_param_get_private_stat_data param = {0};
+
+ chan_ops = NBL_DISP_MGT_TO_CHAN_OPS(disp_mgt);
+
+ param.eth_id = eth_id;
+ param.data_len = data_len;
+ NBL_CHAN_SEND(chan_send, 0, NBL_CHAN_MSG_GET_ETH_STATS, ¶m,
+ sizeof(param), data, data_len, 1);
+ chan_ops->send_msg(NBL_DISP_MGT_TO_CHAN_PRIV(disp_mgt), &chan_send);
+}
+
#define NBL_DISP_OPS_TBL \
do { \
NBL_DISP_SET_OPS(alloc_txrx_queues, nbl_disp_alloc_txrx_queues, \
@@ -859,6 +944,32 @@ do { \
NBL_DISP_SET_OPS(get_stats, nbl_disp_get_stats, \
NBL_DISP_CTRL_LVL_ALWAYS, -1, \
NULL, NULL); \
+ NBL_DISP_SET_OPS(reset_stats, nbl_disp_reset_stats, \
+ NBL_DISP_CTRL_LVL_ALWAYS, -1, \
+ NULL, NULL); \
+ NBL_DISP_SET_OPS(get_txrx_xstats_cnt, \
+ nbl_disp_get_txrx_xstats_cnt, \
+ NBL_DISP_CTRL_LVL_ALWAYS, -1, \
+ NULL, NULL); \
+ NBL_DISP_SET_OPS(get_txrx_xstats, nbl_disp_get_txrx_xstats, \
+ NBL_DISP_CTRL_LVL_ALWAYS, -1, \
+ NULL, NULL); \
+ NBL_DISP_SET_OPS(get_txrx_xstats_names, \
+ nbl_disp_get_txrx_xstats_names, \
+ NBL_DISP_CTRL_LVL_ALWAYS, -1, \
+ NULL, NULL); \
+ NBL_DISP_SET_OPS(get_hw_xstats_cnt, nbl_disp_get_hw_xstats_cnt, \
+ NBL_DISP_CTRL_LVL_ALWAYS, -1, \
+ NULL, NULL); \
+ NBL_DISP_SET_OPS(get_hw_xstats_names, \
+ nbl_disp_get_hw_xstats_names, \
+ NBL_DISP_CTRL_LVL_ALWAYS, -1, \
+ NULL, NULL); \
+ NBL_DISP_SET_OPS(get_private_stat_data, \
+ nbl_disp_get_private_stat_data, \
+ NBL_DISP_CTRL_LVL_MGT, \
+ NBL_CHAN_MSG_GET_ETH_STATS, \
+ nbl_disp_get_private_stat_data_req, NULL); \
} while (0)
/* Structure starts here, adding an op should not modify anything below */
diff --git a/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_res_leonis.c b/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_res_leonis.c
index e7036373f1..41ae423ff0 100644
--- a/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_res_leonis.c
+++ b/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_res_leonis.c
@@ -4,7 +4,120 @@
#include "nbl_res_leonis.h"
+/* store statistics names */
+struct nbl_xstats_name {
+ char name[RTE_ETH_XSTATS_NAME_SIZE];
+};
+
+static const struct nbl_xstats_name nbl_stats_strings[] = {
+ {"eth_frames_tx"},
+ {"eth_frames_tx_ok"},
+ {"eth_frames_tx_badfcs"},
+ {"eth_unicast_frames_tx_ok"},
+ {"eth_multicast_frames_tx_ok"},
+ {"eth_broadcast_frames_tx_ok"},
+ {"eth_macctrl_frames_tx_ok"},
+ {"eth_fragment_frames_tx"},
+ {"eth_fragment_frames_tx_ok"},
+ {"eth_pause_frames_tx"},
+ {"eth_pause_macctrl_frames_tx"},
+ {"eth_pfc_frames_tx"},
+ {"eth_pfc_frames_tx_prio0"},
+ {"eth_pfc_frames_tx_prio1"},
+ {"eth_pfc_frames_tx_prio2"},
+ {"eth_pfc_frames_tx_prio3"},
+ {"eth_pfc_frames_tx_prio4"},
+ {"eth_pfc_frames_tx_prio5"},
+ {"eth_pfc_frames_tx_prio6"},
+ {"eth_pfc_frames_tx_prio7"},
+ {"eth_verify_frames_tx"},
+ {"eth_respond_frames_tx"},
+ {"eth_frames_tx_64B"},
+ {"eth_frames_tx_65_to_127B"},
+ {"eth_frames_tx_128_to_255B"},
+ {"eth_frames_tx_256_to_511B"},
+ {"eth_frames_tx_512_to_1023B"},
+ {"eth_frames_tx_1024_to_1535B"},
+ {"eth_frames_tx_1536_to_2047B"},
+ {"eth_frames_tx_2048_to_MAXB"},
+ {"eth_undersize_frames_tx_goodfcs"},
+ {"eth_oversize_frames_tx_goodfcs"},
+ {"eth_undersize_frames_tx_badfcs"},
+ {"eth_oversize_frames_tx_badfcs"},
+ {"eth_octets_tx"},
+ {"eth_octets_tx_ok"},
+ {"eth_octets_tx_badfcs"},
+ {"eth_frames_rx"},
+ {"eth_frames_rx_ok"},
+ {"eth_frames_rx_badfcs"},
+ {"eth_undersize_frames_rx_goodfcs"},
+ {"eth_undersize_frames_rx_badfcs"},
+ {"eth_oversize_frames_rx_goodfcs"},
+ {"eth_oversize_frames_rx_badfcs"},
+ {"eth_frames_rx_misc_error"},
+ {"eth_frames_rx_misc_dropped"},
+ {"eth_unicast_frames_rx_ok"},
+ {"eth_multicast_frames_rx_ok"},
+ {"eth_broadcast_frames_rx_ok"},
+ {"eth_pause_frames_rx"},
+ {"eth_pfc_frames_rx"},
+ {"eth_pfc_frames_rx_prio0"},
+ {"eth_pfc_frames_rx_prio1"},
+ {"eth_pfc_frames_rx_prio2"},
+ {"eth_pfc_frames_rx_prio3"},
+ {"eth_pfc_frames_rx_prio4"},
+ {"eth_pfc_frames_rx_prio5"},
+ {"eth_pfc_frames_rx_prio6"},
+ {"eth_pfc_frames_rx_prio7"},
+ {"eth_macctrl_frames_rx"},
+ {"eth_verify_frames_rx_ok"},
+ {"eth_respond_frames_rx_ok"},
+ {"eth_fragment_frames_rx_ok"},
+ {"eth_fragment_rx_smdc_nocontext"},
+ {"eth_fragment_rx_smds_seq_error"},
+ {"eth_fragment_rx_smdc_seq_error"},
+ {"eth_fragment_rx_frag_cnt_error"},
+ {"eth_frames_assembled_ok"},
+ {"eth_frames_assembled_error"},
+ {"eth_frames_rx_64B"},
+ {"eth_frames_rx_65_to_127B"},
+ {"eth_frames_rx_128_to_255B"},
+ {"eth_frames_rx_256_to_511B"},
+ {"eth_frames_rx_512_to_1023B"},
+ {"eth_frames_rx_1024_to_1535B"},
+ {"eth_frames_rx_1536_to_2047B"},
+ {"eth_frames_rx_2048_to_MAXB"},
+ {"eth_octets_rx"},
+ {"eth_octets_rx_ok"},
+ {"eth_octets_rx_badfcs"},
+ {"eth_octets_rx_dropped"},
+};
+
+static int nbl_get_xstats_cnt(__rte_unused void *priv, u16 *xstats_cnt)
+{
+ *xstats_cnt = ARRAY_SIZE(nbl_stats_strings);
+ return 0;
+}
+
+static int nbl_get_xstats_names(__rte_unused void *priv,
+ struct rte_eth_xstat_name *xstats_names,
+ u16 *xstats_cnt)
+{
+ u32 i = 0;
+ u16 count = *xstats_cnt;
+
+ for (i = 0; i < ARRAY_SIZE(nbl_stats_strings); i++) {
+ strlcpy(xstats_names[count].name, nbl_stats_strings[i].name,
+ sizeof(nbl_stats_strings[count].name));
+ count++;
+ }
+ *xstats_cnt = count;
+ return 0;
+}
+
static struct nbl_resource_ops res_ops = {
+ .get_hw_xstats_cnt = nbl_get_xstats_cnt,
+ .get_hw_xstats_names = nbl_get_xstats_names,
};
static bool is_ops_inited;
diff --git a/drivers/net/nbl/nbl_hw/nbl_txrx.c b/drivers/net/nbl/nbl_hw/nbl_txrx.c
index 361415cd21..0436f0df88 100644
--- a/drivers/net/nbl/nbl_hw/nbl_txrx.c
+++ b/drivers/net/nbl/nbl_hw/nbl_txrx.c
@@ -538,6 +538,7 @@ nbl_res_txrx_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, u16 nb_pkts, u
txe->mbuf = tx_pkt;
data_len = tx_pkt->data_len;
+ txq->txq_stats.tx_bytes += tx_pkt->data_len;
dma_addr = rte_mbuf_data_iova(tx_pkt);
tx_desc->addr = NBL_DMA_ADDERSS_FULL_TRANSLATE(txq, dma_addr) + addr_offset;
tx_desc->len = data_len - addr_offset;
@@ -617,6 +618,8 @@ nbl_res_txrx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, u16 nb_pkts)
rx_ext_hdr = (union nbl_rx_extend_head *)((char *)rx_mbuf->buf_addr +
RTE_PKTMBUF_HEADROOM);
num_sg = rx_ext_hdr->common.num_buffers;
+ if (num_sg > 1)
+ rxq->rxq_stats.rx_multi_descs++;
rx_mbuf->nb_segs = num_sg;
rx_mbuf->data_len = rx_desc->len - rxq->exthdr_len;
@@ -644,15 +647,19 @@ nbl_res_txrx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, u16 nb_pkts)
if (--num_sg)
continue;
if (drop) {
+ rxq->rxq_stats.rx_drop_proto++;
rte_pktmbuf_free(rx_mbuf);
continue;
}
rx_pkts[nb_recv_pkts++] = rx_mbuf;
+ rxq->rxq_stats.rx_bytes += rx_mbuf->pkt_len;
}
/* BUG on dumplicate pkt free */
- if (unlikely(num_sg))
+ if (unlikely(num_sg)) {
+ rxq->rxq_stats.rx_ierror++;
rte_pktmbuf_free(rx_mbuf);
+ }
/* clean memory */
rxq->next_to_clean = desc_index;
fill_num = rxq->vq_free_cnt;
@@ -722,6 +729,105 @@ static int nbl_res_txrx_get_stats(void *priv, struct rte_eth_stats *rte_stats)
return 0;
}
+static int
+nbl_res_txrx_reset_stats(void *priv)
+{
+ struct nbl_resource_mgt *res_mgt = (struct nbl_resource_mgt *)priv;
+ struct rte_eth_dev *eth_dev = res_mgt->eth_dev;
+ struct nbl_res_rx_ring *rxq;
+ struct nbl_rxq_stats *rxq_stats;
+ struct nbl_res_tx_ring *txq;
+ struct nbl_txq_stats *txq_stats;
+ uint32_t i;
+
+ /* Add software counters. */
+ for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
+ rxq = eth_dev->data->rx_queues[i];
+ if (unlikely(rxq == NULL))
+ continue;
+
+ rxq_stats = &rxq->rxq_stats;
+ memset(rxq_stats, 0, sizeof(struct nbl_rxq_stats));
+ }
+
+ for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
+ txq = eth_dev->data->tx_queues[i];
+ if (unlikely(txq == NULL))
+ continue;
+
+ txq_stats = &txq->txq_stats;
+ memset(txq_stats, 0, sizeof(struct nbl_txq_stats));
+ }
+
+ return 0;
+}
+
+/* store statistics names */
+struct nbl_txrx_xstats_name {
+ char name[RTE_ETH_XSTATS_NAME_SIZE];
+};
+
+static const struct nbl_txrx_xstats_name nbl_stats_strings[] = {
+ {"rx_multidescs_packets"},
+ {"rx_drop_noport_packets"},
+ {"rx_drop_proto_packets"},
+};
+
+static int nbl_res_txrx_get_xstats_cnt(__rte_unused void *priv, u16 *xstats_cnt)
+{
+ *xstats_cnt = ARRAY_SIZE(nbl_stats_strings);
+ return 0;
+}
+
+static int nbl_res_txrx_get_xstats(void *priv, struct rte_eth_xstat *xstats, u16 *xstats_cnt)
+{
+ struct nbl_resource_mgt *res_mgt = (struct nbl_resource_mgt *)priv;
+ struct nbl_txrx_mgt *txrx_mgt = NBL_RES_MGT_TO_TXRX_MGT(res_mgt);
+ struct nbl_res_rx_ring *rxq;
+ uint64_t rx_multi_descs = 0, rx_drop_noport = 0, rx_drop_proto = 0;
+ unsigned int i = 0;
+ u16 count = *xstats_cnt;
+
+ /* todo: get eth stats from emp */
+ for (i = 0; i < txrx_mgt->rx_ring_num; i++) {
+ rxq = NBL_RES_MGT_TO_RX_RING(res_mgt, i);
+
+ if (unlikely(rxq == NULL))
+ return -EINVAL;
+
+ rx_multi_descs += rxq->rxq_stats.rx_multi_descs;
+ rx_drop_noport += rxq->rxq_stats.rx_drop_noport;
+ rx_drop_proto += rxq->rxq_stats.rx_drop_proto;
+ }
+
+ xstats[count].value = rx_multi_descs;
+ xstats[count].id = count;
+ xstats[count + 1].value = rx_drop_noport;
+ xstats[count + 1].id = count + 1;
+ xstats[count + 2].value = rx_drop_proto;
+ xstats[count + 2].id = count + 2;
+
+ *xstats_cnt = count + 3;
+
+ return 0;
+}
+
+static int nbl_res_txrx_get_xstats_names(__rte_unused void *priv,
+ struct rte_eth_xstat_name *xstats_names,
+ u16 *xstats_cnt)
+{
+ unsigned int i = 0;
+ u16 count = *xstats_cnt;
+
+ for (i = 0; i < ARRAY_SIZE(nbl_stats_strings); i++) {
+ strlcpy(xstats_names[count].name, nbl_stats_strings[i].name,
+ sizeof(nbl_stats_strings[count].name));
+ count++;
+ }
+ *xstats_cnt = count;
+ return 0;
+}
+
/* NBL_TXRX_SET_OPS(ops_name, func)
*
* Use X Macros to reduce setup and remove codes.
@@ -740,6 +846,10 @@ do { \
NBL_TXRX_SET_OPS(update_rx_ring, nbl_res_txrx_update_rx_ring); \
NBL_TXRX_SET_OPS(get_resource_pt_ops, nbl_res_get_pt_ops); \
NBL_TXRX_SET_OPS(get_stats, nbl_res_txrx_get_stats); \
+ NBL_TXRX_SET_OPS(reset_stats, nbl_res_txrx_reset_stats); \
+ NBL_TXRX_SET_OPS(get_txrx_xstats_cnt, nbl_res_txrx_get_xstats_cnt); \
+ NBL_TXRX_SET_OPS(get_txrx_xstats_names, nbl_res_txrx_get_xstats_names); \
+ NBL_TXRX_SET_OPS(get_txrx_xstats, nbl_res_txrx_get_xstats); \
} while (0)
/* Structure starts here, adding an op should not modify anything below */
diff --git a/drivers/net/nbl/nbl_include/nbl_def_channel.h b/drivers/net/nbl/nbl_include/nbl_def_channel.h
index ba960ebdbf..30cb14b746 100644
--- a/drivers/net/nbl/nbl_include/nbl_def_channel.h
+++ b/drivers/net/nbl/nbl_include/nbl_def_channel.h
@@ -399,6 +399,11 @@ enum nbl_chan_state {
NBL_CHAN_STATE_MAX
};
+struct nbl_chan_param_get_private_stat_data {
+ u32 eth_id;
+ u32 data_len;
+};
+
struct nbl_channel_ops {
int (*send_msg)(void *priv, struct nbl_chan_send_info *chan_send);
int (*send_ack)(void *priv, struct nbl_chan_ack_info *chan_ack);
diff --git a/drivers/net/nbl/nbl_include/nbl_def_dispatch.h b/drivers/net/nbl/nbl_include/nbl_def_dispatch.h
index 20510f7fa2..92dbc428ef 100644
--- a/drivers/net/nbl/nbl_include/nbl_def_dispatch.h
+++ b/drivers/net/nbl/nbl_include/nbl_def_dispatch.h
@@ -70,6 +70,15 @@ struct nbl_dispatch_ops {
void (*get_board_info)(void *priv, struct nbl_board_port_info *board_info);
void (*get_link_state)(void *priv, u8 eth_id, struct nbl_eth_link_info *eth_link_info);
int (*get_stats)(void *priv, struct rte_eth_stats *rte_stats);
+ int (*reset_stats)(void *priv);
+ int (*get_txrx_xstats_cnt)(void *priv, u16 *xstats_cnt);
+ int (*get_txrx_xstats)(void *priv, struct rte_eth_xstat *xstats, u16 *xstats_cnt);
+ int (*get_txrx_xstats_names)(void *priv, struct rte_eth_xstat_name *xstats_names,
+ u16 *xstats_cnt);
+ int (*get_hw_xstats_cnt)(void *priv, u16 *xstats_cnt);
+ int (*get_hw_xstats_names)(void *priv, struct rte_eth_xstat_name *xstats_names,
+ u16 *xstats_cnt);
+ void (*get_private_stat_data)(void *priv, u32 eth_id, u64 *data, u32 data_len);
void (*dummy_func)(void *priv);
};
diff --git a/drivers/net/nbl/nbl_include/nbl_def_resource.h b/drivers/net/nbl/nbl_include/nbl_def_resource.h
index da683cd957..f9864e261b 100644
--- a/drivers/net/nbl/nbl_include/nbl_def_resource.h
+++ b/drivers/net/nbl/nbl_include/nbl_def_resource.h
@@ -42,6 +42,14 @@ struct nbl_resource_ops {
void (*release_rx_ring)(void *priv, u16 queue_idx);
int (*get_stats)(void *priv, struct rte_eth_stats *rte_stats);
int (*reset_stats)(void *priv);
+ int (*get_txrx_xstats_cnt)(void *priv, u16 *xstats_cnt);
+ int (*get_txrx_xstats)(void *priv, struct rte_eth_xstat *xstats, u16 *xstats_cnt);
+ int (*get_txrx_xstats_names)(void *priv, struct rte_eth_xstat_name *xstats_names,
+ u16 *xstats_cnt);
+ int (*get_hw_xstats_cnt)(void *priv, u16 *xstats_cnt);
+ int (*get_hw_xstats_names)(void *priv, struct rte_eth_xstat_name *xstats_names,
+ u16 *xstats_cnt);
+ void (*get_private_stat_data)(void *priv, u32 eth_id, u64 *data);
void (*update_rx_ring)(void *priv, u16 queue_idx);
u16 (*get_tx_ehdr_len)(void *priv);
int (*alloc_txrx_queues)(void *priv, u16 vsi_id, u16 queue_num);
@@ -54,10 +62,6 @@ struct nbl_resource_ops {
void (*cfg_txrx_vlan)(void *priv, u16 vlan_tci, u16 vlan_proto);
int (*txrx_burst_mode_get)(void *priv, struct rte_eth_dev *dev,
struct rte_eth_burst_mode *mode, bool is_tx);
- int (*get_txrx_xstats_cnt)(void *priv, u16 *xstats_cnt);
- int (*get_txrx_xstats)(void *priv, struct rte_eth_xstat *xstats, u16 *xstats_cnt);
- int (*get_txrx_xstats_names)(void *priv, struct rte_eth_xstat_name *xstats_names,
- u16 *xstats_cnt);
int (*add_macvlan)(void *priv, u8 *mac, u16 vlan_id, u16 vsi_id);
void (*del_macvlan)(void *priv, u8 *mac, u16 vlan_id, u16 vsi_id);
int (*add_multi_rule)(void *priv, u16 vsi_id);
diff --git a/drivers/net/nbl/nbl_include/nbl_include.h b/drivers/net/nbl/nbl_include/nbl_include.h
index 06aaad09d8..3faf4b969f 100644
--- a/drivers/net/nbl/nbl_include/nbl_include.h
+++ b/drivers/net/nbl/nbl_include/nbl_include.h
@@ -58,6 +58,10 @@ typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(arr) RTE_DIM(arr)
+#endif
+
/* Used for macros to pass checkpatch */
#define NBL_NAME(x) x
#define BIT(a) (1UL << (a))
--
2.43.0
next prev parent reply other threads:[~2025-06-12 9:01 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-12 8:58 [PATCH v1 00/17] NBL PMD for Nebulamatrix NICs Kyo Liu
2025-06-12 8:58 ` [PATCH v1 01/17] net/nbl: add doc and minimum nbl build framework Kyo Liu
2025-06-12 8:58 ` [PATCH v1 02/17] net/nbl: add simple probe/remove and log module Kyo Liu
2025-06-12 17:49 ` Stephen Hemminger
2025-06-13 2:32 ` 回复:[PATCH " Kyo.Liu
2025-06-12 8:58 ` [PATCH v1 03/17] net/nbl: add PHY layer definitions and implementation Kyo Liu
2025-06-12 8:58 ` [PATCH v1 04/17] net/nbl: add Channel " Kyo Liu
2025-06-12 8:58 ` [PATCH v1 05/17] net/nbl: add Resource " Kyo Liu
2025-06-12 8:58 ` [PATCH v1 06/17] net/nbl: add Dispatch " Kyo Liu
2025-06-12 8:58 ` [PATCH v1 07/17] net/nbl: add Dev " Kyo Liu
2025-06-12 8:58 ` [PATCH v1 08/17] net/nbl: add complete device init and uninit functionality Kyo Liu
2025-06-12 8:58 ` [PATCH v1 09/17] net/nbl: add uio and vfio mode for nbl Kyo Liu
2025-06-12 8:58 ` [PATCH v1 10/17] net/nbl: bus/pci: introduce get_iova_mode for pci dev Kyo Liu
2025-06-12 17:40 ` Stephen Hemminger
2025-06-13 2:28 ` 回复:[PATCH " Kyo.Liu
2025-06-13 7:35 ` [PATCH " David Marchand
2025-06-13 15:21 ` 回复:[PATCH " Stephen Hemminger
2025-06-12 8:58 ` [PATCH v1 11/17] net/nbl: add nbl coexistence mode for nbl Kyo Liu
2025-06-12 8:58 ` [PATCH v1 12/17] net/nbl: add nbl ethdev configuration Kyo Liu
2025-06-12 8:58 ` [PATCH v1 13/17] net/nbl: add nbl device rxtx queue setup and release ops Kyo Liu
2025-06-12 8:58 ` [PATCH v1 14/17] net/nbl: add nbl device start and stop ops Kyo Liu
2025-06-12 8:58 ` [PATCH v1 15/17] net/nbl: add nbl device tx and rx burst Kyo Liu
2025-06-12 8:58 ` Kyo Liu [this message]
2025-06-12 8:58 ` [PATCH v1 17/17] net/nbl: nbl device support set mtu and promisc Kyo Liu
2025-06-12 17:35 ` [PATCH v1 00/17] NBL PMD for Nebulamatrix NICs Stephen Hemminger
2025-06-12 17:44 ` Stephen Hemminger
2025-06-13 2:31 ` 回复:[PATCH " Kyo.Liu
2025-06-12 17:46 ` [PATCH " Stephen Hemminger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250612085840.729830-17-kyo.liu@nebula-matrix.com \
--to=kyo.liu@nebula-matrix.com \
--cc=dev@dpdk.org \
--cc=dimon.zhao@nebula-matrix.com \
--cc=leon.yu@nebula-matrix.com \
--cc=sam.chen@nebula-matrix.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).