]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: enetc: add support for the standardized counters
authorWei Fang <wei.fang@nxp.com>
Wed, 8 Apr 2026 05:58:45 +0000 (13:58 +0800)
committerJakub Kicinski <kuba@kernel.org>
Sun, 12 Apr 2026 20:03:48 +0000 (13:03 -0700)
ENETC v4 provides 64-bit counters for IEEE 802.3 basic and mandatory
managed objects, the IETF Management Information Database (MIB) package
(RFC2665), and Remote Network Monitoring (RMON) statistics. In addition,
some ENETCs support preemption, so these ENETCs have two MACs: MAC 0 is
the express MAC (eMAC), MAC 1 is the preemptible MAC (pMAC). Both MACs
support these statistics.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
Link: https://patch.msgid.link/20260408055849.1314033-2-wei.fang@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/freescale/enetc/enetc.h
drivers/net/ethernet/freescale/enetc/enetc4_hw.h
drivers/net/ethernet/freescale/enetc/enetc_ethtool.c

index aecd40aeef9c40bda79aaab807ff2535f8db9807..e663bb5e614effa307a245a3c12030460a23665f 100644 (file)
@@ -264,6 +264,8 @@ struct enetc_msg_swbd {
 };
 
 #define ENETC_REV1     0x1
+#define ENETC_REV4     0x4
+
 enum enetc_errata {
        ENETC_ERR_VLAN_ISOL     = BIT(0),
        ENETC_ERR_UCMCSWP       = BIT(1),
index 719c88ceb801a146bd07656c85507eab7d12e09e..392992a646fbc4c5634233c5f0810a92b545aa4a 100644 (file)
 #define  PM_SINGLE_STEP_OFFSET_SET(o)  FIELD_PREP(PM_SINGLE_STEP_OFFSET, o)
 #define  PM_SINGLE_STEP_EN             BIT(31)
 
+/* Port MAC 0/1 Receive Ethernet Octets Counter */
+#define ENETC4_PM_REOCT(mac)           (0x5100 + (mac) * 0x400)
+
+/* Port MAC 0/1 Receive Alignment Error Counter Register */
+#define ENETC4_PM_RALN(mac)            (0x5110 + (mac) * 0x400)
+
+/* Port MAC 0/1 Receive Valid Pause Frame Counter */
+#define ENETC4_PM_RXPF(mac)            (0x5118 + (mac) * 0x400)
+
+/* Port MAC 0/1 Receive Frame Counter */
+#define ENETC4_PM_RFRM(mac)            (0x5120 + (mac) * 0x400)
+
+/* Port MAC 0/1 Receive Frame Check Sequence Error Counter */
+#define ENETC4_PM_RFCS(mac)            (0x5128 + (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 Undersized Packet Counter */
+#define ENETC4_PM_RUND(mac)            (0x5168 + (mac) * 0x400)
+
+/* Port MAC 0/1 Receive 64-Octet Packet Counter */
+#define ENETC4_PM_R64(mac)             (0x5170 + (mac) * 0x400)
+
+/* Port MAC 0/1 Receive 65 to 127-Octet Packet Counter */
+#define ENETC4_PM_R127(mac)            (0x5178 + (mac) * 0x400)
+
+/* Port MAC 0/1 Receive 128 to 255-Octet Packet Counter */
+#define ENETC4_PM_R255(mac)            (0x5180 + (mac) * 0x400)
+
+/* Port MAC 0/1 Receive 256 to 511-Octet Packet Counter */
+#define ENETC4_PM_R511(mac)            (0x5188 + (mac) * 0x400)
+
+/* Port MAC 0/1 Receive 512 to 1023-Octet Packet Counter */
+#define ENETC4_PM_R1023(mac)           (0x5190 + (mac) * 0x400)
+
+/* Port MAC 0/1 Receive 1024 to 1522-Octet Packet Counter */
+#define ENETC4_PM_R1522(mac)           (0x5198 + (mac) * 0x400)
+
+/* Port MAC 0/1 Receive 1523 to Max-Octet Packet Counter */
+#define ENETC4_PM_R1523X(mac)          (0x51a0 + (mac) * 0x400)
+
+/* Port MAC 0/1 Receive Oversized Packet Counter */
+#define ENETC4_PM_ROVR(mac)            (0x51a8 + (mac) * 0x400)
+
+/* Port MAC 0/1 Receive Jabber Packet Counter */
+#define ENETC4_PM_RJBR(mac)            (0x51b0 + (mac) * 0x400)
+
+/* Port MAC 0/1 Receive Fragment Packet Counter */
+#define ENETC4_PM_RFRG(mac)            (0x51b8 + (mac) * 0x400)
+
+/* Port MAC 0/1 Receive Control Packet Counter */
+#define ENETC4_PM_RCNP(mac)            (0x51c0 + (mac) * 0x400)
+
+/* Port MAC 0/1 Receive Dropped Not Truncated Packets Counter */
+#define ENETC4_PM_RDRNTP(mac)          (0x51c8 + (mac) * 0x400)
+
+/* Port MAC 0/1 Transmit Ethernet Octets Counter */
+#define ENETC4_PM_TEOCT(mac)           (0x5200 + (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 Error Counter */
+#define ENETC4_PM_TERR(mac)            (0x5238 + (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 Undersized Packet Counter */
+#define ENETC4_PM_TUND(mac)            (0x5268 + (mac) * 0x400)
+
+/* Port MAC 0/1 Transmit 64-Octet Packet Counter */
+#define ENETC4_PM_T64(mac)             (0x5270 + (mac) * 0x400)
+
+/* Port MAC 0/1 Transmit 65 to 127-Octet Packet Counter */
+#define ENETC4_PM_T127(mac)            (0x5278 + (mac) * 0x400)
+
+/* Port MAC 0/1 Transmit 128 to 255-Octet Packet Counter */
+#define ENETC4_PM_T255(mac)            (0x5280 + (mac) * 0x400)
+
+/* Port MAC 0/1 Transmit 256 to 511-Octet Packet Counter */
+#define ENETC4_PM_T511(mac)            (0x5288 + (mac) * 0x400)
+
+/* Port MAC 0/1 Transmit 512 to 1023-Octet Packet Counter */
+#define ENETC4_PM_T1023(mac)           (0x5290 + (mac) * 0x400)
+
+/* Port MAC 0/1 Transmit 1024 to 1522-Octet Packet Counter */
+#define ENETC4_PM_T1522(mac)           (0x5298 + (mac) * 0x400)
+
+/* Port MAC 0/1 Transmit 1523 to TX_MTU-Octet Packet Counter */
+#define ENETC4_PM_T1523X(mac)          (0x52a0 + (mac) * 0x400)
+
+/* Port MAC 0/1 Transmit Control Packet Counter */
+#define ENETC4_PM_TCNP(mac)            (0x52c0 + (mac) * 0x400)
+
+/* Port MAC 0/1 Transmit Deferred Packet Counter */
+#define ENETC4_PM_TDFR(mac)            (0x52d0 + (mac) * 0x400)
+
+/* Port MAC 0/1 Transmit Multiple Collisions Counter */
+#define ENETC4_PM_TMCOL(mac)           (0x52d8 + (mac) * 0x400)
+
+/* Port MAC 0/1 Transmit Single Collision */
+#define ENETC4_PM_TSCOL(mac)           (0x52e0 + (mac) * 0x400)
+
+/* Port MAC 0/1 Transmit Late Collision Counter */
+#define ENETC4_PM_TLCOL(mac)           (0x52e8 + (mac) * 0x400)
+
+/* Port MAC 0/1 Transmit Excessive Collisions Counter */
+#define ENETC4_PM_TECOL(mac)           (0x52f0 + (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)
index 7c17acaf7a380b1d4a1cf0911e04fa83fdebaf66..c30a119e91420d6508c2849c0940720e8bec9397 100644 (file)
@@ -320,27 +320,38 @@ static void enetc_get_ethtool_stats(struct net_device *ndev,
                data[o++] = enetc_port_rd64(hw, enetc_pm_counters[i].reg);
 }
 
-static void enetc_pause_stats(struct enetc_hw *hw, int mac,
+static void enetc_pause_stats(struct enetc_si *si, int mac,
                              struct ethtool_pause_stats *pause_stats)
 {
-       pause_stats->tx_pause_frames = enetc_port_rd64(hw, ENETC_PM_TXPF(mac));
-       pause_stats->rx_pause_frames = enetc_port_rd64(hw, ENETC_PM_RXPF(mac));
+       struct enetc_hw *hw = &si->hw;
+
+       switch (si->pdev->revision) {
+       case ENETC_REV1:
+               pause_stats->tx_pause_frames = enetc_port_rd64(hw, ENETC_PM_TXPF(mac));
+               pause_stats->rx_pause_frames = enetc_port_rd64(hw, ENETC_PM_RXPF(mac));
+               break;
+       case ENETC_REV4:
+               pause_stats->tx_pause_frames = enetc_port_rd64(hw, ENETC4_PM_TXPF(mac));
+               pause_stats->rx_pause_frames = enetc_port_rd64(hw, ENETC4_PM_RXPF(mac));
+               break;
+       default:
+               break;
+       }
 }
 
 static void enetc_get_pause_stats(struct net_device *ndev,
                                  struct ethtool_pause_stats *pause_stats)
 {
        struct enetc_ndev_priv *priv = netdev_priv(ndev);
-       struct enetc_hw *hw = &priv->si->hw;
        struct enetc_si *si = priv->si;
 
        switch (pause_stats->src) {
        case ETHTOOL_MAC_STATS_SRC_EMAC:
-               enetc_pause_stats(hw, 0, pause_stats);
+               enetc_pause_stats(si, 0, pause_stats);
                break;
        case ETHTOOL_MAC_STATS_SRC_PMAC:
                if (si->hw_features & ENETC_SI_F_QBU)
-                       enetc_pause_stats(hw, 1, pause_stats);
+                       enetc_pause_stats(si, 1, pause_stats);
                break;
        case ETHTOOL_MAC_STATS_SRC_AGGREGATE:
                ethtool_aggregate_pause_stats(ndev, pause_stats);
@@ -371,11 +382,45 @@ static void enetc_mac_stats(struct enetc_hw *hw, int mac,
        s->BroadcastFramesReceivedOK = enetc_port_rd64(hw, ENETC_PM_RBCA(mac));
 }
 
-static void enetc_ctrl_stats(struct enetc_hw *hw, int mac,
+static void enetc4_mac_stats(struct enetc_hw *hw, int mac,
+                            struct ethtool_eth_mac_stats *s)
+{
+       s->FramesTransmittedOK = enetc_port_rd64(hw, ENETC4_PM_TFRM(mac));
+       s->SingleCollisionFrames = enetc_port_rd64(hw, ENETC4_PM_TSCOL(mac));
+       s->MultipleCollisionFrames = enetc_port_rd64(hw, ENETC4_PM_TMCOL(mac));
+       s->FramesReceivedOK = enetc_port_rd64(hw, ENETC4_PM_RFRM(mac));
+       s->FrameCheckSequenceErrors = enetc_port_rd64(hw, ENETC4_PM_RFCS(mac));
+       s->AlignmentErrors = enetc_port_rd64(hw, ENETC4_PM_RALN(mac));
+       s->OctetsTransmittedOK = enetc_port_rd64(hw, ENETC4_PM_TEOCT(mac));
+       s->FramesWithDeferredXmissions = enetc_port_rd64(hw, ENETC4_PM_TDFR(mac));
+       s->LateCollisions = enetc_port_rd64(hw, ENETC4_PM_TLCOL(mac));
+       s->FramesAbortedDueToXSColls = enetc_port_rd64(hw, ENETC4_PM_TECOL(mac));
+       s->FramesLostDueToIntMACXmitError = enetc_port_rd64(hw, ENETC4_PM_TERR(mac));
+       s->OctetsReceivedOK = enetc_port_rd64(hw, ENETC4_PM_REOCT(mac));
+       s->FramesLostDueToIntMACRcvError = enetc_port_rd64(hw, ENETC4_PM_RDRNTP(mac));
+       s->MulticastFramesXmittedOK = enetc_port_rd64(hw, ENETC4_PM_TMCA(mac));
+       s->BroadcastFramesXmittedOK = enetc_port_rd64(hw, ENETC4_PM_TBCA(mac));
+       s->MulticastFramesReceivedOK = enetc_port_rd64(hw, ENETC4_PM_RMCA(mac));
+       s->BroadcastFramesReceivedOK = enetc_port_rd64(hw, ENETC4_PM_RBCA(mac));
+}
+
+static void enetc_ctrl_stats(struct enetc_si *si, int mac,
                             struct ethtool_eth_ctrl_stats *s)
 {
-       s->MACControlFramesTransmitted = enetc_port_rd64(hw, ENETC_PM_TCNP(mac));
-       s->MACControlFramesReceived = enetc_port_rd64(hw, ENETC_PM_RCNP(mac));
+       struct enetc_hw *hw = &si->hw;
+
+       switch (si->pdev->revision) {
+       case ENETC_REV1:
+               s->MACControlFramesTransmitted = enetc_port_rd64(hw, ENETC_PM_TCNP(mac));
+               s->MACControlFramesReceived = enetc_port_rd64(hw, ENETC_PM_RCNP(mac));
+               break;
+       case ENETC_REV4:
+               s->MACControlFramesTransmitted = enetc_port_rd64(hw, ENETC4_PM_TCNP(mac));
+               s->MACControlFramesReceived = enetc_port_rd64(hw, ENETC4_PM_RCNP(mac));
+               break;
+       default:
+               break;
+       }
 }
 
 static const struct ethtool_rmon_hist_range enetc_rmon_ranges[] = {
@@ -414,20 +459,61 @@ static void enetc_rmon_stats(struct enetc_hw *hw, int mac,
        s->hist_tx[6] = enetc_port_rd64(hw, ENETC_PM_T1523X(mac));
 }
 
+static void enetc4_rmon_stats(struct enetc_hw *hw, int mac,
+                             struct ethtool_rmon_stats *s)
+{
+       s->undersize_pkts = enetc_port_rd64(hw, ENETC4_PM_RUND(mac));
+       s->oversize_pkts = enetc_port_rd64(hw, ENETC4_PM_ROVR(mac));
+       s->fragments = enetc_port_rd64(hw, ENETC4_PM_RFRG(mac));
+       s->jabbers = enetc_port_rd64(hw, ENETC4_PM_RJBR(mac));
+
+       s->hist[0] = enetc_port_rd64(hw, ENETC4_PM_R64(mac));
+       s->hist[1] = enetc_port_rd64(hw, ENETC4_PM_R127(mac));
+       s->hist[2] = enetc_port_rd64(hw, ENETC4_PM_R255(mac));
+       s->hist[3] = enetc_port_rd64(hw, ENETC4_PM_R511(mac));
+       s->hist[4] = enetc_port_rd64(hw, ENETC4_PM_R1023(mac));
+       s->hist[5] = enetc_port_rd64(hw, ENETC4_PM_R1522(mac));
+       s->hist[6] = enetc_port_rd64(hw, ENETC4_PM_R1523X(mac));
+
+       s->hist_tx[0] = enetc_port_rd64(hw, ENETC4_PM_T64(mac));
+       s->hist_tx[1] = enetc_port_rd64(hw, ENETC4_PM_T127(mac));
+       s->hist_tx[2] = enetc_port_rd64(hw, ENETC4_PM_T255(mac));
+       s->hist_tx[3] = enetc_port_rd64(hw, ENETC4_PM_T511(mac));
+       s->hist_tx[4] = enetc_port_rd64(hw, ENETC4_PM_T1023(mac));
+       s->hist_tx[5] = enetc_port_rd64(hw, ENETC4_PM_T1522(mac));
+       s->hist_tx[6] = enetc_port_rd64(hw, ENETC4_PM_T1523X(mac));
+}
+
+static void enetc_get_mac_stats(struct enetc_si *si, int mac,
+                               struct ethtool_eth_mac_stats *mac_stats)
+{
+       struct enetc_hw *hw = &si->hw;
+
+       switch (si->pdev->revision) {
+       case ENETC_REV1:
+               enetc_mac_stats(hw, mac, mac_stats);
+               break;
+       case ENETC_REV4:
+               enetc4_mac_stats(hw, mac, mac_stats);
+               break;
+       default:
+               break;
+       }
+}
+
 static void enetc_get_eth_mac_stats(struct net_device *ndev,
                                    struct ethtool_eth_mac_stats *mac_stats)
 {
        struct enetc_ndev_priv *priv = netdev_priv(ndev);
-       struct enetc_hw *hw = &priv->si->hw;
        struct enetc_si *si = priv->si;
 
        switch (mac_stats->src) {
        case ETHTOOL_MAC_STATS_SRC_EMAC:
-               enetc_mac_stats(hw, 0, mac_stats);
+               enetc_get_mac_stats(si, 0, mac_stats);
                break;
        case ETHTOOL_MAC_STATS_SRC_PMAC:
                if (si->hw_features & ENETC_SI_F_QBU)
-                       enetc_mac_stats(hw, 1, mac_stats);
+                       enetc_get_mac_stats(si, 1, mac_stats);
                break;
        case ETHTOOL_MAC_STATS_SRC_AGGREGATE:
                ethtool_aggregate_mac_stats(ndev, mac_stats);
@@ -481,16 +567,15 @@ static void enetc_get_eth_ctrl_stats(struct net_device *ndev,
                                     struct ethtool_eth_ctrl_stats *ctrl_stats)
 {
        struct enetc_ndev_priv *priv = netdev_priv(ndev);
-       struct enetc_hw *hw = &priv->si->hw;
        struct enetc_si *si = priv->si;
 
        switch (ctrl_stats->src) {
        case ETHTOOL_MAC_STATS_SRC_EMAC:
-               enetc_ctrl_stats(hw, 0, ctrl_stats);
+               enetc_ctrl_stats(si, 0, ctrl_stats);
                break;
        case ETHTOOL_MAC_STATS_SRC_PMAC:
                if (si->hw_features & ENETC_SI_F_QBU)
-                       enetc_ctrl_stats(hw, 1, ctrl_stats);
+                       enetc_ctrl_stats(si, 1, ctrl_stats);
                break;
        case ETHTOOL_MAC_STATS_SRC_AGGREGATE:
                ethtool_aggregate_ctrl_stats(ndev, ctrl_stats);
@@ -498,23 +583,39 @@ static void enetc_get_eth_ctrl_stats(struct net_device *ndev,
        }
 }
 
+static void enetc_get_mac_rmon_stats(struct enetc_si *si, int mac,
+                                    struct ethtool_rmon_stats *rmon_stats)
+{
+       struct enetc_hw *hw = &si->hw;
+
+       switch (si->pdev->revision) {
+       case ENETC_REV1:
+               enetc_rmon_stats(hw, mac, rmon_stats);
+               break;
+       case ENETC_REV4:
+               enetc4_rmon_stats(hw, mac, rmon_stats);
+               break;
+       default:
+               break;
+       }
+}
+
 static void enetc_get_rmon_stats(struct net_device *ndev,
                                 struct ethtool_rmon_stats *rmon_stats,
                                 const struct ethtool_rmon_hist_range **ranges)
 {
        struct enetc_ndev_priv *priv = netdev_priv(ndev);
-       struct enetc_hw *hw = &priv->si->hw;
        struct enetc_si *si = priv->si;
 
        *ranges = enetc_rmon_ranges;
 
        switch (rmon_stats->src) {
        case ETHTOOL_MAC_STATS_SRC_EMAC:
-               enetc_rmon_stats(hw, 0, rmon_stats);
+               enetc_get_mac_rmon_stats(si, 0, rmon_stats);
                break;
        case ETHTOOL_MAC_STATS_SRC_PMAC:
                if (si->hw_features & ENETC_SI_F_QBU)
-                       enetc_rmon_stats(hw, 1, rmon_stats);
+                       enetc_get_mac_rmon_stats(si, 1, rmon_stats);
                break;
        case ETHTOOL_MAC_STATS_SRC_AGGREGATE:
                ethtool_aggregate_rmon_stats(ndev, rmon_stats);
@@ -1398,6 +1499,10 @@ const struct ethtool_ops enetc4_pf_ethtool_ops = {
        .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
                                     ETHTOOL_COALESCE_MAX_FRAMES |
                                     ETHTOOL_COALESCE_USE_ADAPTIVE_RX,
+       .get_pause_stats = enetc_get_pause_stats,
+       .get_rmon_stats = enetc_get_rmon_stats,
+       .get_eth_ctrl_stats = enetc_get_eth_ctrl_stats,
+       .get_eth_mac_stats = enetc_get_eth_mac_stats,
        .get_ringparam = enetc_get_ringparam,
        .get_coalesce = enetc_get_coalesce,
        .set_coalesce = enetc_set_coalesce,