]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
eth: fbnic: Add pause stats support
authorMohsin Bashir <mohsin.bashr@gmail.com>
Mon, 25 Aug 2025 20:02:06 +0000 (13:02 -0700)
committerJakub Kicinski <kuba@kernel.org>
Thu, 28 Aug 2025 01:56:19 +0000 (18:56 -0700)
Add support to read pause stats for fbnic. Unlike FEC and PCS stats,
pause stats won't wrap, do not fetch them under the service task. Since,
they are exclusively accessed via the ethtool API, don't include them in
fbnic_get_hw_stats().

]# ethtool -I -a eth0
Pause parameters for eth0:
Autonegotiate: on
RX: off
TX: off
Statistics:
  tx_pause_frames: 0
  rx_pause_frames: 0

Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Link: https://patch.msgid.link/20250825200206.2357713-7-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/meta/fbnic/fbnic_csr.h
drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c
drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h
drivers/net/ethernet/meta/fbnic/fbnic_mac.c
drivers/net/ethernet/meta/fbnic/fbnic_mac.h

index 69cb73ca8bca50daeb4bff2f0549a31102e34e82..e2fffe1597e9fa07b42a2ff4df235a83f747cd9b 100644 (file)
@@ -844,6 +844,10 @@ enum {
 #define FBNIC_CSR_END_SIG              0x1184e /* CSR section delimiter */
 
 #define FBNIC_CSR_START_MAC_STAT       0x11a00
+#define FBNIC_MAC_STAT_RX_XOFF_STB_L   0x11a00         /* 0x46800 */
+#define FBNIC_MAC_STAT_RX_XOFF_STB_H   0x11a01         /* 0x46804 */
+#define FBNIC_MAC_STAT_TX_XOFF_STB_L   0x11a04         /* 0x46810 */
+#define FBNIC_MAC_STAT_TX_XOFF_STB_H   0x11a05         /* 0x46814 */
 #define FBNIC_MAC_STAT_RX_BYTE_COUNT_L 0x11a08         /* 0x46820 */
 #define FBNIC_MAC_STAT_RX_BYTE_COUNT_H 0x11a09         /* 0x46824 */
 #define FBNIC_MAC_STAT_RX_ALIGN_ERROR_L        0x11a0a         /* 0x46828 */
index 4194b30f1074816c6d585381c33bb5b59be755c2..b4ff98ee2051e3dc9ba9dd9e819d46e5b9e72cfd 100644 (file)
@@ -1641,6 +1641,22 @@ static void fbnic_set_counter(u64 *stat, struct fbnic_stat_counter *counter)
                *stat = counter->value;
 }
 
+static void
+fbnic_get_pause_stats(struct net_device *netdev,
+                     struct ethtool_pause_stats *pause_stats)
+{
+       struct fbnic_net *fbn = netdev_priv(netdev);
+       struct fbnic_mac_stats *mac_stats;
+       struct fbnic_dev *fbd = fbn->fbd;
+
+       mac_stats = &fbd->hw_stats.mac;
+
+       fbd->mac->get_pause_stats(fbd, false, &mac_stats->pause);
+
+       pause_stats->tx_pause_frames = mac_stats->pause.tx_pause_frames.value;
+       pause_stats->rx_pause_frames = mac_stats->pause.rx_pause_frames.value;
+}
+
 static void
 fbnic_get_fec_stats(struct net_device *netdev,
                    struct ethtool_fec_stats *fec_stats)
