From: Wei Fang Date: Wed, 8 Apr 2026 05:58:49 +0000 (+0800) Subject: net: enetc: add unstructured counters for ENETC v4 X-Git-Tag: v7.1-rc1~173^2~25^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=98a4f3d341322f3c6dd341902b419f701f3e678e;p=thirdparty%2Flinux.git net: enetc: add unstructured counters for ENETC v4 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 Link: https://patch.msgid.link/20260408055849.1314033-6-wei.fang@nxp.com Signed-off-by: Jakub Kicinski --- diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_hw.h b/drivers/net/ethernet/freescale/enetc/enetc4_hw.h index 392992a646fbc..f18437556a0ee 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 bdc5916e4400d..71f376ef1be1c 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,