Commit c2234161 authored by David Thompson's avatar David Thompson Committed by Jakub Kicinski
Browse files

mlxbf_gige: add support to display pause frame counters



This patch updates the mlxbf_gige driver to support the
"get_pause_stats()" callback, which enables display of
pause frame counters via "ethtool -I -a oob_net0".

The pause frame counters are only enabled if the "counters_en"
bit is asserted in the LLU general config register. The driver
will only report stats, and thus overwrite the default stats
state of ETHTOOL_STAT_NOT_SET, if "counters_en" is asserted.

Reviewed-by: default avatarAsmaa Mnebhi <asmaa@nvidia.com>
Signed-off-by: default avatarDavid Thompson <davthompson@nvidia.com>
Link: https://lore.kernel.org/r/20240305212137.3525-1-davthompson@nvidia.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 1677293e
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -124,6 +124,41 @@ static void mlxbf_gige_get_pauseparam(struct net_device *netdev,
	pause->tx_pause = 1;
}

static bool mlxbf_gige_llu_counters_enabled(struct mlxbf_gige *priv)
{
	u32 data;

	if (priv->hw_version == MLXBF_GIGE_VERSION_BF2) {
		data = readl(priv->llu_base + MLXBF_GIGE_BF2_LLU_GENERAL_CONFIG);
		if (data & MLXBF_GIGE_BF2_LLU_COUNTERS_EN)
			return true;
	} else {
		data = readl(priv->llu_base + MLXBF_GIGE_BF3_LLU_GENERAL_CONFIG);
		if (data & MLXBF_GIGE_BF3_LLU_COUNTERS_EN)
			return true;
	}

	return false;
}

static void mlxbf_gige_get_pause_stats(struct net_device *netdev,
				       struct ethtool_pause_stats *pause_stats)
{
	struct mlxbf_gige *priv = netdev_priv(netdev);
	u64 data_lo, data_hi;

	/* Read LLU counters to provide stats only if counters are enabled */
	if (mlxbf_gige_llu_counters_enabled(priv)) {
		data_lo = readl(priv->llu_base + MLXBF_GIGE_TX_PAUSE_CNT_LO);
		data_hi = readl(priv->llu_base + MLXBF_GIGE_TX_PAUSE_CNT_HI);
		pause_stats->tx_pause_frames = (data_hi << 32) | data_lo;

		data_lo = readl(priv->llu_base + MLXBF_GIGE_RX_PAUSE_CNT_LO);
		data_hi = readl(priv->llu_base + MLXBF_GIGE_RX_PAUSE_CNT_HI);
		pause_stats->rx_pause_frames = (data_hi << 32) | data_lo;
	}
}

const struct ethtool_ops mlxbf_gige_ethtool_ops = {
	.get_link		= ethtool_op_get_link,
	.get_ringparam		= mlxbf_gige_get_ringparam,
@@ -134,6 +169,7 @@ const struct ethtool_ops mlxbf_gige_ethtool_ops = {
	.get_ethtool_stats      = mlxbf_gige_get_ethtool_stats,
	.nway_reset		= phy_ethtool_nway_reset,
	.get_pauseparam		= mlxbf_gige_get_pauseparam,
	.get_pause_stats	= mlxbf_gige_get_pause_stats,
	.get_link_ksettings	= phy_ethtool_get_link_ksettings,
	.set_link_ksettings	= phy_ethtool_set_link_ksettings,
};
+30 −0
Original line number Diff line number Diff line
@@ -99,4 +99,34 @@
#define MLXBF_GIGE_100M_IPG_SIZE                      119
#define MLXBF_GIGE_10M_IPG_SIZE                       1199

/* Offsets into OOB LLU block for pause frame counters */
#define MLXBF_GIGE_BF2_TX_PAUSE_CNT_HI                0x33d8
#define MLXBF_GIGE_BF2_TX_PAUSE_CNT_LO                0x33dc
#define MLXBF_GIGE_BF2_RX_PAUSE_CNT_HI                0x3210
#define MLXBF_GIGE_BF2_RX_PAUSE_CNT_LO                0x3214

#define MLXBF_GIGE_BF3_TX_PAUSE_CNT_HI                0x3a88
#define MLXBF_GIGE_BF3_TX_PAUSE_CNT_LO                0x3a8c
#define MLXBF_GIGE_BF3_RX_PAUSE_CNT_HI                0x38c0
#define MLXBF_GIGE_BF3_RX_PAUSE_CNT_LO                0x38c4

#define MLXBF_GIGE_TX_PAUSE_CNT_HI ((priv->hw_version == MLXBF_GIGE_VERSION_BF2) ? \
				    MLXBF_GIGE_BF2_TX_PAUSE_CNT_HI :    \
				    MLXBF_GIGE_BF3_TX_PAUSE_CNT_HI)
#define MLXBF_GIGE_TX_PAUSE_CNT_LO ((priv->hw_version == MLXBF_GIGE_VERSION_BF2) ? \
				    MLXBF_GIGE_BF2_TX_PAUSE_CNT_LO : \
				    MLXBF_GIGE_BF3_TX_PAUSE_CNT_LO)
#define MLXBF_GIGE_RX_PAUSE_CNT_HI ((priv->hw_version == MLXBF_GIGE_VERSION_BF2) ? \
				    MLXBF_GIGE_BF2_RX_PAUSE_CNT_HI : \
				    MLXBF_GIGE_BF3_RX_PAUSE_CNT_HI)
#define MLXBF_GIGE_RX_PAUSE_CNT_LO ((priv->hw_version == MLXBF_GIGE_VERSION_BF2) ? \
				    MLXBF_GIGE_BF2_RX_PAUSE_CNT_LO : \
				    MLXBF_GIGE_BF3_RX_PAUSE_CNT_LO)

#define MLXBF_GIGE_BF2_LLU_GENERAL_CONFIG             0x2110
#define MLXBF_GIGE_BF3_LLU_GENERAL_CONFIG             0x2030

#define MLXBF_GIGE_BF2_LLU_COUNTERS_EN                BIT(0)
#define MLXBF_GIGE_BF3_LLU_COUNTERS_EN                BIT(4)

#endif /* !defined(__MLXBF_GIGE_REGS_H__) */