drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c
Extension
.c
Size
3949 bytes
Lines
160
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct mlx5e_hv_vhca_per_ring_stats {
	u64     rx_packets;
	u64     rx_bytes;
	u64     tx_packets;
	u64     tx_bytes;
};

static void
mlx5e_hv_vhca_fill_ring_stats(struct mlx5e_priv *priv, int ch,
			      struct mlx5e_hv_vhca_per_ring_stats *data)
{
	struct mlx5e_channel_stats *stats;
	int tc;

	stats = priv->channel_stats[ch];
	data->rx_packets = stats->rq.packets;
	data->rx_bytes   = stats->rq.bytes;

	for (tc = 0; tc < priv->max_opened_tc; tc++) {
		data->tx_packets += stats->sq[tc].packets;
		data->tx_bytes   += stats->sq[tc].bytes;
	}
}

static void mlx5e_hv_vhca_fill_stats(struct mlx5e_priv *priv, void *data,
				     int buf_len)
{
	int ch, i = 0;

	for (ch = 0; ch < priv->stats_nch; ch++) {
		void *buf = data + i;

		if (WARN_ON_ONCE(buf +
				 sizeof(struct mlx5e_hv_vhca_per_ring_stats) >
				 data + buf_len))
			return;

		mlx5e_hv_vhca_fill_ring_stats(priv, ch, buf);
		i += sizeof(struct mlx5e_hv_vhca_per_ring_stats);
	}
}

static int mlx5e_hv_vhca_stats_buf_size(struct mlx5e_priv *priv)
{
	return (sizeof(struct mlx5e_hv_vhca_per_ring_stats) *
		priv->stats_nch);
}

static void mlx5e_hv_vhca_stats_work(struct work_struct *work)
{
	struct mlx5e_hv_vhca_stats_agent *sagent;
	struct mlx5_hv_vhca_agent *agent;
	struct delayed_work *dwork;
	struct mlx5e_priv *priv;
	int buf_len, rc;
	void *buf;

	dwork = to_delayed_work(work);
	sagent = container_of(dwork, struct mlx5e_hv_vhca_stats_agent, work);
	priv = container_of(sagent, struct mlx5e_priv, stats_agent);
	buf_len = mlx5e_hv_vhca_stats_buf_size(priv);
	agent = sagent->agent;
	buf = sagent->buf;

	memset(buf, 0, buf_len);
	mlx5e_hv_vhca_fill_stats(priv, buf, buf_len);

	rc = mlx5_hv_vhca_agent_write(agent, buf, buf_len);
	if (rc) {
		mlx5_core_err(priv->mdev,
			      "%s: Failed to write stats, err = %d\n",
			      __func__, rc);
		return;
	}

	if (sagent->delay)
		queue_delayed_work(priv->wq, &sagent->work, sagent->delay);
}

enum {
	MLX5_HV_VHCA_STATS_VERSION     = 1,
	MLX5_HV_VHCA_STATS_UPDATE_ONCE = 0xFFFF,
};

static void mlx5e_hv_vhca_stats_control(struct mlx5_hv_vhca_agent *agent,
					struct mlx5_hv_vhca_control_block *block)
{
	struct mlx5e_hv_vhca_stats_agent *sagent;
	struct mlx5e_priv *priv;

Annotation

Implementation Notes