drivers/net/ethernet/mellanox/mlx5/core/sf/hw_table.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/sf/hw_table.c
Extension
.c
Size
11491 bytes
Lines
462
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 mlx5_sf_hw {
	u32 usr_sfnum;
	u8 allocated: 1;
	u8 pending_delete: 1;
};

struct mlx5_sf_hwc_table {
	struct mlx5_sf_hw *sfs;
	int max_fn;
	u16 start_fn_id;
	u32 controller;
};

enum {
	MLX5_SF_HWC_LOCAL,
	MLX5_SF_HWC_EXT_HOST,
	MLX5_SF_HWC_FIRST_SPF,
};

struct mlx5_sf_hw_table {
	struct mutex table_lock; /* Serializes sf deletion and vhca state change handler. */
	struct mlx5_sf_hwc_table *hwc;
	int num_hwc;
};

static struct mlx5_sf_hwc_table *
mlx5_sf_controller_to_hwc(struct mlx5_core_dev *dev, u32 controller)
{
	struct mlx5_sf_hw_table *table = dev->priv.sf_hw_table;
	int i;

	for (i = MLX5_SF_HWC_FIRST_SPF; i < table->num_hwc; i++) {
		if (table->hwc[i].controller == controller)
			return &table->hwc[i];
	}

	return &table->hwc[!!controller];
}

u16 mlx5_sf_sw_to_hw_id(struct mlx5_core_dev *dev, u32 controller, u16 sw_id)
{
	struct mlx5_sf_hwc_table *hwc;

	hwc = mlx5_sf_controller_to_hwc(dev, controller);
	return hwc->start_fn_id + sw_id;
}

static u16 mlx5_sf_hw_to_sw_id(struct mlx5_sf_hwc_table *hwc, u16 hw_id)
{
	return hw_id - hwc->start_fn_id;
}

static struct mlx5_sf_hwc_table *
mlx5_sf_table_fn_to_hwc(struct mlx5_sf_hw_table *table, u16 fn_id)
{
	int i;

	for (i = 0; i < table->num_hwc; i++) {
		if (table->hwc[i].max_fn &&
		    fn_id >= table->hwc[i].start_fn_id &&
		    fn_id < (table->hwc[i].start_fn_id + table->hwc[i].max_fn))
			return &table->hwc[i];
	}
	return NULL;
}

static int mlx5_sf_hw_table_id_alloc(struct mlx5_core_dev *dev,
				     struct mlx5_sf_hw_table *table,
				     u32 controller,
				     u32 usr_sfnum)
{
	struct mlx5_sf_hwc_table *hwc;
	int free_idx = -1;
	int i;

	hwc = mlx5_sf_controller_to_hwc(dev, controller);
	if (!hwc->sfs)
		return -ENOSPC;

	for (i = 0; i < hwc->max_fn; i++) {
		if (!hwc->sfs[i].allocated && free_idx == -1) {
			free_idx = i;
			continue;
		}

		if (hwc->sfs[i].allocated && hwc->sfs[i].usr_sfnum == usr_sfnum)
			return -EEXIST;
	}

	if (free_idx == -1)

Annotation

Implementation Notes