drivers/net/ethernet/mellanox/mlx5/core/eswitch.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
Extension
.c
Size
82197 bytes
Lines
3119
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 vport_addr {
	struct l2addr_node     node;
	u8                     action;
	u16                    vport;
	struct mlx5_flow_handle *flow_rule;
	bool mpfs; /* UC MAC was added to MPFs */
	/* A flag indicating that mac was added due to mc promiscuous vport */
	bool mc_promisc;
};

static int mlx5_eswitch_check(const struct mlx5_core_dev *dev)
{
	if (MLX5_CAP_GEN(dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
		return -EOPNOTSUPP;

	if (!MLX5_ESWITCH_MANAGER(dev))
		return -EOPNOTSUPP;

	return 0;
}

static struct mlx5_eswitch *__mlx5_devlink_eswitch_get(struct devlink *devlink, bool check)
{
	struct mlx5_core_dev *dev = devlink_priv(devlink);
	int err;

	if (check) {
		err = mlx5_eswitch_check(dev);
		if (err)
			return ERR_PTR(err);
	}

	return dev->priv.eswitch;
}

struct mlx5_eswitch *__must_check
mlx5_devlink_eswitch_get(struct devlink *devlink)
{
	return __mlx5_devlink_eswitch_get(devlink, true);
}

struct mlx5_eswitch *mlx5_devlink_eswitch_nocheck_get(struct devlink *devlink)
{
	return __mlx5_devlink_eswitch_get(devlink, false);
}

struct mlx5_vport *__must_check
mlx5_eswitch_get_vport(struct mlx5_eswitch *esw, u16 vport_num)
{
	struct mlx5_vport *vport;

	if (!esw)
		return ERR_PTR(-EPERM);

	vport = xa_load(&esw->vports, vport_num);
	if (!vport) {
		esw_debug(esw->dev, "vport out of range: num(0x%x)\n", vport_num);
		return ERR_PTR(-EINVAL);
	}
	return vport;
}

static int arm_vport_context_events_cmd(struct mlx5_core_dev *dev, u16 vport,
					u32 events_mask)
{
	u32 in[MLX5_ST_SZ_DW(modify_nic_vport_context_in)] = {};
	void *nic_vport_ctx;

	MLX5_SET(modify_nic_vport_context_in, in,
		 opcode, MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
	MLX5_SET(modify_nic_vport_context_in, in, field_select.change_event, 1);
	MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
	if (vport || mlx5_core_is_ecpf(dev))
		MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
	nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in,
				     in, nic_vport_context);

	MLX5_SET(nic_vport_context, nic_vport_ctx, arm_change_event, 1);

	if (events_mask & MLX5_VPORT_UC_ADDR_CHANGE)
		MLX5_SET(nic_vport_context, nic_vport_ctx,
			 event_on_uc_address_change, 1);
	if (events_mask & MLX5_VPORT_MC_ADDR_CHANGE)
		MLX5_SET(nic_vport_context, nic_vport_ctx,
			 event_on_mc_address_change, 1);
	if (events_mask & MLX5_VPORT_PROMISC_CHANGE)
		MLX5_SET(nic_vport_context, nic_vport_ctx,
			 event_on_promisc_change, 1);

	return mlx5_cmd_exec_in(dev, modify_nic_vport_context, in);

Annotation

Implementation Notes