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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
Extension
.c
Size
46628 bytes
Lines
1604
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 mlxsw_linecard_ini_file {
	__le16 size;
	union {
		u8 data[0];
		struct {
			__be16 hw_revision;
			__be16 ini_version;
			u8 __dontcare[3];
			u8 type;
			u8 name[20];
		} format;
	};
};

struct mlxsw_linecard_types_info {
	struct mlxsw_linecard_ini_file **ini_files;
	unsigned int count;
	size_t data_size;
	char *data;
};

#define MLXSW_LINECARD_STATUS_EVENT_TO (10 * MSEC_PER_SEC)

static void
mlxsw_linecard_status_event_to_schedule(struct mlxsw_linecard *linecard,
					enum mlxsw_linecard_status_event_type status_event_type)
{
	cancel_delayed_work_sync(&linecard->status_event_to_dw);
	linecard->status_event_type_to = status_event_type;
	mlxsw_core_schedule_dw(&linecard->status_event_to_dw,
			       msecs_to_jiffies(MLXSW_LINECARD_STATUS_EVENT_TO));
}

static void
mlxsw_linecard_status_event_done(struct mlxsw_linecard *linecard,
				 enum mlxsw_linecard_status_event_type status_event_type)
{
	if (linecard->status_event_type_to == status_event_type)
		cancel_delayed_work_sync(&linecard->status_event_to_dw);
}

static const char *
mlxsw_linecard_types_lookup(struct mlxsw_linecards *linecards, u8 card_type)
{
	struct mlxsw_linecard_types_info *types_info;
	struct mlxsw_linecard_ini_file *ini_file;
	int i;

	types_info = linecards->types_info;
	if (!types_info)
		return NULL;
	for (i = 0; i < types_info->count; i++) {
		ini_file = linecards->types_info->ini_files[i];
		if (ini_file->format.type == card_type)
			return ini_file->format.name;
	}
	return NULL;
}

static const char *mlxsw_linecard_type_name(struct mlxsw_linecard *linecard)
{
	struct mlxsw_core *mlxsw_core = linecard->linecards->mlxsw_core;
	char mddq_pl[MLXSW_REG_MDDQ_LEN];
	int err;

	mlxsw_reg_mddq_slot_name_pack(mddq_pl, linecard->slot_index);
	err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mddq), mddq_pl);
	if (err)
		return ERR_PTR(err);
	mlxsw_reg_mddq_slot_name_unpack(mddq_pl, linecard->name);
	return linecard->name;
}

struct mlxsw_linecard_device_fw_info {
	struct mlxfw_dev mlxfw_dev;
	struct mlxsw_core *mlxsw_core;
	struct mlxsw_linecard *linecard;
};

static int mlxsw_linecard_device_fw_component_query(struct mlxfw_dev *mlxfw_dev,
						    u16 component_index,
						    u32 *p_max_size,
						    u8 *p_align_bits,
						    u16 *p_max_write_size)
{
	struct mlxsw_linecard_device_fw_info *info =
		container_of(mlxfw_dev, struct mlxsw_linecard_device_fw_info,
			     mlxfw_dev);
	struct mlxsw_linecard *linecard = info->linecard;
	struct mlxsw_core *mlxsw_core = info->mlxsw_core;

Annotation

Implementation Notes