drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c
Extension
.c
Size
7695 bytes
Lines
321
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

if (!pf_metadata) {
			err = -ENOSPC;
			goto err_metadata;
		}

		ldev->lag_mpesw.pf_metadata[i] = pf_metadata;
		err = mlx5_esw_acl_ingress_vport_metadata_update(esw, MLX5_VPORT_UPLINK,
								 pf_metadata);
		if (err)
			goto err_metadata;
	}

	mlx5_lag_for_each(i, 0, ldev, MLX5_LAG_FILTER_ALL) {
		dev = mlx5_lag_pf(ldev, i)->dev;
		mlx5_notifier_call_chain(dev->priv.events, MLX5_DEV_EVENT_MULTIPORT_ESW,
					 (void *)0);
	}

	return 0;

err_metadata:
	mlx5_mpesw_metadata_cleanup(ldev);
	return err;
}

static void mlx5_mpesw_restore_sd_fdb(struct mlx5_lag *ldev)
{
	struct lag_func *pf;
	int err, i;

	mlx5_ldev_for_each(i, 0, ldev) {
		pf = mlx5_lag_pf(ldev, i);
		err = mlx5_lag_shared_fdb_create(ldev, NULL, 0, pf->group_id);
		if (err)
			mlx5_core_warn(pf->dev,
				       "Failed to restore SD shared FDB (%d)\n",
				       err);
	}
}

static int mlx5_mpesw_teardown_sd_fdb(struct mlx5_lag *ldev)
{
	struct lag_func *pf;
	int i;

	mlx5_ldev_for_each(i, 0, ldev) {
		pf = mlx5_lag_pf(ldev, i);
		if (!pf->sd_fdb_active)
			continue;
		mlx5_lag_shared_fdb_destroy(ldev, pf->group_id);
	}
	return 0;
}

static bool mlx5_lag_has_sd_group(struct mlx5_lag *ldev)
{
	struct lag_func *pf;
	int i;

	mlx5_ldev_for_each(i, 0, ldev) {
		pf = mlx5_lag_pf(ldev, i);
		if (pf->group_id)
			return true;
	}
	return false;
}

static int mlx5_lag_enable_mpesw(struct mlx5_lag *ldev)
{
	int idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
	struct mlx5_core_dev *dev0;
	int err;

	if (ldev->mode == MLX5_LAG_MODE_MPESW)
		return 0;

	if (ldev->mode != MLX5_LAG_MODE_NONE)
		return -EINVAL;

	if (idx < 0)
		return -EINVAL;

	dev0 = mlx5_lag_pf(ldev, idx)->dev;
	if (mlx5_eswitch_mode(dev0) != MLX5_ESWITCH_OFFLOADS ||
	    !MLX5_CAP_PORT_SELECTION(dev0, port_select_flow_table) ||
	    !MLX5_CAP_GEN(dev0, create_lag_when_not_master_up) ||
	    !mlx5_lag_check_prereq(ldev) ||
	    !mlx5_lag_shared_fdb_supported_filter(ldev, MLX5_LAG_FILTER_ALL))
		return -EOPNOTSUPP;

Annotation

Implementation Notes