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 "sf/dev/dev.h"
  11#include "sf/sf.h"
  12
  13static int mlx5_devlink_flash_update(struct devlink *devlink,
  14                                     struct devlink_flash_update_params *params,
  15                                     struct netlink_ext_ack *extack)
  16{
  17        struct mlx5_core_dev *dev = devlink_priv(devlink);
  18
  19        return mlx5_firmware_flash(dev, params->fw, extack);
  20}
  21
  22static u8 mlx5_fw_ver_major(u32 version)
  23{
  24        return (version >> 24) & 0xff;
  25}
  26
  27static u8 mlx5_fw_ver_minor(u32 version)
  28{
  29        return (version >> 16) & 0xff;
  30}
  31
  32static u16 mlx5_fw_ver_subminor(u32 version)
  33{
  34        return version & 0xffff;
  35}
  36
  37#define DEVLINK_FW_STRING_LEN 32
  38
  39static int
  40mlx5_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
  41                      struct netlink_ext_ack *extack)
  42{
  43        struct mlx5_core_dev *dev = devlink_priv(devlink);
  44        char version_str[DEVLINK_FW_STRING_LEN];
  45        u32 running_fw, stored_fw;
  46        int err;
  47
  48        err = devlink_info_driver_name_put(req, KBUILD_MODNAME);
  49        if (err)
  50                return err;
  51
  52        err = devlink_info_version_fixed_put(req, "fw.psid", dev->board_id);
  53        if (err)
  54                return err;
  55
  56        err = mlx5_fw_version_query(dev, &running_fw, &stored_fw);
  57        if (err)
  58                return err;
  59
  60        snprintf(version_str, sizeof(version_str), "%d.%d.%04d",
  61                 mlx5_fw_ver_major(running_fw), mlx5_fw_ver_minor(running_fw),
  62                 mlx5_fw_ver_subminor(running_fw));
  63        err = devlink_info_version_running_put(req, "fw.version", version_str);
  64        if (err)
  65                return err;
  66        err = devlink_info_version_running_put(req,
  67                                               DEVLINK_INFO_VERSION_GENERIC_FW,
  68                                               version_str);
  69        if (err)
  70                return err;
  71
  72        /* no pending version, return running (stored) version */
  73        if (stored_fw == 0)
  74                stored_fw = running_fw;
  75
  76        snprintf(version_str, sizeof(version_str), "%d.%d.%04d",
  77                 mlx5_fw_ver_major(stored_fw), mlx5_fw_ver_minor(stored_fw),
  78                 mlx5_fw_ver_subminor(stored_fw));
  79        err = devlink_info_version_stored_put(req, "fw.version", version_str);
  80        if (err)
  81                return err;
  82        return devlink_info_version_stored_put(req,
  83                                               DEVLINK_INFO_VERSION_GENERIC_FW,
  84                                               version_str);
  85}
  86
  87static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netlink_ext_ack *extack)
  88{
  89        struct mlx5_core_dev *dev = devlink_priv(devlink);
  90        u8 reset_level, reset_type, net_port_alive;
  91        int err;
  92
  93        err = mlx5_fw_reset_query(dev, &reset_level, &reset_type);
  94        if (err)
  95                return err;
  96        if (!(reset_level & MLX5_MFRL_REG_RESET_LEVEL3)) {
  97                NL_SET_ERR_MSG_MOD(extack, "FW activate requires reboot");
  98                return -EINVAL;
  99        }
 100
 101        net_port_alive = !!(reset_type & MLX5_MFRL_REG_RESET_TYPE_NET_PORT_ALIVE);
 102        err = mlx5_fw_reset_set_reset_sync(dev, net_port_alive);
 103        if (err)
 104                goto out;
 105
 106        err = mlx5_fw_reset_wait_reset_done(dev);
 107out:
 108        if (err)
 109                NL_SET_ERR_MSG_MOD(extack, "FW activate command failed");
 110        return err;
 111}
 112
 113static int mlx5_devlink_trigger_fw_live_patch(struct devlink *devlink,
 114                                              struct netlink_ext_ack *extack)
 115{
 116        struct mlx5_core_dev *dev = devlink_priv(devlink);
 117        u8 reset_level;
 118        int err;
 119
 120        err = mlx5_fw_reset_query(dev, &reset_level, NULL);
 121        if (err)
 122                return err;
 123        if (!(reset_level & MLX5_MFRL_REG_RESET_LEVEL0)) {
 124                NL_SET_ERR_MSG_MOD(extack,
 125                                   "FW upgrade to the stored FW can't be done by FW live patching");
 126                return -EINVAL;
 127        }
 128
 129        return mlx5_fw_reset_set_live_patch(dev);
 130}
 131
 132static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
 133                                    enum devlink_reload_action action,
 134                                    enum devlink_reload_limit limit,
 135                                    struct netlink_ext_ack *extack)
 136{
 137        struct mlx5_core_dev *dev = devlink_priv(devlink);
 138        bool sf_dev_allocated;
 139
 140        sf_dev_allocated = mlx5_sf_dev_allocated(dev);
 141        if (sf_dev_allocated) {
 142                /* Reload results in deleting SF device which further results in
 143                 * unregistering devlink instance while holding devlink_mutext.
 144                 * Hence, do not support reload.
 145                 */
 146                NL_SET_ERR_MSG_MOD(extack, "reload is unsupported when SFs are allocated");
 147                return -EOPNOTSUPP;
 148        }
 149
 150        if (mlx5_lag_is_active(dev)) {
 151                NL_SET_ERR_MSG_MOD(extack, "reload is unsupported in Lag mode");
 152                return -EOPNOTSUPP;
 153        }
 154
 155        switch (action) {
 156        case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
 157                mlx5_unload_one(dev);
 158                return 0;
 159        case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
 160                if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
 161                        return mlx5_devlink_trigger_fw_live_patch(devlink, extack);
 162                return mlx5_devlink_reload_fw_activate(devlink, extack);
 163        default:
 164                /* Unsupported action should not get to this function */
 165                WARN_ON(1);
 166                return -EOPNOTSUPP;
 167        }
 168}
 169
 170static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_action action,
 171                                  enum devlink_reload_limit limit, u32 *actions_performed,
 172                                  struct netlink_ext_ack *extack)
 173{
 174        struct mlx5_core_dev *dev = devlink_priv(devlink);
 175
 176        *actions_performed = BIT(action);
 177        switch (action) {
 178        case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
 179                return mlx5_load_one(dev);
 180        case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
 181                if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
 182                        break;
 183                /* On fw_activate action, also driver is reloaded and reinit performed */
 184                *actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
 185                return mlx5_load_one(dev);
 186        default:
 187                /* Unsupported action should not get to this function */
 188                WARN_ON(1);
 189                return -EOPNOTSUPP;
 190        }
 191
 192        return 0;
 193}
 194
 195static struct mlx5_devlink_trap *mlx5_find_trap_by_id(struct mlx5_core_dev *dev, int trap_id)
 196{
 197        struct mlx5_devlink_trap *dl_trap;
 198
 199        list_for_each_entry(dl_trap, &dev->priv.traps, list)
 200                if (dl_trap->trap.id == trap_id)
 201                        return dl_trap;
 202
 203        return NULL;
 204}
 205
 206static int mlx5_devlink_trap_init(struct devlink *devlink, const struct devlink_trap *trap,
 207                                  void *trap_ctx)
 208{
 209        struct mlx5_core_dev *dev = devlink_priv(devlink);
 210        struct mlx5_devlink_trap *dl_trap;
 211
 212        dl_trap = kzalloc(sizeof(*dl_trap), GFP_KERNEL);
 213        if (!dl_trap)
 214                return -ENOMEM;
 215
 216        dl_trap->trap.id = trap->id;
 217        dl_trap->trap.action = DEVLINK_TRAP_ACTION_DROP;
 218        dl_trap->item = trap_ctx;
 219
 220        if (mlx5_find_trap_by_id(dev, trap->id)) {
 221                kfree(dl_trap);
 222                mlx5_core_err(dev, "Devlink trap: Trap 0x%x already found", trap->id);
 223                return -EEXIST;
 224        }
 225
 226        list_add_tail(&dl_trap->list, &dev->priv.traps);
 227        return 0;
 228}
 229
 230static void mlx5_devlink_trap_fini(struct devlink *devlink, const struct devlink_trap *trap,
 231                                   void *trap_ctx)
 232{
 233        struct mlx5_core_dev *dev = devlink_priv(devlink);
 234        struct mlx5_devlink_trap *dl_trap;
 235
 236        dl_trap = mlx5_find_trap_by_id(dev, trap->id);
 237        if (!dl_trap) {
 238                mlx5_core_err(dev, "Devlink trap: Missing trap id 0x%x", trap->id);
 239                return;
 240        }
 241        list_del(&dl_trap->list);
 242        kfree(dl_trap);
 243}
 244
 245static int mlx5_devlink_trap_action_set(struct devlink *devlink,
 246                                        const struct devlink_trap *trap,
 247                                        enum devlink_trap_action action,
 248                                        struct netlink_ext_ack *extack)
 249{
 250        struct mlx5_core_dev *dev = devlink_priv(devlink);
 251        enum devlink_trap_action action_orig;
 252        struct mlx5_devlink_trap *dl_trap;
 253        int err = 0;
 254
 255        if (is_mdev_switchdev_mode(dev)) {
 256                NL_SET_ERR_MSG_MOD(extack, "Devlink traps can't be set in switchdev mode");
 257                return -EOPNOTSUPP;
 258        }
 259
 260        dl_trap = mlx5_find_trap_by_id(dev, trap->id);
 261        if (!dl_trap) {
 262                mlx5_core_err(dev, "Devlink trap: Set action on invalid trap id 0x%x", trap->id);
 263                err = -EINVAL;
 264                goto out;
 265        }
 266
 267        if (action != DEVLINK_TRAP_ACTION_DROP && action != DEVLINK_TRAP_ACTION_TRAP) {
 268                err = -EOPNOTSUPP;
 269                goto out;
 270        }
 271
 272        if (action == dl_trap->trap.action)
 273                goto out;
 274
 275        action_orig = dl_trap->trap.action;
 276        dl_trap->trap.action = action;
 277        err = mlx5_blocking_notifier_call_chain(dev, MLX5_DRIVER_EVENT_TYPE_TRAP,
 278                                                &dl_trap->trap);
 279        if (err)
 280                dl_trap->trap.action = action_orig;
 281out:
 282        return err;
 283}
 284
 285static const struct devlink_ops mlx5_devlink_ops = {
 286#ifdef CONFIG_MLX5_ESWITCH
 287        .eswitch_mode_set = mlx5_devlink_eswitch_mode_set,
 288        .eswitch_mode_get = mlx5_devlink_eswitch_mode_get,
 289        .eswitch_inline_mode_set = mlx5_devlink_eswitch_inline_mode_set,
 290        .eswitch_inline_mode_get = mlx5_devlink_eswitch_inline_mode_get,
 291        .eswitch_encap_mode_set = mlx5_devlink_eswitch_encap_mode_set,
 292        .eswitch_encap_mode_get = mlx5_devlink_eswitch_encap_mode_get,
 293        .port_function_hw_addr_get = mlx5_devlink_port_function_hw_addr_get,
 294        .port_function_hw_addr_set = mlx5_devlink_port_function_hw_addr_set,
 295#endif
 296#ifdef CONFIG_MLX5_SF_MANAGER
 297        .port_new = mlx5_devlink_sf_port_new,
 298        .port_del = mlx5_devlink_sf_port_del,
 299        .port_fn_state_get = mlx5_devlink_sf_port_fn_state_get,
 300        .port_fn_state_set = mlx5_devlink_sf_port_fn_state_set,
 301#endif
 302        .flash_update = mlx5_devlink_flash_update,
 303        .info_get = mlx5_devlink_info_get,
 304        .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
 305                          BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
 306        .reload_limits = BIT(DEVLINK_RELOAD_LIMIT_NO_RESET),
 307        .reload_down = mlx5_devlink_reload_down,
 308        .reload_up = mlx5_devlink_reload_up,
 309        .trap_init = mlx5_devlink_trap_init,
 310        .trap_fini = mlx5_devlink_trap_fini,
 311        .trap_action_set = mlx5_devlink_trap_action_set,
 312};
 313
 314void mlx5_devlink_trap_report(struct mlx5_core_dev *dev, int trap_id, struct sk_buff *skb,
 315                              struct devlink_port *dl_port)
 316{
 317        struct devlink *devlink = priv_to_devlink(dev);
 318        struct mlx5_devlink_trap *dl_trap;
 319
 320        dl_trap = mlx5_find_trap_by_id(dev, trap_id);
 321        if (!dl_trap) {
 322                mlx5_core_err(dev, "Devlink trap: Report on invalid trap id 0x%x", trap_id);
 323                return;
 324        }
 325
 326        if (dl_trap->trap.action != DEVLINK_TRAP_ACTION_TRAP) {
 327                mlx5_core_dbg(dev, "Devlink trap: Trap id %d has action %d", trap_id,
 328                              dl_trap->trap.action);
 329                return;
 330        }
 331        devlink_trap_report(devlink, skb, dl_trap->item, dl_port, NULL);
 332}
 333
 334int mlx5_devlink_trap_get_num_active(struct mlx5_core_dev *dev)
 335{
 336        struct mlx5_devlink_trap *dl_trap;
 337        int count = 0;
 338
 339        list_for_each_entry(dl_trap, &dev->priv.traps, list)
 340                if (dl_trap->trap.action == DEVLINK_TRAP_ACTION_TRAP)
 341                        count++;
 342
 343        return count;
 344}
 345
 346int mlx5_devlink_traps_get_action(struct mlx5_core_dev *dev, int trap_id,
 347                                  enum devlink_trap_action *action)
 348{
 349        struct mlx5_devlink_trap *dl_trap;
 350
 351        dl_trap = mlx5_find_trap_by_id(dev, trap_id);
 352        if (!dl_trap) {
 353                mlx5_core_err(dev, "Devlink trap: Get action on invalid trap id 0x%x",
 354                              trap_id);
 355                return -EINVAL;
 356        }
 357
 358        *action = dl_trap->trap.action;
 359        return 0;
 360}
 361
 362struct devlink *mlx5_devlink_alloc(void)
 363{
 364        return devlink_alloc(&mlx5_devlink_ops, sizeof(struct mlx5_core_dev));
 365}
 366
 367void mlx5_devlink_free(struct devlink *devlink)
 368{
 369        devlink_free(devlink);
 370}
 371
 372static int mlx5_devlink_fs_mode_validate(struct devlink *devlink, u32 id,
 373                                         union devlink_param_value val,
 374                                         struct netlink_ext_ack *extack)
 375{
 376        struct mlx5_core_dev *dev = devlink_priv(devlink);
 377        char *value = val.vstr;
 378        int err = 0;
 379
 380        if (!strcmp(value, "dmfs")) {
 381                return 0;
 382        } else if (!strcmp(value, "smfs")) {
 383                u8 eswitch_mode;
 384                bool smfs_cap;
 385
 386                eswitch_mode = mlx5_eswitch_mode(dev);
 387                smfs_cap = mlx5_fs_dr_is_supported(dev);
 388
 389                if (!smfs_cap) {
 390                        err = -EOPNOTSUPP;
 391                        NL_SET_ERR_MSG_MOD(extack,
 392                                           "Software managed steering is not supported by current device");
 393                }
 394
 395                else if (eswitch_mode == MLX5_ESWITCH_OFFLOADS) {
 396                        NL_SET_ERR_MSG_MOD(extack,
 397                                           "Software managed steering is not supported when eswitch offloads enabled.");
 398                        err = -EOPNOTSUPP;
 399                }
 400        } else {
 401                NL_SET_ERR_MSG_MOD(extack,
 402                                   "Bad parameter: supported values are [\"dmfs\", \"smfs\"]");
 403                err = -EINVAL;
 404        }
 405
 406        return err;
 407}
 408
 409static int mlx5_devlink_fs_mode_set(struct devlink *devlink, u32 id,
 410                                    struct devlink_param_gset_ctx *ctx)
 411{
 412        struct mlx5_core_dev *dev = devlink_priv(devlink);
 413        enum mlx5_flow_steering_mode mode;
 414
 415        if (!strcmp(ctx->val.vstr, "smfs"))
 416                mode = MLX5_FLOW_STEERING_MODE_SMFS;
 417        else
 418                mode = MLX5_FLOW_STEERING_MODE_DMFS;
 419        dev->priv.steering->mode = mode;
 420
 421        return 0;
 422}
 423
 424static int mlx5_devlink_fs_mode_get(struct devlink *devlink, u32 id,
 425                                    struct devlink_param_gset_ctx *ctx)
 426{
 427        struct mlx5_core_dev *dev = devlink_priv(devlink);
 428
 429        if (dev->priv.steering->mode == MLX5_FLOW_STEERING_MODE_SMFS)
 430                strcpy(ctx->val.vstr, "smfs");
 431        else
 432                strcpy(ctx->val.vstr, "dmfs");
 433        return 0;
 434}
 435
 436static int mlx5_devlink_enable_roce_validate(struct devlink *devlink, u32 id,
 437                                             union devlink_param_value val,
 438                                             struct netlink_ext_ack *extack)
 439{
 440        struct mlx5_core_dev *dev = devlink_priv(devlink);
 441        bool new_state = val.vbool;
 442
 443        if (new_state && !MLX5_CAP_GEN(dev, roce)) {
 444                NL_SET_ERR_MSG_MOD(extack, "Device doesn't support RoCE");
 445                return -EOPNOTSUPP;
 446        }
 447        if (mlx5_core_is_mp_slave(dev) || mlx5_lag_is_active(dev)) {
 448                NL_SET_ERR_MSG_MOD(extack, "Multi port slave/Lag device can't configure RoCE");
 449                return -EOPNOTSUPP;
 450        }
 451
 452        return 0;
 453}
 454
 455#ifdef CONFIG_MLX5_ESWITCH
 456static int mlx5_devlink_large_group_num_validate(struct devlink *devlink, u32 id,
 457                                                 union devlink_param_value val,
 458                                                 struct netlink_ext_ack *extack)
 459{
 460        int group_num = val.vu32;
 461
 462        if (group_num < 1 || group_num > 1024) {
 463                NL_SET_ERR_MSG_MOD(extack,
 464                                   "Unsupported group number, supported range is 1-1024");
 465                return -EOPNOTSUPP;
 466        }
 467
 468        return 0;
 469}
 470
 471static int mlx5_devlink_esw_port_metadata_set(struct devlink *devlink, u32 id,
 472                                              struct devlink_param_gset_ctx *ctx)
 473{
 474        struct mlx5_core_dev *dev = devlink_priv(devlink);
 475
 476        if (!MLX5_ESWITCH_MANAGER(dev))
 477                return -EOPNOTSUPP;
 478
 479        return mlx5_esw_offloads_vport_metadata_set(dev->priv.eswitch, ctx->val.vbool);
 480}
 481
 482static int mlx5_devlink_esw_port_metadata_get(struct devlink *devlink, u32 id,
 483                                              struct devlink_param_gset_ctx *ctx)
 484{
 485        struct mlx5_core_dev *dev = devlink_priv(devlink);
 486
 487        if (!MLX5_ESWITCH_MANAGER(dev))
 488                return -EOPNOTSUPP;
 489
 490        ctx->val.vbool = mlx5_eswitch_vport_match_metadata_enabled(dev->priv.eswitch);
 491        return 0;
 492}
 493
 494static int mlx5_devlink_esw_port_metadata_validate(struct devlink *devlink, u32 id,
 495                                                   union devlink_param_value val,
 496                                                   struct netlink_ext_ack *extack)
 497{
 498        struct mlx5_core_dev *dev = devlink_priv(devlink);
 499        u8 esw_mode;
 500
 501        if (!MLX5_ESWITCH_MANAGER(dev)) {
 502                NL_SET_ERR_MSG_MOD(extack, "E-Switch is unsupported");
 503                return -EOPNOTSUPP;
 504        }
 505        esw_mode = mlx5_eswitch_mode(dev);
 506        if (esw_mode == MLX5_ESWITCH_OFFLOADS) {
 507                NL_SET_ERR_MSG_MOD(extack,
 508                                   "E-Switch must either disabled or non switchdev mode");
 509                return -EBUSY;
 510        }
 511        return 0;
 512}
 513
 514#endif
 515
 516static int mlx5_devlink_enable_remote_dev_reset_set(struct devlink *devlink, u32 id,
 517                                                    struct devlink_param_gset_ctx *ctx)
 518{
 519        struct mlx5_core_dev *dev = devlink_priv(devlink);
 520
 521        mlx5_fw_reset_enable_remote_dev_reset_set(dev, ctx->val.vbool);
 522        return 0;
 523}
 524
 525static int mlx5_devlink_enable_remote_dev_reset_get(struct devlink *devlink, u32 id,
 526                                                    struct devlink_param_gset_ctx *ctx)
 527{
 528        struct mlx5_core_dev *dev = devlink_priv(devlink);
 529
 530        ctx->val.vbool = mlx5_fw_reset_enable_remote_dev_reset_get(dev);
 531        return 0;
 532}
 533
 534static const struct devlink_param mlx5_devlink_params[] = {
 535        DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_FLOW_STEERING_MODE,
 536                             "flow_steering_mode", DEVLINK_PARAM_TYPE_STRING,
 537                             BIT(DEVLINK_PARAM_CMODE_RUNTIME),
 538                             mlx5_devlink_fs_mode_get, mlx5_devlink_fs_mode_set,
 539                             mlx5_devlink_fs_mode_validate),
 540        DEVLINK_PARAM_GENERIC(ENABLE_ROCE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
 541                              NULL, NULL, mlx5_devlink_enable_roce_validate),
 542#ifdef CONFIG_MLX5_ESWITCH
 543        DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM,
 544                             "fdb_large_groups", DEVLINK_PARAM_TYPE_U32,
 545                             BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
 546                             NULL, NULL,
 547                             mlx5_devlink_large_group_num_validate),
 548        DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_ESW_PORT_METADATA,
 549                             "esw_port_metadata", DEVLINK_PARAM_TYPE_BOOL,
 550                             BIT(DEVLINK_PARAM_CMODE_RUNTIME),
 551                             mlx5_devlink_esw_port_metadata_get,
 552                             mlx5_devlink_esw_port_metadata_set,
 553                             mlx5_devlink_esw_port_metadata_validate),
 554#endif
 555        DEVLINK_PARAM_GENERIC(ENABLE_REMOTE_DEV_RESET, BIT(DEVLINK_PARAM_CMODE_RUNTIME),
 556                              mlx5_devlink_enable_remote_dev_reset_get,
 557                              mlx5_devlink_enable_remote_dev_reset_set, NULL),
 558};
 559
 560static void mlx5_devlink_set_params_init_values(struct devlink *devlink)
 561{
 562        struct mlx5_core_dev *dev = devlink_priv(devlink);
 563        union devlink_param_value value;
 564
 565        if (dev->priv.steering->mode == MLX5_FLOW_STEERING_MODE_DMFS)
 566                strcpy(value.vstr, "dmfs");
 567        else
 568                strcpy(value.vstr, "smfs");
 569        devlink_param_driverinit_value_set(devlink,
 570                                           MLX5_DEVLINK_PARAM_ID_FLOW_STEERING_MODE,
 571                                           value);
 572
 573        value.vbool = MLX5_CAP_GEN(dev, roce);
 574        devlink_param_driverinit_value_set(devlink,
 575                                           DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
 576                                           value);
 577
 578#ifdef CONFIG_MLX5_ESWITCH
 579        value.vu32 = ESW_OFFLOADS_DEFAULT_NUM_GROUPS;
 580        devlink_param_driverinit_value_set(devlink,
 581                                           MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM,
 582                                           value);
 583
 584        if (MLX5_ESWITCH_MANAGER(dev)) {
 585                if (mlx5_esw_vport_match_metadata_supported(dev->priv.eswitch)) {
 586                        dev->priv.eswitch->flags |= MLX5_ESWITCH_VPORT_MATCH_METADATA;
 587                        value.vbool = true;
 588                } else {
 589                        value.vbool = false;
 590                }
 591                devlink_param_driverinit_value_set(devlink,
 592                                                   MLX5_DEVLINK_PARAM_ID_ESW_PORT_METADATA,
 593                                                   value);
 594        }
 595#endif
 596}
 597
 598#define MLX5_TRAP_DROP(_id, _group_id)                                  \
 599        DEVLINK_TRAP_GENERIC(DROP, DROP, _id,                           \
 600                             DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
 601                             DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT)
 602
 603static const struct devlink_trap mlx5_traps_arr[] = {
 604        MLX5_TRAP_DROP(INGRESS_VLAN_FILTER, L2_DROPS),
 605        MLX5_TRAP_DROP(DMAC_FILTER, L2_DROPS),
 606};
 607
 608static const struct devlink_trap_group mlx5_trap_groups_arr[] = {
 609        DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 0),
 610};
 611
 612static int mlx5_devlink_traps_register(struct devlink *devlink)
 613{
 614        struct mlx5_core_dev *core_dev = devlink_priv(devlink);
 615        int err;
 616
 617        err = devlink_trap_groups_register(devlink, mlx5_trap_groups_arr,
 618                                           ARRAY_SIZE(mlx5_trap_groups_arr));
 619        if (err)
 620                return err;
 621
 622        err = devlink_traps_register(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr),
 623                                     &core_dev->priv);
 624        if (err)
 625                goto err_trap_group;
 626        return 0;
 627
 628err_trap_group:
 629        devlink_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
 630                                       ARRAY_SIZE(mlx5_trap_groups_arr));
 631        return err;
 632}
 633
 634static void mlx5_devlink_traps_unregister(struct devlink *devlink)
 635{
 636        devlink_traps_unregister(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr));
 637        devlink_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
 638                                       ARRAY_SIZE(mlx5_trap_groups_arr));
 639}
 640
 641int mlx5_devlink_register(struct devlink *devlink, struct device *dev)
 642{
 643        int err;
 644
 645        err = devlink_register(devlink, dev);
 646        if (err)
 647                return err;
 648
 649        err = devlink_params_register(devlink, mlx5_devlink_params,
 650                                      ARRAY_SIZE(mlx5_devlink_params));
 651        if (err)
 652                goto params_reg_err;
 653        mlx5_devlink_set_params_init_values(devlink);
 654        devlink_params_publish(devlink);
 655
 656        err = mlx5_devlink_traps_register(devlink);
 657        if (err)
 658                goto traps_reg_err;
 659
 660        return 0;
 661
 662traps_reg_err:
 663        devlink_params_unregister(devlink, mlx5_devlink_params,
 664                                  ARRAY_SIZE(mlx5_devlink_params));
 665params_reg_err:
 666        devlink_unregister(devlink);
 667        return err;
 668}
 669
 670void mlx5_devlink_unregister(struct devlink *devlink)
 671{
 672        mlx5_devlink_traps_unregister(devlink);
 673        devlink_params_unregister(devlink, mlx5_devlink_params,
 674                                  ARRAY_SIZE(mlx5_devlink_params));
 675        devlink_unregister(devlink);
 676}
 677