@@ -1801,6 +1817,7 @@ static const struct ethtool_ops fbnic_ethtool_ops = {
        .set_coalesce                   = fbnic_set_coalesce,
        .get_ringparam                  = fbnic_get_ringparam,
        .set_ringparam                  = fbnic_set_ringparam,
+       .get_pause_stats                = fbnic_get_pause_stats,
        .get_pauseparam                 = fbnic_phylink_get_pauseparam,
        .set_pauseparam                 = fbnic_phylink_set_pauseparam,
        .get_strings                    = fbnic_get_strings,
index 9e7becba73868828615df31d106c2d6bd351bcc8..8b9b2076beecd4bf1b0fdc4f241bf9f1bedc8b10 100644 (file)
@@ -536,6 +536,7 @@ static void fbnic_reset_hw_mac_stats(struct fbnic_dev *fbd,
        const struct fbnic_mac *mac = fbd->mac;
 
        mac->get_eth_mac_stats(fbd, true, &mac_stats->eth_mac);
+       mac->get_pause_stats(fbd, true, &mac_stats->pause);
        mac->get_eth_ctrl_stats(fbd, true, &mac_stats->eth_ctrl);
        mac->get_rmon_stats(fbd, true, &mac_stats->rmon);
 }
index baffae1868a675ca665db3f8dfd3c1906c74cff4..aa3f429a9aedaccbbcfa1c85198e8633894d1a5d 100644 (file)
@@ -50,6 +50,12 @@ struct fbnic_rmon_stats {
        struct fbnic_stat_counter hist_tx[ETHTOOL_RMON_HIST_MAX];
 };
 
+/* Note: not updated by fbnic_get_hw_stats() */
+struct fbnic_pause_stats {
+       struct fbnic_stat_counter tx_pause_frames;
+       struct fbnic_stat_counter rx_pause_frames;
+};
+
 struct fbnic_eth_mac_stats {
        struct fbnic_stat_counter FramesTransmittedOK;
        struct fbnic_stat_counter FramesReceivedOK;
@@ -73,6 +79,7 @@ struct fbnic_phy_stats {
 
 struct fbnic_mac_stats {
        struct fbnic_eth_mac_stats eth_mac;
+       struct fbnic_pause_stats pause;
        struct fbnic_eth_ctrl_stats eth_ctrl;
        struct fbnic_rmon_stats rmon;
 };
index ffdaebd4002aff8dbb266c258d957946e4318818..8f998d26b9a34a74e6bc1439a22c104178c2529e 100644 (file)
@@ -709,6 +709,16 @@ fbnic_mac_get_eth_mac_stats(struct fbnic_dev *fbd, bool reset,
                            MAC_STAT_TX_BROADCAST);
 }
 
+static void
+fbnic_mac_get_pause_stats(struct fbnic_dev *fbd, bool reset,
+                         struct fbnic_pause_stats *pause_stats)
+{
+       fbnic_mac_stat_rd64(fbd, reset, pause_stats->tx_pause_frames,
+                           MAC_STAT_TX_XOFF_STB);
+       fbnic_mac_stat_rd64(fbd, reset, pause_stats->rx_pause_frames,
+                           MAC_STAT_RX_XOFF_STB);
+}
+
 static void
 fbnic_mac_get_eth_ctrl_stats(struct fbnic_dev *fbd, bool reset,
                             struct fbnic_eth_ctrl_stats *ctrl_stats)
@@ -856,6 +866,7 @@ static const struct fbnic_mac fbnic_mac_asic = {
        .get_fec_stats = fbnic_mac_get_fec_stats,
        .get_pcs_stats = fbnic_mac_get_pcs_stats,
        .get_eth_mac_stats = fbnic_mac_get_eth_mac_stats,
+       .get_pause_stats = fbnic_mac_get_pause_stats,
        .get_eth_ctrl_stats = fbnic_mac_get_eth_ctrl_stats,
        .get_rmon_stats = fbnic_mac_get_rmon_stats,
        .link_down = fbnic_mac_link_down_asic,
index 92dd6efb920a09c1827d91c0fb67dd6b0b10e5f4..ede5ff0dae22fdff4a8479c86690c76293d7c173 100644 (file)
@@ -85,6 +85,8 @@ struct fbnic_mac {
                              struct fbnic_pcs_stats *pcs_stats);
        void (*get_eth_mac_stats)(struct fbnic_dev *fbd, bool reset,
                                  struct fbnic_eth_mac_stats *mac_stats);
+       void (*get_pause_stats)(struct fbnic_dev *fbd, bool reset,
+                               struct fbnic_pause_stats *pause_stats);
        void (*get_eth_ctrl_stats)(struct fbnic_dev *fbd, bool reset,
                                   struct fbnic_eth_ctrl_stats *ctrl_stats);
        void (*get_rmon_stats)(struct fbnic_dev *fbd, bool reset,