From: Wei Fang <wei.fang@nxp.com>
To: claudiu.manoil@nxp.com, vladimir.oltean@nxp.com,
xiaoning.wang@nxp.com, andrew+netdev@lunn.ch,
davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
imx@lists.linux.dev
Subject: [PATCH net-next 5/5] net: enetc: add unstructured counters for ENETC v4
Date: Wed, 8 Apr 2026 13:58:49 +0800 [thread overview]
Message-ID: <20260408055849.1314033-6-wei.fang@nxp.com> (raw)
In-Reply-To: <20260408055849.1314033-1-wei.fang@nxp.com>
Like ENETC v1, ENETC v4 also has many non-standard counters, so these
counters are added to improve statistical coverage.
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
.../net/ethernet/freescale/enetc/enetc4_hw.h | 72 +++++++
.../ethernet/freescale/enetc/enetc_ethtool.c | 187 +++++++++++++++---
2 files changed, 234 insertions(+), 25 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_hw.h b/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
index 392992a646fb..f18437556a0e 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
@@ -64,6 +64,9 @@
#define ENETC4_PPAUONTR 0x108
#define ENETC4_PPAUOFFTR 0x10c
+/* Port ingress congestion DRa (a=0,1,2,3) discard count register */
+#define ENETC4_PICDRDCR(a) ((a) * 0x10 + 0x140)
+
/* Port Station interface promiscuous MAC mode register */
#define ENETC4_PSIPMMR 0x200
#define PSIPMMR_SI_MAC_UP(a) BIT(a) /* a = SI index */
@@ -72,6 +75,12 @@
/* Port Station interface promiscuous VLAN mode register */
#define ENETC4_PSIPVMR 0x204
+/* Port broadcast frames dropped due to MAC filtering register */
+#define ENETC4_PBFDSIR 0x208
+
+/* Port frame drop MAC source address pruning register */
+#define ENETC4_PFDMSAPR 0x20c
+
/* Port RSS key register n. n = 0,1,2,...,9 */
#define ENETC4_PRSSKR(n) ((n) * 0x4 + 0x250)
@@ -79,6 +88,12 @@
#define ENETC4_PSIMAFCAPR 0x280
#define PSIMAFCAPR_NUM_MAC_AFTE GENMASK(11, 0)
+/* Port unicast frames dropped due to MAC filtering register */
+#define ENETC4_PUFDMFR 0x284
+
+/* Port multicast frames dropped due to MAC filtering register */
+#define ENETC4_PMFDMFR 0x288
+
/* Port station interface VLAN filtering capability register */
#define ENETC4_PSIVLANFCAPR 0x2c0
#define PSIVLANFCAPR_NUM_VLAN_FTE GENMASK(11, 0)
@@ -87,6 +102,15 @@
#define ENETC4_PSIVLANFMR 0x2c4
#define PSIVLANFMR_VS BIT(0)
+/* Port unicast frames dropped VLAN filtering register */
+#define ENETC4_PUFDVFR 0x2d0
+
+/* Port multicast frames dropped VLAN filtering register */
+#define ENETC4_PMFDVFR 0x2d4
+
+/* Port broadcast frames dropped VLAN filtering register */
+#define ENETC4_PBFDVFR 0x2d8
+
/* Port Station interface a primary MAC address registers */
#define ENETC4_PSIPMAR0(a) ((a) * 0x80 + 0x2000)
#define ENETC4_PSIPMAR1(a) ((a) * 0x80 + 0x2004)
@@ -141,6 +165,18 @@
#define ENETC4_PSR 0x4104
#define PSR_RX_BUSY BIT(1)
+/* Port Rx discard count register */
+#define ENETC4_PRXDCR 0x41c0
+
+/* Port Rx discard count read-reset register */
+#define ENETC4_PRXDCRRR 0x41c4
+
+/* Port Rx discard count reason register 0 */
+#define ENETC4_PRXDCRR0 0x41c8
+
+/* Port Rx discard count reason register 1 */
+#define ENETC4_PRXDCRR1 0x41cc
+
/* Port traffic class a transmit maximum SDU register */
#define ENETC4_PTCTMSDUR(a) ((a) * 0x20 + 0x4208)
#define PTCTMSDUR_MAXSDU GENMASK(15, 0)
@@ -199,6 +235,9 @@
/* Port MAC 0/1 Receive Ethernet Octets Counter */
#define ENETC4_PM_REOCT(mac) (0x5100 + (mac) * 0x400)
+/* Port MAC 0/1 Receive Octets Counter */
+#define ENETC4_PM_ROCT(mac) (0x5108 + (mac) * 0x400)
+
/* Port MAC 0/1 Receive Alignment Error Counter Register */
#define ENETC4_PM_RALN(mac) (0x5110 + (mac) * 0x400)
@@ -211,12 +250,27 @@
/* Port MAC 0/1 Receive Frame Check Sequence Error Counter */
#define ENETC4_PM_RFCS(mac) (0x5128 + (mac) * 0x400)
+/* Port MAC 0/1 Receive VLAN Frame Counter */
+#define ENETC4_PM_RVLAN(mac) (0x5130 + (mac) * 0x400)
+
+/* Port MAC 0/1 Receive Frame Error Counter */
+#define ENETC4_PM_RERR(mac) (0x5138 + (mac) * 0x400)
+
+/* Port MAC 0/1 Receive Unicast Frame Counter */
+#define ENETC4_PM_RUCA(mac) (0x5140 + (mac) * 0x400)
+
/* Port MAC 0/1 Receive Multicast Frame Counter */
#define ENETC4_PM_RMCA(mac) (0x5148 + (mac) * 0x400)
/* Port MAC 0/1 Receive Broadcast Frame Counter */
#define ENETC4_PM_RBCA(mac) (0x5150 + (mac) * 0x400)
+/* Port MAC 0/1 Receive Dropped Packets Counter */
+#define ENETC4_PM_RDRP(mac) (0x5158 + (mac) * 0x400)
+
+/* Port MAC 0/1 Receive Packets Counter */
+#define ENETC4_PM_RPKT(mac) (0x5160 + (mac) * 0x400)
+
/* Port MAC 0/1 Receive Undersized Packet Counter */
#define ENETC4_PM_RUND(mac) (0x5168 + (mac) * 0x400)
@@ -259,21 +313,36 @@
/* Port MAC 0/1 Transmit Ethernet Octets Counter */
#define ENETC4_PM_TEOCT(mac) (0x5200 + (mac) * 0x400)
+/* Port MAC 0/1 Transmit Octets Counter */
+#define ENETC4_PM_TOCT(mac) (0x5208 + (mac) * 0x400)
+
/* Port MAC 0/1 Transmit Valid Pause Frame Counter */
#define ENETC4_PM_TXPF(mac) (0x5218 + (mac) * 0x400)
/* Port MAC 0/1 Transmit Frame Counter */
#define ENETC4_PM_TFRM(mac) (0x5220 + (mac) * 0x400)
+/* Port MAC 0/1 Transmit Frame Check Sequence Error Counter */
+#define ENETC4_PM_TFCS(mac) (0x5228 + (mac) * 0x400)
+
+/* Port MAC 0/1 Transmit VLAN Frame Counter */
+#define ENETC4_PM_TVLAN(mac) (0x5230 + (mac) * 0x400)
+
/* Port MAC 0/1 Transmit Frame Error Counter */
#define ENETC4_PM_TERR(mac) (0x5238 + (mac) * 0x400)
+/* Port MAC 0/1 Transmit Unicast Frame Counter */
+#define ENETC4_PM_TUCA(mac) (0x5240 + (mac) * 0x400)
+
/* Port MAC 0/1 Transmit Multicast Frame Counter */
#define ENETC4_PM_TMCA(mac) (0x5248 + (mac) * 0x400)
/* Port MAC 0/1 Transmit Broadcast Frame Counter */
#define ENETC4_PM_TBCA(mac) (0x5250 + (mac) * 0x400)
+/* Port MAC 0/1 Transmit Packets Counter */
+#define ENETC4_PM_TPKT(mac) (0x5260 + (mac) * 0x400)
+
/* Port MAC 0/1 Transmit Undersized Packet Counter */
#define ENETC4_PM_TUND(mac) (0x5268 + (mac) * 0x400)
@@ -316,6 +385,9 @@
/* Port MAC 0/1 Transmit Excessive Collisions Counter */
#define ENETC4_PM_TECOL(mac) (0x52f0 + (mac) * 0x400)
+/* Port MAC 0/1 Transmit Invalid Octets Counter */
+#define ENETC4_PM_TIOCT(mac) (0x52f8 + (mac) * 0x400)
+
/* Port MAC 0 Interface Mode Control Register */
#define ENETC4_PM_IF_MODE(mac) (0x5300 + (mac) * 0x400)
#define PM_IF_MODE_IFMODE GENMASK(2, 0)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
index bdc5916e4400..71f376ef1be1 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
@@ -177,6 +177,65 @@ static const struct {
{ ENETC_PICDR(3), "ICM DR3 discarded frames" },
};
+static const struct {
+ int reg;
+ char name[ETH_GSTRING_LEN] __nonstring;
+} enetc4_emac_counters[] = {
+ { ENETC4_PM_ROCT(0), "eMAC rx octets" },
+ { ENETC4_PM_RVLAN(0), "eMAC rx VLAN frames" },
+ { ENETC4_PM_RERR(0), "eMAC rx frame errors" },
+ { ENETC4_PM_RUCA(0), "eMAC rx unicast frames" },
+ { ENETC4_PM_RDRP(0), "eMAC rx dropped packets" },
+ { ENETC4_PM_RPKT(0), "eMAC rx packets" },
+ { ENETC4_PM_TOCT(0), "eMAC tx octets" },
+ { ENETC4_PM_TVLAN(0), "eMAC tx VLAN frames" },
+ { ENETC4_PM_TFCS(0), "eMAC tx fcs errors" },
+ { ENETC4_PM_TUCA(0), "eMAC tx unicast frames" },
+ { ENETC4_PM_TPKT(0), "eMAC tx packets" },
+ { ENETC4_PM_TUND(0), "eMAC tx undersized packets" },
+ { ENETC4_PM_TIOCT(0), "eMAC tx invalid octets" },
+};
+
+static const struct {
+ int reg;
+ char name[ETH_GSTRING_LEN] __nonstring;
+} enetc4_pmac_counters[] = {
+ { ENETC4_PM_ROCT(1), "pMAC rx octets" },
+ { ENETC4_PM_RVLAN(1), "pMAC rx VLAN frames" },
+ { ENETC4_PM_RERR(1), "pMAC rx frame errors" },
+ { ENETC4_PM_RUCA(1), "pMAC rx unicast frames" },
+ { ENETC4_PM_RDRP(1), "pMAC rx dropped packets" },
+ { ENETC4_PM_RPKT(1), "pMAC rx packets" },
+ { ENETC4_PM_TOCT(1), "pMAC tx octets" },
+ { ENETC4_PM_TVLAN(1), "pMAC tx VLAN frames" },
+ { ENETC4_PM_TFCS(1), "pMAC tx fcs errors" },
+ { ENETC4_PM_TUCA(1), "pMAC tx unicast frames" },
+ { ENETC4_PM_TPKT(1), "pMAC tx packets" },
+ { ENETC4_PM_TUND(1), "pMAC tx undersized packets" },
+ { ENETC4_PM_TIOCT(1), "pMAC tx invalid octets" },
+};
+
+static const struct {
+ int reg;
+ char name[ETH_GSTRING_LEN] __nonstring;
+} enetc4_port_counters[] = {
+ { ENETC4_PICDRDCR(0), "ICM DR0 discarded frames" },
+ { ENETC4_PICDRDCR(1), "ICM DR1 discarded frames" },
+ { ENETC4_PICDRDCR(2), "ICM DR2 discarded frames" },
+ { ENETC4_PICDRDCR(3), "ICM DR3 discarded frames" },
+ { ENETC4_PUFDMFR, "MAC filter discarded unicast" },
+ { ENETC4_PMFDMFR, "MAC filter discarded multicast" },
+ { ENETC4_PBFDSIR, "MAC filter discarded broadcast" },
+ { ENETC4_PFDMSAPR, "MAC SA pruning discarded frames" },
+ { ENETC4_PUFDVFR, "VLAN filter discarded unicast" },
+ { ENETC4_PMFDVFR, "VLAN filter discarded multicast" },
+ { ENETC4_PBFDVFR, "VLAN filter discarded broadcast" },
+ { ENETC4_PRXDCR, "MAC rx discarded frames" },
+ { ENETC4_PRXDCRRR, "MAC rx discard read-reset" },
+ { ENETC4_PRXDCRR0, "MAC rx discard reason 0" },
+ { ENETC4_PRXDCRR1, "MAC rx discard reason 1" },
+};
+
static const char rx_ring_stats[][ETH_GSTRING_LEN] = {
"Rx ring %2d frames",
"Rx ring %2d alloc errors",
@@ -211,15 +270,62 @@ static int enetc_get_sset_count(struct net_device *ndev, int sset)
if (!enetc_si_is_pf(si))
return len;
- len += ARRAY_SIZE(enetc_port_counters);
- len += ARRAY_SIZE(enetc_emac_counters);
+ if (is_enetc_rev1(si)) {
+ len += ARRAY_SIZE(enetc_port_counters);
+ len += ARRAY_SIZE(enetc_emac_counters);
+ if (si->hw_features & ENETC_SI_F_QBU)
+ len += ARRAY_SIZE(enetc_pmac_counters);
+ } else {
+ len += ARRAY_SIZE(enetc4_port_counters);
- if (si->hw_features & ENETC_SI_F_QBU)
- len += ARRAY_SIZE(enetc_pmac_counters);
+ if (enetc_is_pseudo_mac(si))
+ return len;
+
+ len += ARRAY_SIZE(enetc4_emac_counters);
+ if (si->hw_features & ENETC_SI_F_QBU)
+ len += ARRAY_SIZE(enetc4_pmac_counters);
+ }
return len;
}
+static void enetc_get_pf_strings(struct enetc_si *si, u8 *data)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(enetc_port_counters); i++)
+ ethtool_cpy(&data, enetc_port_counters[i].name);
+
+ for (i = 0; i < ARRAY_SIZE(enetc_emac_counters); i++)
+ ethtool_cpy(&data, enetc_emac_counters[i].name);
+
+ if (!(si->hw_features & ENETC_SI_F_QBU))
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(enetc_pmac_counters); i++)
+ ethtool_cpy(&data, enetc_pmac_counters[i].name);
+}
+
+static void enetc4_get_pf_strings(struct enetc_si *si, u8 *data)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(enetc4_port_counters); i++)
+ ethtool_cpy(&data, enetc4_port_counters[i].name);
+
+ if (enetc_is_pseudo_mac(si))
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(enetc4_emac_counters); i++)
+ ethtool_cpy(&data, enetc4_emac_counters[i].name);
+
+ if (!(si->hw_features & ENETC_SI_F_QBU))
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(enetc4_pmac_counters); i++)
+ ethtool_cpy(&data, enetc4_pmac_counters[i].name);
+}
+
static void enetc_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
{
struct enetc_ndev_priv *priv = netdev_priv(ndev);
@@ -240,20 +346,52 @@ static void enetc_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
if (!enetc_si_is_pf(si))
break;
- for (i = 0; i < ARRAY_SIZE(enetc_port_counters); i++)
- ethtool_cpy(&data, enetc_port_counters[i].name);
+ if (is_enetc_rev1(si))
+ enetc_get_pf_strings(si, data);
+ else
+ enetc4_get_pf_strings(si, data);
- for (i = 0; i < ARRAY_SIZE(enetc_emac_counters); i++)
- ethtool_cpy(&data, enetc_emac_counters[i].name);
+ break;
+ }
+}
- if (!(si->hw_features & ENETC_SI_F_QBU))
- break;
+static void enetc_pf_get_ethtool_stats(struct enetc_si *si, int *o, u64 *data)
+{
+ struct enetc_hw *hw = &si->hw;
+ int i;
- for (i = 0; i < ARRAY_SIZE(enetc_pmac_counters); i++)
- ethtool_cpy(&data, enetc_pmac_counters[i].name);
+ for (i = 0; i < ARRAY_SIZE(enetc_port_counters); i++)
+ data[(*o)++] = enetc_port_rd(hw, enetc_port_counters[i].reg);
- break;
- }
+ for (i = 0; i < ARRAY_SIZE(enetc_emac_counters); i++)
+ data[(*o)++] = enetc_port_rd64(hw, enetc_emac_counters[i].reg);
+
+ if (!(si->hw_features & ENETC_SI_F_QBU))
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(enetc_pmac_counters); i++)
+ data[(*o)++] = enetc_port_rd64(hw, enetc_pmac_counters[i].reg);
+}
+
+static void enetc4_pf_get_ethtool_stats(struct enetc_si *si, int *o, u64 *data)
+{
+ struct enetc_hw *hw = &si->hw;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(enetc4_port_counters); i++)
+ data[(*o)++] = enetc_port_rd(hw, enetc4_port_counters[i].reg);
+
+ if (enetc_is_pseudo_mac(si))
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(enetc4_emac_counters); i++)
+ data[(*o)++] = enetc_port_rd64(hw, enetc4_emac_counters[i].reg);
+
+ if (!(si->hw_features & ENETC_SI_F_QBU))
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(enetc4_pmac_counters); i++)
+ data[(*o)++] = enetc_port_rd64(hw, enetc4_pmac_counters[i].reg);
}
static void enetc_get_ethtool_stats(struct net_device *ndev,
@@ -288,17 +426,10 @@ static void enetc_get_ethtool_stats(struct net_device *ndev,
if (!enetc_si_is_pf(si))
return;
- for (i = 0; i < ARRAY_SIZE(enetc_port_counters); i++)
- data[o++] = enetc_port_rd(hw, enetc_port_counters[i].reg);
-
- for (i = 0; i < ARRAY_SIZE(enetc_emac_counters); i++)
- data[o++] = enetc_port_rd64(hw, enetc_emac_counters[i].reg);
-
- if (!(si->hw_features & ENETC_SI_F_QBU))
- return;
-
- for (i = 0; i < ARRAY_SIZE(enetc_pmac_counters); i++)
- data[o++] = enetc_port_rd64(hw, enetc_pmac_counters[i].reg);
+ if (is_enetc_rev1(si))
+ enetc_pf_get_ethtool_stats(si, &o, data);
+ else
+ enetc4_pf_get_ethtool_stats(si, &o, data);
}
static void enetc_pause_stats(struct enetc_si *si, int mac,
@@ -1438,6 +1569,9 @@ const struct ethtool_ops enetc4_ppm_ethtool_ops = {
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
ETHTOOL_COALESCE_MAX_FRAMES |
ETHTOOL_COALESCE_USE_ADAPTIVE_RX,
+ .get_sset_count = enetc_get_sset_count,
+ .get_strings = enetc_get_strings,
+ .get_ethtool_stats = enetc_get_ethtool_stats,
.get_eth_mac_stats = enetc_ppm_get_eth_mac_stats,
.get_rx_ring_count = enetc_get_rx_ring_count,
.get_rxfh_key_size = enetc_get_rxfh_key_size,
@@ -1480,6 +1614,9 @@ const struct ethtool_ops enetc4_pf_ethtool_ops = {
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
ETHTOOL_COALESCE_MAX_FRAMES |
ETHTOOL_COALESCE_USE_ADAPTIVE_RX,
+ .get_sset_count = enetc_get_sset_count,
+ .get_strings = enetc_get_strings,
+ .get_ethtool_stats = enetc_get_ethtool_stats,
.get_pause_stats = enetc_get_pause_stats,
.get_rmon_stats = enetc_get_rmon_stats,
.get_eth_ctrl_stats = enetc_get_eth_ctrl_stats,
--
2.34.1
next prev parent reply other threads:[~2026-04-08 6:24 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-08 5:58 [PATCH net-next 0/5] net: enetc: improve statistics for v1 and add statistics for v4 Wei Fang
2026-04-08 5:58 ` [PATCH net-next 1/5] net: enetc: add support for the standardized counters Wei Fang
2026-04-08 5:58 ` [PATCH net-next 2/5] net: enetc: show RX drop counters only for assigned RX rings Wei Fang
2026-04-08 5:58 ` [PATCH net-next 3/5] net: enetc: remove standardized counters from enetc_pm_counters Wei Fang
2026-04-08 5:58 ` [PATCH net-next 4/5] net: enetc: add unstructured pMAC counters for ENETC v1 Wei Fang
2026-04-08 5:58 ` Wei Fang [this message]
2026-04-12 20:20 ` [PATCH net-next 0/5] net: enetc: improve statistics for v1 and add statistics for v4 patchwork-bot+netdevbpf
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=20260408055849.1314033-6-wei.fang@nxp.com \
--to=wei.fang@nxp.com \
--cc=andrew+netdev@lunn.ch \
--cc=claudiu.manoil@nxp.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=imx@lists.linux.dev \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=vladimir.oltean@nxp.com \
--cc=xiaoning.wang@nxp.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.