Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac35dcd6 authored by Vu Pham's avatar Vu Pham Committed by Saeed Mahameed
Browse files

net/mlx5: E-Switch, Handle representors creation in handler context



Unified representors creation in esw_functions_changed context
handler. Emulate the esw_function_changed event for FW/HW that
does not support this event.

Signed-off-by: default avatarVu Pham <vuhuong@mellanox.com>
Reviewed-by: default avatarParav Pandit <parav@mellanox.com>
Reviewed-by: default avatarBodong Wang <bodong@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent b8a92577
Loading
Loading
Loading
Loading
+3 −9
Original line number Diff line number Diff line
@@ -1720,7 +1720,6 @@ int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode)
{
	struct mlx5_vport *vport;
	int total_nvports = 0;
	u16 vf_nvports = 0;
	int err;
	int i, enabled_events;

@@ -1739,16 +1738,11 @@ int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode)
	esw_info(esw->dev, "E-Switch enable SRIOV: nvfs(%d) mode (%d)\n", nvfs, mode);

	if (mode == SRIOV_OFFLOADS) {
		if (mlx5_core_is_ecpf_esw_manager(esw->dev)) {
			err = mlx5_esw_query_functions(esw->dev, &vf_nvports);
			if (err)
				return err;
		if (mlx5_core_is_ecpf_esw_manager(esw->dev))
			total_nvports = esw->total_vports;
		} else {
			vf_nvports = nvfs;
		else
			total_nvports = nvfs + MLX5_SPECIAL_VPORTS(esw->dev);
	}
	}

	esw->mode = mode;

@@ -1761,7 +1755,7 @@ int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode)
	} else {
		mlx5_reload_interface(esw->dev, MLX5_INTERFACE_PROTOCOL_ETH);
		mlx5_reload_interface(esw->dev, MLX5_INTERFACE_PROTOCOL_IB);
		err = esw_offloads_init(esw, vf_nvports, total_nvports);
		err = esw_offloads_init(esw, nvfs, total_nvports);
	}

	if (err)
+47 −42
Original line number Diff line number Diff line
@@ -1436,34 +1436,13 @@ static int esw_offloads_load_vf_reps(struct mlx5_eswitch *esw, int nvports)
	return err;
}

static int __load_reps_all_vport(struct mlx5_eswitch *esw, int nvports,
				 u8 rep_type)
{
	int err;

	/* Special vports must be loaded first. */
	err = __load_reps_special_vport(esw, rep_type);
	if (err)
		return err;

	err = __load_reps_vf_vport(esw, nvports, rep_type);
	if (err)
		goto err_vfs;

	return 0;

err_vfs:
	__unload_reps_special_vport(esw, rep_type);
	return err;
}

static int esw_offloads_load_all_reps(struct mlx5_eswitch *esw, int nvports)
static int esw_offloads_load_special_vport(struct mlx5_eswitch *esw)
{
	u8 rep_type = 0;
	int err;

	for (rep_type = 0; rep_type < NUM_REP_TYPES; rep_type++) {
		err = __load_reps_all_vport(esw, nvports, rep_type);
		err = __load_reps_special_vport(esw, rep_type);
		if (err)
			goto err_reps;
	}
@@ -1472,7 +1451,7 @@ static int esw_offloads_load_all_reps(struct mlx5_eswitch *esw, int nvports)

err_reps:
	while (rep_type-- > 0)
		__unload_reps_all_vport(esw, nvports, rep_type);
		__unload_reps_special_vport(esw, rep_type);
	return err;
}

@@ -1811,6 +1790,21 @@ static void esw_functions_changed_event_handler(struct work_struct *work)
	kfree(host_work);
}

static void esw_emulate_event_handler(struct work_struct *work)
{
	struct mlx5_host_work *host_work =
		container_of(work, struct mlx5_host_work, work);
	struct mlx5_eswitch *esw = host_work->esw;
	int err;

	if (esw->esw_funcs.num_vfs) {
		err = esw_offloads_load_vf_reps(esw, esw->esw_funcs.num_vfs);
		if (err)
			esw_warn(esw->dev, "Load vf reps err=%d\n", err);
	}
	kfree(host_work);
}

static int esw_functions_changed_event(struct notifier_block *nb,
				       unsigned long type, void *data)
{
@@ -1827,7 +1821,11 @@ static int esw_functions_changed_event(struct notifier_block *nb,

	host_work->esw = esw;

	INIT_WORK(&host_work->work, esw_functions_changed_event_handler);
	if (mlx5_eswitch_is_funcs_handler(esw->dev))
		INIT_WORK(&host_work->work,
			  esw_functions_changed_event_handler);
	else
		INIT_WORK(&host_work->work, esw_emulate_event_handler);
	queue_work(esw->work_queue, &host_work->work);

	return NOTIFY_OK;
@@ -1836,14 +1834,15 @@ static int esw_functions_changed_event(struct notifier_block *nb,
static void esw_functions_changed_event_init(struct mlx5_eswitch *esw,
					     u16 vf_nvports)
{
	if (!mlx5_eswitch_is_funcs_handler(esw->dev))
		return;

	if (mlx5_eswitch_is_funcs_handler(esw->dev)) {
		esw->esw_funcs.num_vfs = 0;
		MLX5_NB_INIT(&esw->esw_funcs.nb, esw_functions_changed_event,
			     ESW_FUNCTIONS_CHANGED);
		mlx5_eq_notifier_register(esw->dev, &esw->esw_funcs.nb);
	} else {
		esw->esw_funcs.num_vfs = vf_nvports;
	}
}

static void esw_functions_changed_event_cleanup(struct mlx5_eswitch *esw)
{
@@ -1863,7 +1862,11 @@ int esw_offloads_init(struct mlx5_eswitch *esw, int vf_nvports,
	if (err)
		return err;

	err = esw_offloads_load_all_reps(esw, vf_nvports);
	/* Only load special vports reps. VF reps will be loaded in
	 * context of functions_changed event handler through real
	 * or emulated event.
	 */
	err = esw_offloads_load_special_vport(esw);
	if (err)
		goto err_reps;

@@ -1873,6 +1876,16 @@ int esw_offloads_init(struct mlx5_eswitch *esw, int vf_nvports,

	mlx5_rdma_enable_roce(esw->dev);

	/* Call esw_functions_changed event to load VF reps:
	 * 1. HW does not support the event then emulate it
	 * Or
	 * 2. The event was already notified when num_vfs changed
	 * and eswitch was in legacy mode
	 */
	esw_functions_changed_event(&esw->esw_funcs.nb.nb,
				    MLX5_EVENT_TYPE_ESW_FUNCTIONS_CHANGED,
				    NULL);

	return 0;

err_reps:
@@ -1901,18 +1914,10 @@ static int esw_offloads_stop(struct mlx5_eswitch *esw,

void esw_offloads_cleanup(struct mlx5_eswitch *esw)
{
	u16 num_vfs;

	esw_functions_changed_event_cleanup(esw);

	if (mlx5_eswitch_is_funcs_handler(esw->dev))
		num_vfs = esw->esw_funcs.num_vfs;
	else
		num_vfs = esw->dev->priv.sriov.num_vfs;

	mlx5_rdma_disable_roce(esw->dev);
	esw_offloads_devcom_cleanup(esw);
	esw_offloads_unload_all_reps(esw, num_vfs);
	esw_offloads_unload_all_reps(esw, esw->esw_funcs.num_vfs);
	esw_offloads_steering_cleanup(esw);
}