Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
0002 /* Copyright (c) 2019 Mellanox Technologies */
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     /* no pending version, return running (stored) version */
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         /* Reload results in deleting SF device which further results in
0151          * unregistering devlink instance while holding devlink_mutext.
0152          * Hence, do not support reload.
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         /* Unsupported action should not get to this function */
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         /* On fw_activate action, also driver is reloaded and reinit performed */
0202         *actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
0203         ret = mlx5_load_one_devl_locked(dev, false);
0204         break;
0205     default:
0206         /* Unsupported action should not get to this function */
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 }