Commit e5b9642a authored by Shay Drory's avatar Shay Drory Committed by Jakub Kicinski

net/mlx5: E-Switch, Implement devlink port function cmds to control migratable

Implement devlink port function commands to enable / disable migratable.
This is used to control the migratable capability of the device.
Signed-off-by: default avatarShay Drory <shayd@nvidia.com>
Reviewed-by: default avatarMark Bloch <mbloch@nvidia.com>
Acked-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent a8ce7b26
......@@ -364,6 +364,14 @@ PCI devices/SF.
mlx5 driver support devlink port function attr mechanism to setup RoCE
capability. (refer to Documentation/networking/devlink/devlink-port.rst)
migratable capability setup
---------------------------
User who wants mlx5 PCI VFs to be able to perform live migration need to
explicitly enable the VF migratable capability.
mlx5 driver support devlink port function attr mechanism to setup migratable
capability. (refer to Documentation/networking/devlink/devlink-port.rst)
SF state setup
--------------
To use the SF, the user must activate the SF using the SF function state
......
......@@ -316,6 +316,8 @@ static const struct devlink_ops mlx5_devlink_ops = {
.rate_leaf_parent_set = mlx5_esw_devlink_rate_parent_set,
.port_fn_roce_get = mlx5_devlink_port_fn_roce_get,
.port_fn_roce_set = mlx5_devlink_port_fn_roce_set,
.port_fn_migratable_get = mlx5_devlink_port_fn_migratable_get,
.port_fn_migratable_set = mlx5_devlink_port_fn_migratable_set,
#endif
#ifdef CONFIG_MLX5_SF_MANAGER
.port_new = mlx5_devlink_sf_port_new,
......
......@@ -794,6 +794,14 @@ static int mlx5_esw_vport_caps_get(struct mlx5_eswitch *esw, struct mlx5_vport *
hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability);
vport->info.roce_enabled = MLX5_GET(cmd_hca_cap, hca_caps, roce);
memset(query_ctx, 0, query_out_sz);
err = mlx5_vport_get_other_func_cap(esw->dev, vport->vport, query_ctx,
MLX5_CAP_GENERAL_2);
if (err)
goto out_free;
hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability);
vport->info.mig_enabled = MLX5_GET(cmd_hca_cap_2, hca_caps, migratable);
out_free:
kfree(query_ctx);
return err;
......
......@@ -154,6 +154,7 @@ struct mlx5_vport_info {
u8 spoofchk: 1;
u8 trusted: 1;
u8 roce_enabled: 1;
u8 mig_enabled: 1;
};
/* Vport context events */
......@@ -513,6 +514,10 @@ int mlx5_devlink_port_fn_roce_get(struct devlink_port *port, bool *is_enabled,
struct netlink_ext_ack *extack);
int mlx5_devlink_port_fn_roce_set(struct devlink_port *port, bool enable,
struct netlink_ext_ack *extack);
int mlx5_devlink_port_fn_migratable_get(struct devlink_port *port, bool *is_enabled,
struct netlink_ext_ack *extack);
int mlx5_devlink_port_fn_migratable_set(struct devlink_port *port, bool enable,
struct netlink_ext_ack *extack);
void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw, u8 rep_type);
int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw,
......
......@@ -4038,6 +4038,107 @@ mlx5_devlink_port_fn_get_vport(struct devlink_port *port, struct mlx5_eswitch *e
return mlx5_eswitch_get_vport(esw, vport_num);
}
int mlx5_devlink_port_fn_migratable_get(struct devlink_port *port, bool *is_enabled,
struct netlink_ext_ack *extack)
{
struct mlx5_eswitch *esw;
struct mlx5_vport *vport;
int err = -EOPNOTSUPP;
esw = mlx5_devlink_eswitch_get(port->devlink);
if (IS_ERR(esw))
return PTR_ERR(esw);
if (!MLX5_CAP_GEN(esw->dev, migration)) {
NL_SET_ERR_MSG_MOD(extack, "Device doesn't support migration");
return err;
}
vport = mlx5_devlink_port_fn_get_vport(port, esw);
if (IS_ERR(vport)) {
NL_SET_ERR_MSG_MOD(extack, "Invalid port");
return PTR_ERR(vport);
}
mutex_lock(&esw->state_lock);
if (vport->enabled) {
*is_enabled = vport->info.mig_enabled;
err = 0;
}
mutex_unlock(&esw->state_lock);
return err;
}
int mlx5_devlink_port_fn_migratable_set(struct devlink_port *port, bool enable,
struct netlink_ext_ack *extack)
{
int query_out_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out);
struct mlx5_eswitch *esw;
struct mlx5_vport *vport;
void *query_ctx;
void *hca_caps;
int err = -EOPNOTSUPP;
esw = mlx5_devlink_eswitch_get(port->devlink);
if (IS_ERR(esw))
return PTR_ERR(esw);
if (!MLX5_CAP_GEN(esw->dev, migration)) {
NL_SET_ERR_MSG_MOD(extack, "Device doesn't support migration");
return err;
}
vport = mlx5_devlink_port_fn_get_vport(port, esw);
if (IS_ERR(vport)) {
NL_SET_ERR_MSG_MOD(extack, "Invalid port");
return PTR_ERR(vport);
}
mutex_lock(&esw->state_lock);
if (!vport->enabled) {
NL_SET_ERR_MSG_MOD(extack, "Eswitch vport is disabled");
goto out;
}
if (vport->info.mig_enabled == enable) {
err = 0;
goto out;
}
query_ctx = kzalloc(query_out_sz, GFP_KERNEL);
if (!query_ctx) {
err = -ENOMEM;
goto out;
}
err = mlx5_vport_get_other_func_cap(esw->dev, vport->vport, query_ctx,
MLX5_CAP_GENERAL_2);
if (err) {
NL_SET_ERR_MSG_MOD(extack, "Failed getting HCA caps");
goto out_free;
}
hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability);
memcpy(hca_caps, MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability),
MLX5_UN_SZ_BYTES(hca_cap_union));
MLX5_SET(cmd_hca_cap_2, hca_caps, migratable, 1);
err = mlx5_vport_set_other_func_cap(esw->dev, hca_caps, vport->vport,
MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE2);
if (err) {
NL_SET_ERR_MSG_MOD(extack, "Failed setting HCA migratable cap");
goto out_free;
}
vport->info.mig_enabled = enable;
out_free:
kfree(query_ctx);
out:
mutex_unlock(&esw->state_lock);
return err;
}
int mlx5_devlink_port_fn_roce_get(struct devlink_port *port, bool *is_enabled,
struct netlink_ext_ack *extack)
{
......
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