Commit 2f8bc491 authored by Eyal Davidovich's avatar Eyal Davidovich Committed by Saeed Mahameed

net/mlx5e: Monitor counters commands support

new file monitor_stats.c for the new API.
add arm_monitor_counter new command support.
add set_monitor_counter new command support.

The device can monitor specific counters and provide an event to notify
when these counters are changed.
The monitoring is done in best effort manner where the minimum
notification period is 200 ms, however when the device is loaded, the
notification might be delayed.
To configure the required counters to be monitored, the
SET_MONITOR_COUNTER command shall be used with a list of counters to be
monitored.
The device firmware can monitor up to HCA_CAP.max_num_of_monitor_counters.
The configuration is done based on counter type (such as ppcnt, q counter,
etc) and additional param according to the type of counter selected.
Upon monitor counter change, the device will generate
Monitor_Counter_Change event.
The device will not generate new events unless the driver re-arms the
monitoring functionality, using the ARM_MONITOR_COUNTER command.
Signed-off-by: default avatarEyal Davidovich <eyald@mellanox.com>
Reviewed-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 75370eb0
...@@ -22,7 +22,7 @@ mlx5_core-y := main.o cmd.o debugfs.o fw.o eq.o uar.o pagealloc.o \ ...@@ -22,7 +22,7 @@ mlx5_core-y := main.o cmd.o debugfs.o fw.o eq.o uar.o pagealloc.o \
# #
mlx5_core-$(CONFIG_MLX5_CORE_EN) += en_main.o en_common.o en_fs.o en_ethtool.o \ mlx5_core-$(CONFIG_MLX5_CORE_EN) += en_main.o en_common.o en_fs.o en_ethtool.o \
en_tx.o en_rx.o en_dim.o en_txrx.o en/xdp.o en_stats.o \ en_tx.o en_rx.o en_dim.o en_txrx.o en/xdp.o en_stats.o \
en_selftest.o en/port.o en_selftest.o en/port.o en/monitor_stats.o
# #
# Netdev extra # Netdev extra
......
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2018 Mellanox Technologies. */
#include "en.h"
#include "monitor_stats.h"
/* Driver will set the following watch counters list:
* Ppcnt.802_3:
* a_in_range_length_errors Type: 0x0, Counter: 0x0, group_id = N/A
* a_out_of_range_length_field Type: 0x0, Counter: 0x1, group_id = N/A
* a_frame_too_long_errors Type: 0x0, Counter: 0x2, group_id = N/A
* a_frame_check_sequence_errors Type: 0x0, Counter: 0x3, group_id = N/A
* a_alignment_errors Type: 0x0, Counter: 0x4, group_id = N/A
* if_out_discards Type: 0x0, Counter: 0x5, group_id = N/A
* Q_Counters:
* Q[index].rx_out_of_buffer Type: 0x1, Counter: 0x4, group_id = counter_ix
*/
#define NUM_REQ_PPCNT_COUNTER_S1 MLX5_CMD_SET_MONITOR_NUM_PPCNT_COUNTER_SET1
#define NUM_REQ_Q_COUNTERS_S1 MLX5_CMD_SET_MONITOR_NUM_Q_COUNTERS_SET1
int mlx5e_monitor_counter_supported(struct mlx5e_priv *priv)
{
struct mlx5_core_dev *mdev = priv->mdev;
if (!MLX5_CAP_GEN(mdev, max_num_of_monitor_counters))
return false;
if (MLX5_CAP_PCAM_REG(mdev, ppcnt) &&
MLX5_CAP_GEN(mdev, num_ppcnt_monitor_counters) <
NUM_REQ_PPCNT_COUNTER_S1)
return false;
if (MLX5_CAP_GEN(mdev, num_q_monitor_counters) <
NUM_REQ_Q_COUNTERS_S1)
return false;
return true;
}
void mlx5e_monitor_counter_arm(struct mlx5e_priv *priv)
{
u32 in[MLX5_ST_SZ_DW(arm_monitor_counter_in)] = {};
u32 out[MLX5_ST_SZ_DW(arm_monitor_counter_out)] = {};
MLX5_SET(arm_monitor_counter_in, in, opcode,
MLX5_CMD_OP_ARM_MONITOR_COUNTER);
mlx5_cmd_exec(priv->mdev, in, sizeof(in), out, sizeof(out));
}
static int fill_monitor_counter_ppcnt_set1(int cnt, u32 *in)
{
enum mlx5_monitor_counter_ppcnt ppcnt_cnt;
for (ppcnt_cnt = 0;
ppcnt_cnt < NUM_REQ_PPCNT_COUNTER_S1;
ppcnt_cnt++, cnt++) {
MLX5_SET(set_monitor_counter_in, in,
monitor_counter[cnt].type,
MLX5_QUERY_MONITOR_CNT_TYPE_PPCNT);
MLX5_SET(set_monitor_counter_in, in,
monitor_counter[cnt].counter,
ppcnt_cnt);
}
return ppcnt_cnt;
}
static int fill_monitor_counter_q_counter_set1(int cnt, int q_counter, u32 *in)
{
MLX5_SET(set_monitor_counter_in, in,
monitor_counter[cnt].type,
MLX5_QUERY_MONITOR_CNT_TYPE_Q_COUNTER);
MLX5_SET(set_monitor_counter_in, in,
monitor_counter[cnt].counter,
MLX5_QUERY_MONITOR_Q_COUNTER_RX_OUT_OF_BUFFER);
MLX5_SET(set_monitor_counter_in, in,
monitor_counter[cnt].counter_group_id,
q_counter);
return 1;
}
/* check if mlx5e_monitor_counter_supported before calling this function*/
static void mlx5e_set_monitor_counter(struct mlx5e_priv *priv)
{
struct mlx5_core_dev *mdev = priv->mdev;
int max_num_of_counters = MLX5_CAP_GEN(mdev, max_num_of_monitor_counters);
int num_q_counters = MLX5_CAP_GEN(mdev, num_q_monitor_counters);
int num_ppcnt_counters = !MLX5_CAP_PCAM_REG(mdev, ppcnt) ? 0 :
MLX5_CAP_GEN(mdev, num_ppcnt_monitor_counters);
u32 in[MLX5_ST_SZ_DW(set_monitor_counter_in)] = {};
u32 out[MLX5_ST_SZ_DW(set_monitor_counter_out)] = {};
int q_counter = priv->q_counter;
int cnt = 0;
if (num_ppcnt_counters >= NUM_REQ_PPCNT_COUNTER_S1 &&
max_num_of_counters >= (NUM_REQ_PPCNT_COUNTER_S1 + cnt))
cnt += fill_monitor_counter_ppcnt_set1(cnt, in);
if (num_q_counters >= NUM_REQ_Q_COUNTERS_S1 &&
max_num_of_counters >= (NUM_REQ_Q_COUNTERS_S1 + cnt) &&
q_counter)
cnt += fill_monitor_counter_q_counter_set1(cnt, q_counter, in);
MLX5_SET(set_monitor_counter_in, in, num_of_counters, cnt);
MLX5_SET(set_monitor_counter_in, in, opcode,
MLX5_CMD_OP_SET_MONITOR_COUNTER);
mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
}
/* check if mlx5e_monitor_counter_supported before calling this function*/
void mlx5e_monitor_counter_init(struct mlx5e_priv *priv)
{
mlx5e_set_monitor_counter(priv);
mlx5e_monitor_counter_arm(priv);
}
/* check if mlx5e_monitor_counter_supported before calling this function*/
void mlx5e_monitor_counter_cleanup(struct mlx5e_priv *priv)
{
u32 in[MLX5_ST_SZ_DW(set_monitor_counter_in)] = {};
u32 out[MLX5_ST_SZ_DW(set_monitor_counter_out)] = {};
MLX5_SET(set_monitor_counter_in, in, num_of_counters, 0);
MLX5_SET(set_monitor_counter_in, in, opcode,
MLX5_CMD_OP_SET_MONITOR_COUNTER);
mlx5_cmd_exec(priv->mdev, in, sizeof(in), out, sizeof(out));
}
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
/* Copyright (c) 2018 Mellanox Technologies. */
#ifndef __MLX5_MONITOR_H__
#define __MLX5_MONITOR_H__
int mlx5e_monitor_counter_supported(struct mlx5e_priv *priv);
void mlx5e_monitor_counter_init(struct mlx5e_priv *priv);
void mlx5e_monitor_counter_cleanup(struct mlx5e_priv *priv);
void mlx5e_monitor_counter_arm(struct mlx5e_priv *priv);
#endif /* __MLX5_MONITOR_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment