/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2018 Mellanox Technologies. */

#include "en.h"
#include "monitor_stats.h"
#include "lib/eq.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)] = {};

	MLX5_SET(arm_monitor_counter_in, in, opcode,
		 MLX5_CMD_OP_ARM_MONITOR_COUNTER);
	mlx5_cmd_exec_in(priv->mdev, arm_monitor_counter, in);
}

static void mlx5e_monitor_counters_work(struct work_struct *work)
{
	struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
					       monitor_counters_work);

	mutex_lock(&priv->state_lock);
	mlx5e_stats_update_ndo_stats(priv);
	mutex_unlock(&priv->state_lock);
	mlx5e_monitor_counter_arm(priv);
}

static int mlx5e_monitor_event_handler(struct notifier_block *nb,
				       unsigned long event, void *eqe)
{
	struct mlx5e_priv *priv = mlx5_nb_cof(nb, struct mlx5e_priv,
					      monitor_counters_nb);
	queue_work(priv->wq, &priv->monitor_counters_work);
	return NOTIFY_OK;
}

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)] = {};
	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_in(mdev, set_monitor_counter, in);
}

/* check if mlx5e_monitor_counter_supported before calling this function*/
void mlx5e_monitor_counter_init(struct mlx5e_priv *priv)
{
	INIT_WORK(&priv->monitor_counters_work, mlx5e_monitor_counters_work);
	MLX5_NB_INIT(&priv->monitor_counters_nb, mlx5e_monitor_event_handler,
		     MONITOR_COUNTER);
	mlx5_eq_notifier_register(priv->mdev, &priv->monitor_counters_nb);

	mlx5e_set_monitor_counter(priv);
	mlx5e_monitor_counter_arm(priv);
	queue_work(priv->wq, &priv->update_stats_work);
}

/* 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)] = {};

	MLX5_SET(set_monitor_counter_in, in, opcode,
		 MLX5_CMD_OP_SET_MONITOR_COUNTER);

	mlx5_cmd_exec_in(priv->mdev, set_monitor_counter, in);
	mlx5_eq_notifier_unregister(priv->mdev, &priv->monitor_counters_nb);
	cancel_work_sync(&priv->monitor_counters_work);
}
