0001
0002
0003
0004 #include <devlink.h>
0005
0006 #include "mlx5_core.h"
0007 #include "fw_reset.h"
0008 #include "fs_core.h"
0009 #include "eswitch.h"
0010 #include "esw/qos.h"
0011 #include "sf/dev/dev.h"
0012 #include "sf/sf.h"
0013
0014 static int mlx5_devlink_flash_update(struct devlink *devlink,
0015 struct devlink_flash_update_params *params,
0016 struct netlink_ext_ack *extack)
0017 {
0018 struct mlx5_core_dev *dev = devlink_priv(devlink);
0019
0020 return mlx5_firmware_flash(dev, params->fw, extack);
0021 }
0022
0023 static u8 mlx5_fw_ver_major(u32 version)
0024 {
0025 return (version >> 24) & 0xff;
0026 }
0027
0028 static u8 mlx5_fw_ver_minor(u32 version)
0029 {
0030 return (version >> 16) & 0xff;
0031 }
0032
0033 static u16 mlx5_fw_ver_subminor(u32 version)
0034 {
0035 return version & 0xffff;
0036 }
0037
0038 #define DEVLINK_FW_STRING_LEN 32
0039
0040 static int
0041 mlx5_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
0042 struct netlink_ext_ack *extack)
0043 {
0044 struct mlx5_core_dev *dev = devlink_priv(devlink);
0045 char version_str[DEVLINK_FW_STRING_LEN];
0046 u32 running_fw, stored_fw;
0047 int err;
0048
0049 err = devlink_info_driver_name_put(req, KBUILD_MODNAME);
0050 if (err)
0051 return err;
0052
0053 err = devlink_info_version_fixed_put(req, "fw.psid", dev->board_id);
0054 if (err)
0055 return err;
0056
0057 err = mlx5_fw_version_query(dev, &running_fw, &stored_fw);
0058 if (err)
0059 return err;
0060
0061 snprintf(version_str, sizeof(version_str), "%d.%d.%04d",
0062 mlx5_fw_ver_major(running_fw), mlx5_fw_ver_minor(running_fw),
0063 mlx5_fw_ver_subminor(running_fw));
0064 err = devlink_info_version_running_put(req, "fw.version", version_str);
0065 if (err)
0066 return err;
0067 err = devlink_info_version_running_put(req,
0068 DEVLINK_INFO_VERSION_GENERIC_FW,
0069 version_str);
0070 if (err)
0071 return err;
0072
0073
0074 if (stored_fw == 0)
0075 stored_fw = running_fw;
0076
0077 snprintf(version_str, sizeof(version_str), "%d.%d.%04d",
0078 mlx5_fw_ver_major(stored_fw), mlx5_fw_ver_minor(stored_fw),
0079 mlx5_fw_ver_subminor(stored_fw));
0080 err = devlink_info_version_stored_put(req, "fw.version", version_str);
0081 if (err)
0082 return err;
0083 return devlink_info_version_stored_put(req,
0084 DEVLINK_INFO_VERSION_GENERIC_FW,
0085 version_str);
0086 }
0087
0088 static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netlink_ext_ack *extack)
0089 {
0090 struct mlx5_core_dev *dev = devlink_priv(devlink);
0091 u8 reset_level, reset_type, net_port_alive;
0092 int err;
0093
0094 err = mlx5_fw_reset_query(dev, &reset_level, &reset_type);
0095 if (err)
0096 return err;
0097 if (!(reset_level & MLX5_MFRL_REG_RESET_LEVEL3)) {
0098 NL_SET_ERR_MSG_MOD(extack, "FW activate requires reboot");
0099 return -EINVAL;
0100 }
0101
0102 net_port_alive = !!(reset_type & MLX5_MFRL_REG_RESET_TYPE_NET_PORT_ALIVE);
0103 err = mlx5_fw_reset_set_reset_sync(dev, net_port_alive, extack);
0104 if (err)
0105 return err;
0106
0107 err = mlx5_fw_reset_wait_reset_done(dev);
0108 if (err)
0109 return err;
0110
0111 mlx5_unload_one_devl_locked(dev);
0112 err = mlx5_health_wait_pci_up(dev);
0113 if (err)
0114 NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
0115
0116 return err;
0117 }
0118
0119 static int mlx5_devlink_trigger_fw_live_patch(struct devlink *devlink,
0120 struct netlink_ext_ack *extack)
0121 {
0122 struct mlx5_core_dev *dev = devlink_priv(devlink);
0123 u8 reset_level;
0124 int err;
0125
0126 err = mlx5_fw_reset_query(dev, &reset_level, NULL);
0127 if (err)
0128 return err;
0129 if (!(reset_level & MLX5_MFRL_REG_RESET_LEVEL0)) {
0130 NL_SET_ERR_MSG_MOD(extack,
0131 "FW upgrade to the stored FW can't be done by FW live patching");
0132 return -EINVAL;
0133 }
0134
0135 return mlx5_fw_reset_set_live_patch(dev);
0136 }
0137
0138 static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
0139 enum devlink_reload_action action,
0140 enum devlink_reload_limit limit,
0141 struct netlink_ext_ack *extack)
0142 {
0143 struct mlx5_core_dev *dev = devlink_priv(devlink);
0144 struct pci_dev *pdev = dev->pdev;
0145 bool sf_dev_allocated;
0146 int ret = 0;
0147
0148 sf_dev_allocated = mlx5_sf_dev_allocated(dev);
0149 if (sf_dev_allocated) {
0150
0151
0152
0153
0154 NL_SET_ERR_MSG_MOD(extack, "reload is unsupported when SFs are allocated");
0155 return -EOPNOTSUPP;
0156 }
0157
0158 if (mlx5_lag_is_active(dev)) {
0159 NL_SET_ERR_MSG_MOD(extack, "reload is unsupported in Lag mode");
0160 return -EOPNOTSUPP;
0161 }
0162
0163 if (pci_num_vf(pdev)) {
0164 NL_SET_ERR_MSG_MOD(extack, "reload while VFs are present is unfavorable");
0165 }
0166
0167 switch (action) {
0168 case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
0169 mlx5_unload_one_devl_locked(dev);
0170 break;
0171 case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
0172 if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
0173 ret = mlx5_devlink_trigger_fw_live_patch(devlink, extack);
0174 else
0175 ret = mlx5_devlink_reload_fw_activate(devlink, extack);
0176 break;
0177 default:
0178
0179 WARN_ON(1);
0180 ret = -EOPNOTSUPP;
0181 }
0182
0183 return ret;
0184 }
0185
0186 static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_action action,
0187 enum devlink_reload_limit limit, u32 *actions_performed,
0188 struct netlink_ext_ack *extack)
0189 {
0190 struct mlx5_core_dev *dev = devlink_priv(devlink);
0191 int ret = 0;
0192
0193 *actions_performed = BIT(action);
0194 switch (action) {
0195 case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
0196 ret = mlx5_load_one_devl_locked(dev, false);
0197 break;
0198 case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
0199 if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
0200 break;
0201
0202 *actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
0203 ret = mlx5_load_one_devl_locked(dev, false);
0204 break;
0205 default:
0206
0207 WARN_ON(1);
0208 ret = -EOPNOTSUPP;
0209 }
0210
0211 return ret;
0212 }
0213
0214 static struct mlx5_devlink_trap *mlx5_find_trap_by_id(struct mlx5_core_dev *dev, int trap_id)
0215 {
0216 struct mlx5_devlink_trap *dl_trap;
0217
0218 list_for_each_entry(dl_trap, &dev->priv.traps, list)
0219 if (dl_trap->trap.id == trap_id)
0220 return dl_trap;
0221
0222 return NULL;
0223 }
0224
0225 static int mlx5_devlink_trap_init(struct devlink *devlink, const struct devlink_trap *trap,
0226 void *trap_ctx)
0227 {
0228 struct mlx5_core_dev *dev = devlink_priv(devlink);
0229 struct mlx5_devlink_trap *dl_trap;
0230
0231 dl_trap = kzalloc(sizeof(*dl_trap), GFP_KERNEL);
0232 if (!dl_trap)
0233 return -ENOMEM;
0234
0235 dl_trap->trap.id = trap->id;
0236 dl_trap->trap.action = DEVLINK_TRAP_ACTION_DROP;
0237 dl_trap->item = trap_ctx;
0238
0239 if (mlx5_find_trap_by_id(dev, trap->id)) {
0240 kfree(dl_trap);
0241 mlx5_core_err(dev, "Devlink trap: Trap 0x%x already found", trap->id);
0242 return -EEXIST;
0243 }
0244
0245 list_add_tail(&dl_trap->list, &dev->priv.traps);
0246 return 0;
0247 }
0248
0249 static void mlx5_devlink_trap_fini(struct devlink *devlink, const struct devlink_trap *trap,
0250 void *trap_ctx)
0251 {
0252 struct mlx5_core_dev *dev = devlink_priv(devlink);
0253 struct mlx5_devlink_trap *dl_trap;
0254
0255 dl_trap = mlx5_find_trap_by_id(dev, trap->id);
0256 if (!dl_trap) {
0257 mlx5_core_err(dev, "Devlink trap: Missing trap id 0x%x", trap->id);
0258 return;
0259 }
0260 list_del(&dl_trap->list);
0261 kfree(dl_trap);
0262 }
0263
0264 static int mlx5_devlink_trap_action_set(struct devlink *devlink,
0265 const struct devlink_trap *trap,
0266 enum devlink_trap_action action,
0267 struct netlink_ext_ack *extack)
0268 {
0269 struct mlx5_core_dev *dev = devlink_priv(devlink);
0270 enum devlink_trap_action action_orig;
0271 struct mlx5_devlink_trap *dl_trap;
0272 int err = 0;
0273
0274 if (is_mdev_switchdev_mode(dev)) {
0275 NL_SET_ERR_MSG_MOD(extack, "Devlink traps can't be set in switchdev mode");
0276 return -EOPNOTSUPP;
0277 }
0278
0279 dl_trap = mlx5_find_trap_by_id(dev, trap->id);
0280 if (!dl_trap) {
0281 mlx5_core_err(dev, "Devlink trap: Set action on invalid trap id 0x%x", trap->id);
0282 err = -EINVAL;
0283 goto out;
0284 }
0285
0286 if (action != DEVLINK_TRAP_ACTION_DROP && action != DEVLINK_TRAP_ACTION_TRAP) {
0287 err = -EOPNOTSUPP;
0288 goto out;
0289 }
0290
0291 if (action == dl_trap->trap.action)
0292 goto out;
0293
0294 action_orig = dl_trap->trap.action;
0295 dl_trap->trap.action = action;
0296 err = mlx5_blocking_notifier_call_chain(dev, MLX5_DRIVER_EVENT_TYPE_TRAP,
0297 &dl_trap->trap);
0298 if (err)
0299 dl_trap->trap.action = action_orig;
0300 out:
0301 return err;
0302 }
0303
0304 static const struct devlink_ops mlx5_devlink_ops = {
0305 #ifdef CONFIG_MLX5_ESWITCH
0306 .eswitch_mode_set = mlx5_devlink_eswitch_mode_set,
0307 .eswitch_mode_get = mlx5_devlink_eswitch_mode_get,
0308 .eswitch_inline_mode_set = mlx5_devlink_eswitch_inline_mode_set,
0309 .eswitch_inline_mode_get = mlx5_devlink_eswitch_inline_mode_get,
0310 .eswitch_encap_mode_set = mlx5_devlink_eswitch_encap_mode_set,
0311 .eswitch_encap_mode_get = mlx5_devlink_eswitch_encap_mode_get,
0312 .port_function_hw_addr_get = mlx5_devlink_port_function_hw_addr_get,
0313 .port_function_hw_addr_set = mlx5_devlink_port_function_hw_addr_set,
0314 .rate_leaf_tx_share_set = mlx5_esw_devlink_rate_leaf_tx_share_set,
0315 .rate_leaf_tx_max_set = mlx5_esw_devlink_rate_leaf_tx_max_set,
0316 .rate_node_tx_share_set = mlx5_esw_devlink_rate_node_tx_share_set,
0317 .rate_node_tx_max_set = mlx5_esw_devlink_rate_node_tx_max_set,
0318 .rate_node_new = mlx5_esw_devlink_rate_node_new,
0319 .rate_node_del = mlx5_esw_devlink_rate_node_del,
0320 .rate_leaf_parent_set = mlx5_esw_devlink_rate_parent_set,
0321 #endif
0322 #ifdef CONFIG_MLX5_SF_MANAGER
0323 .port_new = mlx5_devlink_sf_port_new,
0324 .port_del = mlx5_devlink_sf_port_del,
0325 .port_fn_state_get = mlx5_devlink_sf_port_fn_state_get,
0326 .port_fn_state_set = mlx5_devlink_sf_port_fn_state_set,
0327 #endif
0328 .flash_update = mlx5_devlink_flash_update,
0329 .info_get = mlx5_devlink_info_get,
0330 .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
0331 BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
0332 .reload_limits = BIT(DEVLINK_RELOAD_LIMIT_NO_RESET),
0333 .reload_down = mlx5_devlink_reload_down,
0334 .reload_up = mlx5_devlink_reload_up,
0335 .trap_init = mlx5_devlink_trap_init,
0336 .trap_fini = mlx5_devlink_trap_fini,
0337 .trap_action_set = mlx5_devlink_trap_action_set,
0338 };
0339
0340 void mlx5_devlink_trap_report(struct mlx5_core_dev *dev, int trap_id, struct sk_buff *skb,
0341 struct devlink_port *dl_port)
0342 {
0343 struct devlink *devlink = priv_to_devlink(dev);
0344 struct mlx5_devlink_trap *dl_trap;
0345
0346 dl_trap = mlx5_find_trap_by_id(dev, trap_id);
0347 if (!dl_trap) {
0348 mlx5_core_err(dev, "Devlink trap: Report on invalid trap id 0x%x", trap_id);
0349 return;
0350 }
0351
0352 if (dl_trap->trap.action != DEVLINK_TRAP_ACTION_TRAP) {
0353 mlx5_core_dbg(dev, "Devlink trap: Trap id %d has action %d", trap_id,
0354 dl_trap->trap.action);
0355 return;
0356 }
0357 devlink_trap_report(devlink, skb, dl_trap->item, dl_port, NULL);
0358 }
0359
0360 int mlx5_devlink_trap_get_num_active(struct mlx5_core_dev *dev)
0361 {
0362 struct mlx5_devlink_trap *dl_trap;
0363 int count = 0;
0364
0365 list_for_each_entry(dl_trap, &dev->priv.traps, list)
0366 if (dl_trap->trap.action == DEVLINK_TRAP_ACTION_TRAP)
0367 count++;
0368
0369 return count;
0370 }
0371
0372 int mlx5_devlink_traps_get_action(struct mlx5_core_dev *dev, int trap_id,
0373 enum devlink_trap_action *action)
0374 {
0375 struct mlx5_devlink_trap *dl_trap;
0376
0377 dl_trap = mlx5_find_trap_by_id(dev, trap_id);
0378 if (!dl_trap) {
0379 mlx5_core_err(dev, "Devlink trap: Get action on invalid trap id 0x%x",
0380 trap_id);
0381 return -EINVAL;
0382 }
0383
0384 *action = dl_trap->trap.action;
0385 return 0;
0386 }
0387
0388 struct devlink *mlx5_devlink_alloc(struct device *dev)
0389 {
0390 return devlink_alloc(&mlx5_devlink_ops, sizeof(struct mlx5_core_dev),
0391 dev);
0392 }
0393
0394 void mlx5_devlink_free(struct devlink *devlink)
0395 {
0396 devlink_free(devlink);
0397 }
0398
0399 static int mlx5_devlink_fs_mode_validate(struct devlink *devlink, u32 id,
0400 union devlink_param_value val,
0401 struct netlink_ext_ack *extack)
0402 {
0403 struct mlx5_core_dev *dev = devlink_priv(devlink);
0404 char *value = val.vstr;
0405 int err = 0;
0406
0407 if (!strcmp(value, "dmfs")) {
0408 return 0;
0409 } else if (!strcmp(value, "smfs")) {
0410 u8 eswitch_mode;
0411 bool smfs_cap;
0412
0413 eswitch_mode = mlx5_eswitch_mode(dev);
0414 smfs_cap = mlx5_fs_dr_is_supported(dev);
0415
0416 if (!smfs_cap) {
0417 err = -EOPNOTSUPP;
0418 NL_SET_ERR_MSG_MOD(extack,
0419 "Software managed steering is not supported by current device");
0420 }
0421
0422 else if (eswitch_mode == MLX5_ESWITCH_OFFLOADS) {
0423 NL_SET_ERR_MSG_MOD(extack,
0424 "Software managed steering is not supported when eswitch offloads enabled.");
0425 err = -EOPNOTSUPP;
0426 }
0427 } else {
0428 NL_SET_ERR_MSG_MOD(extack,
0429 "Bad parameter: supported values are [\"dmfs\", \"smfs\"]");
0430 err = -EINVAL;
0431 }
0432
0433 return err;
0434 }
0435
0436 static int mlx5_devlink_fs_mode_set(struct devlink *devlink, u32 id,
0437 struct devlink_param_gset_ctx *ctx)
0438 {
0439 struct mlx5_core_dev *dev = devlink_priv(devlink);
0440 enum mlx5_flow_steering_mode mode;
0441
0442 if (!strcmp(ctx->val.vstr, "smfs"))
0443 mode = MLX5_FLOW_STEERING_MODE_SMFS;
0444 else
0445 mode = MLX5_FLOW_STEERING_MODE_DMFS;
0446 dev->priv.steering->mode = mode;
0447
0448 return 0;
0449 }
0450
0451 static int mlx5_devlink_fs_mode_get(struct devlink *devlink, u32 id,
0452 struct devlink_param_gset_ctx *ctx)
0453 {
0454 struct mlx5_core_dev *dev = devlink_priv(devlink);
0455
0456 if (dev->priv.steering->mode == MLX5_FLOW_STEERING_MODE_SMFS)
0457 strcpy(ctx->val.vstr, "smfs");
0458 else
0459 strcpy(ctx->val.vstr, "dmfs");
0460 return 0;
0461 }
0462
0463 static int mlx5_devlink_enable_roce_validate(struct devlink *devlink, u32 id,
0464 union devlink_param_value val,
0465 struct netlink_ext_ack *extack)
0466 {
0467 struct mlx5_core_dev *dev = devlink_priv(devlink);
0468 bool new_state = val.vbool;
0469
0470 if (new_state && !MLX5_CAP_GEN(dev, roce) &&
0471 !MLX5_CAP_GEN(dev, roce_rw_supported)) {
0472 NL_SET_ERR_MSG_MOD(extack, "Device doesn't support RoCE");
0473 return -EOPNOTSUPP;
0474 }
0475 if (mlx5_core_is_mp_slave(dev) || mlx5_lag_is_active(dev)) {
0476 NL_SET_ERR_MSG_MOD(extack, "Multi port slave/Lag device can't configure RoCE");
0477 return -EOPNOTSUPP;
0478 }
0479
0480 return 0;
0481 }
0482
0483 #ifdef CONFIG_MLX5_ESWITCH
0484 static int mlx5_devlink_large_group_num_validate(struct devlink *devlink, u32 id,
0485 union devlink_param_value val,
0486 struct netlink_ext_ack *extack)
0487 {
0488 int group_num = val.vu32;
0489
0490 if (group_num < 1 || group_num > 1024) {
0491 NL_SET_ERR_MSG_MOD(extack,
0492 "Unsupported group number, supported range is 1-1024");
0493 return -EOPNOTSUPP;
0494 }
0495
0496 return 0;
0497 }
0498
0499 static int mlx5_devlink_esw_port_metadata_set(struct devlink *devlink, u32 id,
0500 struct devlink_param_gset_ctx *ctx)
0501 {
0502 struct mlx5_core_dev *dev = devlink_priv(devlink);
0503
0504 if (!MLX5_ESWITCH_MANAGER(dev))
0505 return -EOPNOTSUPP;
0506
0507 return mlx5_esw_offloads_vport_metadata_set(dev->priv.eswitch, ctx->val.vbool);
0508 }
0509
0510 static int mlx5_devlink_esw_port_metadata_get(struct devlink *devlink, u32 id,
0511 struct devlink_param_gset_ctx *ctx)
0512 {
0513 struct mlx5_core_dev *dev = devlink_priv(devlink);
0514
0515 if (!MLX5_ESWITCH_MANAGER(dev))
0516 return -EOPNOTSUPP;
0517
0518 ctx->val.vbool = mlx5_eswitch_vport_match_metadata_enabled(dev->priv.eswitch);
0519 return 0;
0520 }
0521
0522 static int mlx5_devlink_esw_port_metadata_validate(struct devlink *devlink, u32 id,
0523 union devlink_param_value val,
0524 struct netlink_ext_ack *extack)
0525 {
0526 struct mlx5_core_dev *dev = devlink_priv(devlink);
0527 u8 esw_mode;
0528
0529 if (!MLX5_ESWITCH_MANAGER(dev)) {
0530 NL_SET_ERR_MSG_MOD(extack, "E-Switch is unsupported");
0531 return -EOPNOTSUPP;
0532 }
0533 esw_mode = mlx5_eswitch_mode(dev);
0534 if (esw_mode == MLX5_ESWITCH_OFFLOADS) {
0535 NL_SET_ERR_MSG_MOD(extack,
0536 "E-Switch must either disabled or non switchdev mode");
0537 return -EBUSY;
0538 }
0539 return 0;
0540 }
0541
0542 #endif
0543
0544 static int mlx5_devlink_enable_remote_dev_reset_set(struct devlink *devlink, u32 id,
0545 struct devlink_param_gset_ctx *ctx)
0546 {
0547 struct mlx5_core_dev *dev = devlink_priv(devlink);
0548
0549 mlx5_fw_reset_enable_remote_dev_reset_set(dev, ctx->val.vbool);
0550 return 0;
0551 }
0552
0553 static int mlx5_devlink_enable_remote_dev_reset_get(struct devlink *devlink, u32 id,
0554 struct devlink_param_gset_ctx *ctx)
0555 {
0556 struct mlx5_core_dev *dev = devlink_priv(devlink);
0557
0558 ctx->val.vbool = mlx5_fw_reset_enable_remote_dev_reset_get(dev);
0559 return 0;
0560 }
0561
0562 static int mlx5_devlink_eq_depth_validate(struct devlink *devlink, u32 id,
0563 union devlink_param_value val,
0564 struct netlink_ext_ack *extack)
0565 {
0566 return (val.vu16 >= 64 && val.vu16 <= 4096) ? 0 : -EINVAL;
0567 }
0568
0569 static const struct devlink_param mlx5_devlink_params[] = {
0570 DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_FLOW_STEERING_MODE,
0571 "flow_steering_mode", DEVLINK_PARAM_TYPE_STRING,
0572 BIT(DEVLINK_PARAM_CMODE_RUNTIME),
0573 mlx5_devlink_fs_mode_get, mlx5_devlink_fs_mode_set,
0574 mlx5_devlink_fs_mode_validate),
0575 DEVLINK_PARAM_GENERIC(ENABLE_ROCE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
0576 NULL, NULL, mlx5_devlink_enable_roce_validate),
0577 #ifdef CONFIG_MLX5_ESWITCH
0578 DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM,
0579 "fdb_large_groups", DEVLINK_PARAM_TYPE_U32,
0580 BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
0581 NULL, NULL,
0582 mlx5_devlink_large_group_num_validate),
0583 DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_ESW_PORT_METADATA,
0584 "esw_port_metadata", DEVLINK_PARAM_TYPE_BOOL,
0585 BIT(DEVLINK_PARAM_CMODE_RUNTIME),
0586 mlx5_devlink_esw_port_metadata_get,
0587 mlx5_devlink_esw_port_metadata_set,
0588 mlx5_devlink_esw_port_metadata_validate),
0589 #endif
0590 DEVLINK_PARAM_GENERIC(ENABLE_REMOTE_DEV_RESET, BIT(DEVLINK_PARAM_CMODE_RUNTIME),
0591 mlx5_devlink_enable_remote_dev_reset_get,
0592 mlx5_devlink_enable_remote_dev_reset_set, NULL),
0593 DEVLINK_PARAM_GENERIC(IO_EQ_SIZE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
0594 NULL, NULL, mlx5_devlink_eq_depth_validate),
0595 DEVLINK_PARAM_GENERIC(EVENT_EQ_SIZE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
0596 NULL, NULL, mlx5_devlink_eq_depth_validate),
0597 };
0598
0599 static void mlx5_devlink_set_params_init_values(struct devlink *devlink)
0600 {
0601 struct mlx5_core_dev *dev = devlink_priv(devlink);
0602 union devlink_param_value value;
0603
0604 value.vbool = MLX5_CAP_GEN(dev, roce);
0605 devlink_param_driverinit_value_set(devlink,
0606 DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
0607 value);
0608
0609 #ifdef CONFIG_MLX5_ESWITCH
0610 value.vu32 = ESW_OFFLOADS_DEFAULT_NUM_GROUPS;
0611 devlink_param_driverinit_value_set(devlink,
0612 MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM,
0613 value);
0614 #endif
0615
0616 value.vu32 = MLX5_COMP_EQ_SIZE;
0617 devlink_param_driverinit_value_set(devlink,
0618 DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE,
0619 value);
0620
0621 value.vu32 = MLX5_NUM_ASYNC_EQE;
0622 devlink_param_driverinit_value_set(devlink,
0623 DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE,
0624 value);
0625 }
0626
0627 static const struct devlink_param enable_eth_param =
0628 DEVLINK_PARAM_GENERIC(ENABLE_ETH, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
0629 NULL, NULL, NULL);
0630
0631 static int mlx5_devlink_eth_param_register(struct devlink *devlink)
0632 {
0633 struct mlx5_core_dev *dev = devlink_priv(devlink);
0634 union devlink_param_value value;
0635 int err;
0636
0637 if (!mlx5_eth_supported(dev))
0638 return 0;
0639
0640 err = devlink_param_register(devlink, &enable_eth_param);
0641 if (err)
0642 return err;
0643
0644 value.vbool = true;
0645 devlink_param_driverinit_value_set(devlink,
0646 DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH,
0647 value);
0648 return 0;
0649 }
0650
0651 static void mlx5_devlink_eth_param_unregister(struct devlink *devlink)
0652 {
0653 struct mlx5_core_dev *dev = devlink_priv(devlink);
0654
0655 if (!mlx5_eth_supported(dev))
0656 return;
0657
0658 devlink_param_unregister(devlink, &enable_eth_param);
0659 }
0660
0661 static int mlx5_devlink_enable_rdma_validate(struct devlink *devlink, u32 id,
0662 union devlink_param_value val,
0663 struct netlink_ext_ack *extack)
0664 {
0665 struct mlx5_core_dev *dev = devlink_priv(devlink);
0666 bool new_state = val.vbool;
0667
0668 if (new_state && !mlx5_rdma_supported(dev))
0669 return -EOPNOTSUPP;
0670 return 0;
0671 }
0672
0673 static const struct devlink_param enable_rdma_param =
0674 DEVLINK_PARAM_GENERIC(ENABLE_RDMA, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
0675 NULL, NULL, mlx5_devlink_enable_rdma_validate);
0676
0677 static int mlx5_devlink_rdma_param_register(struct devlink *devlink)
0678 {
0679 union devlink_param_value value;
0680 int err;
0681
0682 if (!IS_ENABLED(CONFIG_MLX5_INFINIBAND))
0683 return 0;
0684
0685 err = devlink_param_register(devlink, &enable_rdma_param);
0686 if (err)
0687 return err;
0688
0689 value.vbool = true;
0690 devlink_param_driverinit_value_set(devlink,
0691 DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA,
0692 value);
0693 return 0;
0694 }
0695
0696 static void mlx5_devlink_rdma_param_unregister(struct devlink *devlink)
0697 {
0698 if (!IS_ENABLED(CONFIG_MLX5_INFINIBAND))
0699 return;
0700
0701 devlink_param_unregister(devlink, &enable_rdma_param);
0702 }
0703
0704 static const struct devlink_param enable_vnet_param =
0705 DEVLINK_PARAM_GENERIC(ENABLE_VNET, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
0706 NULL, NULL, NULL);
0707
0708 static int mlx5_devlink_vnet_param_register(struct devlink *devlink)
0709 {
0710 struct mlx5_core_dev *dev = devlink_priv(devlink);
0711 union devlink_param_value value;
0712 int err;
0713
0714 if (!mlx5_vnet_supported(dev))
0715 return 0;
0716
0717 err = devlink_param_register(devlink, &enable_vnet_param);
0718 if (err)
0719 return err;
0720
0721 value.vbool = true;
0722 devlink_param_driverinit_value_set(devlink,
0723 DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET,
0724 value);
0725 return 0;
0726 }
0727
0728 static void mlx5_devlink_vnet_param_unregister(struct devlink *devlink)
0729 {
0730 struct mlx5_core_dev *dev = devlink_priv(devlink);
0731
0732 if (!mlx5_vnet_supported(dev))
0733 return;
0734
0735 devlink_param_unregister(devlink, &enable_vnet_param);
0736 }
0737
0738 static int mlx5_devlink_auxdev_params_register(struct devlink *devlink)
0739 {
0740 int err;
0741
0742 err = mlx5_devlink_eth_param_register(devlink);
0743 if (err)
0744 return err;
0745
0746 err = mlx5_devlink_rdma_param_register(devlink);
0747 if (err)
0748 goto rdma_err;
0749
0750 err = mlx5_devlink_vnet_param_register(devlink);
0751 if (err)
0752 goto vnet_err;
0753 return 0;
0754
0755 vnet_err:
0756 mlx5_devlink_rdma_param_unregister(devlink);
0757 rdma_err:
0758 mlx5_devlink_eth_param_unregister(devlink);
0759 return err;
0760 }
0761
0762 static void mlx5_devlink_auxdev_params_unregister(struct devlink *devlink)
0763 {
0764 mlx5_devlink_vnet_param_unregister(devlink);
0765 mlx5_devlink_rdma_param_unregister(devlink);
0766 mlx5_devlink_eth_param_unregister(devlink);
0767 }
0768
0769 static int mlx5_devlink_max_uc_list_validate(struct devlink *devlink, u32 id,
0770 union devlink_param_value val,
0771 struct netlink_ext_ack *extack)
0772 {
0773 struct mlx5_core_dev *dev = devlink_priv(devlink);
0774
0775 if (val.vu32 == 0) {
0776 NL_SET_ERR_MSG_MOD(extack, "max_macs value must be greater than 0");
0777 return -EINVAL;
0778 }
0779
0780 if (!is_power_of_2(val.vu32)) {
0781 NL_SET_ERR_MSG_MOD(extack, "Only power of 2 values are supported for max_macs");
0782 return -EINVAL;
0783 }
0784
0785 if (ilog2(val.vu32) >
0786 MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list)) {
0787 NL_SET_ERR_MSG_MOD(extack, "max_macs value is out of the supported range");
0788 return -EINVAL;
0789 }
0790
0791 return 0;
0792 }
0793
0794 static const struct devlink_param max_uc_list_param =
0795 DEVLINK_PARAM_GENERIC(MAX_MACS, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
0796 NULL, NULL, mlx5_devlink_max_uc_list_validate);
0797
0798 static int mlx5_devlink_max_uc_list_param_register(struct devlink *devlink)
0799 {
0800 struct mlx5_core_dev *dev = devlink_priv(devlink);
0801 union devlink_param_value value;
0802 int err;
0803
0804 if (!MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list_wr_supported))
0805 return 0;
0806
0807 err = devlink_param_register(devlink, &max_uc_list_param);
0808 if (err)
0809 return err;
0810
0811 value.vu32 = 1 << MLX5_CAP_GEN(dev, log_max_current_uc_list);
0812 devlink_param_driverinit_value_set(devlink,
0813 DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
0814 value);
0815 return 0;
0816 }
0817
0818 static void
0819 mlx5_devlink_max_uc_list_param_unregister(struct devlink *devlink)
0820 {
0821 struct mlx5_core_dev *dev = devlink_priv(devlink);
0822
0823 if (!MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list_wr_supported))
0824 return;
0825
0826 devlink_param_unregister(devlink, &max_uc_list_param);
0827 }
0828
0829 #define MLX5_TRAP_DROP(_id, _group_id) \
0830 DEVLINK_TRAP_GENERIC(DROP, DROP, _id, \
0831 DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
0832 DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT)
0833
0834 static const struct devlink_trap mlx5_traps_arr[] = {
0835 MLX5_TRAP_DROP(INGRESS_VLAN_FILTER, L2_DROPS),
0836 MLX5_TRAP_DROP(DMAC_FILTER, L2_DROPS),
0837 };
0838
0839 static const struct devlink_trap_group mlx5_trap_groups_arr[] = {
0840 DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 0),
0841 };
0842
0843 static int mlx5_devlink_traps_register(struct devlink *devlink)
0844 {
0845 struct mlx5_core_dev *core_dev = devlink_priv(devlink);
0846 int err;
0847
0848 err = devl_trap_groups_register(devlink, mlx5_trap_groups_arr,
0849 ARRAY_SIZE(mlx5_trap_groups_arr));
0850 if (err)
0851 return err;
0852
0853 err = devl_traps_register(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr),
0854 &core_dev->priv);
0855 if (err)
0856 goto err_trap_group;
0857 return 0;
0858
0859 err_trap_group:
0860 devl_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
0861 ARRAY_SIZE(mlx5_trap_groups_arr));
0862 return err;
0863 }
0864
0865 static void mlx5_devlink_traps_unregister(struct devlink *devlink)
0866 {
0867 devl_traps_unregister(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr));
0868 devl_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
0869 ARRAY_SIZE(mlx5_trap_groups_arr));
0870 }
0871
0872 int mlx5_devlink_register(struct devlink *devlink)
0873 {
0874 struct mlx5_core_dev *dev = devlink_priv(devlink);
0875 int err;
0876
0877 err = devlink_params_register(devlink, mlx5_devlink_params,
0878 ARRAY_SIZE(mlx5_devlink_params));
0879 if (err)
0880 return err;
0881
0882 mlx5_devlink_set_params_init_values(devlink);
0883
0884 err = mlx5_devlink_auxdev_params_register(devlink);
0885 if (err)
0886 goto auxdev_reg_err;
0887
0888 err = mlx5_devlink_max_uc_list_param_register(devlink);
0889 if (err)
0890 goto max_uc_list_err;
0891
0892 err = mlx5_devlink_traps_register(devlink);
0893 if (err)
0894 goto traps_reg_err;
0895
0896 if (!mlx5_core_is_mp_slave(dev))
0897 devlink_set_features(devlink, DEVLINK_F_RELOAD);
0898
0899 return 0;
0900
0901 traps_reg_err:
0902 mlx5_devlink_max_uc_list_param_unregister(devlink);
0903 max_uc_list_err:
0904 mlx5_devlink_auxdev_params_unregister(devlink);
0905 auxdev_reg_err:
0906 devlink_params_unregister(devlink, mlx5_devlink_params,
0907 ARRAY_SIZE(mlx5_devlink_params));
0908 return err;
0909 }
0910
0911 void mlx5_devlink_unregister(struct devlink *devlink)
0912 {
0913 mlx5_devlink_traps_unregister(devlink);
0914 mlx5_devlink_max_uc_list_param_unregister(devlink);
0915 mlx5_devlink_auxdev_params_unregister(devlink);
0916 devlink_params_unregister(devlink, mlx5_devlink_params,
0917 ARRAY_SIZE(mlx5_devlink_params));
0918 }