Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf678570 authored by Gal Pressman's avatar Gal Pressman Committed by David S. Miller
Browse files

net/mlx5e: Add per priority group to PPort counters



Expose counters providing information for each priority level (PCP) through
ethtool -S option and DCBNL.
This includes rx/tx bytes, frames, and pause counters.

Signed-off-by: default avatarGal Pressman <galp@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8075cb72
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -174,8 +174,14 @@ static int mlx5e_dcbnl_ieee_getpfc(struct net_device *dev,
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	struct mlx5_core_dev *mdev = priv->mdev;
	struct mlx5e_pport_stats *pstats = &priv->stats.pport;
	int i;

	pfc->pfc_cap = mlx5_max_tc(mdev) + 1;
	for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
		pfc->requests[i]    = PPORT_PER_PRIO_GET(pstats, i, tx_pause);
		pfc->indications[i] = PPORT_PER_PRIO_GET(pstats, i, rx_pause);
	}

	return mlx5_query_port_pfc(mdev, &pfc->pfc_en, NULL);
}
+48 −3
Original line number Diff line number Diff line
@@ -165,6 +165,18 @@ static const struct {
	},
};

static unsigned long mlx5e_query_pfc_combined(struct mlx5e_priv *priv)
{
	struct mlx5_core_dev *mdev = priv->mdev;
	u8 pfc_en_tx;
	u8 pfc_en_rx;
	int err;

	err = mlx5_query_port_pfc(mdev, &pfc_en_tx, &pfc_en_rx);

	return err ? 0 : pfc_en_tx | pfc_en_rx;
}

#define MLX5E_NUM_Q_CNTRS(priv) (NUM_Q_COUNTERS * (!!priv->q_counter))
#define MLX5E_NUM_RQ_STATS(priv) \
	(NUM_RQ_STATS * priv->params.num_channels * \
@@ -172,6 +184,7 @@ static const struct {
#define MLX5E_NUM_SQ_STATS(priv) \
	(NUM_SQ_STATS * priv->params.num_channels * priv->params.num_tc * \
	 test_bit(MLX5E_STATE_OPENED, &priv->state))
#define MLX5E_NUM_PFC_COUNTERS(priv) hweight8(mlx5e_query_pfc_combined(priv))

static int mlx5e_get_sset_count(struct net_device *dev, int sset)
{
@@ -183,7 +196,8 @@ static int mlx5e_get_sset_count(struct net_device *dev, int sset)
		       MLX5E_NUM_Q_CNTRS(priv) +
		       NUM_VPORT_COUNTERS + NUM_PPORT_COUNTERS +
		       MLX5E_NUM_RQ_STATS(priv) +
		       MLX5E_NUM_SQ_STATS(priv);
		       MLX5E_NUM_SQ_STATS(priv) +
		       MLX5E_NUM_PFC_COUNTERS(priv);
	/* fallthrough */
	default:
		return -EOPNOTSUPP;
@@ -192,7 +206,8 @@ static int mlx5e_get_sset_count(struct net_device *dev, int sset)

static void mlx5e_fill_stats_strings(struct mlx5e_priv *priv, uint8_t *data)
{
	int i, j, tc, idx = 0;
	int i, j, tc, prio, idx = 0;
	unsigned long pfc_combined;

	/* SW counters */
	for (i = 0; i < NUM_SW_COUNTERS; i++)
@@ -220,6 +235,21 @@ static void mlx5e_fill_stats_strings(struct mlx5e_priv *priv, uint8_t *data)
		strcpy(data + (idx++) * ETH_GSTRING_LEN,
		       pport_2819_stats_desc[i].name);

	for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
		for (i = 0; i < NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS; i++)
			sprintf(data + (idx++) * ETH_GSTRING_LEN, "prio%d_%s",
				prio,
				pport_per_prio_traffic_stats_desc[i].name);
	}

	pfc_combined = mlx5e_query_pfc_combined(priv);
	for_each_set_bit(prio, &pfc_combined, NUM_PPORT_PRIO) {
		for (i = 0; i < NUM_PPORT_PER_PRIO_PFC_COUNTERS; i++) {
			sprintf(data + (idx++) * ETH_GSTRING_LEN, "prio%d_%s",
				prio, pport_per_prio_pfc_stats_desc[i].name);
		}
	}

	if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
		return;

@@ -260,7 +290,8 @@ static void mlx5e_get_ethtool_stats(struct net_device *dev,
				    struct ethtool_stats *stats, u64 *data)
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	int i, j, tc, idx = 0;
	int i, j, tc, prio, idx = 0;
	unsigned long pfc_combined;

	if (!data)
		return;
@@ -294,6 +325,20 @@ static void mlx5e_get_ethtool_stats(struct net_device *dev,
		data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.RFC_2819_counters,
						  pport_2819_stats_desc, i);

	for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
		for (i = 0; i < NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS; i++)
			data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.per_prio_counters[prio],
						 pport_per_prio_traffic_stats_desc, i);
	}

	pfc_combined = mlx5e_query_pfc_combined(priv);
	for_each_set_bit(prio, &pfc_combined, NUM_PPORT_PRIO) {
		for (i = 0; i < NUM_PPORT_PER_PRIO_PFC_COUNTERS; i++) {
			data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.per_prio_counters[prio],
							  pport_per_prio_pfc_stats_desc, i);
		}
	}

	if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
		return;

