1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2 /* Copyright (c) 2019 Mellanox Technologies */ 3 4 #include <devlink.h> 5 6 #include "mlx5_core.h" 7 #include "fw_reset.h" 8 #include "fs_core.h" 9 #include "eswitch.h" 10 11 static int mlx5_devlink_flash_update(struct devlink *devlink, 12 struct devlink_flash_update_params *params, 13 struct netlink_ext_ack *extack) 14 { 15 struct mlx5_core_dev *dev = devlink_priv(devlink); 16 const struct firmware *fw; 17 int err; 18 19 err = request_firmware_direct(&fw, params->file_name, &dev->pdev->dev); 20 if (err) 21 return err; 22 23 err = mlx5_firmware_flash(dev, fw, extack); 24 release_firmware(fw); 25 26 return err; 27 } 28 29 static u8 mlx5_fw_ver_major(u32 version) 30 { 31 return (version >> 24) & 0xff; 32 } 33 34 static u8 mlx5_fw_ver_minor(u32 version) 35 { 36 return (version >> 16) & 0xff; 37 } 38 39 static u16 mlx5_fw_ver_subminor(u32 version) 40 { 41 return version & 0xffff; 42 } 43 44 #define DEVLINK_FW_STRING_LEN 32 45 46 static int 47 mlx5_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req, 48 struct netlink_ext_ack *extack) 49 { 50 struct mlx5_core_dev *dev = devlink_priv(devlink); 51 char version_str[DEVLINK_FW_STRING_LEN]; 52 u32 running_fw, stored_fw; 53 int err; 54 55 err = devlink_info_driver_name_put(req, DRIVER_NAME); 56 if (err) 57 return err; 58 59 err = devlink_info_version_fixed_put(req, "fw.psid", dev->board_id); 60 if (err) 61 return err; 62 63 err = mlx5_fw_version_query(dev, &running_fw, &stored_fw); 64 if (err) 65 return err; 66 67 snprintf(version_str, sizeof(version_str), "%d.%d.%04d", 68 mlx5_fw_ver_major(running_fw), mlx5_fw_ver_minor(running_fw), 69 mlx5_fw_ver_subminor(running_fw)); 70 err = devlink_info_version_running_put(req, "fw.version", version_str); 71 if (err) 72 return err; 73 74 /* no pending version, return running (stored) version */ 75 if (stored_fw == 0) 76 stored_fw = running_fw; 77 78 snprintf(version_str, sizeof(version_str), "%d.%d.%04d", 79 mlx5_fw_ver_major(stored_fw), mlx5_fw_ver_minor(stored_fw), 80 mlx5_fw_ver_subminor(stored_fw)); 81 err = devlink_info_version_stored_put(req, "fw.version", version_str); 82 if (err) 83 return err; 84 85 return 0; 86 } 87 88 static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netlink_ext_ack *extack) 89 { 90 struct mlx5_core_dev *dev = devlink_priv(devlink); 91 u8 reset_level, reset_type, net_port_alive; 92 int err; 93 94 err = mlx5_fw_reset_query(dev, &reset_level, &reset_type); 95 if (err) 96 return err; 97 if (!(reset_level & MLX5_MFRL_REG_RESET_LEVEL3)) { 98 NL_SET_ERR_MSG_MOD(extack, "FW activate requires reboot"); 99 return -EINVAL; 100 } 101 102 net_port_alive = !!(reset_type & MLX5_MFRL_REG_RESET_TYPE_NET_PORT_ALIVE); 103 err = mlx5_fw_reset_set_reset_sync(dev, net_port_alive); 104 if (err) 105 goto out; 106 107 err = mlx5_fw_reset_wait_reset_done(dev); 108 out: 109 if (err) 110 NL_SET_ERR_MSG_MOD(extack, "FW activate command failed"); 111 return err; 112 } 113 114 static int mlx5_devlink_trigger_fw_live_patch(struct devlink *devlink, 115 struct netlink_ext_ack *extack) 116 { 117 struct mlx5_core_dev *dev = devlink_priv(devlink); 118 u8 reset_level; 119 int err; 120 121 err = mlx5_fw_reset_query(dev, &reset_level, NULL); 122 if (err) 123 return err; 124 if (!(reset_level & MLX5_MFRL_REG_RESET_LEVEL0)) { 125 NL_SET_ERR_MSG_MOD(extack, 126 "FW upgrade to the stored FW can't be done by FW live patching"); 127 return -EINVAL; 128 } 129 130 return mlx5_fw_reset_set_live_patch(dev); 131 } 132 133 static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change, 134 enum devlink_reload_action action, 135 enum devlink_reload_limit limit, 136 struct netlink_ext_ack *extack) 137 { 138 struct mlx5_core_dev *dev = devlink_priv(devlink); 139 140 switch (action) { 141 case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: 142 mlx5_unload_one(dev, false); 143 return 0; 144 case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: 145 if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET) 146 return mlx5_devlink_trigger_fw_live_patch(devlink, extack); 147 return mlx5_devlink_reload_fw_activate(devlink, extack); 148 default: 149 /* Unsupported action should not get to this function */ 150 WARN_ON(1); 151 return -EOPNOTSUPP; 152 } 153 } 154 155 static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_action action, 156 enum devlink_reload_limit limit, u32 *actions_performed, 157 struct netlink_ext_ack *extack) 158 { 159 struct mlx5_core_dev *dev = devlink_priv(devlink); 160 161 *actions_performed = BIT(action); 162 switch (action) { 163 case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: 164 return mlx5_load_one(dev, false); 165 case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: 166 if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET) 167 break; 168 /* On fw_activate action, also driver is reloaded and reinit performed */ 169 *actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT); 170 return mlx5_load_one(dev, false); 171 default: 172 /* Unsupported action should not get to this function */ 173 WARN_ON(1); 174 return -EOPNOTSUPP; 175 } 176 177 return 0; 178 } 179 180 static const struct devlink_ops mlx5_devlink_ops = { 181 #ifdef CONFIG_MLX5_ESWITCH 182 .eswitch_mode_set = mlx5_devlink_eswitch_mode_set, 183 .eswitch_mode_get = mlx5_devlink_eswitch_mode_get, 184 .eswitch_inline_mode_set = mlx5_devlink_eswitch_inline_mode_set, 185 .eswitch_inline_mode_get = mlx5_devlink_eswitch_inline_mode_get, 186 .eswitch_encap_mode_set = mlx5_devlink_eswitch_encap_mode_set, 187 .eswitch_encap_mode_get = mlx5_devlink_eswitch_encap_mode_get, 188 .port_function_hw_addr_get = mlx5_devlink_port_function_hw_addr_get, 189 .port_function_hw_addr_set = mlx5_devlink_port_function_hw_addr_set, 190 #endif 191 .flash_update = mlx5_devlink_flash_update, 192 .info_get = mlx5_devlink_info_get, 193 .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) | 194 BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE), 195 .reload_limits = BIT(DEVLINK_RELOAD_LIMIT_NO_RESET), 196 .reload_down = mlx5_devlink_reload_down, 197 .reload_up = mlx5_devlink_reload_up, 198 }; 199 200 struct devlink *mlx5_devlink_alloc(void) 201 { 202 return devlink_alloc(&mlx5_devlink_ops, sizeof(struct mlx5_core_dev)); 203 } 204 205 void mlx5_devlink_free(struct devlink *devlink) 206 { 207 devlink_free(devlink); 208 } 209 210 static int mlx5_devlink_fs_mode_validate(struct devlink *devlink, u32 id, 211 union devlink_param_value val, 212 struct netlink_ext_ack *extack) 213 { 214 struct mlx5_core_dev *dev = devlink_priv(devlink); 215 char *value = val.vstr; 216 int err = 0; 217 218 if (!strcmp(value, "dmfs")) { 219 return 0; 220 } else if (!strcmp(value, "smfs")) { 221 u8 eswitch_mode; 222 bool smfs_cap; 223 224 eswitch_mode = mlx5_eswitch_mode(dev->priv.eswitch); 225 smfs_cap = mlx5_fs_dr_is_supported(dev); 226 227 if (!smfs_cap) { 228 err = -EOPNOTSUPP; 229 NL_SET_ERR_MSG_MOD(extack, 230 "Software managed steering is not supported by current device"); 231 } 232 233 else if (eswitch_mode == MLX5_ESWITCH_OFFLOADS) { 234 NL_SET_ERR_MSG_MOD(extack, 235 "Software managed steering is not supported when eswitch offloads enabled."); 236 err = -EOPNOTSUPP; 237 } 238 } else { 239 NL_SET_ERR_MSG_MOD(extack, 240 "Bad parameter: supported values are [\"dmfs\", \"smfs\"]"); 241 err = -EINVAL; 242 } 243 244 return err; 245 } 246 247 static int mlx5_devlink_fs_mode_set(struct devlink *devlink, u32 id, 248 struct devlink_param_gset_ctx *ctx) 249 { 250 struct mlx5_core_dev *dev = devlink_priv(devlink); 251 enum mlx5_flow_steering_mode mode; 252 253 if (!strcmp(ctx->val.vstr, "smfs")) 254 mode = MLX5_FLOW_STEERING_MODE_SMFS; 255 else 256 mode = MLX5_FLOW_STEERING_MODE_DMFS; 257 dev->priv.steering->mode = mode; 258 259 return 0; 260 } 261 262 static int mlx5_devlink_fs_mode_get(struct devlink *devlink, u32 id, 263 struct devlink_param_gset_ctx *ctx) 264 { 265 struct mlx5_core_dev *dev = devlink_priv(devlink); 266 267 if (dev->priv.steering->mode == MLX5_FLOW_STEERING_MODE_SMFS) 268 strcpy(ctx->val.vstr, "smfs"); 269 else 270 strcpy(ctx->val.vstr, "dmfs"); 271 return 0; 272 } 273 274 static int mlx5_devlink_enable_roce_validate(struct devlink *devlink, u32 id, 275 union devlink_param_value val, 276 struct netlink_ext_ack *extack) 277 { 278 struct mlx5_core_dev *dev = devlink_priv(devlink); 279 bool new_state = val.vbool; 280 281 if (new_state && !MLX5_CAP_GEN(dev, roce)) { 282 NL_SET_ERR_MSG_MOD(extack, "Device doesn't support RoCE"); 283 return -EOPNOTSUPP; 284 } 285 286 return 0; 287 } 288 289 #ifdef CONFIG_MLX5_ESWITCH 290 static int mlx5_devlink_large_group_num_validate(struct devlink *devlink, u32 id, 291 union devlink_param_value val, 292 struct netlink_ext_ack *extack) 293 { 294 int group_num = val.vu32; 295 296 if (group_num < 1 || group_num > 1024) { 297 NL_SET_ERR_MSG_MOD(extack, 298 "Unsupported group number, supported range is 1-1024"); 299 return -EOPNOTSUPP; 300 } 301 302 return 0; 303 } 304 #endif 305 306 static int mlx5_devlink_enable_remote_dev_reset_set(struct devlink *devlink, u32 id, 307 struct devlink_param_gset_ctx *ctx) 308 { 309 struct mlx5_core_dev *dev = devlink_priv(devlink); 310 311 mlx5_fw_reset_enable_remote_dev_reset_set(dev, ctx->val.vbool); 312 return 0; 313 } 314 315 static int mlx5_devlink_enable_remote_dev_reset_get(struct devlink *devlink, u32 id, 316 struct devlink_param_gset_ctx *ctx) 317 { 318 struct mlx5_core_dev *dev = devlink_priv(devlink); 319 320 ctx->val.vbool = mlx5_fw_reset_enable_remote_dev_reset_get(dev); 321 return 0; 322 } 323 324 static const struct devlink_param mlx5_devlink_params[] = { 325 DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_FLOW_STEERING_MODE, 326 "flow_steering_mode", DEVLINK_PARAM_TYPE_STRING, 327 BIT(DEVLINK_PARAM_CMODE_RUNTIME), 328 mlx5_devlink_fs_mode_get, mlx5_devlink_fs_mode_set, 329 mlx5_devlink_fs_mode_validate), 330 DEVLINK_PARAM_GENERIC(ENABLE_ROCE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), 331 NULL, NULL, mlx5_devlink_enable_roce_validate), 332 #ifdef CONFIG_MLX5_ESWITCH 333 DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM, 334 "fdb_large_groups", DEVLINK_PARAM_TYPE_U32, 335 BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), 336 NULL, NULL, 337 mlx5_devlink_large_group_num_validate), 338 #endif 339 DEVLINK_PARAM_GENERIC(ENABLE_REMOTE_DEV_RESET, BIT(DEVLINK_PARAM_CMODE_RUNTIME), 340 mlx5_devlink_enable_remote_dev_reset_get, 341 mlx5_devlink_enable_remote_dev_reset_set, NULL), 342 }; 343 344 static void mlx5_devlink_set_params_init_values(struct devlink *devlink) 345 { 346 struct mlx5_core_dev *dev = devlink_priv(devlink); 347 union devlink_param_value value; 348 349 if (dev->priv.steering->mode == MLX5_FLOW_STEERING_MODE_DMFS) 350 strcpy(value.vstr, "dmfs"); 351 else 352 strcpy(value.vstr, "smfs"); 353 devlink_param_driverinit_value_set(devlink, 354 MLX5_DEVLINK_PARAM_ID_FLOW_STEERING_MODE, 355 value); 356 357 value.vbool = MLX5_CAP_GEN(dev, roce); 358 devlink_param_driverinit_value_set(devlink, 359 DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE, 360 value); 361 362 #ifdef CONFIG_MLX5_ESWITCH 363 value.vu32 = ESW_OFFLOADS_DEFAULT_NUM_GROUPS; 364 devlink_param_driverinit_value_set(devlink, 365 MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM, 366 value); 367 #endif 368 } 369 370 int mlx5_devlink_register(struct devlink *devlink, struct device *dev) 371 { 372 int err; 373 374 err = devlink_register(devlink, dev); 375 if (err) 376 return err; 377 378 err = devlink_params_register(devlink, mlx5_devlink_params, 379 ARRAY_SIZE(mlx5_devlink_params)); 380 if (err) 381 goto params_reg_err; 382 mlx5_devlink_set_params_init_values(devlink); 383 devlink_params_publish(devlink); 384 return 0; 385 386 params_reg_err: 387 devlink_unregister(devlink); 388 return err; 389 } 390 391 void mlx5_devlink_unregister(struct devlink *devlink) 392 { 393 devlink_params_unregister(devlink, mlx5_devlink_params, 394 ARRAY_SIZE(mlx5_devlink_params)); 395 devlink_unregister(devlink); 396 } 397