From: Mark Bloch Deployments that always operate in switchdev mode currently require manual devlink configuration after driver probe, which complicates automated provisioning. Introduce MLX5_PROF_MASK_DEF_SWITCHDEV, a new profile mask bit, and profile index 8. When a device is initialized or reloaded with this profile, the driver automatically switches the e-switch to switchdev mode by calling mlx5_devlink_eswitch_mode_set() immediately after bringing the device online. A no-op stub of mlx5_devlink_eswitch_mode_set() is added for builds without CONFIG_MLX5_ESWITCH. Signed-off-by: Mark Bloch Reviewed-by: Moshe Shemesh Signed-off-by: Tariq Toukan --- .../net/ethernet/mellanox/mlx5/core/eswitch.h | 6 +++ .../net/ethernet/mellanox/mlx5/core/main.c | 43 ++++++++++++++++++- include/linux/mlx5/driver.h | 2 + 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h index 3858690e09b4..cfb9595f9de8 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h @@ -1049,6 +1049,12 @@ mlx5_esw_lag_demux_rule_create(struct mlx5_eswitch *esw, u16 vport_num, return ERR_PTR(-EOPNOTSUPP); } +static inline int +mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode, + struct netlink_ext_ack *extack) +{ + return -EOPNOTSUPP; +} #endif /* CONFIG_MLX5_ESWITCH */ #endif /* __MLX5_ESWITCH_H__ */ diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 74827e8ca125..4cdda15ed7f5 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -86,7 +86,7 @@ MODULE_PARM_DESC(debug_mask, "debug mask: 1 = dump cmd data, 2 = dump cmd exec t static unsigned int prof_sel = MLX5_DEFAULT_PROF; module_param_named(prof_sel, prof_sel, uint, 0444); -MODULE_PARM_DESC(prof_sel, "profile selector. Valid range 0 - 2"); +MODULE_PARM_DESC(prof_sel, "profile selector. Valid range 0 - 3 and 8"); static u32 sw_owner_id[4]; #define MAX_SW_VHCA_ID (BIT(__mlx5_bit_sz(cmd_hca_cap_2, sw_vhca_id)) - 1) @@ -99,6 +99,8 @@ enum { #define LOG_MAX_SUPPORTED_QPS 0xff +#define MLX5_PROF_SEL_LAST_NIC 3 +#define MLX5_PROF_SEL_FIRST_ESW 8 static struct mlx5_profile profile[] = { [0] = { .mask = 0, @@ -120,6 +122,11 @@ static struct mlx5_profile profile[] = { .log_max_qp = LOG_MAX_SUPPORTED_QPS, .num_cmd_caches = 0, }, + [8] = { + .mask = MLX5_PROF_MASK_DEF_SWITCHDEV | MLX5_PROF_MASK_QP_SIZE, + .log_max_qp = LOG_MAX_SUPPORTED_QPS, + .num_cmd_caches = MLX5_NUM_COMMAND_CACHES, + }, }; static int wait_fw_init(struct mlx5_core_dev *dev, u32 max_wait_mili, @@ -1385,6 +1392,22 @@ static void mlx5_unload(struct mlx5_core_dev *dev) mlx5_free_bfreg(dev, &dev->priv.bfreg); } +static void mlx5_set_default_switchdev(struct mlx5_core_dev *dev) +{ + int err; + + /* Default switchdev is best-effort; keep the device usable on + * failure. + */ + err = mlx5_devlink_eswitch_mode_set(priv_to_devlink(dev), + DEVLINK_ESWITCH_MODE_SWITCHDEV, + NULL); + if (err && err != -EOPNOTSUPP) + mlx5_core_warn(dev, + "Failed to set switchdev as default, continuing in current mode, err(%d)\n", + err); +} + int mlx5_init_one_devl_locked(struct mlx5_core_dev *dev) { bool light_probe = mlx5_dev_is_lightweight(dev); @@ -1431,6 +1454,10 @@ int mlx5_init_one_devl_locked(struct mlx5_core_dev *dev) mlx5_core_err(dev, "mlx5_hwmon_dev_register failed with error code %d\n", err); mutex_unlock(&dev->intf_state_mutex); + + if (dev->profile.mask & MLX5_PROF_MASK_DEF_SWITCHDEV) + mlx5_set_default_switchdev(dev); + return 0; err_register: @@ -1532,6 +1559,10 @@ int mlx5_load_one_devl_locked(struct mlx5_core_dev *dev, bool recovery) goto err_attach; mutex_unlock(&dev->intf_state_mutex); + + if (dev->profile.mask & MLX5_PROF_MASK_DEF_SWITCHDEV) + mlx5_set_default_switchdev(dev); + return 0; err_attach: @@ -2314,6 +2345,16 @@ static void mlx5_core_verify_params(void) MLX5_DEFAULT_PROF); prof_sel = MLX5_DEFAULT_PROF; } + + if (prof_sel > MLX5_PROF_SEL_LAST_NIC && + prof_sel < MLX5_PROF_SEL_FIRST_ESW) { + pr_warn("mlx5_core: WARNING: Invalid module parameter prof_sel %d invalid range %d - %d, changing back to default (%d)\n", + prof_sel, + MLX5_PROF_SEL_LAST_NIC + 1, + MLX5_PROF_SEL_FIRST_ESW - 1, + MLX5_DEFAULT_PROF); + prof_sel = MLX5_DEFAULT_PROF; + } } static int __init mlx5_init(void) diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index 04b96c5abb57..65298c07df4d 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -705,6 +705,8 @@ struct mlx5_st; enum { MLX5_PROF_MASK_QP_SIZE = (u64)1 << 0, + MLX5_PROF_MASK_MR_CACHE = (u64)1 << 1, + MLX5_PROF_MASK_DEF_SWITCHDEV = (u64)1 << 2, }; struct mlx5_profile { -- 2.44.0