Commit 868678c5 authored by Danielle Ratson's avatar Danielle Ratson Committed by David S. Miller
Browse files

mlxsw: spectrum: Register switched port analyzers (SPAN) as resource



The switch supports an enhanced switched port analyzer that enables
selecting network traffic for analysis by a network analyzer.

SPAN agents are configured and consumed whenever a tc filter is added
with a mirror action to a new destination. The destination can either be
a physical port (e.g., swp1), a VLAN device or a gretap.

Expose the maximum number of SPAN agents and their current usage to the
user.

Signed-off-by: default avatarDanielle Ratson <danieller@mellanox.com>
Acked-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f86854a2
Loading
Loading
Loading
Loading
+49 −2
Original line number Original line Diff line number Diff line
@@ -5202,14 +5202,61 @@ static int mlxsw_sp2_resources_kvd_register(struct mlxsw_core *mlxsw_core)
					 &kvd_size_params);
					 &kvd_size_params);
}
}


static int mlxsw_sp_resources_span_register(struct mlxsw_core *mlxsw_core)
{
	struct devlink *devlink = priv_to_devlink(mlxsw_core);
	struct devlink_resource_size_params span_size_params;
	u32 max_span;

	if (!MLXSW_CORE_RES_VALID(mlxsw_core, MAX_SPAN))
		return -EIO;

	max_span = MLXSW_CORE_RES_GET(mlxsw_core, MAX_SPAN);
	devlink_resource_size_params_init(&span_size_params, max_span, max_span,
					  1, DEVLINK_RESOURCE_UNIT_ENTRY);

	return devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_SPAN,
					 max_span, MLXSW_SP_RESOURCE_SPAN,
					 DEVLINK_RESOURCE_ID_PARENT_TOP,
					 &span_size_params);
}

static int mlxsw_sp1_resources_register(struct mlxsw_core *mlxsw_core)
static int mlxsw_sp1_resources_register(struct mlxsw_core *mlxsw_core)
{
{
	return mlxsw_sp1_resources_kvd_register(mlxsw_core);
	int err;

	err = mlxsw_sp1_resources_kvd_register(mlxsw_core);
	if (err)
		return err;

	err = mlxsw_sp_resources_span_register(mlxsw_core);
	if (err)
		goto err_resources_span_register;

	return 0;

err_resources_span_register:
	devlink_resources_unregister(priv_to_devlink(mlxsw_core), NULL);
	return err;
}
}


static int mlxsw_sp2_resources_register(struct mlxsw_core *mlxsw_core)
static int mlxsw_sp2_resources_register(struct mlxsw_core *mlxsw_core)
{
{
	return mlxsw_sp2_resources_kvd_register(mlxsw_core);
	int err;

	err = mlxsw_sp2_resources_kvd_register(mlxsw_core);
	if (err)
		return err;

	err = mlxsw_sp_resources_span_register(mlxsw_core);
	if (err)
		goto err_resources_span_register;

	return 0;

err_resources_span_register:
	devlink_resources_unregister(priv_to_devlink(mlxsw_core), NULL);
	return err;
}
}


static int mlxsw_sp_kvd_sizes_get(struct mlxsw_core *mlxsw_core,
static int mlxsw_sp_kvd_sizes_get(struct mlxsw_core *mlxsw_core,
+3 −0
Original line number Original line Diff line number Diff line
@@ -48,6 +48,8 @@
#define MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_CHUNKS "chunks"
#define MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_CHUNKS "chunks"
#define MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_LARGE_CHUNKS "large_chunks"
#define MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_LARGE_CHUNKS "large_chunks"


#define MLXSW_SP_RESOURCE_NAME_SPAN "span_agents"

enum mlxsw_sp_resource_id {
enum mlxsw_sp_resource_id {
	MLXSW_SP_RESOURCE_KVD = 1,
	MLXSW_SP_RESOURCE_KVD = 1,
	MLXSW_SP_RESOURCE_KVD_LINEAR,
	MLXSW_SP_RESOURCE_KVD_LINEAR,
@@ -56,6 +58,7 @@ enum mlxsw_sp_resource_id {
	MLXSW_SP_RESOURCE_KVD_LINEAR_SINGLE,
	MLXSW_SP_RESOURCE_KVD_LINEAR_SINGLE,
	MLXSW_SP_RESOURCE_KVD_LINEAR_CHUNKS,
	MLXSW_SP_RESOURCE_KVD_LINEAR_CHUNKS,
	MLXSW_SP_RESOURCE_KVD_LINEAR_LARGE_CHUNKS,
	MLXSW_SP_RESOURCE_KVD_LINEAR_LARGE_CHUNKS,
	MLXSW_SP_RESOURCE_SPAN,
};
};


struct mlxsw_sp_port;
struct mlxsw_sp_port;
+21 −0
Original line number Original line Diff line number Diff line
@@ -14,8 +14,23 @@
#include "spectrum_span.h"
#include "spectrum_span.h"
#include "spectrum_switchdev.h"
#include "spectrum_switchdev.h"


static u64 mlxsw_sp_span_occ_get(void *priv)
{
	const struct mlxsw_sp *mlxsw_sp = priv;
	u64 occ = 0;
	int i;

	for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
		if (mlxsw_sp->span.entries[i].ref_count)
			occ++;
	}

	return occ;
}

int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp)
int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp)
{
{
	struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
	int i;
	int i;


	if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_SPAN))
	if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_SPAN))
@@ -36,13 +51,19 @@ int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp)
		curr->id = i;
		curr->id = i;
	}
	}


	devlink_resource_occ_get_register(devlink, MLXSW_SP_RESOURCE_SPAN,
					  mlxsw_sp_span_occ_get, mlxsw_sp);

	return 0;
	return 0;
}
}


void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp)
void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp)
{
{
	struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
	int i;
	int i;


	devlink_resource_occ_get_unregister(devlink, MLXSW_SP_RESOURCE_SPAN);

	for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
	for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
		struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
		struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];