+9 −0
Original line number Diff line number Diff line
@@ -161,6 +161,7 @@ static void mlx5e_update_pport_counters(struct mlx5e_priv *priv)
	struct mlx5e_pport_stats *pstats = &priv->stats.pport;
	struct mlx5_core_dev *mdev = priv->mdev;
	int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
	int prio;
	void *out;
	u32 *in;

@@ -182,6 +183,14 @@ static void mlx5e_update_pport_counters(struct mlx5e_priv *priv)
	MLX5_SET(ppcnt_reg, in, grp, MLX5_RFC_2819_COUNTERS_GROUP);
	mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);

	MLX5_SET(ppcnt_reg, in, grp, MLX5_PER_PRIORITY_COUNTERS_GROUP);
	for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
		out = pstats->per_prio_counters[prio];
		MLX5_SET(ppcnt_reg, in, prio_tc, prio);
		mlx5_core_access_reg(mdev, in, sz, out, sz,
				     MLX5_REG_PPCNT, 0, 0);
	}

free_out:
	kvfree(in);
}
+30 −1
Original line number Diff line number Diff line
@@ -165,11 +165,19 @@ static const struct counter_desc vport_stats_desc[] = {
#define PPORT_2819_GET(pstats, c) \
	MLX5_GET64(ppcnt_reg, pstats->RFC_2819_counters, \
		   counter_set.eth_2819_cntrs_grp_data_layout.c##_high)
#define PPORT_PER_PRIO_OFF(c) \
	MLX5_BYTE_OFF(ppcnt_reg, \
		      counter_set.eth_per_prio_grp_data_layout.c##_high)
#define PPORT_PER_PRIO_GET(pstats, prio, c) \
	MLX5_GET64(ppcnt_reg, pstats->per_prio_counters[prio], \
		   counter_set.eth_per_prio_grp_data_layout.c##_high)
#define NUM_PPORT_PRIO				8

struct mlx5e_pport_stats {
	__be64 IEEE_802_3_counters[MLX5_ST_SZ_QW(ppcnt_reg)];
	__be64 RFC_2863_counters[MLX5_ST_SZ_QW(ppcnt_reg)];
	__be64 RFC_2819_counters[MLX5_ST_SZ_QW(ppcnt_reg)];
	__be64 per_prio_counters[NUM_PPORT_PRIO][MLX5_ST_SZ_QW(ppcnt_reg)];
};

static const struct counter_desc pport_802_3_stats_desc[] = {
@@ -241,6 +249,21 @@ static const struct counter_desc pport_2819_stats_desc[] = {
		PPORT_2819_OFF(ether_stats_pkts8192to10239octets) },
};

static const struct counter_desc pport_per_prio_traffic_stats_desc[] = {
	{ "rx_octets", PPORT_PER_PRIO_OFF(rx_octets) },
	{ "rx_frames", PPORT_PER_PRIO_OFF(rx_frames) },
	{ "tx_octets", PPORT_PER_PRIO_OFF(tx_octets) },
	{ "tx_frames", PPORT_PER_PRIO_OFF(tx_frames) },
};

static const struct counter_desc pport_per_prio_pfc_stats_desc[] = {
	{ "rx_pause", PPORT_PER_PRIO_OFF(rx_pause) },
	{ "rx_pause_duration", PPORT_PER_PRIO_OFF(rx_pause_duration) },
	{ "tx_pause", PPORT_PER_PRIO_OFF(tx_pause) },
	{ "tx_pause_duration", PPORT_PER_PRIO_OFF(tx_pause_duration) },
	{ "rx_pause_transition", PPORT_PER_PRIO_OFF(rx_pause_transition) },
};

struct mlx5e_rq_stats {
	u64 packets;
	u64 bytes;
@@ -305,9 +328,15 @@ static const struct counter_desc sq_stats_desc[] = {
#define NUM_PPORT_802_3_COUNTERS	ARRAY_SIZE(pport_802_3_stats_desc)
#define NUM_PPORT_2863_COUNTERS		ARRAY_SIZE(pport_2863_stats_desc)
#define NUM_PPORT_2819_COUNTERS		ARRAY_SIZE(pport_2819_stats_desc)
#define NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS \
	ARRAY_SIZE(pport_per_prio_traffic_stats_desc)
#define NUM_PPORT_PER_PRIO_PFC_COUNTERS \
	ARRAY_SIZE(pport_per_prio_pfc_stats_desc)
#define NUM_PPORT_COUNTERS		(NUM_PPORT_802_3_COUNTERS + \
					 NUM_PPORT_2863_COUNTERS  + \
					 NUM_PPORT_2819_COUNTERS)
					 NUM_PPORT_2819_COUNTERS  + \
					 NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS * \
					 NUM_PPORT_PRIO)
#define NUM_RQ_STATS			ARRAY_SIZE(rq_stats_desc)
#define NUM_SQ_STATS			ARRAY_SIZE(sq_stats_desc)