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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c
Extension
.c
Size
10623 bytes
Lines
407
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_dev_table {
	struct xarray devices;
	phys_addr_t base_address;
	u64 sf_bar_length;
	struct workqueue_struct *active_wq;
	struct work_struct work;
	u8 stop_active_wq:1;
	struct mlx5_core_dev *dev;
};

struct mlx5_sf_dev_active_work_ctx {
	struct work_struct work;
	struct mlx5_vhca_state_event event;
	struct mlx5_sf_dev_table *table;
	int sf_index;
};

static bool mlx5_sf_dev_supported(const struct mlx5_core_dev *dev)
{
	return MLX5_CAP_GEN(dev, sf) && mlx5_vhca_event_supported(dev);
}

bool mlx5_sf_dev_allocated(const struct mlx5_core_dev *dev)
{
	struct mlx5_sf_dev_table *table = dev->priv.sf_dev_table;

	return table && !xa_empty(&table->devices);
}

static ssize_t sfnum_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct auxiliary_device *adev = container_of(dev, struct auxiliary_device, dev);
	struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev);

	return sysfs_emit(buf, "%u\n", sf_dev->sfnum);
}
static DEVICE_ATTR_RO(sfnum);

static struct attribute *sf_device_attrs[] = {
	&dev_attr_sfnum.attr,
	NULL,
};

static const struct attribute_group sf_attr_group = {
	.attrs = sf_device_attrs,
};

static const struct attribute_group *sf_attr_groups[2] = {
	&sf_attr_group,
	NULL
};

static void mlx5_sf_dev_release(struct device *device)
{
	struct auxiliary_device *adev = container_of(device, struct auxiliary_device, dev);
	struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev);

	mlx5_adev_idx_free(adev->id);
	kfree(sf_dev);
}

static void mlx5_sf_dev_remove_aux(struct mlx5_core_dev *dev,
				   struct mlx5_sf_dev *sf_dev)
{
	int id;

	id = sf_dev->adev.id;
	trace_mlx5_sf_dev_del(dev, sf_dev, id);

	auxiliary_device_delete(&sf_dev->adev);
	auxiliary_device_uninit(&sf_dev->adev);
}

static void mlx5_sf_dev_add(struct mlx5_core_dev *dev, u16 sf_index, u16 fn_id, u32 sfnum)
{
	struct mlx5_sf_dev_table *table = dev->priv.sf_dev_table;
	struct mlx5_sf_dev *sf_dev;
	struct pci_dev *pdev;
	int err;
	int id;

	id = mlx5_adev_idx_alloc();
	if (id < 0) {
		err = id;
		goto add_err;
	}

	sf_dev = kzalloc_obj(*sf_dev);
	if (!sf_dev) {
		mlx5_adev_idx_free(id);

Annotation

Implementation Notes