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: Asmaa Mnebhi <asmaa@nvidia.com>
Signed-off-by: David Thompson <davthompson@nvidia.com>
Link: https://lore.kernel.org/r/20240305212137.3525-1-davthompson@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
David Thompson 2024-03-05 16:21:37 -05:00 committed by Jakub Kicinski
parent 1677293ed8
commit c223416198
2 changed files with 66 additions and 0 deletions

View file

@ -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,
};

View file

@ -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__) */