drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c
Extension
.c
Size
8999 bytes
Lines
305
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 mlxsw_sp_counter_sub_pool {
	u64 size;
	unsigned int base_index;
	enum mlxsw_res_id entry_size_res_id;
	const char *resource_name; /* devlink resource name */
	u64 resource_id; /* devlink resource id */
	unsigned int entry_size;
	unsigned int bank_count;
	atomic_t active_entries_count;
};

struct mlxsw_sp_counter_pool {
	u64 pool_size;
	unsigned long *usage; /* Usage bitmap */
	spinlock_t counter_pool_lock; /* Protects counter pool allocations */
	atomic_t active_entries_count;
	unsigned int sub_pools_count;
	struct mlxsw_sp_counter_sub_pool sub_pools[] __counted_by(sub_pools_count);
};

static const struct mlxsw_sp_counter_sub_pool mlxsw_sp_counter_sub_pools[] = {
	[MLXSW_SP_COUNTER_SUB_POOL_FLOW] = {
		.entry_size_res_id = MLXSW_RES_ID_COUNTER_SIZE_PACKETS_BYTES,
		.resource_name = MLXSW_SP_RESOURCE_NAME_COUNTERS_FLOW,
		.resource_id = MLXSW_SP_RESOURCE_COUNTERS_FLOW,
		.bank_count = 6,
	},
	[MLXSW_SP_COUNTER_SUB_POOL_RIF] = {
		.entry_size_res_id = MLXSW_RES_ID_COUNTER_SIZE_ROUTER_BASIC,
		.resource_name = MLXSW_SP_RESOURCE_NAME_COUNTERS_RIF,
		.resource_id = MLXSW_SP_RESOURCE_COUNTERS_RIF,
		.bank_count = 2,
	}
};

static u64 mlxsw_sp_counter_sub_pool_occ_get(void *priv)
{
	const struct mlxsw_sp_counter_sub_pool *sub_pool = priv;

	return atomic_read(&sub_pool->active_entries_count);
}

static int mlxsw_sp_counter_sub_pools_init(struct mlxsw_sp *mlxsw_sp)
{
	struct mlxsw_sp_counter_pool *pool = mlxsw_sp->counter_pool;
	struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
	struct mlxsw_sp_counter_sub_pool *sub_pool;
	unsigned int base_index = 0;
	enum mlxsw_res_id res_id;
	int err;
	int i;

	for (i = 0; i < pool->sub_pools_count; i++) {
		sub_pool = &pool->sub_pools[i];
		res_id = sub_pool->entry_size_res_id;

		if (!mlxsw_core_res_valid(mlxsw_sp->core, res_id))
			return -EIO;
		sub_pool->entry_size = mlxsw_core_res_get(mlxsw_sp->core,
							  res_id);
		err = devl_resource_size_get(devlink,
					     sub_pool->resource_id,
					     &sub_pool->size);
		if (err)
			goto err_resource_size_get;

		devl_resource_occ_get_register(devlink,
					       sub_pool->resource_id,
					       mlxsw_sp_counter_sub_pool_occ_get,
					       sub_pool);

		sub_pool->base_index = base_index;
		base_index += sub_pool->size;
		atomic_set(&sub_pool->active_entries_count, 0);
	}
	return 0;

err_resource_size_get:
	for (i--; i >= 0; i--) {
		sub_pool = &pool->sub_pools[i];

		devl_resource_occ_get_unregister(devlink,
						 sub_pool->resource_id);
	}
	return err;
}

static void mlxsw_sp_counter_sub_pools_fini(struct mlxsw_sp *mlxsw_sp)
{
	struct mlxsw_sp_counter_pool *pool = mlxsw_sp->counter_pool;

Annotation

Implementation Notes