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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlxsw/spectrum_pgt.c
Extension
.c
Size
7926 bytes
Lines
337
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_pgt {
	struct idr pgt_idr;
	u16 end_index; /* Exclusive. */
	struct mutex lock; /* Protects PGT. */
	bool smpe_index_valid;
};

struct mlxsw_sp_pgt_entry {
	struct list_head ports_list;
	u16 index;
	u16 smpe_index;
};

struct mlxsw_sp_pgt_entry_port {
	struct list_head list; /* Member of 'ports_list'. */
	u16 local_port;
};

int mlxsw_sp_pgt_mid_alloc(struct mlxsw_sp *mlxsw_sp, u16 *p_mid)
{
	int index, err = 0;

	mutex_lock(&mlxsw_sp->pgt->lock);
	index = idr_alloc(&mlxsw_sp->pgt->pgt_idr, NULL, 0,
			  mlxsw_sp->pgt->end_index, GFP_KERNEL);

	if (index < 0) {
		err = index;
		goto err_idr_alloc;
	}

	*p_mid = index;
	mutex_unlock(&mlxsw_sp->pgt->lock);
	return 0;

err_idr_alloc:
	mutex_unlock(&mlxsw_sp->pgt->lock);
	return err;
}

void mlxsw_sp_pgt_mid_free(struct mlxsw_sp *mlxsw_sp, u16 mid_base)
{
	mutex_lock(&mlxsw_sp->pgt->lock);
	WARN_ON(idr_remove(&mlxsw_sp->pgt->pgt_idr, mid_base));
	mutex_unlock(&mlxsw_sp->pgt->lock);
}

int mlxsw_sp_pgt_mid_alloc_range(struct mlxsw_sp *mlxsw_sp, u16 *p_mid_base,
				 u16 count)
{
	unsigned int mid_base;
	int i, err;

	mutex_lock(&mlxsw_sp->pgt->lock);

	mid_base = idr_get_cursor(&mlxsw_sp->pgt->pgt_idr);
	for (i = 0; i < count; i++) {
		err = idr_alloc_cyclic(&mlxsw_sp->pgt->pgt_idr, NULL,
				       mid_base, mid_base + count, GFP_KERNEL);
		if (err < 0)
			goto err_idr_alloc_cyclic;
	}

	mutex_unlock(&mlxsw_sp->pgt->lock);
	*p_mid_base = mid_base;
	return 0;

err_idr_alloc_cyclic:
	for (i--; i >= 0; i--)
		idr_remove(&mlxsw_sp->pgt->pgt_idr, mid_base + i);
	mutex_unlock(&mlxsw_sp->pgt->lock);
	return err;
}

void
mlxsw_sp_pgt_mid_free_range(struct mlxsw_sp *mlxsw_sp, u16 mid_base, u16 count)
{
	struct idr *pgt_idr = &mlxsw_sp->pgt->pgt_idr;
	int i;

	mutex_lock(&mlxsw_sp->pgt->lock);

	for (i = 0; i < count; i++)
		WARN_ON_ONCE(idr_remove(pgt_idr, mid_base + i));

	mutex_unlock(&mlxsw_sp->pgt->lock);
}

static struct mlxsw_sp_pgt_entry_port *
mlxsw_sp_pgt_entry_port_lookup(struct mlxsw_sp_pgt_entry *pgt_entry,

Annotation

Implementation Notes