File Index
Files and directories
Sign in
FILE

monitor_stats.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/mellanox/mlx5/core/en/monitor_stats.c C
  1/* SPDX-License-Identifier: GPL-2.0 */
  2/* Copyright (c) 2018 Mellanox Technologies. */
  3
  4#include "en.h"
  5#include "monitor_stats.h"
  6#include "lib/eq.h"
  7
  8/* Driver will set the following watch counters list:
  9 * Ppcnt.802_3:
 10 * a_in_range_length_errors      Type: 0x0, Counter:  0x0, group_id = N/A
 11 * a_out_of_range_length_field   Type: 0x0, Counter:  0x1, group_id = N/A
 12 * a_frame_too_long_errors       Type: 0x0, Counter:  0x2, group_id = N/A
 13 * a_frame_check_sequence_errors Type: 0x0, Counter:  0x3, group_id = N/A
 14 * a_alignment_errors            Type: 0x0, Counter:  0x4, group_id = N/A
 15 * if_out_discards               Type: 0x0, Counter:  0x5, group_id = N/A
 16 * Q_Counters:
 17 * Q[index].rx_out_of_buffer   Type: 0x1, Counter:  0x4, group_id = counter_ix
 18 */
 19
 20#define NUM_REQ_PPCNT_COUNTER_S1 MLX5_CMD_SET_MONITOR_NUM_PPCNT_COUNTER_SET1
 21#define NUM_REQ_Q_COUNTERS_S1    MLX5_CMD_SET_MONITOR_NUM_Q_COUNTERS_SET1
 22
 23static int mlx5e_monitor_counter_cap(struct mlx5_core_dev *mdev)
 24{
 25	if (!MLX5_CAP_GEN(mdev, max_num_of_monitor_counters))
 26		return false;
 27	if (MLX5_CAP_PCAM_REG(mdev, ppcnt) &&
 28	    MLX5_CAP_GEN(mdev, num_ppcnt_monitor_counters) <
 29	    NUM_REQ_PPCNT_COUNTER_S1)
 30		return false;
 31	if (MLX5_CAP_GEN(mdev, num_q_monitor_counters) <
 32	    NUM_REQ_Q_COUNTERS_S1)
 33		return false;
 34	return true;
 35}
 36
 37int mlx5e_monitor_counter_supported(struct mlx5e_priv *priv)
 38{
 39	struct mlx5_core_dev *pos;
 40	int i;
 41
 42	mlx5_sd_for_each_dev(i, priv->mdev, pos)
 43		if (!mlx5e_monitor_counter_cap(pos))
 44			return false;
 45	return true;
 46}
 47
 48static void mlx5e_monitor_counter_arm(struct mlx5_core_dev *mdev)
 49{
 50	u32 in[MLX5_ST_SZ_DW(arm_monitor_counter_in)] = {};
 51
 52	MLX5_SET(arm_monitor_counter_in, in, opcode,
 53		 MLX5_CMD_OP_ARM_MONITOR_COUNTER);
 54	mlx5_cmd_exec_in(mdev, arm_monitor_counter, in);
 55}
 56
 57static void mlx5e_monitor_counters_work(struct work_struct *work)
 58{
 59	struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
 60					       monitor_counters_work);
 61	struct mlx5_core_dev *pos;
 62	int i;
 63
 64	mutex_lock(&priv->state_lock);
 65	mlx5e_stats_update_ndo_stats(priv);
 66	mutex_unlock(&priv->state_lock);
 67	mlx5_sd_for_each_dev(i, priv->mdev, pos)
 68		mlx5e_monitor_counter_arm(pos);
 69}
 70
 71static int mlx5e_monitor_event_handler(struct notifier_block *nb,
 72				       unsigned long event, void *eqe)
 73{
 74	struct mlx5e_priv *priv = mlx5_nb_cof(nb, struct mlx5e_priv,
 75					      monitor_counters_nb);
 76	queue_work(priv->wq, &priv->monitor_counters_work);
 77	return NOTIFY_OK;
 78}
 79
 80static int fill_monitor_counter_ppcnt_set1(int cnt, u32 *in)
 81{
 82	enum mlx5_monitor_counter_ppcnt ppcnt_cnt;
 83
 84	for (ppcnt_cnt = 0;
 85	     ppcnt_cnt < NUM_REQ_PPCNT_COUNTER_S1;
 86	     ppcnt_cnt++, cnt++) {
 87		MLX5_SET(set_monitor_counter_in, in,
 88			 monitor_counter[cnt].type,
 89			 MLX5_QUERY_MONITOR_CNT_TYPE_PPCNT);
 90		MLX5_SET(set_monitor_counter_in, in,
 91			 monitor_counter[cnt].counter,
 92			 ppcnt_cnt);
 93	}
 94	return ppcnt_cnt;
 95}
 96
 97static int fill_monitor_counter_q_counter_set1(int cnt, int q_counter, u32 *in)
 98{
 99	MLX5_SET(set_monitor_counter_in, in,
100		 monitor_counter[cnt].type,
101		 MLX5_QUERY_MONITOR_CNT_TYPE_Q_COUNTER);
102	MLX5_SET(set_monitor_counter_in, in,
103		 monitor_counter[cnt].counter,
104		 MLX5_QUERY_MONITOR_Q_COUNTER_RX_OUT_OF_BUFFER);
105	MLX5_SET(set_monitor_counter_in, in,
106		 monitor_counter[cnt].counter_group_id,
107		 q_counter);
108	return 1;
109}
110
111/* check if mlx5e_monitor_counter_supported before calling this function*/
112static void mlx5e_set_monitor_counter(struct mlx5_core_dev *mdev, int q_counter)
113{
114	int max_num_of_counters = MLX5_CAP_GEN(mdev, max_num_of_monitor_counters);
115	int num_q_counters      = MLX5_CAP_GEN(mdev, num_q_monitor_counters);
116	int num_ppcnt_counters  = !MLX5_CAP_PCAM_REG(mdev, ppcnt) ? 0 :
117				  MLX5_CAP_GEN(mdev, num_ppcnt_monitor_counters);
118	u32 in[MLX5_ST_SZ_DW(set_monitor_counter_in)] = {};
119	int cnt	= 0;
120
121	if (num_ppcnt_counters  >=  NUM_REQ_PPCNT_COUNTER_S1 &&
122	    max_num_of_counters >= (NUM_REQ_PPCNT_COUNTER_S1 + cnt))
123		cnt += fill_monitor_counter_ppcnt_set1(cnt, in);
124
125	if (num_q_counters      >=  NUM_REQ_Q_COUNTERS_S1 &&
126	    max_num_of_counters >= (NUM_REQ_Q_COUNTERS_S1 + cnt) &&
127	    q_counter)
128		cnt += fill_monitor_counter_q_counter_set1(cnt, q_counter, in);
129
130	MLX5_SET(set_monitor_counter_in, in, num_of_counters, cnt);
131	MLX5_SET(set_monitor_counter_in, in, opcode,
132		 MLX5_CMD_OP_SET_MONITOR_COUNTER);
133
134	mlx5_cmd_exec_in(mdev, set_monitor_counter, in);
135}
136
137/* check if mlx5e_monitor_counter_supported before calling this function*/
138void mlx5e_monitor_counter_init(struct mlx5e_priv *priv)
139{
140	struct mlx5_core_dev *pos;
141	int i;
142
143	INIT_WORK(&priv->monitor_counters_work, mlx5e_monitor_counters_work);
144	MLX5_NB_INIT(&priv->monitor_counters_nb, mlx5e_monitor_event_handler,
145		     MONITOR_COUNTER);
146	mlx5_sd_for_each_dev(i, priv->mdev, pos) {
147		mlx5_eq_notifier_register(pos, &priv->monitor_counters_nb);
148		mlx5e_set_monitor_counter(pos, priv->q_counter[i]);
149		mlx5e_monitor_counter_arm(pos);
150	}
151	queue_work(priv->wq, &priv->update_stats_work);
152}
153
154/* check if mlx5e_monitor_counter_supported before calling this function*/
155void mlx5e_monitor_counter_cleanup(struct mlx5e_priv *priv)
156{
157	u32 in[MLX5_ST_SZ_DW(set_monitor_counter_in)] = {};
158	struct mlx5_core_dev *pos;
159	int i;
160
161	MLX5_SET(set_monitor_counter_in, in, opcode,
162		 MLX5_CMD_OP_SET_MONITOR_COUNTER);
163
164	mlx5_sd_for_each_dev(i, priv->mdev, pos) {
165		mlx5_cmd_exec_in(pos, set_monitor_counter, in);
166		mlx5_eq_notifier_unregister(pos, &priv->monitor_counters_nb);
167	}
168	cancel_work_sync(&priv->monitor_counters_work);
169}
~/ Read-only file preview.