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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlxsw/spectrum1_kvdl.c
Extension
.c
Size
12173 bytes
Lines
427
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_sp1_kvdl_part_info {
	unsigned int part_index;
	unsigned int start_index;
	unsigned int end_index;
	unsigned int alloc_size;
	enum mlxsw_sp_resource_id resource_id;
};

enum mlxsw_sp1_kvdl_part_id {
	MLXSW_SP1_KVDL_PART_ID_SINGLE,
	MLXSW_SP1_KVDL_PART_ID_CHUNKS,
	MLXSW_SP1_KVDL_PART_ID_LARGE_CHUNKS,
};

#define MLXSW_SP1_KVDL_PART_INFO(id)				\
[MLXSW_SP1_KVDL_PART_ID_##id] = {				\
	.start_index = MLXSW_SP1_KVDL_##id##_BASE,		\
	.end_index = MLXSW_SP1_KVDL_##id##_END,			\
	.alloc_size = MLXSW_SP1_KVDL_##id##_ALLOC_SIZE,		\
	.resource_id = MLXSW_SP_RESOURCE_KVD_LINEAR_##id,	\
}

static const struct mlxsw_sp1_kvdl_part_info mlxsw_sp1_kvdl_parts_info[] = {
	MLXSW_SP1_KVDL_PART_INFO(SINGLE),
	MLXSW_SP1_KVDL_PART_INFO(CHUNKS),
	MLXSW_SP1_KVDL_PART_INFO(LARGE_CHUNKS),
};

#define MLXSW_SP1_KVDL_PARTS_INFO_LEN ARRAY_SIZE(mlxsw_sp1_kvdl_parts_info)

struct mlxsw_sp1_kvdl_part {
	struct mlxsw_sp1_kvdl_part_info info;
	unsigned long usage[];	/* Entries */
};

struct mlxsw_sp1_kvdl {
	struct mlxsw_sp1_kvdl_part *parts[MLXSW_SP1_KVDL_PARTS_INFO_LEN];
};

static struct mlxsw_sp1_kvdl_part *
mlxsw_sp1_kvdl_alloc_size_part(struct mlxsw_sp1_kvdl *kvdl,
			       unsigned int alloc_size)
{
	struct mlxsw_sp1_kvdl_part *part, *min_part = NULL;
	int i;

	for (i = 0; i < MLXSW_SP1_KVDL_PARTS_INFO_LEN; i++) {
		part = kvdl->parts[i];
		if (alloc_size <= part->info.alloc_size &&
		    (!min_part ||
		     part->info.alloc_size <= min_part->info.alloc_size))
			min_part = part;
	}

	return min_part ?: ERR_PTR(-ENOBUFS);
}

static struct mlxsw_sp1_kvdl_part *
mlxsw_sp1_kvdl_index_part(struct mlxsw_sp1_kvdl *kvdl, u32 kvdl_index)
{
	struct mlxsw_sp1_kvdl_part *part;
	int i;

	for (i = 0; i < MLXSW_SP1_KVDL_PARTS_INFO_LEN; i++) {
		part = kvdl->parts[i];
		if (kvdl_index >= part->info.start_index &&
		    kvdl_index <= part->info.end_index)
			return part;
	}

	return ERR_PTR(-EINVAL);
}

static u32
mlxsw_sp1_kvdl_to_kvdl_index(const struct mlxsw_sp1_kvdl_part_info *info,
			     unsigned int entry_index)
{
	return info->start_index + entry_index * info->alloc_size;
}

static unsigned int
mlxsw_sp1_kvdl_to_entry_index(const struct mlxsw_sp1_kvdl_part_info *info,
			      u32 kvdl_index)
{
	return (kvdl_index - info->start_index) / info->alloc_size;
}

static int mlxsw_sp1_kvdl_part_alloc(struct mlxsw_sp1_kvdl_part *part,
				     u32 *p_kvdl_index)
{

Annotation

Implementation Notes