From: MD Danish Anwar <danishanwar@ti.com>
To: "David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>, Jonathan Corbet <corbet@lwn.net>,
Shuah Khan <skhan@linuxfoundation.org>,
MD Danish Anwar <danishanwar@ti.com>,
Roger Quadros <rogerq@kernel.org>,
Andrew Lunn <andrew+netdev@lunn.ch>,
Jacob Keller <jacob.e.keller@intel.com>,
"Meghana Malladi" <m-malladi@ti.com>,
David Carlier <devnexen@gmail.com>,
"Vadim Fedorenko" <vadim.fedorenko@linux.dev>,
Kevin Hao <haokexin@gmail.com>,
Himanshu Mittal <h-mittal1@ti.com>,
Hangbin Liu <liuhangbin@gmail.com>,
Markus Elfring <elfring@users.sourceforge.net>,
Fernando Fernandez Mancera <fmancera@suse.de>,
Jan Vaclav <jvaclav@redhat.com>
Cc: <netdev@vger.kernel.org>, <linux-doc@vger.kernel.org>,
<linux-kernel@vger.kernel.org>,
<linux-arm-kernel@lists.infradead.org>
Subject: [PATCH net-next v3 3/3] net: ti: icssg: Add HSR offload statistics support
Date: Mon, 8 Jun 2026 15:39:30 +0530 [thread overview]
Message-ID: <20260608100930.210149-4-danishanwar@ti.com> (raw)
In-Reply-To: <20260608100930.210149-1-danishanwar@ti.com>
Add support for exposing ICSSG HSR statistics through two interfaces:
ethtool and the standard RTM_GETSTATS / IFLA_STATS_LINK_XSTATS path.
Add a standard_stats flag to struct icssg_pa_stats and extend
icssg_all_pa_stats[] with 10 new entries:
Firmware-specific HSR counters (standard_stats=false, ethtool only):
- FW_HSR_FWD_CHECK_FAIL_DROP
- FW_HSR_HE_CHECK_FAIL_DROP
- FW_HSR_SKIP_HOST_DUP_DISCARD
IEC 62439-3 LRE counters (standard_stats=true, excluded from ethtool):
- FW_LRE_CNT_UNIQUE_RX, FW_LRE_CNT_DUPLICATE_RX, FW_LRE_CNT_MULTIPLE_RX
- FW_LRE_CNT_RX, FW_LRE_CNT_TX, FW_LRE_CNT_OWN_RX
- FW_LRE_CNT_ERRWRONGLAN
The ethtool get_strings/get_ethtool_stats callbacks skip entries with
standard_stats=true so they do not appear as ethtool counters.
ICSSG_NUM_PA_STANDARD_STATS is introduced and accounted for in
ICSSG_NUM_ETHTOOL_STATS so the sset count stays accurate.
ICSSG_NUM_PA_STATS is updated from 32 to 42.
Implement ndo_has_offload_stats() and ndo_get_offload_stats() in
emac_netdev_ops to expose the IEC 62439-3 LRE counters via the HSR
stack's RTM_GETSTATS / IFLA_STATS_LINK_XSTATS interface. The HSR stack
calls these NDOs on slave A; the callback reads PA stat registers for
both ports (MAC0 = port A, MAC1 = port B) from the shared prueth
instance and fills struct hsr_lre_stats. Port C counters are not
available in ICSSG hardware and remain at ~0ULL.
Export emac_update_hardware_stats() and emac_get_stat_by_name() as
GPL symbols so they can be called from icssg_prueth.c. Also change
emac_get_stat_by_name() return type from int to u64 and make it return
~0ULL on an unknown stat name instead of -EINVAL, consistent with the
hsr_lre_stats sentinel convention.
Add FW_HSR_FWD_CHECK_FAIL_DROP and FW_HSR_HE_CHECK_FAIL_DROP to the
rx_dropped sum in ndo_get_stats64, as these represent frames discarded
by the HSR forwarding logic.
Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
---
.../ethernet/ti/icssg_prueth.rst | 19 ++++
drivers/net/ethernet/ti/icssg/icssg_common.c | 7 +-
drivers/net/ethernet/ti/icssg/icssg_ethtool.c | 10 +-
drivers/net/ethernet/ti/icssg/icssg_prueth.c | 91 +++++++++++++++++++
drivers/net/ethernet/ti/icssg/icssg_prueth.h | 10 +-
drivers/net/ethernet/ti/icssg/icssg_stats.c | 6 +-
drivers/net/ethernet/ti/icssg/icssg_stats.h | 85 +++++++++--------
.../net/ethernet/ti/icssg/icssg_switch_map.h | 10 ++
8 files changed, 192 insertions(+), 46 deletions(-)
diff --git a/Documentation/networking/device_drivers/ethernet/ti/icssg_prueth.rst b/Documentation/networking/device_drivers/ethernet/ti/icssg_prueth.rst
index da21ddf431bbc..faa1fc18a6737 100644
--- a/Documentation/networking/device_drivers/ethernet/ti/icssg_prueth.rst
+++ b/Documentation/networking/device_drivers/ethernet/ti/icssg_prueth.rst
@@ -54,3 +54,22 @@ These statistics are as follows,
- ``FW_HOST_TX_PKT_CNT``: Number of valid packets copied by RTU0 to Tx queues
- ``FW_HOST_EGRESS_Q_PRE_OVERFLOW``: Host Egress Q (Pre-emptible) Overflow Counter
- ``FW_HOST_EGRESS_Q_EXP_OVERFLOW``: Host Egress Q (Pre-emptible) Overflow Counter
+ - ``FW_HSR_FWD_CHECK_FAIL_DROP``: Packets dropped on the HSR forwarding path due to failed checks
+ - ``FW_HSR_HE_CHECK_FAIL_DROP``: Packets dropped on the host egress path due to failed checks
+ - ``FW_HSR_SKIP_HOST_DUP_DISCARD``: Frames for which the host duplicate discard check was skipped
+
+HSR/LRE Standard Statistics
+============================
+
+When the ICSSG operates in HSR offload mode the driver exposes the IEC 62439-3
+LRE counters through the standard netlink stats interface.
+
+The following per-port (port A and port B) LRE counters are reported:
+
+ - ``lreCntTx``: Number of HSR/PRP tagged frames sent
+ - ``lreCntRx``: Number of HSR/PRP tagged frames received
+ - ``lreCntUnique``: Number of frames received with no duplicate detected
+ - ``lreCntDuplicate``: Number of frames received for which exactly one duplicate was detected
+ - ``lreCntMultiple``: Number of frames received for which more than one duplicate was detected
+ - ``lreCntOwnRx``: Number of HSR/PRP tagged frames received whose source MAC matches the node's own address
+ - ``lreCntErrWrongLan``: Number of frames received with a wrong LAN identifier (PRP only)
diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/ethernet/ti/icssg/icssg_common.c
index a28a608f9bf4b..1fcb031949535 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_common.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_common.c
@@ -1643,7 +1643,12 @@ void icssg_ndo_get_stats64(struct net_device *ndev,
emac_get_stat_by_name(emac, "FW_INF_DROP_TAGGED") +
emac_get_stat_by_name(emac, "FW_INF_DROP_PRIOTAGGED") +
emac_get_stat_by_name(emac, "FW_INF_DROP_NOTAG") +
- emac_get_stat_by_name(emac, "FW_INF_DROP_NOTMEMBER");
+ emac_get_stat_by_name(emac,
+ "FW_INF_DROP_NOTMEMBER") +
+ emac_get_stat_by_name(emac,
+ "FW_HSR_FWD_CHECK_FAIL_DROP") +
+ emac_get_stat_by_name(emac,
+ "FW_HSR_HE_CHECK_FAIL_DROP");
stats->tx_errors = ndev->stats.tx_errors;
stats->tx_dropped = ndev->stats.tx_dropped +
emac_get_stat_by_name(emac, "FW_RTU_PKT_DROP") +
diff --git a/drivers/net/ethernet/ti/icssg/icssg_ethtool.c b/drivers/net/ethernet/ti/icssg/icssg_ethtool.c
index b715af21d23ac..7a99c99aab1e8 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_ethtool.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_ethtool.c
@@ -74,7 +74,9 @@ static int emac_get_sset_count(struct net_device *ndev, int stringset)
if (emac->prueth->pa_stats)
return ICSSG_NUM_ETHTOOL_STATS;
else
- return ICSSG_NUM_ETHTOOL_STATS - ICSSG_NUM_PA_STATS;
+ return ICSSG_NUM_ETHTOOL_STATS -
+ (ICSSG_NUM_PA_STATS -
+ ICSSG_NUM_PA_STANDARD_STATS);
default:
return -EOPNOTSUPP;
}
@@ -93,7 +95,8 @@ static void emac_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
ethtool_puts(&p, icssg_all_miig_stats[i].name);
if (emac->prueth->pa_stats)
for (i = 0; i < ARRAY_SIZE(icssg_all_pa_stats); i++)
- ethtool_puts(&p, icssg_all_pa_stats[i].name);
+ if (!icssg_all_pa_stats[i].standard_stats)
+ ethtool_puts(&p, icssg_all_pa_stats[i].name);
break;
default:
break;
@@ -114,7 +117,8 @@ static void emac_get_ethtool_stats(struct net_device *ndev,
if (emac->prueth->pa_stats)
for (i = 0; i < ARRAY_SIZE(icssg_all_pa_stats); i++)
- *(data++) = emac->pa_stats[i];
+ if (!icssg_all_pa_stats[i].standard_stats)
+ *(data++) = emac->pa_stats[i];
}
static int emac_get_ts_info(struct net_device *ndev,
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
index 591be5c8056b4..bd390ccf7e450 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
@@ -14,6 +14,7 @@
#include <linux/etherdevice.h>
#include <linux/genalloc.h>
#include <linux/if_hsr.h>
+#include <linux/if_link.h>
#include <linux/if_vlan.h>
#include <linux/interrupt.h>
#include <linux/io-64-nonatomic-hi-lo.h>
@@ -1633,6 +1634,94 @@ int prueth_xsk_wakeup(struct net_device *ndev, u32 qid, u32 flags)
return 0;
}
+/**
+ * prueth_ndo_get_offload_stats - Fill standard LRE counters from ICSSG.
+ * @attr_id: Stats attribute ID; only IFLA_STATS_LINK_XSTATS is handled.
+ * @dev: Slave net_device (port A) whose offload stats are requested.
+ * @sp: Output pointer; cast to struct hsr_lre_stats *.
+ *
+ * Called by the HSR stack via ndo_get_offload_stats on the slave A device.
+ * Fetches the per-port PA stat register snapshots for port A and port B,
+ * and fills the IEC-62439-3 per-port LRE counters. Port C (interlink)
+ * counters are not available in ICSSG hardware and remain at ~0ULL.
+ *
+ * Return: 0 on success, -EOPNOTSUPP if the device does not support
+ * HSR offload statistics for the requested attribute.
+ */
+static int prueth_ndo_get_offload_stats(int attr_id,
+ const struct net_device *dev,
+ void *sp)
+{
+ struct hsr_lre_stats *stats = sp;
+ struct prueth_emac *emac0;
+ struct prueth_emac *emac1;
+ struct prueth_emac *emac = netdev_priv(dev);
+ struct prueth *prueth = emac->prueth;
+
+ if (attr_id != IFLA_STATS_LINK_XSTATS)
+ return -EOPNOTSUPP;
+
+ if (!prueth->is_hsr_offload_mode)
+ return -EOPNOTSUPP;
+
+ emac0 = prueth->emac[PRUETH_MAC0];
+ emac1 = prueth->emac[PRUETH_MAC1];
+
+ if (!prueth->pa_stats)
+ return -EOPNOTSUPP;
+
+ /* Initialise all fields to ~0ULL ("unsupported"); only port A and B
+ * counters are filled — port C and aggregate counters are not
+ * available in ICSSG hardware.
+ */
+ memset(stats, 0xff, sizeof(*stats));
+
+ emac_update_hardware_stats(emac0);
+ stats->cnt_tx_a =
+ emac_get_stat_by_name(emac0, "FW_LRE_CNT_TX");
+ stats->cnt_rx_a =
+ emac_get_stat_by_name(emac0, "FW_LRE_CNT_RX");
+ stats->cnt_unique_a =
+ emac_get_stat_by_name(emac0, "FW_LRE_CNT_UNIQUE_RX");
+ stats->cnt_duplicate_a =
+ emac_get_stat_by_name(emac0, "FW_LRE_CNT_DUPLICATE_RX");
+ stats->cnt_multi_a =
+ emac_get_stat_by_name(emac0, "FW_LRE_CNT_MULTIPLE_RX");
+ stats->cnt_own_rx_a =
+ emac_get_stat_by_name(emac0, "FW_LRE_CNT_OWN_RX");
+ /* lreCntErrWrongLan is PRP only */
+ stats->cnt_err_wrong_lan_a =
+ emac_get_stat_by_name(emac0, "FW_LRE_CNT_ERRWRONGLAN");
+
+ emac_update_hardware_stats(emac1);
+ stats->cnt_tx_b =
+ emac_get_stat_by_name(emac1, "FW_LRE_CNT_TX");
+ stats->cnt_rx_b =
+ emac_get_stat_by_name(emac1, "FW_LRE_CNT_RX");
+ stats->cnt_unique_b =
+ emac_get_stat_by_name(emac1, "FW_LRE_CNT_UNIQUE_RX");
+ stats->cnt_duplicate_b =
+ emac_get_stat_by_name(emac1, "FW_LRE_CNT_DUPLICATE_RX");
+ stats->cnt_multi_b =
+ emac_get_stat_by_name(emac1, "FW_LRE_CNT_MULTIPLE_RX");
+ stats->cnt_own_rx_b =
+ emac_get_stat_by_name(emac1, "FW_LRE_CNT_OWN_RX");
+ stats->cnt_err_wrong_lan_b =
+ emac_get_stat_by_name(emac1, "FW_LRE_CNT_ERRWRONGLAN");
+
+ return 0;
+}
+
+static bool prueth_ndo_has_offload_stats(const struct net_device *dev,
+ int attr_id)
+{
+ struct prueth_emac *emac = netdev_priv(dev);
+ struct prueth *prueth = emac->prueth;
+
+ return attr_id == IFLA_STATS_LINK_XSTATS &&
+ prueth->is_hsr_offload_mode && prueth->pa_stats;
+}
+
static const struct net_device_ops emac_netdev_ops = {
.ndo_open = emac_ndo_open,
.ndo_stop = emac_ndo_stop,
@@ -1652,6 +1741,8 @@ static const struct net_device_ops emac_netdev_ops = {
.ndo_hwtstamp_get = icssg_ndo_get_ts_config,
.ndo_hwtstamp_set = icssg_ndo_set_ts_config,
.ndo_xsk_wakeup = prueth_xsk_wakeup,
+ .ndo_has_offload_stats = prueth_ndo_has_offload_stats,
+ .ndo_get_offload_stats = prueth_ndo_get_offload_stats,
};
static int prueth_netdev_init(struct prueth *prueth,
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
index df93d15c5b786..d6c221e897924 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
@@ -57,12 +57,14 @@
#define ICSSG_MAX_RFLOWS 8 /* per slice */
-#define ICSSG_NUM_PA_STATS 32
+#define ICSSG_NUM_PA_STATS 42
#define ICSSG_NUM_MIIG_STATS 60
/* Number of ICSSG related stats */
#define ICSSG_NUM_STATS (ICSSG_NUM_MIIG_STATS + ICSSG_NUM_PA_STATS)
-#define ICSSG_NUM_STANDARD_STATS 31
-#define ICSSG_NUM_ETHTOOL_STATS (ICSSG_NUM_STATS - ICSSG_NUM_STANDARD_STATS)
+#define ICSSG_NUM_STANDARD_STATS 31
+#define ICSSG_NUM_PA_STANDARD_STATS 7
+#define ICSSG_NUM_ETHTOOL_STATS (ICSSG_NUM_STATS - ICSSG_NUM_STANDARD_STATS - \
+ ICSSG_NUM_PA_STANDARD_STATS)
#define IEP_DEFAULT_CYCLE_TIME_NS 1000000 /* 1 ms */
@@ -458,7 +460,7 @@ int emac_fdb_flow_id_updated(struct prueth_emac *emac);
void icssg_stats_work_handler(struct work_struct *work);
void emac_update_hardware_stats(struct prueth_emac *emac);
-int emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name);
+u64 emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name);
/* Common functions */
void prueth_cleanup_rx_chns(struct prueth_emac *emac,
diff --git a/drivers/net/ethernet/ti/icssg/icssg_stats.c b/drivers/net/ethernet/ti/icssg/icssg_stats.c
index 7159baa0155cf..9950d0ba899fa 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_stats.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_stats.c
@@ -62,6 +62,7 @@ void emac_update_hardware_stats(struct prueth_emac *emac)
spin_unlock(&prueth->stats_lock);
}
+EXPORT_SYMBOL_GPL(emac_update_hardware_stats);
void icssg_stats_work_handler(struct work_struct *work)
{
@@ -74,7 +75,7 @@ void icssg_stats_work_handler(struct work_struct *work)
}
EXPORT_SYMBOL_GPL(icssg_stats_work_handler);
-int emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name)
+u64 emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name)
{
int i;
@@ -91,5 +92,6 @@ int emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name)
}
netdev_err(emac->ndev, "Invalid stats %s\n", stat_name);
- return -EINVAL;
+ return ~0ULL;
}
+EXPORT_SYMBOL_GPL(emac_get_stat_by_name);
diff --git a/drivers/net/ethernet/ti/icssg/icssg_stats.h b/drivers/net/ethernet/ti/icssg/icssg_stats.h
index 6f4400d8a0f61..373debfb815cc 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_stats.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_stats.h
@@ -157,50 +157,63 @@ static const struct icssg_miig_stats icssg_all_miig_stats[] = {
static_assert(ARRAY_SIZE(icssg_all_miig_stats) == ICSSG_NUM_MIIG_STATS);
-#define ICSSG_PA_STATS(field) \
-{ \
- #field, \
- field, \
+#define ICSSG_PA_STATS(field, stats_type) \
+{ \
+ #field, \
+ field, \
+ stats_type \
}
struct icssg_pa_stats {
char name[ETH_GSTRING_LEN];
u32 offset;
+ bool standard_stats;
};
static const struct icssg_pa_stats icssg_all_pa_stats[] = {
- ICSSG_PA_STATS(FW_RTU_PKT_DROP),
- ICSSG_PA_STATS(FW_Q0_OVERFLOW),
- ICSSG_PA_STATS(FW_Q1_OVERFLOW),
- ICSSG_PA_STATS(FW_Q2_OVERFLOW),
- ICSSG_PA_STATS(FW_Q3_OVERFLOW),
- ICSSG_PA_STATS(FW_Q4_OVERFLOW),
- ICSSG_PA_STATS(FW_Q5_OVERFLOW),
- ICSSG_PA_STATS(FW_Q6_OVERFLOW),
- ICSSG_PA_STATS(FW_Q7_OVERFLOW),
- ICSSG_PA_STATS(FW_DROPPED_PKT),
- ICSSG_PA_STATS(FW_RX_ERROR),
- ICSSG_PA_STATS(FW_RX_DS_INVALID),
- ICSSG_PA_STATS(FW_TX_DROPPED_PACKET),
- ICSSG_PA_STATS(FW_TX_TS_DROPPED_PACKET),
- ICSSG_PA_STATS(FW_INF_PORT_DISABLED),
- ICSSG_PA_STATS(FW_INF_SAV),
- ICSSG_PA_STATS(FW_INF_SA_DL),
- ICSSG_PA_STATS(FW_INF_PORT_BLOCKED),
- ICSSG_PA_STATS(FW_INF_DROP_TAGGED),
- ICSSG_PA_STATS(FW_INF_DROP_PRIOTAGGED),
- ICSSG_PA_STATS(FW_INF_DROP_NOTAG),
- ICSSG_PA_STATS(FW_INF_DROP_NOTMEMBER),
- ICSSG_PA_STATS(FW_RX_EOF_SHORT_FRMERR),
- ICSSG_PA_STATS(FW_RX_B0_DROP_EARLY_EOF),
- ICSSG_PA_STATS(FW_TX_JUMBO_FRM_CUTOFF),
- ICSSG_PA_STATS(FW_RX_EXP_FRAG_Q_DROP),
- ICSSG_PA_STATS(FW_RX_FIFO_OVERRUN),
- ICSSG_PA_STATS(FW_CUT_THR_PKT),
- ICSSG_PA_STATS(FW_HOST_RX_PKT_CNT),
- ICSSG_PA_STATS(FW_HOST_TX_PKT_CNT),
- ICSSG_PA_STATS(FW_HOST_EGRESS_Q_PRE_OVERFLOW),
- ICSSG_PA_STATS(FW_HOST_EGRESS_Q_EXP_OVERFLOW),
+ /* Firmware-specific stats: exposed via ethtool -S only */
+ ICSSG_PA_STATS(FW_RTU_PKT_DROP, false),
+ ICSSG_PA_STATS(FW_Q0_OVERFLOW, false),
+ ICSSG_PA_STATS(FW_Q1_OVERFLOW, false),
+ ICSSG_PA_STATS(FW_Q2_OVERFLOW, false),
+ ICSSG_PA_STATS(FW_Q3_OVERFLOW, false),
+ ICSSG_PA_STATS(FW_Q4_OVERFLOW, false),
+ ICSSG_PA_STATS(FW_Q5_OVERFLOW, false),
+ ICSSG_PA_STATS(FW_Q6_OVERFLOW, false),
+ ICSSG_PA_STATS(FW_Q7_OVERFLOW, false),
+ ICSSG_PA_STATS(FW_DROPPED_PKT, false),
+ ICSSG_PA_STATS(FW_RX_ERROR, false),
+ ICSSG_PA_STATS(FW_RX_DS_INVALID, false),
+ ICSSG_PA_STATS(FW_TX_DROPPED_PACKET, false),
+ ICSSG_PA_STATS(FW_TX_TS_DROPPED_PACKET, false),
+ ICSSG_PA_STATS(FW_INF_PORT_DISABLED, false),
+ ICSSG_PA_STATS(FW_INF_SAV, false),
+ ICSSG_PA_STATS(FW_INF_SA_DL, false),
+ ICSSG_PA_STATS(FW_INF_PORT_BLOCKED, false),
+ ICSSG_PA_STATS(FW_INF_DROP_TAGGED, false),
+ ICSSG_PA_STATS(FW_INF_DROP_PRIOTAGGED, false),
+ ICSSG_PA_STATS(FW_INF_DROP_NOTAG, false),
+ ICSSG_PA_STATS(FW_INF_DROP_NOTMEMBER, false),
+ ICSSG_PA_STATS(FW_RX_EOF_SHORT_FRMERR, false),
+ ICSSG_PA_STATS(FW_RX_B0_DROP_EARLY_EOF, false),
+ ICSSG_PA_STATS(FW_TX_JUMBO_FRM_CUTOFF, false),
+ ICSSG_PA_STATS(FW_RX_EXP_FRAG_Q_DROP, false),
+ ICSSG_PA_STATS(FW_RX_FIFO_OVERRUN, false),
+ ICSSG_PA_STATS(FW_CUT_THR_PKT, false),
+ ICSSG_PA_STATS(FW_HOST_RX_PKT_CNT, false),
+ ICSSG_PA_STATS(FW_HOST_TX_PKT_CNT, false),
+ ICSSG_PA_STATS(FW_HOST_EGRESS_Q_PRE_OVERFLOW, false),
+ ICSSG_PA_STATS(FW_HOST_EGRESS_Q_EXP_OVERFLOW, false),
+ ICSSG_PA_STATS(FW_HSR_FWD_CHECK_FAIL_DROP, false),
+ ICSSG_PA_STATS(FW_HSR_HE_CHECK_FAIL_DROP, false),
+ ICSSG_PA_STATS(FW_HSR_SKIP_HOST_DUP_DISCARD, false),
+ ICSSG_PA_STATS(FW_LRE_CNT_UNIQUE_RX, true),
+ ICSSG_PA_STATS(FW_LRE_CNT_DUPLICATE_RX, true),
+ ICSSG_PA_STATS(FW_LRE_CNT_MULTIPLE_RX, true),
+ ICSSG_PA_STATS(FW_LRE_CNT_RX, true),
+ ICSSG_PA_STATS(FW_LRE_CNT_TX, true),
+ ICSSG_PA_STATS(FW_LRE_CNT_OWN_RX, true),
+ ICSSG_PA_STATS(FW_LRE_CNT_ERRWRONGLAN, true),
};
static_assert(ARRAY_SIZE(icssg_all_pa_stats) == ICSSG_NUM_PA_STATS);
diff --git a/drivers/net/ethernet/ti/icssg/icssg_switch_map.h b/drivers/net/ethernet/ti/icssg/icssg_switch_map.h
index 7e053b8af3ece..556facb33e0ce 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_switch_map.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_switch_map.h
@@ -266,5 +266,15 @@
#define FW_HOST_TX_PKT_CNT 0x0250
#define FW_HOST_EGRESS_Q_PRE_OVERFLOW 0x0258
#define FW_HOST_EGRESS_Q_EXP_OVERFLOW 0x0260
+#define FW_HSR_FWD_CHECK_FAIL_DROP 0x0500
+#define FW_HSR_HE_CHECK_FAIL_DROP 0x0508
+#define FW_HSR_SKIP_HOST_DUP_DISCARD 0x0510
+#define FW_LRE_CNT_UNIQUE_RX 0x0518
+#define FW_LRE_CNT_DUPLICATE_RX 0x0520
+#define FW_LRE_CNT_MULTIPLE_RX 0x0528
+#define FW_LRE_CNT_RX 0x0530
+#define FW_LRE_CNT_TX 0x0538
+#define FW_LRE_CNT_OWN_RX 0x0540
+#define FW_LRE_CNT_ERRWRONGLAN 0x0548
#endif /* __NET_TI_ICSSG_SWITCH_MAP_H */
--
2.34.1
next prev parent reply other threads:[~2026-06-08 10:09 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-08 10:09 [PATCH net-next v3 0/3] Add standard stats for HSR/PRP MD Danish Anwar
2026-06-08 10:09 ` [PATCH net-next v3 1/3] net: hsr: Add standard LRE stats via RTM_GETSTATS / IFLA_STATS_LINK_XSTATS MD Danish Anwar
2026-06-08 10:09 ` [PATCH net-next v3 2/3] net: ti: icssg: Add static_assert to guard stat array counts MD Danish Anwar
2026-06-08 10:09 ` MD Danish Anwar [this message]
2026-06-10 18:47 ` [PATCH net-next v3 0/3] Add standard stats for HSR/PRP Simon Horman
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=20260608100930.210149-4-danishanwar@ti.com \
--to=danishanwar@ti.com \
--cc=andrew+netdev@lunn.ch \
--cc=corbet@lwn.net \
--cc=davem@davemloft.net \
--cc=devnexen@gmail.com \
--cc=edumazet@google.com \
--cc=elfring@users.sourceforge.net \
--cc=fmancera@suse.de \
--cc=h-mittal1@ti.com \
--cc=haokexin@gmail.com \
--cc=horms@kernel.org \
--cc=jacob.e.keller@intel.com \
--cc=jvaclav@redhat.com \
--cc=kuba@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=liuhangbin@gmail.com \
--cc=m-malladi@ti.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=rogerq@kernel.org \
--cc=skhan@linuxfoundation.org \
--cc=vadim.fedorenko@linux.dev \
/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