linux/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
<<
>>
Prefs
   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#include "esw/qos.h"
  11#include "sf/dev/dev.h"
  12#include "sf/sf.h"
  13
  14static int mlx5_devlink_flash_update(struct devlink *devlink,
  15                                     struct devlink_flash_update_params *params,
  16                                     struct netlink_ext_ack *extack)
  17{
  18        struct mlx5_core_dev *dev = devlink_priv(devlink);
  19
  20        return mlx5_firmware_flash(dev, params->fw, extack);
  21}
  22
  23static u8 mlx5_fw_ver_major(u32 version)
  24{
  25        return (version >> 24) & 0xff;
  26}
  27
  28static u8 mlx5_fw_ver_minor(u32 version)
  29{
  30        return (version >> 16) & 0xff;
  31}
  32
  33static u16 mlx5_fw_ver_subminor(u32 version)
  34{
  35        return version & 0xffff;
  36}
  37
  38#define DEVLINK_FW_STRING_LEN 32
  39
  40static int
  41mlx5_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
  42                      struct netlink_ext_ack *extack)
  43{
  44        struct mlx5_core_dev *dev = devlink_priv(devlink);
  45        char version_str[DEVLINK_FW_STRING_LEN];
  46        u32 running_fw, stored_fw;
  47        int err;
  48
  49        err = devlink_info_driver_name_put(req, KBUILD_MODNAME);
  50        if (err)
  51                return err;
  52
  53        err = devlink_info_version_fixed_put(req, "fw.psid", dev->board_id);
  54        if (err)
  55                return err;
  56
  57        err = mlx5_fw_version_query(dev, &running_fw, &stored_fw);
  58        if (err)
  59                return err;
  60
  61        snprintf(version_str, sizeof(version_str), "%d.%d.%04d",
  62                 mlx5_fw_ver_major(running_fw), mlx5_fw_ver_minor(running_fw),
  63                 mlx5_fw_ver_subminor(running_fw));
  64        err = devlink_info_version_running_put(req, "fw.version", version_str);
  65        if (err)
  66                return err;
  67        err = devlink_info_version_running_put(req,
  68                                               DEVLINK_INFO_VERSION_GENERIC_FW,
  69                                               version_str);
  70        if (err)
  71                return err;
  72
  73        /* no pending version, return running (stored) version */
  74        if (stored_fw == 0)
  75                stored_fw = running_fw;
  76
  77        snprintf(version_str, sizeof(version_str), "%d.%d.%04d",
  78                 mlx5_fw_ver_major(stored_fw), mlx5_fw_ver_minor(stored_fw),
  79                 mlx5_fw_ver_subminor(stored_fw));
  80        err = devlink_info_version_stored_put(req, "fw.version", version_str);
  81        if (err)
  82                return err;
  83        return devlink_info_version_stored_put(req,
  84                                               DEVLINK_INFO_VERSION_GENERIC_FW,
  85                                               version_str);
  86}
  87
  88static 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);
 108out:
 109        if (err)
 110                NL_SET_ERR_MSG_MOD(extack, "FW activate command failed");
 111        return err;
 112}
 113
 114static 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
 133static 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        struct pci_dev *pdev = dev->pdev;
 140        bool sf_dev_allocated;
 141
 142        sf_dev_allocated = mlx5_sf_dev_allocated(dev);
 143        if (sf_dev_allocated) {
 144                /* Reload results in deleting SF device which further results in
 145                 * unregistering devlink instance while holding devlink_mutext.
 146                 * Hence, do not support reload.
 147                 */
 148                NL_SET_ERR_MSG_MOD(extack, "reload is unsupported when SFs are allocated");
 149                return -EOPNOTSUPP;
 150        }
 151
 152        if (mlx5_lag_is_active(dev)) {
 153                NL_SET_ERR_MSG_MOD(extack, "reload is unsupported in Lag mode");
 154                return -EOPNOTSUPP;
 155        }
 156
 157        if (pci_num_vf(pdev)) {
 158                NL_SET_ERR_MSG_MOD(extack, "reload while VFs are present is unfavorable");
 159        }
 160
 161        switch (action) {
 162        case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
 163                mlx5_unload_one(dev);
 164                return 0;
 165        case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
 166                if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
 167                        return mlx5_devlink_trigger_fw_live_patch(devlink, extack);
 168                return mlx5_devlink_reload_fw_activate(devlink, extack);
 169        default:
 170                /* Unsupported action should not get to this function */
 171                WARN_ON(1);
 172                return -EOPNOTSUPP;
 173        }
 174}
 175
 176static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_action action,
 177                                  enum devlink_reload_limit limit, u32 *actions_performed,
 178                                  struct netlink_ext_ack *extack)
 179{
 180        struct mlx5_core_dev *dev = devlink_priv(devlink);
 181
 182        *actions_performed = BIT(action);
 183        switch (action) {
 184        case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
 185                return mlx5_load_one(dev);
 186        case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
 187                if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
 188                        break;
 189                /* On fw_activate action, also driver is reloaded and reinit performed */
 190                *actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
 191                return mlx5_load_one(dev);
 192        default:
 193                /* Unsupported action should not get to this function */
 194                WARN_ON(1);
 195                return -EOPNOTSUPP;
 196        }
 197
 198        return 0;
 199}
 200
 201static struct mlx5_devlink_trap *mlx5_find_trap_by_id(struct mlx5_core_dev *dev, int trap_id)
 202{
 203        struct mlx5_devlink_trap *dl_trap;
 204
 205        list_for_each_entry(dl_trap, &dev->priv.traps, list)
 206                if (dl_trap->trap.id == trap_id)
 207                        return dl_trap;
 208
 209        return NULL;
 210}
 211
 212static int mlx5_devlink_trap_init(struct devlink *devlink, const struct devlink_trap *trap,
 213                                  void *trap_ctx)
 214{
 215        struct mlx5_core_dev *dev = devlink_priv(devlink);
 216        struct mlx5_devlink_trap *dl_trap;
 217
 218        dl_trap = kzalloc(sizeof(*dl_trap), GFP_KERNEL);
 219        if (!dl_trap)
 220                return -ENOMEM;
 221
 222        dl_trap->trap.id = trap->id;
 223        dl_trap->trap.action = DEVLINK_TRAP_ACTION_DROP;
 224        dl_trap->item = trap_ctx;
 225
 226        if (mlx5_find_trap_by_id(dev, trap->id)) {
 227                kfree(dl_trap);
 228                mlx5_core_err(dev, "Devlink trap: Trap 0x%x already found", trap->id);
 229                return -EEXIST;
 230        }
 231
 232        list_add_tail(&dl_trap->list, &dev->priv.traps);
 233        return 0;
 234}
 235
 236static void mlx5_devlink_trap_fini(struct devlink *devlink, const struct devlink_trap *trap,
 237                                   void *trap_ctx)
 238{
 239        struct mlx5_core_dev *dev = devlink_priv(devlink);
 240        struct mlx5_devlink_trap *dl_trap;
 241
 242        dl_trap = mlx5_find_trap_by_id(dev, trap->id);
 243        if (!dl_trap) {
 244                mlx5_core_err(dev, "Devlink trap: Missing trap id 0x%x", trap->id);
 245                return;
 246        }
 247        list_del(&dl_trap->list);
 248        kfree(dl_trap);
 249}
 250
 251static int mlx5_devlink_trap_action_set(struct devlink *devlink,
 252                                        const struct devlink_trap *trap,
 253                                        enum devlink_trap_action action,
 254                                        struct netlink_ext_ack *extack)
 255{
 256        struct mlx5_core_dev *dev = devlink_priv(devlink);
 257        enum devlink_trap_action action_orig;
 258        struct mlx5_devlink_trap *dl_trap;
 259        int err = 0;
 260
 261        if (is_mdev_switchdev_mode(dev)) {
 262                NL_SET_ERR_MSG_MOD(extack, "Devlink traps can't be set in switchdev mode");
 263                return -EOPNOTSUPP;
 264        }
 265
 266        dl_trap = mlx5_find_trap_by_id(dev, trap->id);
 267        if (!dl_trap) {
 268                mlx5_core_err(dev, "Devlink trap: Set action on invalid trap id 0x%x", trap->id);
 269                err = -EINVAL;
 270                goto out;
 271        }
 272
 273        if (action != DEVLINK_TRAP_ACTION_DROP && action != DEVLINK_TRAP_ACTION_TRAP) {
 274                err = -EOPNOTSUPP;
 275                goto out;
 276        }
 277
 278        if (action == dl_trap->trap.action)
 279                goto out;
 280
 281        action_orig = dl_trap->trap.action;
 282        dl_trap->trap.action = action;
 283        err = mlx5_blocking_notifier_call_chain(dev, MLX5_DRIVER_EVENT_TYPE_TRAP,
 284                                                &dl_trap->trap);
 285        if (err)
 286                dl_trap->trap.action = action_orig;
 287out:
 288        return err;
 289}
 290
 291static const struct devlink_ops mlx5_devlink_ops = {
 292#ifdef CONFIG_MLX5_ESWITCH
 293        .eswitch_mode_set = mlx5_devlink_eswitch_mode_set,
 294        .eswitch_mode_get = mlx5_devlink_eswitch_mode_get,
 295        .eswitch_inline_mode_set = mlx5_devlink_eswitch_inline_mode_set,
 296        .eswitch_inline_mode_get = mlx5_devlink_eswitch_inline_mode_get,
 297        .eswitch_encap_mode_set = mlx5_devlink_eswitch_encap_mode_set,
 298        .eswitch_encap_mode_get = mlx5_devlink_eswitch_encap_mode_get,
 299        .port_function_hw_addr_get = mlx5_devlink_port_function_hw_addr_get,
 300        .port_function_hw_addr_set = mlx5_devlink_port_function_hw_addr_set,
 301        .rate_leaf_tx_share_set = mlx5_esw_devlink_rate_leaf_tx_share_set,
 302        .rate_leaf_tx_max_set = mlx5_esw_devlink_rate_leaf_tx_max_set,
 303        .rate_node_tx_share_set = mlx5_esw_devlink_rate_node_tx_share_set,
 304        .rate_node_tx_max_set = mlx5_esw_devlink_rate_node_tx_max_set,
 305        .rate_node_new = mlx5_esw_devlink_rate_node_new,
 306        .rate_node_del = mlx5_esw_devlink_rate_node_del,
 307        .rate_leaf_parent_set = mlx5_esw_devlink_rate_parent_set,
 308#endif
 309#ifdef CONFIG_MLX5_SF_MANAGER
 310        .port_new = mlx5_devlink_sf_port_new,
 311        .port_del = mlx5_devlink_sf_port_del,
 312        .port_fn_state_get = mlx5_devlink_sf_port_fn_state_get,
 313        .port_fn_state_set = mlx5_devlink_sf_port_fn_state_set,
 314#endif
 315        .flash_update = mlx5_devlink_flash_update,
 316        .info_get = mlx5_devlink_info_get,
 317        .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
 318                          BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
 319        .reload_limits = BIT(DEVLINK_RELOAD_LIMIT_NO_RESET),
 320        .reload_down = mlx5_devlink_reload_down,
 321        .reload_up = mlx5_devlink_reload_up,
 322        .trap_init = mlx5_devlink_trap_init,
 323        .trap_fini = mlx5_devlink_trap_fini,
 324        .trap_action_set = mlx5_devlink_trap_action_set,
 325};
 326
 327void mlx5_devlink_trap_report(struct mlx5_core_dev *dev, int trap_id, struct sk_buff *skb,
 328                              struct devlink_port *dl_port)
 329{
 330        struct devlink *devlink = priv_to_devlink(dev);
 331        struct mlx5_devlink_trap *dl_trap;
 332
 333        dl_trap = mlx5_find_trap_by_id(dev, trap_id);
 334        if (!dl_trap) {
 335                mlx5_core_err(dev, "Devlink trap: Report on invalid trap id 0x%x", trap_id);
 336                return;
 337        }
 338
 339        if (dl_trap->trap.action != DEVLINK_TRAP_ACTION_TRAP) {
 340                mlx5_core_dbg(dev, "Devlink trap: Trap id %d has action %d", trap_id,
 341                              dl_trap->trap.action);
 342                return;
 343        }
 344        devlink_trap_report(devlink, skb, dl_trap->item, dl_port, NULL);
 345}
 346
 347int mlx5_devlink_trap_get_num_active(struct mlx5_core_dev *dev)
 348{
 349        struct mlx5_devlink_trap *dl_trap;
 350        int count = 0;
 351
 352        list_for_each_entry(dl_trap, &dev->priv.traps, list)
 353                if (dl_trap->trap.action == DEVLINK_TRAP_ACTION_TRAP)
 354                        count++;
 355
 356        return count;
 357}
 358
 359int mlx5_devlink_traps_get_action(struct mlx5_core_dev *dev, int trap_id,
 360                                  enum devlink_trap_action *action)
 361{
 362        struct mlx5_devlink_trap *dl_trap;
 363
 364        dl_trap = mlx5_find_trap_by_id(dev, trap_id);
 365        if (!dl_trap) {
 366                mlx5_core_err(dev, "Devlink trap: Get action on invalid trap id 0x%x",
 367                              trap_id);
 368                return -EINVAL;
 369        }
 370
 371        *action = dl_trap->trap.action;
 372        return 0;
 373}
 374
 375struct devlink *mlx5_devlink_alloc(struct device *dev)
 376{
 377        return devlink_alloc(&mlx5_devlink_ops, sizeof(struct mlx5_core_dev),
 378                             dev);
 379}
 380
 381void mlx5_devlink_free(struct devlink *devlink)
 382{
 383        devlink_free(devlink);
 384}
 385
 386static int mlx5_devlink_fs_mode_validate(struct devlink *devlink, u32 id,
 387                                         union devlink_param_value val,
 388                                         struct netlink_ext_ack *extack)
 389{
 390        struct mlx5_core_dev *dev = devlink_priv(devlink);
 391        char *value = val.vstr;
 392        int err = 0;
 393
 394        if (!strcmp(value, "dmfs")) {
 395                return 0;
 396        } else if (!strcmp(value, "smfs")) {
 397                u8 eswitch_mode;
 398                bool smfs_cap;
 399
 400                eswitch_mode = mlx5_eswitch_mode(dev);
 401                smfs_cap = mlx5_fs_dr_is_supported(dev);
 402
 403                if (!smfs_cap) {
 404                        err = -EOPNOTSUPP;
 405                        NL_SET_ERR_MSG_MOD(extack,
 406                                           "Software managed steering is not supported by current device");
 407                }
 408
 409                else if (eswitch_mode == MLX5_ESWITCH_OFFLOADS) {
 410                        NL_SET_ERR_MSG_MOD(extack,
 411                                           "Software managed steering is not supported when eswitch offloads enabled.");
 412                        err = -EOPNOTSUPP;
 413                }
 414        } else {
 415                NL_SET_ERR_MSG_MOD(extack,
 416                                   "Bad parameter: supported values are [\"dmfs\", \"smfs\"]");
 417                err = -EINVAL;
 418        }
 419
 420        return err;
 421}
 422
 423static int mlx5_devlink_fs_mode_set(struct devlink *devlink, u32 id,
 424                                    struct devlink_param_gset_ctx *ctx)
 425{
 426        struct mlx5_core_dev *dev = devlink_priv(devlink);
 427        enum mlx5_flow_steering_mode mode;
 428
 429        if (!strcmp(ctx->val.vstr, "smfs"))
 430                mode = MLX5_FLOW_STEERING_MODE_SMFS;
 431        else
 432                mode = MLX5_FLOW_STEERING_MODE_DMFS;
 433        dev->priv.steering->mode = mode;
 434
 435        return 0;
 436}
 437
 438static int mlx5_devlink_fs_mode_get(struct devlink *devlink, u32 id,
 439                                    struct devlink_param_gset_ctx *ctx)
 440{
 441        struct mlx5_core_dev *dev = devlink_priv(devlink);
 442
 443        if (dev->priv.steering->mode == MLX5_FLOW_STEERING_MODE_SMFS)
 444                strcpy(ctx->val.vstr, "smfs");
 445        else
 446                strcpy(ctx->val.vstr, "dmfs");
 447        return 0;
 448}
 449
 450static int mlx5_devlink_enable_roce_validate(struct devlink *devlink, u32 id,
 451                                             union devlink_param_value val,
 452                                             struct netlink_ext_ack *extack)
 453{
 454        struct mlx5_core_dev *dev = devlink_priv(devlink);
 455        bool new_state = val.vbool;
 456
 457        if (new_state && !MLX5_CAP_GEN(dev, roce) &&
 458            !MLX5_CAP_GEN(dev, roce_rw_supported)) {
 459                NL_SET_ERR_MSG_MOD(extack, "Device doesn't support RoCE");
 460                return -EOPNOTSUPP;
 461        }
 462        if (mlx5_core_is_mp_slave(dev) || mlx5_lag_is_active(dev)) {
 463                NL_SET_ERR_MSG_MOD(extack, "Multi port slave/Lag device can't configure RoCE");
 464                return -EOPNOTSUPP;
 465        }
 466
 467        return 0;
 468}
 469
 470#ifdef CONFIG_MLX5_ESWITCH
 471static int mlx5_devlink_large_group_num_validate(struct devlink *devlink, u32 id,
 472                                                 union devlink_param_value val,
 473                                                 struct netlink_ext_ack *extack)
 474{
 475        int group_num = val.vu32;
 476
 477        if (group_num < 1 || group_num > 1024) {
 478                NL_SET_ERR_MSG_MOD(extack,
 479                                   "Unsupported group number, supported range is 1-1024");
 480                return -EOPNOTSUPP;
 481        }
 482
 483        return 0;
 484}
 485
 486static int mlx5_devlink_esw_port_metadata_set(struct devlink *devlink, u32 id,
 487                                              struct devlink_param_gset_ctx *ctx)
 488{
 489        struct mlx5_core_dev *dev = devlink_priv(devlink);
 490
 491        if (!MLX5_ESWITCH_MANAGER(dev))
 492                return -EOPNOTSUPP;
 493
 494        return mlx5_esw_offloads_vport_metadata_set(dev->priv.eswitch, ctx->val.vbool);
 495}
 496
 497static int mlx5_devlink_esw_port_metadata_get(struct devlink *devlink, u32 id,
 498                                              struct devlink_param_gset_ctx *ctx)
 499{
 500        struct mlx5_core_dev *dev = devlink_priv(devlink);
 501
 502        if (!MLX5_ESWITCH_MANAGER(dev))
 503                return -EOPNOTSUPP;
 504
 505        ctx->val.vbool = mlx5_eswitch_vport_match_metadata_enabled(dev->priv.eswitch);
 506        return 0;
 507}
 508
 509static int mlx5_devlink_esw_port_metadata_validate(struct devlink *devlink, u32 id,
 510                                                   union devlink_param_value val,
 511                                                   struct netlink_ext_ack *extack)
 512{
 513        struct mlx5_core_dev *dev = devlink_priv(devlink);
 514        u8 esw_mode;
 515
 516        if (!MLX5_ESWITCH_MANAGER(dev)) {
 517                NL_SET_ERR_MSG_MOD(extack, "E-Switch is unsupported");
 518                return -EOPNOTSUPP;
 519        }
 520        esw_mode = mlx5_eswitch_mode(dev);
 521        if (esw_mode == MLX5_ESWITCH_OFFLOADS) {
 522                NL_SET_ERR_MSG_MOD(extack,
 523                                   "E-Switch must either disabled or non switchdev mode");
 524                return -EBUSY;
 525        }
 526        return 0;
 527}
 528
 529#endif
 530
 531static int mlx5_devlink_enable_remote_dev_reset_set(struct devlink *devlink, u32 id,
 532                                                    struct devlink_param_gset_ctx *ctx)
 533{
 534        struct mlx5_core_dev *dev = devlink_priv(devlink);
 535
 536        mlx5_fw_reset_enable_remote_dev_reset_set(dev, ctx->val.vbool);
 537        return 0;
 538}
 539
 540static int mlx5_devlink_enable_remote_dev_reset_get(struct devlink *devlink, u32 id,
 541                                                    struct devlink_param_gset_ctx *ctx)
 542{
 543        struct mlx5_core_dev *dev = devlink_priv(devlink);
 544
 545        ctx->val.vbool = mlx5_fw_reset_enable_remote_dev_reset_get(dev);
 546        return 0;
 547}
 548
 549static int mlx5_devlink_eq_depth_validate(struct devlink *devlink, u32 id,
 550                                          union devlink_param_value val,
 551                                          struct netlink_ext_ack *extack)
 552{
 553        return (val.vu16 >= 64 && val.vu16 <= 4096) ? 0 : -EINVAL;
 554}
 555
 556static const struct devlink_param mlx5_devlink_params[] = {
 557        DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_FLOW_STEERING_MODE,
 558                             "flow_steering_mode", DEVLINK_PARAM_TYPE_STRING,
 559                             BIT(DEVLINK_PARAM_CMODE_RUNTIME),
 560                             mlx5_devlink_fs_mode_get, mlx5_devlink_fs_mode_set,
 561                             mlx5_devlink_fs_mode_validate),
 562        DEVLINK_PARAM_GENERIC(ENABLE_ROCE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
 563                              NULL, NULL, mlx5_devlink_enable_roce_validate),
 564#ifdef CONFIG_MLX5_ESWITCH
 565        DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM,
 566                             "fdb_large_groups", DEVLINK_PARAM_TYPE_U32,
 567                             BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
 568                             NULL, NULL,
 569                             mlx5_devlink_large_group_num_validate),
 570        DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_ESW_PORT_METADATA,
 571                             "esw_port_metadata", DEVLINK_PARAM_TYPE_BOOL,
 572                             BIT(DEVLINK_PARAM_CMODE_RUNTIME),
 573                             mlx5_devlink_esw_port_metadata_get,
 574                             mlx5_devlink_esw_port_metadata_set,
 575                             mlx5_devlink_esw_port_metadata_validate),
 576#endif
 577        DEVLINK_PARAM_GENERIC(ENABLE_REMOTE_DEV_RESET, BIT(DEVLINK_PARAM_CMODE_RUNTIME),
 578                              mlx5_devlink_enable_remote_dev_reset_get,
 579                              mlx5_devlink_enable_remote_dev_reset_set, NULL),
 580        DEVLINK_PARAM_GENERIC(IO_EQ_SIZE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
 581                              NULL, NULL, mlx5_devlink_eq_depth_validate),
 582        DEVLINK_PARAM_GENERIC(EVENT_EQ_SIZE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
 583                              NULL, NULL, mlx5_devlink_eq_depth_validate),
 584};
 585
 586static void mlx5_devlink_set_params_init_values(struct devlink *devlink)
 587{
 588        struct mlx5_core_dev *dev = devlink_priv(devlink);
 589        union devlink_param_value value;
 590
 591        if (dev->priv.steering->mode == MLX5_FLOW_STEERING_MODE_DMFS)
 592                strcpy(value.vstr, "dmfs");
 593        else
 594                strcpy(value.vstr, "smfs");
 595        devlink_param_driverinit_value_set(devlink,
 596                                           MLX5_DEVLINK_PARAM_ID_FLOW_STEERING_MODE,
 597                                           value);
 598
 599        value.vbool = MLX5_CAP_GEN(dev, roce);
 600        devlink_param_driverinit_value_set(devlink,
 601                                           DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
 602                                           value);
 603
 604#ifdef CONFIG_MLX5_ESWITCH
 605        value.vu32 = ESW_OFFLOADS_DEFAULT_NUM_GROUPS;
 606        devlink_param_driverinit_value_set(devlink,
 607                                           MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM,
 608                                           value);
 609
 610        if (MLX5_ESWITCH_MANAGER(dev)) {
 611                if (mlx5_esw_vport_match_metadata_supported(dev->priv.eswitch)) {
 612                        dev->priv.eswitch->flags |= MLX5_ESWITCH_VPORT_MATCH_METADATA;
 613                        value.vbool = true;
 614                } else {
 615                        value.vbool = false;
 616                }
 617                devlink_param_driverinit_value_set(devlink,
 618                                                   MLX5_DEVLINK_PARAM_ID_ESW_PORT_METADATA,
 619                                                   value);
 620        }
 621#endif
 622
 623        value.vu32 = MLX5_COMP_EQ_SIZE;
 624        devlink_param_driverinit_value_set(devlink,
 625                                           DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE,
 626                                           value);
 627
 628        value.vu32 = MLX5_NUM_ASYNC_EQE;
 629        devlink_param_driverinit_value_set(devlink,
 630                                           DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE,
 631                                           value);
 632}
 633
 634static const struct devlink_param enable_eth_param =
 635        DEVLINK_PARAM_GENERIC(ENABLE_ETH, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
 636                              NULL, NULL, NULL);
 637
 638static int mlx5_devlink_eth_param_register(struct devlink *devlink)
 639{
 640        struct mlx5_core_dev *dev = devlink_priv(devlink);
 641        union devlink_param_value value;
 642        int err;
 643
 644        if (!mlx5_eth_supported(dev))
 645                return 0;
 646
 647        err = devlink_param_register(devlink, &enable_eth_param);
 648        if (err)
 649                return err;
 650
 651        value.vbool = true;
 652        devlink_param_driverinit_value_set(devlink,
 653                                           DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH,
 654                                           value);
 655        return 0;
 656}
 657
 658static void mlx5_devlink_eth_param_unregister(struct devlink *devlink)
 659{
 660        struct mlx5_core_dev *dev = devlink_priv(devlink);
 661
 662        if (!mlx5_eth_supported(dev))
 663                return;
 664
 665        devlink_param_unregister(devlink, &enable_eth_param);
 666}
 667
 668static int mlx5_devlink_enable_rdma_validate(struct devlink *devlink, u32 id,
 669                                             union devlink_param_value val,
 670                                             struct netlink_ext_ack *extack)
 671{
 672        struct mlx5_core_dev *dev = devlink_priv(devlink);
 673        bool new_state = val.vbool;
 674
 675        if (new_state && !mlx5_rdma_supported(dev))
 676                return -EOPNOTSUPP;
 677        return 0;
 678}
 679
 680static const struct devlink_param enable_rdma_param =
 681        DEVLINK_PARAM_GENERIC(ENABLE_RDMA, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
 682                              NULL, NULL, mlx5_devlink_enable_rdma_validate);
 683
 684static int mlx5_devlink_rdma_param_register(struct devlink *devlink)
 685{
 686        union devlink_param_value value;
 687        int err;
 688
 689        if (!IS_ENABLED(CONFIG_MLX5_INFINIBAND))
 690                return 0;
 691
 692        err = devlink_param_register(devlink, &enable_rdma_param);
 693        if (err)
 694                return err;
 695
 696        value.vbool = true;
 697        devlink_param_driverinit_value_set(devlink,
 698                                           DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA,
 699                                           value);
 700        return 0;
 701}
 702
 703static void mlx5_devlink_rdma_param_unregister(struct devlink *devlink)
 704{
 705        if (!IS_ENABLED(CONFIG_MLX5_INFINIBAND))
 706                return;
 707
 708        devlink_param_unregister(devlink, &enable_rdma_param);
 709}
 710
 711static const struct devlink_param enable_vnet_param =
 712        DEVLINK_PARAM_GENERIC(ENABLE_VNET, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
 713                              NULL, NULL, NULL);
 714
 715static int mlx5_devlink_vnet_param_register(struct devlink *devlink)
 716{
 717        struct mlx5_core_dev *dev = devlink_priv(devlink);
 718        union devlink_param_value value;
 719        int err;
 720
 721        if (!mlx5_vnet_supported(dev))
 722                return 0;
 723
 724        err = devlink_param_register(devlink, &enable_vnet_param);
 725        if (err)
 726                return err;
 727
 728        value.vbool = true;
 729        devlink_param_driverinit_value_set(devlink,
 730                                           DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET,
 731                                           value);
 732        return 0;
 733}
 734
 735static void mlx5_devlink_vnet_param_unregister(struct devlink *devlink)
 736{
 737        struct mlx5_core_dev *dev = devlink_priv(devlink);
 738
 739        if (!mlx5_vnet_supported(dev))
 740                return;
 741
 742        devlink_param_unregister(devlink, &enable_vnet_param);
 743}
 744
 745static int mlx5_devlink_auxdev_params_register(struct devlink *devlink)
 746{
 747        int err;
 748
 749        err = mlx5_devlink_eth_param_register(devlink);
 750        if (err)
 751                return err;
 752
 753        err = mlx5_devlink_rdma_param_register(devlink);
 754        if (err)
 755                goto rdma_err;
 756
 757        err = mlx5_devlink_vnet_param_register(devlink);
 758        if (err)
 759                goto vnet_err;
 760        return 0;
 761
 762vnet_err:
 763        mlx5_devlink_rdma_param_unregister(devlink);
 764rdma_err:
 765        mlx5_devlink_eth_param_unregister(devlink);
 766        return err;
 767}
 768
 769static void mlx5_devlink_auxdev_params_unregister(struct devlink *devlink)
 770{
 771        mlx5_devlink_vnet_param_unregister(devlink);
 772        mlx5_devlink_rdma_param_unregister(devlink);
 773        mlx5_devlink_eth_param_unregister(devlink);
 774}
 775
 776static int mlx5_devlink_max_uc_list_validate(struct devlink *devlink, u32 id,
 777                                             union devlink_param_value val,
 778                                             struct netlink_ext_ack *extack)
 779{
 780        struct mlx5_core_dev *dev = devlink_priv(devlink);
 781
 782        if (val.vu32 == 0) {
 783                NL_SET_ERR_MSG_MOD(extack, "max_macs value must be greater than 0");
 784                return -EINVAL;
 785        }
 786
 787        if (!is_power_of_2(val.vu32)) {
 788                NL_SET_ERR_MSG_MOD(extack, "Only power of 2 values are supported for max_macs");
 789                return -EINVAL;
 790        }
 791
 792        if (ilog2(val.vu32) >
 793            MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list)) {
 794                NL_SET_ERR_MSG_MOD(extack, "max_macs value is out of the supported range");
 795                return -EINVAL;
 796        }
 797
 798        return 0;
 799}
 800
 801static const struct devlink_param max_uc_list_param =
 802        DEVLINK_PARAM_GENERIC(MAX_MACS, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
 803                              NULL, NULL, mlx5_devlink_max_uc_list_validate);
 804
 805static int mlx5_devlink_max_uc_list_param_register(struct devlink *devlink)
 806{
 807        struct mlx5_core_dev *dev = devlink_priv(devlink);
 808        union devlink_param_value value;
 809        int err;
 810
 811        if (!MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list_wr_supported))
 812                return 0;
 813
 814        err = devlink_param_register(devlink, &max_uc_list_param);
 815        if (err)
 816                return err;
 817
 818        value.vu32 = 1 << MLX5_CAP_GEN(dev, log_max_current_uc_list);
 819        devlink_param_driverinit_value_set(devlink,
 820                                           DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
 821                                           value);
 822        return 0;
 823}
 824
 825static void
 826mlx5_devlink_max_uc_list_param_unregister(struct devlink *devlink)
 827{
 828        struct mlx5_core_dev *dev = devlink_priv(devlink);
 829
 830        if (!MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list_wr_supported))
 831                return;
 832
 833        devlink_param_unregister(devlink, &max_uc_list_param);
 834}
 835
 836#define MLX5_TRAP_DROP(_id, _group_id)                                  \
 837        DEVLINK_TRAP_GENERIC(DROP, DROP, _id,                           \
 838                             DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
 839                             DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT)
 840
 841static const struct devlink_trap mlx5_traps_arr[] = {
 842        MLX5_TRAP_DROP(INGRESS_VLAN_FILTER, L2_DROPS),
 843        MLX5_TRAP_DROP(DMAC_FILTER, L2_DROPS),
 844};
 845
 846static const struct devlink_trap_group mlx5_trap_groups_arr[] = {
 847        DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 0),
 848};
 849
 850static int mlx5_devlink_traps_register(struct devlink *devlink)
 851{
 852        struct mlx5_core_dev *core_dev = devlink_priv(devlink);
 853        int err;
 854
 855        err = devlink_trap_groups_register(devlink, mlx5_trap_groups_arr,
 856                                           ARRAY_SIZE(mlx5_trap_groups_arr));
 857        if (err)
 858                return err;
 859
 860        err = devlink_traps_register(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr),
 861                                     &core_dev->priv);
 862        if (err)
 863                goto err_trap_group;
 864        return 0;
 865
 866err_trap_group:
 867        devlink_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
 868                                       ARRAY_SIZE(mlx5_trap_groups_arr));
 869        return err;
 870}
 871
 872static void mlx5_devlink_traps_unregister(struct devlink *devlink)
 873{
 874        devlink_traps_unregister(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr));
 875        devlink_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
 876                                       ARRAY_SIZE(mlx5_trap_groups_arr));
 877}
 878
 879int mlx5_devlink_register(struct devlink *devlink)
 880{
 881        struct mlx5_core_dev *dev = devlink_priv(devlink);
 882        int err;
 883
 884        err = devlink_params_register(devlink, mlx5_devlink_params,
 885                                      ARRAY_SIZE(mlx5_devlink_params));
 886        if (err)
 887                return err;
 888
 889        mlx5_devlink_set_params_init_values(devlink);
 890
 891        err = mlx5_devlink_auxdev_params_register(devlink);
 892        if (err)
 893                goto auxdev_reg_err;
 894
 895        err = mlx5_devlink_max_uc_list_param_register(devlink);
 896        if (err)
 897                goto max_uc_list_err;
 898
 899        err = mlx5_devlink_traps_register(devlink);
 900        if (err)
 901                goto traps_reg_err;
 902
 903        if (!mlx5_core_is_mp_slave(dev))
 904                devlink_set_features(devlink, DEVLINK_F_RELOAD);
 905
 906        return 0;
 907
 908traps_reg_err:
 909        mlx5_devlink_max_uc_list_param_unregister(devlink);
 910max_uc_list_err:
 911        mlx5_devlink_auxdev_params_unregister(devlink);
 912auxdev_reg_err:
 913        devlink_params_unregister(devlink, mlx5_devlink_params,
 914                                  ARRAY_SIZE(mlx5_devlink_params));
 915        return err;
 916}
 917
 918void mlx5_devlink_unregister(struct devlink *devlink)
 919{
 920        mlx5_devlink_traps_unregister(devlink);
 921        mlx5_devlink_max_uc_list_param_unregister(devlink);
 922        mlx5_devlink_auxdev_params_unregister(devlink);
 923        devlink_params_unregister(devlink, mlx5_devlink_params,
 924                                  ARRAY_SIZE(mlx5_devlink_params));
 925}
 926