{
struct mlx5_vport *vport;
int total_nvports = 0;
- u16 vf_nvports = 0;
int err;
int i, enabled_events;
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;
} 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)
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;
}
err_reps:
while (rep_type-- > 0)
- __unload_reps_all_vport(esw, nvports, rep_type);
+ __unload_reps_special_vport(esw, rep_type);
return err;
}
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)
{
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;
static void esw_functions_changed_event_init(struct mlx5_eswitch *esw,
u16 vf_nvports)
{
- if (!mlx5_eswitch_is_funcs_handler(esw->dev))
- return;
-
- MLX5_NB_INIT(&esw->esw_funcs.nb, esw_functions_changed_event,
- ESW_FUNCTIONS_CHANGED);
- mlx5_eq_notifier_register(esw->dev, &esw->esw_funcs.nb);
- esw->esw_funcs.num_vfs = vf_nvports;
+ 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)
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;
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:
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);
}