drivers/net/ethernet/mellanox/mlx5/core/diag/rsc_dump.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/diag/rsc_dump.c
Extension
.c
Size
8144 bytes
Lines
312
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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_rsc_dump {
	u32 pdn;
	u32 mkey;
	u32 number_of_menu_items;
	u16 fw_segment_type[MLX5_SGMT_TYPE_NUM];
};

struct mlx5_rsc_dump_cmd {
	u64 mem_size;
	u8 cmd[MLX5_ST_SZ_BYTES(resource_dump)];
};

static int mlx5_rsc_dump_sgmt_get_by_name(char *name)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(mlx5_rsc_sgmt_name); i++)
		if (!strcmp(name, mlx5_rsc_sgmt_name[i]))
			return i;

	return -EINVAL;
}

#define MLX5_RSC_DUMP_MENU_HEADER_SIZE (MLX5_ST_SZ_BYTES(resource_dump_info_segment) + \
					MLX5_ST_SZ_BYTES(resource_dump_command_segment) + \
					MLX5_ST_SZ_BYTES(resource_dump_menu_segment))

static int mlx5_rsc_dump_read_menu_sgmt(struct mlx5_rsc_dump *rsc_dump, struct page *page,
					int read_size, int start_idx)
{
	void *data = page_address(page);
	enum mlx5_sgmt_type sgmt_idx;
	int num_of_items;
	char *sgmt_name;
	void *member;
	int size = 0;
	void *menu;
	int i;

	if (!start_idx) {
		menu = MLX5_ADDR_OF(menu_resource_dump_response, data, menu);
		rsc_dump->number_of_menu_items = MLX5_GET(resource_dump_menu_segment, menu,
							  num_of_records);
		size = MLX5_RSC_DUMP_MENU_HEADER_SIZE;
		data += size;
	}
	num_of_items = rsc_dump->number_of_menu_items;

	for (i = 0; start_idx + i < num_of_items; i++) {
		size += MLX5_ST_SZ_BYTES(resource_dump_menu_record);
		if (size >= read_size)
			return start_idx + i;

		member = data + MLX5_ST_SZ_BYTES(resource_dump_menu_record) * i;
		sgmt_name =  MLX5_ADDR_OF(resource_dump_menu_record, member, segment_name);
		sgmt_idx = mlx5_rsc_dump_sgmt_get_by_name(sgmt_name);
		if (sgmt_idx == -EINVAL)
			continue;
		rsc_dump->fw_segment_type[sgmt_idx] = MLX5_GET(resource_dump_menu_record,
							       member, segment_type);
	}
	return 0;
}

static int mlx5_rsc_dump_trigger(struct mlx5_core_dev *dev, struct mlx5_rsc_dump_cmd *cmd,
				 struct page *page)
{
	struct mlx5_rsc_dump *rsc_dump = dev->rsc_dump;
	struct device *ddev = mlx5_core_dma_dev(dev);
	u32 out_seq_num;
	u32 in_seq_num;
	dma_addr_t dma;
	int err;

	dma = dma_map_page(ddev, page, 0, cmd->mem_size, DMA_FROM_DEVICE);
	if (unlikely(dma_mapping_error(ddev, dma)))
		return -ENOMEM;

	in_seq_num = MLX5_GET(resource_dump, cmd->cmd, seq_num);
	MLX5_SET(resource_dump, cmd->cmd, mkey, rsc_dump->mkey);
	MLX5_SET64(resource_dump, cmd->cmd, address, dma);

	err = mlx5_core_access_reg(dev, cmd->cmd, sizeof(cmd->cmd), cmd->cmd,
				   sizeof(cmd->cmd), MLX5_REG_RESOURCE_DUMP, 0, 1);
	if (err) {
		mlx5_core_err(dev, "Resource dump: Failed to access err %d\n", err);
		goto out;
	}
	out_seq_num = MLX5_GET(resource_dump, cmd->cmd, seq_num);
	if (out_seq_num && (in_seq_num + 1 != out_seq_num))

Annotation

Implementation Notes