Check if the pause stats are reported by HW by checking the bitmap.
Calculation is based on the order of strings in main_strings from
ethtool -S. Hopefully the semantics of these stats match the standard..

Signed-off-by: Jakub Kicinski <k...@kernel.org>
Reviewed-by: Saeed Mahameed <sae...@nvidia.com>
---
 .../net/ethernet/mellanox/mlx4/en_ethtool.c   | 19 +++++++++++++++++++
 .../net/ethernet/mellanox/mlx4/mlx4_stats.h   | 12 ++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c 
b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index b816154bc79a..23849f2b9c25 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -1106,6 +1106,24 @@ static int mlx4_en_set_pauseparam(struct net_device *dev,
        return err;
 }
 
+static void mlx4_en_get_pause_stats(struct net_device *dev,
+                                   struct ethtool_pause_stats *stats)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct bitmap_iterator it;
+
+       bitmap_iterator_init(&it, priv->stats_bitmap.bitmap, NUM_ALL_STATS);
+
+       spin_lock_bh(&priv->stats_lock);
+       if (test_bit(FLOW_PRIORITY_STATS_IDX_TX_FRAMES,
+                    priv->stats_bitmap.bitmap))
+               stats->tx_pause_frames = priv->tx_flowstats.tx_pause;
+       if (test_bit(FLOW_PRIORITY_STATS_IDX_RX_FRAMES,
+                    priv->stats_bitmap.bitmap))
+               stats->rx_pause_frames = priv->rx_flowstats.rx_pause;
+       spin_unlock_bh(&priv->stats_lock);
+}
+
 static void mlx4_en_get_pauseparam(struct net_device *dev,
                                 struct ethtool_pauseparam *pause)
 {
@@ -2138,6 +2156,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
        .set_msglevel = mlx4_en_set_msglevel,
        .get_coalesce = mlx4_en_get_coalesce,
        .set_coalesce = mlx4_en_set_coalesce,
+       .get_pause_stats = mlx4_en_get_pause_stats,
        .get_pauseparam = mlx4_en_get_pauseparam,
        .set_pauseparam = mlx4_en_set_pauseparam,
        .get_ringparam = mlx4_en_get_ringparam,
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h 
b/drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h
index 86b6051da8ec..51d4eaab6a2f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h
@@ -84,6 +84,11 @@ struct mlx4_en_flow_stats_rx {
                                         MLX4_NUM_PRIORITIES)
 };
 
+#define FLOW_PRIORITY_STATS_IDX_RX_FRAMES      (NUM_MAIN_STATS +       \
+                                                NUM_PORT_STATS +       \
+                                                NUM_PF_STATS +         \
+                                                NUM_FLOW_PRIORITY_STATS_RX)
+
 struct mlx4_en_flow_stats_tx {
        u64 tx_pause;
        u64 tx_pause_duration;
@@ -93,6 +98,13 @@ struct mlx4_en_flow_stats_tx {
                                         MLX4_NUM_PRIORITIES)
 };
 
+#define FLOW_PRIORITY_STATS_IDX_TX_FRAMES      (NUM_MAIN_STATS +       \
+                                                NUM_PORT_STATS +       \
+                                                NUM_PF_STATS +         \
+                                                NUM_FLOW_PRIORITY_STATS_RX + \
+                                                NUM_FLOW_STATS_RX +    \
+                                                NUM_FLOW_PRIORITY_STATS_TX)
+
 #define NUM_FLOW_STATS (NUM_FLOW_STATS_RX + NUM_FLOW_STATS_TX + \
                        NUM_FLOW_PRIORITY_STATS_TX + \
                        NUM_FLOW_PRIORITY_STATS_RX)
-- 
2.26.2

Reply via email to