drivers/infiniband/hw/mlx5/dm.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/mlx5/dm.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/mlx5/dm.c
Extension
.c
Size
17305 bytes
Lines
613
Domain
Driver Families
Bucket
drivers/infiniband
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

if (ret) {
			spin_lock(&dm->lock);
			bitmap_clear(dm->memic_alloc_pages,
				     page_idx, num_pages);
			spin_unlock(&dm->lock);

			if (ret == -EAGAIN) {
				page_idx++;
				continue;
			}

			return ret;
		}

		*addr = dev->bar_addr +
			MLX5_GET64(alloc_memic_out, out, memic_start_addr);

		return 0;
	}

	return -ENOMEM;
}

void mlx5_cmd_dealloc_memic(struct mlx5_dm *dm, phys_addr_t addr,
			    u64 length)
{
	struct mlx5_core_dev *dev = dm->dev;
	u64 hw_start_addr = MLX5_CAP64_DEV_MEM(dev, memic_bar_start_addr);
	u32 num_pages = DIV_ROUND_UP(length, PAGE_SIZE);
	u32 in[MLX5_ST_SZ_DW(dealloc_memic_in)] = {};
	u64 start_page_idx;
	int err;

	addr -= dev->bar_addr;
	start_page_idx = (addr - hw_start_addr) >> PAGE_SHIFT;

	MLX5_SET(dealloc_memic_in, in, opcode, MLX5_CMD_OP_DEALLOC_MEMIC);
	MLX5_SET64(dealloc_memic_in, in, memic_start_addr, addr);
	MLX5_SET(dealloc_memic_in, in, memic_size, length);

	err =  mlx5_cmd_exec_in(dev, dealloc_memic, in);
	if (err)
		return;

	spin_lock(&dm->lock);
	bitmap_clear(dm->memic_alloc_pages,
		     start_page_idx, num_pages);
	spin_unlock(&dm->lock);
}

void mlx5_cmd_dealloc_memic_op(struct mlx5_dm *dm, phys_addr_t addr,
			       u8 operation)
{
	u32 in[MLX5_ST_SZ_DW(modify_memic_in)] = {};
	struct mlx5_core_dev *dev = dm->dev;

	MLX5_SET(modify_memic_in, in, opcode, MLX5_CMD_OP_MODIFY_MEMIC);
	MLX5_SET(modify_memic_in, in, op_mod, MLX5_MODIFY_MEMIC_OP_MOD_DEALLOC);
	MLX5_SET(modify_memic_in, in, memic_operation_type, operation);
	MLX5_SET64(modify_memic_in, in, memic_start_addr, addr - dev->bar_addr);

	mlx5_cmd_exec_in(dev, modify_memic, in);
}

static int mlx5_cmd_alloc_memic_op(struct mlx5_dm *dm, phys_addr_t addr,
				   u8 operation, phys_addr_t *op_addr)
{
	u32 out[MLX5_ST_SZ_DW(modify_memic_out)] = {};
	u32 in[MLX5_ST_SZ_DW(modify_memic_in)] = {};
	struct mlx5_core_dev *dev = dm->dev;
	int err;

	MLX5_SET(modify_memic_in, in, opcode, MLX5_CMD_OP_MODIFY_MEMIC);
	MLX5_SET(modify_memic_in, in, op_mod, MLX5_MODIFY_MEMIC_OP_MOD_ALLOC);
	MLX5_SET(modify_memic_in, in, memic_operation_type, operation);
	MLX5_SET64(modify_memic_in, in, memic_start_addr, addr - dev->bar_addr);

	err = mlx5_cmd_exec_inout(dev, modify_memic, in, out);
	if (err)
		return err;

	*op_addr = dev->bar_addr +
		   MLX5_GET64(modify_memic_out, out, memic_operation_addr);
	return 0;
}

static int add_dm_mmap_entry(struct ib_ucontext *context,
			     struct mlx5_user_mmap_entry *mentry, u8 mmap_flag,
			     size_t size, u64 address)
{

Annotation

Implementation Notes