Commit cd56f929 authored by Vu Pham's avatar Vu Pham Committed by Saeed Mahameed

net/mlx5: E-Switch, Replace host_params event with functions_changed event

To support sriov on a E-Switch manager, num_vfs are queried
to the firmware whenever E-Switch manager is notified by
esw_functions_changed event.

Replace host_params event with esw_functions_changed event that reflects
more appropriate naming.

While at it, also correct num_vfs type from int to u16 as expected by
the function mlx5_esw_query_functions().
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 c6d4e45d
......@@ -316,7 +316,7 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op,
case MLX5_CMD_OP_DESTROY_GENERAL_OBJECT:
case MLX5_CMD_OP_DEALLOC_MEMIC:
case MLX5_CMD_OP_PAGE_FAULT_RESUME:
case MLX5_CMD_OP_QUERY_HOST_PARAMS:
case MLX5_CMD_OP_QUERY_ESW_FUNCTIONS:
return MLX5_CMD_STAT_OK;
case MLX5_CMD_OP_QUERY_HCA_CAP:
......@@ -628,7 +628,7 @@ const char *mlx5_command_str(int command)
MLX5_COMMAND_STR_CASE(QUERY_MODIFY_HEADER_CONTEXT);
MLX5_COMMAND_STR_CASE(ALLOC_MEMIC);
MLX5_COMMAND_STR_CASE(DEALLOC_MEMIC);
MLX5_COMMAND_STR_CASE(QUERY_HOST_PARAMS);
MLX5_COMMAND_STR_CASE(QUERY_ESW_FUNCTIONS);
default: return "unknown command opcode";
}
}
......
......@@ -83,30 +83,3 @@ void mlx5_ec_cleanup(struct mlx5_core_dev *dev)
mlx5_peer_pf_cleanup(dev);
}
static int mlx5_query_host_params_context(struct mlx5_core_dev *dev,
u32 *out, int outlen)
{
u32 in[MLX5_ST_SZ_DW(query_host_params_in)] = {};
MLX5_SET(query_host_params_in, in, opcode,
MLX5_CMD_OP_QUERY_HOST_PARAMS);
return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen);
}
int mlx5_query_host_params_num_vfs(struct mlx5_core_dev *dev, int *num_vf)
{
u32 out[MLX5_ST_SZ_DW(query_host_params_out)] = {};
int err;
err = mlx5_query_host_params_context(dev, out, sizeof(out));
if (err)
return err;
*num_vf = MLX5_GET(query_host_params_out, out,
host_params_context.host_num_of_vfs);
mlx5_core_dbg(dev, "host_num_of_vfs %d\n", *num_vf);
return 0;
}
......@@ -16,7 +16,6 @@ enum {
bool mlx5_read_embedded_cpu(struct mlx5_core_dev *dev);
int mlx5_ec_init(struct mlx5_core_dev *dev);
void mlx5_ec_cleanup(struct mlx5_core_dev *dev);
int mlx5_query_host_params_num_vfs(struct mlx5_core_dev *dev, int *num_vf);
#else /* CONFIG_MLX5_ESWITCH */
......@@ -24,9 +23,6 @@ static inline bool
mlx5_read_embedded_cpu(struct mlx5_core_dev *dev) { return false; }
static inline int mlx5_ec_init(struct mlx5_core_dev *dev) { return 0; }
static inline void mlx5_ec_cleanup(struct mlx5_core_dev *dev) {}
static inline int
mlx5_query_host_params_num_vfs(struct mlx5_core_dev *dev, int *num_vf)
{ return -EOPNOTSUPP; }
#endif /* CONFIG_MLX5_ESWITCH */
......
......@@ -534,7 +534,8 @@ static u64 gather_async_events_mask(struct mlx5_core_dev *dev)
async_event_mask |= (1ull << MLX5_EVENT_TYPE_MONITOR_COUNTER);
if (mlx5_core_is_ecpf_esw_manager(dev))
async_event_mask |= (1ull << MLX5_EVENT_TYPE_HOST_PARAMS_CHANGE);
async_event_mask |=
(1ull << MLX5_EVENT_TYPE_ESW_FUNCTIONS_CHANGED);
return async_event_mask;
}
......
......@@ -1686,13 +1686,41 @@ static int eswitch_vport_event(struct notifier_block *nb,
return NOTIFY_OK;
}
static int query_esw_functions(struct mlx5_core_dev *dev,
u32 *out, int outlen)
{
u32 in[MLX5_ST_SZ_DW(query_esw_functions_in)] = {0};
MLX5_SET(query_esw_functions_in, in, opcode,
MLX5_CMD_OP_QUERY_ESW_FUNCTIONS);
return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen);
}
int mlx5_esw_query_functions(struct mlx5_core_dev *dev, u16 *num_vfs)
{
u32 out[MLX5_ST_SZ_DW(query_esw_functions_out)] = {0};
int err;
err = query_esw_functions(dev, out, sizeof(out));
if (err)
return err;
*num_vfs = MLX5_GET(query_esw_functions_out, out,
host_params_context.host_num_of_vfs);
esw_debug(dev, "host_num_of_vfs=%d\n", *num_vfs);
return 0;
}
/* Public E-Switch API */
#define ESW_ALLOWED(esw) ((esw) && MLX5_ESWITCH_MANAGER((esw)->dev))
int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode)
{
int vf_nvports = 0, total_nvports = 0;
struct mlx5_vport *vport;
int total_nvports = 0;
u16 vf_nvports = 0;
int err;
int i, enabled_events;
......@@ -1712,7 +1740,7 @@ int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode)
if (mode == SRIOV_OFFLOADS) {
if (mlx5_core_is_ecpf_esw_manager(esw->dev)) {
err = mlx5_query_host_params_num_vfs(esw->dev, &vf_nvports);
err = mlx5_esw_query_functions(esw->dev, &vf_nvports);
if (err)
return err;
total_nvports = esw->total_vports;
......
......@@ -190,7 +190,7 @@ struct mlx5_host_work {
struct mlx5_eswitch *esw;
};
struct mlx5_host_info {
struct mlx5_esw_functions {
struct mlx5_nb nb;
u16 num_vfs;
};
......@@ -219,7 +219,7 @@ struct mlx5_eswitch {
int mode;
int nvports;
u16 manager_vport;
struct mlx5_host_info host_info;
struct mlx5_esw_functions esw_funcs;
};
void esw_offloads_cleanup(struct mlx5_eswitch *esw);
......@@ -386,6 +386,8 @@ bool mlx5_esw_lag_prereq(struct mlx5_core_dev *dev0,
bool mlx5_esw_multipath_prereq(struct mlx5_core_dev *dev0,
struct mlx5_core_dev *dev1);
int mlx5_esw_query_functions(struct mlx5_core_dev *dev, u16 *num_vfs);
#define MLX5_DEBUG_ESWITCH_MASK BIT(3)
#define esw_info(__dev, format, ...) \
......
......@@ -41,7 +41,6 @@
#include "en.h"
#include "fs_core.h"
#include "lib/devcom.h"
#include "ecpf.h"
#include "lib/eq.h"
/* There are two match-all miss flows, one for unicast dst mac and
......@@ -1782,57 +1781,79 @@ static void esw_offloads_steering_cleanup(struct mlx5_eswitch *esw)
esw_prio_tag_acls_cleanup(esw);
}
static void esw_host_params_event_handler(struct work_struct *work)
static void esw_functions_changed_event_handler(struct work_struct *work)
{
struct mlx5_host_work *host_work;
struct mlx5_eswitch *esw;
int err, num_vf = 0;
u16 num_vfs = 0;
int err;
host_work = container_of(work, struct mlx5_host_work, work);
esw = host_work->esw;
err = mlx5_query_host_params_num_vfs(esw->dev, &num_vf);
if (err || num_vf == esw->host_info.num_vfs)
err = mlx5_esw_query_functions(esw->dev, &num_vfs);
if (err || num_vfs == esw->esw_funcs.num_vfs)
goto out;
/* Number of VFs can only change from "0 to x" or "x to 0". */
if (esw->host_info.num_vfs > 0) {
esw_offloads_unload_vf_reps(esw, esw->host_info.num_vfs);
if (esw->esw_funcs.num_vfs > 0) {
esw_offloads_unload_vf_reps(esw, esw->esw_funcs.num_vfs);
} else {
err = esw_offloads_load_vf_reps(esw, num_vf);
err = esw_offloads_load_vf_reps(esw, num_vfs);
if (err)
goto out;
}
esw->host_info.num_vfs = num_vf;
esw->esw_funcs.num_vfs = num_vfs;
out:
kfree(host_work);
}
static int esw_host_params_event(struct notifier_block *nb,
static int esw_functions_changed_event(struct notifier_block *nb,
unsigned long type, void *data)
{
struct mlx5_esw_functions *esw_funcs;
struct mlx5_host_work *host_work;
struct mlx5_host_info *host_info;
struct mlx5_eswitch *esw;
host_work = kzalloc(sizeof(*host_work), GFP_ATOMIC);
if (!host_work)
return NOTIFY_DONE;
host_info = mlx5_nb_cof(nb, struct mlx5_host_info, nb);
esw = container_of(host_info, struct mlx5_eswitch, host_info);
esw_funcs = mlx5_nb_cof(nb, struct mlx5_esw_functions, nb);
esw = container_of(esw_funcs, struct mlx5_eswitch, esw_funcs);
host_work->esw = esw;
INIT_WORK(&host_work->work, esw_host_params_event_handler);
INIT_WORK(&host_work->work, esw_functions_changed_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_core_is_ecpf_esw_manager(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;
}
static void esw_functions_changed_event_cleanup(struct mlx5_eswitch *esw)
{
if (!mlx5_core_is_ecpf_esw_manager(esw->dev))
return;
mlx5_eq_notifier_unregister(esw->dev, &esw->esw_funcs.nb);
flush_workqueue(esw->work_queue);
}
int esw_offloads_init(struct mlx5_eswitch *esw, int vf_nvports,
int total_nvports)
{
......@@ -1848,12 +1869,7 @@ int esw_offloads_init(struct mlx5_eswitch *esw, int vf_nvports,
esw_offloads_devcom_init(esw);
if (mlx5_core_is_ecpf_esw_manager(esw->dev)) {
MLX5_NB_INIT(&esw->host_info.nb, esw_host_params_event,
HOST_PARAMS_CHANGE);
mlx5_eq_notifier_register(esw->dev, &esw->host_info.nb);
esw->host_info.num_vfs = vf_nvports;
}
esw_functions_changed_event_init(esw, vf_nvports);
mlx5_rdma_enable_roce(esw->dev);
......@@ -1887,13 +1903,12 @@ void esw_offloads_cleanup(struct mlx5_eswitch *esw)
{
u16 num_vfs;
if (mlx5_core_is_ecpf_esw_manager(esw->dev)) {
mlx5_eq_notifier_unregister(esw->dev, &esw->host_info.nb);
flush_workqueue(esw->work_queue);
num_vfs = esw->host_info.num_vfs;
} else {
esw_functions_changed_event_cleanup(esw);
if (mlx5_core_is_ecpf_esw_manager(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);
......
......@@ -108,8 +108,8 @@ static const char *eqe_type_str(u8 type)
return "MLX5_EVENT_TYPE_STALL_EVENT";
case MLX5_EVENT_TYPE_CMD:
return "MLX5_EVENT_TYPE_CMD";
case MLX5_EVENT_TYPE_HOST_PARAMS_CHANGE:
return "MLX5_EVENT_TYPE_HOST_PARAMS_CHANGE";
case MLX5_EVENT_TYPE_ESW_FUNCTIONS_CHANGED:
return "MLX5_EVENT_TYPE_ESW_FUNCTIONS_CHANGED";
case MLX5_EVENT_TYPE_PAGE_REQUEST:
return "MLX5_EVENT_TYPE_PAGE_REQUEST";
case MLX5_EVENT_TYPE_PAGE_FAULT:
......
......@@ -342,7 +342,7 @@ enum mlx5_event {
MLX5_EVENT_TYPE_PAGE_FAULT = 0xc,
MLX5_EVENT_TYPE_NIC_VPORT_CHANGE = 0xd,
MLX5_EVENT_TYPE_HOST_PARAMS_CHANGE = 0xe,
MLX5_EVENT_TYPE_ESW_FUNCTIONS_CHANGED = 0xe,
MLX5_EVENT_TYPE_DCT_DRAINED = 0x1c,
......
......@@ -155,7 +155,7 @@ enum {
MLX5_CMD_OP_QUERY_XRQ_DC_PARAMS_ENTRY = 0x725,
MLX5_CMD_OP_SET_XRQ_DC_PARAMS_ENTRY = 0x726,
MLX5_CMD_OP_QUERY_XRQ_ERROR_PARAMS = 0x727,
MLX5_CMD_OP_QUERY_HOST_PARAMS = 0x740,
MLX5_CMD_OP_QUERY_ESW_FUNCTIONS = 0x740,
MLX5_CMD_OP_QUERY_VPORT_STATE = 0x750,
MLX5_CMD_OP_MODIFY_VPORT_STATE = 0x751,
MLX5_CMD_OP_QUERY_ESW_VPORT_CONTEXT = 0x752,
......@@ -9721,7 +9721,7 @@ struct mlx5_ifc_host_params_context_bits {
u8 reserved_at_80[0x180];
};
struct mlx5_ifc_query_host_params_in_bits {
struct mlx5_ifc_query_esw_functions_in_bits {
u8 opcode[0x10];
u8 reserved_at_10[0x10];
......@@ -9731,7 +9731,7 @@ struct mlx5_ifc_query_host_params_in_bits {
u8 reserved_at_40[0x40];
};
struct mlx5_ifc_query_host_params_out_bits {
struct mlx5_ifc_query_esw_functions_out_bits {
u8 status[0x8];
u8 reserved_at_8[0x18];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment