linux/drivers/net/netdevsim/dev.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2018 Cumulus Networks. All rights reserved.
   3 * Copyright (c) 2018 David Ahern <dsa@cumulusnetworks.com>
   4 * Copyright (c) 2019 Mellanox Technologies. All rights reserved.
   5 *
   6 * This software is licensed under the GNU General License Version 2,
   7 * June 1991 as shown in the file COPYING in the top-level directory of this
   8 * source tree.
   9 *
  10 * THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS"
  11 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
  12 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13 * FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
  14 * OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
  15 * THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
  16 */
  17
  18#include <linux/debugfs.h>
  19#include <linux/device.h>
  20#include <linux/etherdevice.h>
  21#include <linux/inet.h>
  22#include <linux/jiffies.h>
  23#include <linux/kernel.h>
  24#include <linux/list.h>
  25#include <linux/mutex.h>
  26#include <linux/random.h>
  27#include <linux/rtnetlink.h>
  28#include <linux/workqueue.h>
  29#include <net/devlink.h>
  30#include <net/ip.h>
  31#include <net/flow_offload.h>
  32#include <uapi/linux/devlink.h>
  33#include <uapi/linux/ip.h>
  34#include <uapi/linux/udp.h>
  35
  36#include "netdevsim.h"
  37
  38static unsigned int
  39nsim_dev_port_index(enum nsim_dev_port_type type, unsigned int port_index)
  40{
  41        switch (type) {
  42        case NSIM_DEV_PORT_TYPE_VF:
  43                port_index = NSIM_DEV_VF_PORT_INDEX_BASE + port_index;
  44                break;
  45        case NSIM_DEV_PORT_TYPE_PF:
  46                break;
  47        }
  48
  49        return port_index;
  50}
  51
  52static inline unsigned int nsim_dev_port_index_to_vf_index(unsigned int port_index)
  53{
  54        return port_index - NSIM_DEV_VF_PORT_INDEX_BASE;
  55}
  56
  57static struct dentry *nsim_dev_ddir;
  58
  59unsigned int nsim_dev_get_vfs(struct nsim_dev *nsim_dev)
  60{
  61        WARN_ON(!lockdep_rtnl_is_held() &&
  62                !devl_lock_is_held(priv_to_devlink(nsim_dev)));
  63
  64        return nsim_dev->nsim_bus_dev->num_vfs;
  65}
  66
  67static void
  68nsim_bus_dev_set_vfs(struct nsim_bus_dev *nsim_bus_dev, unsigned int num_vfs)
  69{
  70        rtnl_lock();
  71        nsim_bus_dev->num_vfs = num_vfs;
  72        rtnl_unlock();
  73}
  74
  75#define NSIM_DEV_DUMMY_REGION_SIZE (1024 * 32)
  76
  77static int
  78nsim_dev_take_snapshot(struct devlink *devlink,
  79                       const struct devlink_region_ops *ops,
  80                       struct netlink_ext_ack *extack,
  81                       u8 **data)
  82{
  83        void *dummy_data;
  84
  85        dummy_data = kmalloc(NSIM_DEV_DUMMY_REGION_SIZE, GFP_KERNEL);
  86        if (!dummy_data)
  87                return -ENOMEM;
  88
  89        get_random_bytes(dummy_data, NSIM_DEV_DUMMY_REGION_SIZE);
  90
  91        *data = dummy_data;
  92
  93        return 0;
  94}
  95
  96static ssize_t nsim_dev_take_snapshot_write(struct file *file,
  97                                            const char __user *data,
  98                                            size_t count, loff_t *ppos)
  99{
 100        struct nsim_dev *nsim_dev = file->private_data;
 101        struct devlink *devlink;
 102        u8 *dummy_data;
 103        int err;
 104        u32 id;
 105
 106        devlink = priv_to_devlink(nsim_dev);
 107
 108        err = nsim_dev_take_snapshot(devlink, NULL, NULL, &dummy_data);
 109        if (err)
 110                return err;
 111
 112        err = devlink_region_snapshot_id_get(devlink, &id);
 113        if (err) {
 114                pr_err("Failed to get snapshot id\n");
 115                kfree(dummy_data);
 116                return err;
 117        }
 118        err = devlink_region_snapshot_create(nsim_dev->dummy_region,
 119                                             dummy_data, id);
 120        devlink_region_snapshot_id_put(devlink, id);
 121        if (err) {
 122                pr_err("Failed to create region snapshot\n");
 123                kfree(dummy_data);
 124                return err;
 125        }
 126
 127        return count;
 128}
 129
 130static const struct file_operations nsim_dev_take_snapshot_fops = {
 131        .open = simple_open,
 132        .write = nsim_dev_take_snapshot_write,
 133        .llseek = generic_file_llseek,
 134        .owner = THIS_MODULE,
 135};
 136
 137static ssize_t nsim_dev_trap_fa_cookie_read(struct file *file,
 138                                            char __user *data,
 139                                            size_t count, loff_t *ppos)
 140{
 141        struct nsim_dev *nsim_dev = file->private_data;
 142        struct flow_action_cookie *fa_cookie;
 143        unsigned int buf_len;
 144        ssize_t ret;
 145        char *buf;
 146
 147        spin_lock(&nsim_dev->fa_cookie_lock);
 148        fa_cookie = nsim_dev->fa_cookie;
 149        if (!fa_cookie) {
 150                ret = -EINVAL;
 151                goto errout;
 152        }
 153        buf_len = fa_cookie->cookie_len * 2;
 154        buf = kmalloc(buf_len, GFP_ATOMIC);
 155        if (!buf) {
 156                ret = -ENOMEM;
 157                goto errout;
 158        }
 159        bin2hex(buf, fa_cookie->cookie, fa_cookie->cookie_len);
 160        spin_unlock(&nsim_dev->fa_cookie_lock);
 161
 162        ret = simple_read_from_buffer(data, count, ppos, buf, buf_len);
 163
 164        kfree(buf);
 165        return ret;
 166
 167errout:
 168        spin_unlock(&nsim_dev->fa_cookie_lock);
 169        return ret;
 170}
 171
 172static ssize_t nsim_dev_trap_fa_cookie_write(struct file *file,
 173                                             const char __user *data,
 174                                             size_t count, loff_t *ppos)
 175{
 176        struct nsim_dev *nsim_dev = file->private_data;
 177        struct flow_action_cookie *fa_cookie;
 178        size_t cookie_len;
 179        ssize_t ret;
 180        char *buf;
 181
 182        if (*ppos != 0)
 183                return -EINVAL;
 184        cookie_len = (count - 1) / 2;
 185        if ((count - 1) % 2)
 186                return -EINVAL;
 187        buf = kmalloc(count, GFP_KERNEL | __GFP_NOWARN);
 188        if (!buf)
 189                return -ENOMEM;
 190
 191        ret = simple_write_to_buffer(buf, count, ppos, data, count);
 192        if (ret < 0)
 193                goto free_buf;
 194
 195        fa_cookie = kmalloc(sizeof(*fa_cookie) + cookie_len,
 196                            GFP_KERNEL | __GFP_NOWARN);
 197        if (!fa_cookie) {
 198                ret = -ENOMEM;
 199                goto free_buf;
 200        }
 201
 202        fa_cookie->cookie_len = cookie_len;
 203        ret = hex2bin(fa_cookie->cookie, buf, cookie_len);
 204        if (ret)
 205                goto free_fa_cookie;
 206        kfree(buf);
 207
 208        spin_lock(&nsim_dev->fa_cookie_lock);
 209        kfree(nsim_dev->fa_cookie);
 210        nsim_dev->fa_cookie = fa_cookie;
 211        spin_unlock(&nsim_dev->fa_cookie_lock);
 212
 213        return count;
 214
 215free_fa_cookie:
 216        kfree(fa_cookie);
 217free_buf:
 218        kfree(buf);
 219        return ret;
 220}
 221
 222static const struct file_operations nsim_dev_trap_fa_cookie_fops = {
 223        .open = simple_open,
 224        .read = nsim_dev_trap_fa_cookie_read,
 225        .write = nsim_dev_trap_fa_cookie_write,
 226        .llseek = generic_file_llseek,
 227        .owner = THIS_MODULE,
 228};
 229
 230static ssize_t nsim_bus_dev_max_vfs_read(struct file *file, char __user *data,
 231                                         size_t count, loff_t *ppos)
 232{
 233        struct nsim_dev *nsim_dev = file->private_data;
 234        char buf[11];
 235        ssize_t len;
 236
 237        len = scnprintf(buf, sizeof(buf), "%u\n",
 238                        READ_ONCE(nsim_dev->nsim_bus_dev->max_vfs));
 239
 240        return simple_read_from_buffer(data, count, ppos, buf, len);
 241}
 242
 243static ssize_t nsim_bus_dev_max_vfs_write(struct file *file,
 244                                          const char __user *data,
 245                                          size_t count, loff_t *ppos)
 246{
 247        struct nsim_vf_config *vfconfigs;
 248        struct nsim_dev *nsim_dev;
 249        char buf[10];
 250        ssize_t ret;
 251        u32 val;
 252
 253        if (*ppos != 0)
 254                return 0;
 255
 256        if (count >= sizeof(buf))
 257                return -ENOSPC;
 258
 259        ret = copy_from_user(buf, data, count);
 260        if (ret)
 261                return -EFAULT;
 262        buf[count] = '\0';
 263
 264        ret = kstrtouint(buf, 10, &val);
 265        if (ret)
 266                return -EINVAL;
 267
 268        /* max_vfs limited by the maximum number of provided port indexes */
 269        if (val > NSIM_DEV_VF_PORT_INDEX_MAX - NSIM_DEV_VF_PORT_INDEX_BASE)
 270                return -ERANGE;
 271
 272        vfconfigs = kcalloc(val, sizeof(struct nsim_vf_config),
 273                            GFP_KERNEL | __GFP_NOWARN);
 274        if (!vfconfigs)
 275                return -ENOMEM;
 276
 277        nsim_dev = file->private_data;
 278        devl_lock(priv_to_devlink(nsim_dev));
 279        /* Reject if VFs are configured */
 280        if (nsim_dev_get_vfs(nsim_dev)) {
 281                ret = -EBUSY;
 282        } else {
 283                swap(nsim_dev->vfconfigs, vfconfigs);
 284                WRITE_ONCE(nsim_dev->nsim_bus_dev->max_vfs, val);
 285                *ppos += count;
 286                ret = count;
 287        }
 288        devl_unlock(priv_to_devlink(nsim_dev));
 289
 290        kfree(vfconfigs);
 291        return ret;
 292}
 293
 294static const struct file_operations nsim_dev_max_vfs_fops = {
 295        .open = simple_open,
 296        .read = nsim_bus_dev_max_vfs_read,
 297        .write = nsim_bus_dev_max_vfs_write,
 298        .llseek = generic_file_llseek,
 299        .owner = THIS_MODULE,
 300};
 301
 302static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
 303{
 304        char dev_ddir_name[sizeof(DRV_NAME) + 10];
 305        int err;
 306
 307        sprintf(dev_ddir_name, DRV_NAME "%u", nsim_dev->nsim_bus_dev->dev.id);
 308        nsim_dev->ddir = debugfs_create_dir(dev_ddir_name, nsim_dev_ddir);
 309        if (IS_ERR(nsim_dev->ddir))
 310                return PTR_ERR(nsim_dev->ddir);
 311        nsim_dev->ports_ddir = debugfs_create_dir("ports", nsim_dev->ddir);
 312        if (IS_ERR(nsim_dev->ports_ddir))
 313                return PTR_ERR(nsim_dev->ports_ddir);
 314        debugfs_create_bool("fw_update_status", 0600, nsim_dev->ddir,
 315                            &nsim_dev->fw_update_status);
 316        debugfs_create_u32("fw_update_overwrite_mask", 0600, nsim_dev->ddir,
 317                            &nsim_dev->fw_update_overwrite_mask);
 318        debugfs_create_u32("max_macs", 0600, nsim_dev->ddir,
 319                           &nsim_dev->max_macs);
 320        debugfs_create_bool("test1", 0600, nsim_dev->ddir,
 321                            &nsim_dev->test1);
 322        nsim_dev->take_snapshot = debugfs_create_file("take_snapshot",
 323                                                      0200,
 324                                                      nsim_dev->ddir,
 325                                                      nsim_dev,
 326                                                &nsim_dev_take_snapshot_fops);
 327        debugfs_create_bool("dont_allow_reload", 0600, nsim_dev->ddir,
 328                            &nsim_dev->dont_allow_reload);
 329        debugfs_create_bool("fail_reload", 0600, nsim_dev->ddir,
 330                            &nsim_dev->fail_reload);
 331        debugfs_create_file("trap_flow_action_cookie", 0600, nsim_dev->ddir,
 332                            nsim_dev, &nsim_dev_trap_fa_cookie_fops);
 333        debugfs_create_bool("fail_trap_group_set", 0600,
 334                            nsim_dev->ddir,
 335                            &nsim_dev->fail_trap_group_set);
 336        debugfs_create_bool("fail_trap_policer_set", 0600,
 337                            nsim_dev->ddir,
 338                            &nsim_dev->fail_trap_policer_set);
 339        debugfs_create_bool("fail_trap_policer_counter_get", 0600,
 340                            nsim_dev->ddir,
 341                            &nsim_dev->fail_trap_policer_counter_get);
 342        /* caution, dev_max_vfs write takes devlink lock */
 343        debugfs_create_file("max_vfs", 0600, nsim_dev->ddir,
 344                            nsim_dev, &nsim_dev_max_vfs_fops);
 345
 346        nsim_dev->nodes_ddir = debugfs_create_dir("rate_nodes", nsim_dev->ddir);
 347        if (IS_ERR(nsim_dev->nodes_ddir)) {
 348                err = PTR_ERR(nsim_dev->nodes_ddir);
 349                goto err_out;
 350        }
 351        debugfs_create_bool("fail_trap_drop_counter_get", 0600,
 352                            nsim_dev->ddir,
 353                            &nsim_dev->fail_trap_drop_counter_get);
 354        nsim_udp_tunnels_debugfs_create(nsim_dev);
 355        return 0;
 356
 357err_out:
 358        debugfs_remove_recursive(nsim_dev->ports_ddir);
 359        debugfs_remove_recursive(nsim_dev->ddir);
 360        return err;
 361}
 362
 363static void nsim_dev_debugfs_exit(struct nsim_dev *nsim_dev)
 364{
 365        debugfs_remove_recursive(nsim_dev->nodes_ddir);
 366        debugfs_remove_recursive(nsim_dev->ports_ddir);
 367        debugfs_remove_recursive(nsim_dev->ddir);
 368}
 369
 370static ssize_t nsim_dev_rate_parent_read(struct file *file,
 371                                         char __user *data,
 372                                         size_t count, loff_t *ppos)
 373{
 374        char **name_ptr = file->private_data;
 375        size_t len;
 376
 377        if (!*name_ptr)
 378                return 0;
 379
 380        len = strlen(*name_ptr);
 381        return simple_read_from_buffer(data, count, ppos, *name_ptr, len);
 382}
 383
 384static const struct file_operations nsim_dev_rate_parent_fops = {
 385        .open = simple_open,
 386        .read = nsim_dev_rate_parent_read,
 387        .llseek = generic_file_llseek,
 388        .owner = THIS_MODULE,
 389};
 390
 391static int nsim_dev_port_debugfs_init(struct nsim_dev *nsim_dev,
 392                                      struct nsim_dev_port *nsim_dev_port)
 393{
 394        struct nsim_bus_dev *nsim_bus_dev = nsim_dev->nsim_bus_dev;
 395        unsigned int port_index = nsim_dev_port->port_index;
 396        char port_ddir_name[16];
 397        char dev_link_name[32];
 398
 399        sprintf(port_ddir_name, "%u", port_index);
 400        nsim_dev_port->ddir = debugfs_create_dir(port_ddir_name,
 401                                                 nsim_dev->ports_ddir);
 402        if (IS_ERR(nsim_dev_port->ddir))
 403                return PTR_ERR(nsim_dev_port->ddir);
 404
 405        sprintf(dev_link_name, "../../../" DRV_NAME "%u", nsim_bus_dev->dev.id);
 406        if (nsim_dev_port_is_vf(nsim_dev_port)) {
 407                unsigned int vf_id = nsim_dev_port_index_to_vf_index(port_index);
 408
 409                debugfs_create_u16("tx_share", 0400, nsim_dev_port->ddir,
 410                                   &nsim_dev->vfconfigs[vf_id].min_tx_rate);
 411                debugfs_create_u16("tx_max", 0400, nsim_dev_port->ddir,
 412                                   &nsim_dev->vfconfigs[vf_id].max_tx_rate);
 413                nsim_dev_port->rate_parent = debugfs_create_file("rate_parent",
 414                                                                 0400,
 415                                                                 nsim_dev_port->ddir,
 416                                                                 &nsim_dev_port->parent_name,
 417                                                                 &nsim_dev_rate_parent_fops);
 418        }
 419        debugfs_create_symlink("dev", nsim_dev_port->ddir, dev_link_name);
 420
 421        return 0;
 422}
 423
 424static void nsim_dev_port_debugfs_exit(struct nsim_dev_port *nsim_dev_port)
 425{
 426        debugfs_remove_recursive(nsim_dev_port->ddir);
 427}
 428
 429static int nsim_dev_resources_register(struct devlink *devlink)
 430{
 431        struct devlink_resource_size_params params = {
 432                .size_max = (u64)-1,
 433                .size_granularity = 1,
 434                .unit = DEVLINK_RESOURCE_UNIT_ENTRY
 435        };
 436        int err;
 437
 438        /* Resources for IPv4 */
 439        err = devlink_resource_register(devlink, "IPv4", (u64)-1,
 440                                        NSIM_RESOURCE_IPV4,
 441                                        DEVLINK_RESOURCE_ID_PARENT_TOP,
 442                                        &params);
 443        if (err) {
 444                pr_err("Failed to register IPv4 top resource\n");
 445                goto out;
 446        }
 447
 448        err = devlink_resource_register(devlink, "fib", (u64)-1,
 449                                        NSIM_RESOURCE_IPV4_FIB,
 450                                        NSIM_RESOURCE_IPV4, &params);
 451        if (err) {
 452                pr_err("Failed to register IPv4 FIB resource\n");
 453                return err;
 454        }
 455
 456        err = devlink_resource_register(devlink, "fib-rules", (u64)-1,
 457                                        NSIM_RESOURCE_IPV4_FIB_RULES,
 458                                        NSIM_RESOURCE_IPV4, &params);
 459        if (err) {
 460                pr_err("Failed to register IPv4 FIB rules resource\n");
 461                return err;
 462        }
 463
 464        /* Resources for IPv6 */
 465        err = devlink_resource_register(devlink, "IPv6", (u64)-1,
 466                                        NSIM_RESOURCE_IPV6,
 467                                        DEVLINK_RESOURCE_ID_PARENT_TOP,
 468                                        &params);
 469        if (err) {
 470                pr_err("Failed to register IPv6 top resource\n");
 471                goto out;
 472        }
 473
 474        err = devlink_resource_register(devlink, "fib", (u64)-1,
 475                                        NSIM_RESOURCE_IPV6_FIB,
 476                                        NSIM_RESOURCE_IPV6, &params);
 477        if (err) {
 478                pr_err("Failed to register IPv6 FIB resource\n");
 479                return err;
 480        }
 481
 482        err = devlink_resource_register(devlink, "fib-rules", (u64)-1,
 483                                        NSIM_RESOURCE_IPV6_FIB_RULES,
 484                                        NSIM_RESOURCE_IPV6, &params);
 485        if (err) {
 486                pr_err("Failed to register IPv6 FIB rules resource\n");
 487                return err;
 488        }
 489
 490        /* Resources for nexthops */
 491        err = devlink_resource_register(devlink, "nexthops", (u64)-1,
 492                                        NSIM_RESOURCE_NEXTHOPS,
 493                                        DEVLINK_RESOURCE_ID_PARENT_TOP,
 494                                        &params);
 495
 496out:
 497        return err;
 498}
 499
 500enum nsim_devlink_param_id {
 501        NSIM_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
 502        NSIM_DEVLINK_PARAM_ID_TEST1,
 503};
 504
 505static const struct devlink_param nsim_devlink_params[] = {
 506        DEVLINK_PARAM_GENERIC(MAX_MACS,
 507                              BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
 508                              NULL, NULL, NULL),
 509        DEVLINK_PARAM_DRIVER(NSIM_DEVLINK_PARAM_ID_TEST1,
 510                             "test1", DEVLINK_PARAM_TYPE_BOOL,
 511                             BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
 512                             NULL, NULL, NULL),
 513};
 514
 515static void nsim_devlink_set_params_init_values(struct nsim_dev *nsim_dev,
 516                                                struct devlink *devlink)
 517{
 518        union devlink_param_value value;
 519
 520        value.vu32 = nsim_dev->max_macs;
 521        devlink_param_driverinit_value_set(devlink,
 522                                           DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
 523                                           value);
 524        value.vbool = nsim_dev->test1;
 525        devlink_param_driverinit_value_set(devlink,
 526                                           NSIM_DEVLINK_PARAM_ID_TEST1,
 527                                           value);
 528}
 529
 530static void nsim_devlink_param_load_driverinit_values(struct devlink *devlink)
 531{
 532        struct nsim_dev *nsim_dev = devlink_priv(devlink);
 533        union devlink_param_value saved_value;
 534        int err;
 535
 536        err = devlink_param_driverinit_value_get(devlink,
 537                                                 DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
 538                                                 &saved_value);
 539        if (!err)
 540                nsim_dev->max_macs = saved_value.vu32;
 541        err = devlink_param_driverinit_value_get(devlink,
 542                                                 NSIM_DEVLINK_PARAM_ID_TEST1,
 543                                                 &saved_value);
 544        if (!err)
 545                nsim_dev->test1 = saved_value.vbool;
 546}
 547
 548#define NSIM_DEV_DUMMY_REGION_SNAPSHOT_MAX 16
 549
 550static const struct devlink_region_ops dummy_region_ops = {
 551        .name = "dummy",
 552        .destructor = &kfree,
 553        .snapshot = nsim_dev_take_snapshot,
 554};
 555
 556static int nsim_dev_dummy_region_init(struct nsim_dev *nsim_dev,
 557                                      struct devlink *devlink)
 558{
 559        nsim_dev->dummy_region =
 560                devlink_region_create(devlink, &dummy_region_ops,
 561                                      NSIM_DEV_DUMMY_REGION_SNAPSHOT_MAX,
 562                                      NSIM_DEV_DUMMY_REGION_SIZE);
 563        return PTR_ERR_OR_ZERO(nsim_dev->dummy_region);
 564}
 565
 566static void nsim_dev_dummy_region_exit(struct nsim_dev *nsim_dev)
 567{
 568        devlink_region_destroy(nsim_dev->dummy_region);
 569}
 570
 571static int
 572__nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_type type,
 573                    unsigned int port_index);
 574static void __nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port);
 575
 576static int nsim_esw_legacy_enable(struct nsim_dev *nsim_dev,
 577                                  struct netlink_ext_ack *extack)
 578{
 579        struct devlink *devlink = priv_to_devlink(nsim_dev);
 580        struct nsim_dev_port *nsim_dev_port, *tmp;
 581
 582        devl_rate_nodes_destroy(devlink);
 583        list_for_each_entry_safe(nsim_dev_port, tmp, &nsim_dev->port_list, list)
 584                if (nsim_dev_port_is_vf(nsim_dev_port))
 585                        __nsim_dev_port_del(nsim_dev_port);
 586        nsim_dev->esw_mode = DEVLINK_ESWITCH_MODE_LEGACY;
 587        return 0;
 588}
 589
 590static int nsim_esw_switchdev_enable(struct nsim_dev *nsim_dev,
 591                                     struct netlink_ext_ack *extack)
 592{
 593        struct nsim_dev_port *nsim_dev_port, *tmp;
 594        int i, err;
 595
 596        for (i = 0; i < nsim_dev_get_vfs(nsim_dev); i++) {
 597                err = __nsim_dev_port_add(nsim_dev, NSIM_DEV_PORT_TYPE_VF, i);
 598                if (err) {
 599                        NL_SET_ERR_MSG_MOD(extack, "Failed to initialize VFs' netdevsim ports");
 600                        pr_err("Failed to initialize VF id=%d. %d.\n", i, err);
 601                        goto err_port_add_vfs;
 602                }
 603        }
 604        nsim_dev->esw_mode = DEVLINK_ESWITCH_MODE_SWITCHDEV;
 605        return 0;
 606
 607err_port_add_vfs:
 608        list_for_each_entry_safe(nsim_dev_port, tmp, &nsim_dev->port_list, list)
 609                if (nsim_dev_port_is_vf(nsim_dev_port))
 610                        __nsim_dev_port_del(nsim_dev_port);
 611        return err;
 612}
 613
 614static int nsim_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
 615                                         struct netlink_ext_ack *extack)
 616{
 617        struct nsim_dev *nsim_dev = devlink_priv(devlink);
 618
 619        if (mode == nsim_dev->esw_mode)
 620                return 0;
 621
 622        if (mode == DEVLINK_ESWITCH_MODE_LEGACY)
 623                return nsim_esw_legacy_enable(nsim_dev, extack);
 624        if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV)
 625                return nsim_esw_switchdev_enable(nsim_dev, extack);
 626
 627        return -EINVAL;
 628}
 629
 630static int nsim_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode)
 631{
 632        struct nsim_dev *nsim_dev = devlink_priv(devlink);
 633
 634        *mode = nsim_dev->esw_mode;
 635        return 0;
 636}
 637
 638struct nsim_trap_item {
 639        void *trap_ctx;
 640        enum devlink_trap_action action;
 641};
 642
 643struct nsim_trap_data {
 644        struct delayed_work trap_report_dw;
 645        struct nsim_trap_item *trap_items_arr;
 646        u64 *trap_policers_cnt_arr;
 647        u64 trap_pkt_cnt;
 648        struct nsim_dev *nsim_dev;
 649        spinlock_t trap_lock;   /* Protects trap_items_arr */
 650};
 651
 652/* All driver-specific traps must be documented in
 653 * Documentation/networking/devlink/netdevsim.rst
 654 */
 655enum {
 656        NSIM_TRAP_ID_BASE = DEVLINK_TRAP_GENERIC_ID_MAX,
 657        NSIM_TRAP_ID_FID_MISS,
 658};
 659
 660#define NSIM_TRAP_NAME_FID_MISS "fid_miss"
 661
 662#define NSIM_TRAP_METADATA DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT
 663
 664#define NSIM_TRAP_DROP(_id, _group_id)                                        \
 665        DEVLINK_TRAP_GENERIC(DROP, DROP, _id,                                 \
 666                             DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,       \
 667                             NSIM_TRAP_METADATA)
 668#define NSIM_TRAP_DROP_EXT(_id, _group_id, _metadata)                         \
 669        DEVLINK_TRAP_GENERIC(DROP, DROP, _id,                                 \
 670                             DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,       \
 671                             NSIM_TRAP_METADATA | (_metadata))
 672#define NSIM_TRAP_EXCEPTION(_id, _group_id)                                   \
 673        DEVLINK_TRAP_GENERIC(EXCEPTION, TRAP, _id,                            \
 674                             DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,       \
 675                             NSIM_TRAP_METADATA)
 676#define NSIM_TRAP_CONTROL(_id, _group_id, _action)                            \
 677        DEVLINK_TRAP_GENERIC(CONTROL, _action, _id,                           \
 678                             DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,       \
 679                             NSIM_TRAP_METADATA)
 680#define NSIM_TRAP_DRIVER_EXCEPTION(_id, _group_id)                            \
 681        DEVLINK_TRAP_DRIVER(EXCEPTION, TRAP, NSIM_TRAP_ID_##_id,              \
 682                            NSIM_TRAP_NAME_##_id,                             \
 683                            DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,        \
 684                            NSIM_TRAP_METADATA)
 685
 686#define NSIM_DEV_TRAP_POLICER_MIN_RATE  1
 687#define NSIM_DEV_TRAP_POLICER_MAX_RATE  8000
 688#define NSIM_DEV_TRAP_POLICER_MIN_BURST 8
 689#define NSIM_DEV_TRAP_POLICER_MAX_BURST 65536
 690
 691#define NSIM_TRAP_POLICER(_id, _rate, _burst)                                 \
 692        DEVLINK_TRAP_POLICER(_id, _rate, _burst,                              \
 693                             NSIM_DEV_TRAP_POLICER_MAX_RATE,                  \
 694                             NSIM_DEV_TRAP_POLICER_MIN_RATE,                  \
 695                             NSIM_DEV_TRAP_POLICER_MAX_BURST,                 \
 696                             NSIM_DEV_TRAP_POLICER_MIN_BURST)
 697
 698static const struct devlink_trap_policer nsim_trap_policers_arr[] = {
 699        NSIM_TRAP_POLICER(1, 1000, 128),
 700        NSIM_TRAP_POLICER(2, 2000, 256),
 701        NSIM_TRAP_POLICER(3, 3000, 512),
 702};
 703
 704static const struct devlink_trap_group nsim_trap_groups_arr[] = {
 705        DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 0),
 706        DEVLINK_TRAP_GROUP_GENERIC(L3_DROPS, 1),
 707        DEVLINK_TRAP_GROUP_GENERIC(L3_EXCEPTIONS, 1),
 708        DEVLINK_TRAP_GROUP_GENERIC(BUFFER_DROPS, 2),
 709        DEVLINK_TRAP_GROUP_GENERIC(ACL_DROPS, 3),
 710        DEVLINK_TRAP_GROUP_GENERIC(MC_SNOOPING, 3),
 711};
 712
 713static const struct devlink_trap nsim_traps_arr[] = {
 714        NSIM_TRAP_DROP(SMAC_MC, L2_DROPS),
 715        NSIM_TRAP_DROP(VLAN_TAG_MISMATCH, L2_DROPS),
 716        NSIM_TRAP_DROP(INGRESS_VLAN_FILTER, L2_DROPS),
 717        NSIM_TRAP_DROP(INGRESS_STP_FILTER, L2_DROPS),
 718        NSIM_TRAP_DROP(EMPTY_TX_LIST, L2_DROPS),
 719        NSIM_TRAP_DROP(PORT_LOOPBACK_FILTER, L2_DROPS),
 720        NSIM_TRAP_DRIVER_EXCEPTION(FID_MISS, L2_DROPS),
 721        NSIM_TRAP_DROP(BLACKHOLE_ROUTE, L3_DROPS),
 722        NSIM_TRAP_EXCEPTION(TTL_ERROR, L3_EXCEPTIONS),
 723        NSIM_TRAP_DROP(TAIL_DROP, BUFFER_DROPS),
 724        NSIM_TRAP_DROP_EXT(INGRESS_FLOW_ACTION_DROP, ACL_DROPS,
 725                           DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE),
 726        NSIM_TRAP_DROP_EXT(EGRESS_FLOW_ACTION_DROP, ACL_DROPS,
 727                           DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE),
 728        NSIM_TRAP_CONTROL(IGMP_QUERY, MC_SNOOPING, MIRROR),
 729        NSIM_TRAP_CONTROL(IGMP_V1_REPORT, MC_SNOOPING, TRAP),
 730};
 731
 732#define NSIM_TRAP_L4_DATA_LEN 100
 733
 734static struct sk_buff *nsim_dev_trap_skb_build(void)
 735{
 736        int tot_len, data_len = NSIM_TRAP_L4_DATA_LEN;
 737        struct sk_buff *skb;
 738        struct udphdr *udph;
 739        struct ethhdr *eth;
 740        struct iphdr *iph;
 741
 742        skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
 743        if (!skb)
 744                return NULL;
 745        tot_len = sizeof(struct iphdr) + sizeof(struct udphdr) + data_len;
 746
 747        skb_reset_mac_header(skb);
 748        eth = skb_put(skb, sizeof(struct ethhdr));
 749        eth_random_addr(eth->h_dest);
 750        eth_random_addr(eth->h_source);
 751        eth->h_proto = htons(ETH_P_IP);
 752        skb->protocol = htons(ETH_P_IP);
 753
 754        skb_set_network_header(skb, skb->len);
 755        iph = skb_put(skb, sizeof(struct iphdr));
 756        iph->protocol = IPPROTO_UDP;
 757        iph->saddr = in_aton("192.0.2.1");
 758        iph->daddr = in_aton("198.51.100.1");
 759        iph->version = 0x4;
 760        iph->frag_off = 0;
 761        iph->ihl = 0x5;
 762        iph->tot_len = htons(tot_len);
 763        iph->ttl = 100;
 764        iph->check = 0;
 765        iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
 766
 767        skb_set_transport_header(skb, skb->len);
 768        udph = skb_put_zero(skb, sizeof(struct udphdr) + data_len);
 769        get_random_bytes(&udph->source, sizeof(u16));
 770        get_random_bytes(&udph->dest, sizeof(u16));
 771        udph->len = htons(sizeof(struct udphdr) + data_len);
 772
 773        return skb;
 774}
 775
 776static void nsim_dev_trap_report(struct nsim_dev_port *nsim_dev_port)
 777{
 778        struct nsim_dev *nsim_dev = nsim_dev_port->ns->nsim_dev;
 779        struct devlink *devlink = priv_to_devlink(nsim_dev);
 780        struct nsim_trap_data *nsim_trap_data;
 781        int i;
 782
 783        nsim_trap_data = nsim_dev->trap_data;
 784
 785        spin_lock(&nsim_trap_data->trap_lock);
 786        for (i = 0; i < ARRAY_SIZE(nsim_traps_arr); i++) {
 787                struct flow_action_cookie *fa_cookie = NULL;
 788                struct nsim_trap_item *nsim_trap_item;
 789                struct sk_buff *skb;
 790                bool has_fa_cookie;
 791
 792                has_fa_cookie = nsim_traps_arr[i].metadata_cap &
 793                                DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE;
 794
 795                nsim_trap_item = &nsim_trap_data->trap_items_arr[i];
 796                if (nsim_trap_item->action == DEVLINK_TRAP_ACTION_DROP)
 797                        continue;
 798
 799                skb = nsim_dev_trap_skb_build();
 800                if (!skb)
 801                        continue;
 802                skb->dev = nsim_dev_port->ns->netdev;
 803
 804                /* Trapped packets are usually passed to devlink in softIRQ,
 805                 * but in this case they are generated in a workqueue. Disable
 806                 * softIRQs to prevent lockdep from complaining about
 807                 * "incosistent lock state".
 808                 */
 809
 810                spin_lock_bh(&nsim_dev->fa_cookie_lock);
 811                fa_cookie = has_fa_cookie ? nsim_dev->fa_cookie : NULL;
 812                devlink_trap_report(devlink, skb, nsim_trap_item->trap_ctx,
 813                                    &nsim_dev_port->devlink_port, fa_cookie);
 814                spin_unlock_bh(&nsim_dev->fa_cookie_lock);
 815                consume_skb(skb);
 816        }
 817        spin_unlock(&nsim_trap_data->trap_lock);
 818}
 819
 820#define NSIM_TRAP_REPORT_INTERVAL_MS    100
 821
 822static void nsim_dev_trap_report_work(struct work_struct *work)
 823{
 824        struct nsim_trap_data *nsim_trap_data;
 825        struct nsim_dev_port *nsim_dev_port;
 826        struct nsim_dev *nsim_dev;
 827
 828        nsim_trap_data = container_of(work, struct nsim_trap_data,
 829                                      trap_report_dw.work);
 830        nsim_dev = nsim_trap_data->nsim_dev;
 831
 832        /* For each running port and enabled packet trap, generate a UDP
 833         * packet with a random 5-tuple and report it.
 834         */
 835        devl_lock(priv_to_devlink(nsim_dev));
 836        list_for_each_entry(nsim_dev_port, &nsim_dev->port_list, list) {
 837                if (!netif_running(nsim_dev_port->ns->netdev))
 838                        continue;
 839
 840                nsim_dev_trap_report(nsim_dev_port);
 841        }
 842        devl_unlock(priv_to_devlink(nsim_dev));
 843
 844        schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw,
 845                              msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS));
 846}
 847
 848static int nsim_dev_traps_init(struct devlink *devlink)
 849{
 850        size_t policers_count = ARRAY_SIZE(nsim_trap_policers_arr);
 851        struct nsim_dev *nsim_dev = devlink_priv(devlink);
 852        struct nsim_trap_data *nsim_trap_data;
 853        int err;
 854
 855        nsim_trap_data = kzalloc(sizeof(*nsim_trap_data), GFP_KERNEL);
 856        if (!nsim_trap_data)
 857                return -ENOMEM;
 858
 859        nsim_trap_data->trap_items_arr = kcalloc(ARRAY_SIZE(nsim_traps_arr),
 860                                                 sizeof(struct nsim_trap_item),
 861                                                 GFP_KERNEL);
 862        if (!nsim_trap_data->trap_items_arr) {
 863                err = -ENOMEM;
 864                goto err_trap_data_free;
 865        }
 866
 867        nsim_trap_data->trap_policers_cnt_arr = kcalloc(policers_count,
 868                                                        sizeof(u64),
 869                                                        GFP_KERNEL);
 870        if (!nsim_trap_data->trap_policers_cnt_arr) {
 871                err = -ENOMEM;
 872                goto err_trap_items_free;
 873        }
 874
 875        /* The lock is used to protect the action state of the registered
 876         * traps. The value is written by user and read in delayed work when
 877         * iterating over all the traps.
 878         */
 879        spin_lock_init(&nsim_trap_data->trap_lock);
 880        nsim_trap_data->nsim_dev = nsim_dev;
 881        nsim_dev->trap_data = nsim_trap_data;
 882
 883        err = devlink_trap_policers_register(devlink, nsim_trap_policers_arr,
 884                                             policers_count);
 885        if (err)
 886                goto err_trap_policers_cnt_free;
 887
 888        err = devlink_trap_groups_register(devlink, nsim_trap_groups_arr,
 889                                           ARRAY_SIZE(nsim_trap_groups_arr));
 890        if (err)
 891                goto err_trap_policers_unregister;
 892
 893        err = devlink_traps_register(devlink, nsim_traps_arr,
 894                                     ARRAY_SIZE(nsim_traps_arr), NULL);
 895        if (err)
 896                goto err_trap_groups_unregister;
 897
 898        INIT_DELAYED_WORK(&nsim_dev->trap_data->trap_report_dw,
 899                          nsim_dev_trap_report_work);
 900        schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw,
 901                              msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS));
 902
 903        return 0;
 904
 905err_trap_groups_unregister:
 906        devlink_trap_groups_unregister(devlink, nsim_trap_groups_arr,
 907                                       ARRAY_SIZE(nsim_trap_groups_arr));
 908err_trap_policers_unregister:
 909        devlink_trap_policers_unregister(devlink, nsim_trap_policers_arr,
 910                                         ARRAY_SIZE(nsim_trap_policers_arr));
 911err_trap_policers_cnt_free:
 912        kfree(nsim_trap_data->trap_policers_cnt_arr);
 913err_trap_items_free:
 914        kfree(nsim_trap_data->trap_items_arr);
 915err_trap_data_free:
 916        kfree(nsim_trap_data);
 917        return err;
 918}
 919
 920static void nsim_dev_traps_exit(struct devlink *devlink)
 921{
 922        struct nsim_dev *nsim_dev = devlink_priv(devlink);
 923
 924        /* caution, trap work takes devlink lock */
 925        cancel_delayed_work_sync(&nsim_dev->trap_data->trap_report_dw);
 926        devlink_traps_unregister(devlink, nsim_traps_arr,
 927                                 ARRAY_SIZE(nsim_traps_arr));
 928        devlink_trap_groups_unregister(devlink, nsim_trap_groups_arr,
 929                                       ARRAY_SIZE(nsim_trap_groups_arr));
 930        devlink_trap_policers_unregister(devlink, nsim_trap_policers_arr,
 931                                         ARRAY_SIZE(nsim_trap_policers_arr));
 932        kfree(nsim_dev->trap_data->trap_policers_cnt_arr);
 933        kfree(nsim_dev->trap_data->trap_items_arr);
 934        kfree(nsim_dev->trap_data);
 935}
 936
 937static int nsim_dev_reload_create(struct nsim_dev *nsim_dev,
 938                                  struct netlink_ext_ack *extack);
 939static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev);
 940
 941static int nsim_dev_reload_down(struct devlink *devlink, bool netns_change,
 942                                enum devlink_reload_action action, enum devlink_reload_limit limit,
 943                                struct netlink_ext_ack *extack)
 944{
 945        struct nsim_dev *nsim_dev = devlink_priv(devlink);
 946        struct nsim_bus_dev *nsim_bus_dev;
 947
 948        nsim_bus_dev = nsim_dev->nsim_bus_dev;
 949        if (!mutex_trylock(&nsim_bus_dev->nsim_bus_reload_lock))
 950                return -EOPNOTSUPP;
 951
 952        if (nsim_dev->dont_allow_reload) {
 953                /* For testing purposes, user set debugfs dont_allow_reload
 954                 * value to true. So forbid it.
 955                 */
 956                NL_SET_ERR_MSG_MOD(extack, "User forbid the reload for testing purposes");
 957                mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock);
 958                return -EOPNOTSUPP;
 959        }
 960        nsim_bus_dev->in_reload = true;
 961
 962        nsim_dev_reload_destroy(nsim_dev);
 963        mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock);
 964        return 0;
 965}
 966
 967static int nsim_dev_reload_up(struct devlink *devlink, enum devlink_reload_action action,
 968                              enum devlink_reload_limit limit, u32 *actions_performed,
 969                              struct netlink_ext_ack *extack)
 970{
 971        struct nsim_dev *nsim_dev = devlink_priv(devlink);
 972        struct nsim_bus_dev *nsim_bus_dev;
 973        int ret;
 974
 975        nsim_bus_dev = nsim_dev->nsim_bus_dev;
 976        mutex_lock(&nsim_bus_dev->nsim_bus_reload_lock);
 977        nsim_bus_dev->in_reload = false;
 978
 979        if (nsim_dev->fail_reload) {
 980                /* For testing purposes, user set debugfs fail_reload
 981                 * value to true. Fail right away.
 982                 */
 983                NL_SET_ERR_MSG_MOD(extack, "User setup the reload to fail for testing purposes");
 984                mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock);
 985                return -EINVAL;
 986        }
 987
 988        *actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
 989        ret = nsim_dev_reload_create(nsim_dev, extack);
 990        mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock);
 991        return ret;
 992}
 993
 994static int nsim_dev_info_get(struct devlink *devlink,
 995                             struct devlink_info_req *req,
 996                             struct netlink_ext_ack *extack)
 997{
 998        return devlink_info_driver_name_put(req, DRV_NAME);
 999}
1000
1001#define NSIM_DEV_FLASH_SIZE 500000
1002#define NSIM_DEV_FLASH_CHUNK_SIZE 1000
1003#define NSIM_DEV_FLASH_CHUNK_TIME_MS 10
1004
1005static int nsim_dev_flash_update(struct devlink *devlink,
1006                                 struct devlink_flash_update_params *params,
1007                                 struct netlink_ext_ack *extack)
1008{
1009        struct nsim_dev *nsim_dev = devlink_priv(devlink);
1010        int i;
1011
1012        if ((params->overwrite_mask & ~nsim_dev->fw_update_overwrite_mask) != 0)
1013                return -EOPNOTSUPP;
1014
1015        if (nsim_dev->fw_update_status) {
1016                devlink_flash_update_status_notify(devlink,
1017                                                   "Preparing to flash",
1018                                                   params->component, 0, 0);
1019        }
1020
1021        for (i = 0; i < NSIM_DEV_FLASH_SIZE / NSIM_DEV_FLASH_CHUNK_SIZE; i++) {
1022                if (nsim_dev->fw_update_status)
1023                        devlink_flash_update_status_notify(devlink, "Flashing",
1024                                                           params->component,
1025                                                           i * NSIM_DEV_FLASH_CHUNK_SIZE,
1026                                                           NSIM_DEV_FLASH_SIZE);
1027                msleep(NSIM_DEV_FLASH_CHUNK_TIME_MS);
1028        }
1029
1030        if (nsim_dev->fw_update_status) {
1031                devlink_flash_update_status_notify(devlink, "Flashing",
1032                                                   params->component,
1033                                                   NSIM_DEV_FLASH_SIZE,
1034                                                   NSIM_DEV_FLASH_SIZE);
1035                devlink_flash_update_timeout_notify(devlink, "Flash select",
1036                                                    params->component, 81);
1037                devlink_flash_update_status_notify(devlink, "Flashing done",
1038                                                   params->component, 0, 0);
1039        }
1040
1041        return 0;
1042}
1043
1044static struct nsim_trap_item *
1045nsim_dev_trap_item_lookup(struct nsim_dev *nsim_dev, u16 trap_id)
1046{
1047        struct nsim_trap_data *nsim_trap_data = nsim_dev->trap_data;
1048        int i;
1049
1050        for (i = 0; i < ARRAY_SIZE(nsim_traps_arr); i++) {
1051                if (nsim_traps_arr[i].id == trap_id)
1052                        return &nsim_trap_data->trap_items_arr[i];
1053        }
1054
1055        return NULL;
1056}
1057
1058static int nsim_dev_devlink_trap_init(struct devlink *devlink,
1059                                      const struct devlink_trap *trap,
1060                                      void *trap_ctx)
1061{
1062        struct nsim_dev *nsim_dev = devlink_priv(devlink);
1063        struct nsim_trap_item *nsim_trap_item;
1064
1065        nsim_trap_item = nsim_dev_trap_item_lookup(nsim_dev, trap->id);
1066        if (WARN_ON(!nsim_trap_item))
1067                return -ENOENT;
1068
1069        nsim_trap_item->trap_ctx = trap_ctx;
1070        nsim_trap_item->action = trap->init_action;
1071
1072        return 0;
1073}
1074
1075static int
1076nsim_dev_devlink_trap_action_set(struct devlink *devlink,
1077                                 const struct devlink_trap *trap,
1078                                 enum devlink_trap_action action,
1079                                 struct netlink_ext_ack *extack)
1080{
1081        struct nsim_dev *nsim_dev = devlink_priv(devlink);
1082        struct nsim_trap_item *nsim_trap_item;
1083
1084        nsim_trap_item = nsim_dev_trap_item_lookup(nsim_dev, trap->id);
1085        if (WARN_ON(!nsim_trap_item))
1086                return -ENOENT;
1087
1088        spin_lock(&nsim_dev->trap_data->trap_lock);
1089        nsim_trap_item->action = action;
1090        spin_unlock(&nsim_dev->trap_data->trap_lock);
1091
1092        return 0;
1093}
1094
1095static int
1096nsim_dev_devlink_trap_group_set(struct devlink *devlink,
1097                                const struct devlink_trap_group *group,
1098                                const struct devlink_trap_policer *policer,
1099                                struct netlink_ext_ack *extack)
1100{
1101        struct nsim_dev *nsim_dev = devlink_priv(devlink);
1102
1103        if (nsim_dev->fail_trap_group_set)
1104                return -EINVAL;
1105
1106        return 0;
1107}
1108
1109static int
1110nsim_dev_devlink_trap_policer_set(struct devlink *devlink,
1111                                  const struct devlink_trap_policer *policer,
1112                                  u64 rate, u64 burst,
1113                                  struct netlink_ext_ack *extack)
1114{
1115        struct nsim_dev *nsim_dev = devlink_priv(devlink);
1116
1117        if (nsim_dev->fail_trap_policer_set) {
1118                NL_SET_ERR_MSG_MOD(extack, "User setup the operation to fail for testing purposes");
1119                return -EINVAL;
1120        }
1121
1122        return 0;
1123}
1124
1125static int
1126nsim_dev_devlink_trap_policer_counter_get(struct devlink *devlink,
1127                                          const struct devlink_trap_policer *policer,
1128                                          u64 *p_drops)
1129{
1130        struct nsim_dev *nsim_dev = devlink_priv(devlink);
1131        u64 *cnt;
1132
1133        if (nsim_dev->fail_trap_policer_counter_get)
1134                return -EINVAL;
1135
1136        cnt = &nsim_dev->trap_data->trap_policers_cnt_arr[policer->id - 1];
1137        *p_drops = (*cnt)++;
1138
1139        return 0;
1140}
1141
1142#define NSIM_LINK_SPEED_MAX     5000 /* Mbps */
1143#define NSIM_LINK_SPEED_UNIT    125000 /* 1 Mbps given in bytes/sec to avoid
1144                                        * u64 overflow during conversion from
1145                                        * bytes to bits.
1146                                        */
1147
1148static int nsim_rate_bytes_to_units(char *name, u64 *rate, struct netlink_ext_ack *extack)
1149{
1150        u64 val;
1151        u32 rem;
1152
1153        val = div_u64_rem(*rate, NSIM_LINK_SPEED_UNIT, &rem);
1154        if (rem) {
1155                pr_err("%s rate value %lluBps not in link speed units of 1Mbps.\n",
1156                       name, *rate);
1157                NL_SET_ERR_MSG_MOD(extack, "TX rate value not in link speed units of 1Mbps.");
1158                return -EINVAL;
1159        }
1160
1161        if (val > NSIM_LINK_SPEED_MAX) {
1162                pr_err("%s rate value %lluMbps exceed link maximum speed 5000Mbps.\n",
1163                       name, val);
1164                NL_SET_ERR_MSG_MOD(extack, "TX rate value exceed link maximum speed 5000Mbps.");
1165                return -EINVAL;
1166        }
1167        *rate = val;
1168        return 0;
1169}
1170
1171static int nsim_leaf_tx_share_set(struct devlink_rate *devlink_rate, void *priv,
1172                                  u64 tx_share, struct netlink_ext_ack *extack)
1173{
1174        struct nsim_dev_port *nsim_dev_port = priv;
1175        struct nsim_dev *nsim_dev = nsim_dev_port->ns->nsim_dev;
1176        int vf_id = nsim_dev_port_index_to_vf_index(nsim_dev_port->port_index);
1177        int err;
1178
1179        err = nsim_rate_bytes_to_units("tx_share", &tx_share, extack);
1180        if (err)
1181                return err;
1182
1183        nsim_dev->vfconfigs[vf_id].min_tx_rate = tx_share;
1184        return 0;
1185}
1186
1187static int nsim_leaf_tx_max_set(struct devlink_rate *devlink_rate, void *priv,
1188                                u64 tx_max, struct netlink_ext_ack *extack)
1189{
1190        struct nsim_dev_port *nsim_dev_port = priv;
1191        struct nsim_dev *nsim_dev = nsim_dev_port->ns->nsim_dev;
1192        int vf_id = nsim_dev_port_index_to_vf_index(nsim_dev_port->port_index);
1193        int err;
1194
1195        err = nsim_rate_bytes_to_units("tx_max", &tx_max, extack);
1196        if (err)
1197                return err;
1198
1199        nsim_dev->vfconfigs[vf_id].max_tx_rate = tx_max;
1200        return 0;
1201}
1202
1203struct nsim_rate_node {
1204        struct dentry *ddir;
1205        struct dentry *rate_parent;
1206        char *parent_name;
1207        u16 tx_share;
1208        u16 tx_max;
1209};
1210
1211static int nsim_node_tx_share_set(struct devlink_rate *devlink_rate, void *priv,
1212                                  u64 tx_share, struct netlink_ext_ack *extack)
1213{
1214        struct nsim_rate_node *nsim_node = priv;
1215        int err;
1216
1217        err = nsim_rate_bytes_to_units("tx_share", &tx_share, extack);
1218        if (err)
1219                return err;
1220
1221        nsim_node->tx_share = tx_share;
1222        return 0;
1223}
1224
1225static int nsim_node_tx_max_set(struct devlink_rate *devlink_rate, void *priv,
1226                                u64 tx_max, struct netlink_ext_ack *extack)
1227{
1228        struct nsim_rate_node *nsim_node = priv;
1229        int err;
1230
1231        err = nsim_rate_bytes_to_units("tx_max", &tx_max, extack);
1232        if (err)
1233                return err;
1234
1235        nsim_node->tx_max = tx_max;
1236        return 0;
1237}
1238
1239static int nsim_rate_node_new(struct devlink_rate *node, void **priv,
1240                              struct netlink_ext_ack *extack)
1241{
1242        struct nsim_dev *nsim_dev = devlink_priv(node->devlink);
1243        struct nsim_rate_node *nsim_node;
1244
1245        if (!nsim_esw_mode_is_switchdev(nsim_dev)) {
1246                NL_SET_ERR_MSG_MOD(extack, "Node creation allowed only in switchdev mode.");
1247                return -EOPNOTSUPP;
1248        }
1249
1250        nsim_node = kzalloc(sizeof(*nsim_node), GFP_KERNEL);
1251        if (!nsim_node)
1252                return -ENOMEM;
1253
1254        nsim_node->ddir = debugfs_create_dir(node->name, nsim_dev->nodes_ddir);
1255
1256        debugfs_create_u16("tx_share", 0400, nsim_node->ddir, &nsim_node->tx_share);
1257        debugfs_create_u16("tx_max", 0400, nsim_node->ddir, &nsim_node->tx_max);
1258        nsim_node->rate_parent = debugfs_create_file("rate_parent", 0400,
1259                                                     nsim_node->ddir,
1260                                                     &nsim_node->parent_name,
1261                                                     &nsim_dev_rate_parent_fops);
1262
1263        *priv = nsim_node;
1264        return 0;
1265}
1266
1267static int nsim_rate_node_del(struct devlink_rate *node, void *priv,
1268                              struct netlink_ext_ack *extack)
1269{
1270        struct nsim_rate_node *nsim_node = priv;
1271
1272        debugfs_remove(nsim_node->rate_parent);
1273        debugfs_remove_recursive(nsim_node->ddir);
1274        kfree(nsim_node);
1275        return 0;
1276}
1277
1278static int nsim_rate_leaf_parent_set(struct devlink_rate *child,
1279                                     struct devlink_rate *parent,
1280                                     void *priv_child, void *priv_parent,
1281                                     struct netlink_ext_ack *extack)
1282{
1283        struct nsim_dev_port *nsim_dev_port = priv_child;
1284
1285        if (parent)
1286                nsim_dev_port->parent_name = parent->name;
1287        else
1288                nsim_dev_port->parent_name = NULL;
1289        return 0;
1290}
1291
1292static int nsim_rate_node_parent_set(struct devlink_rate *child,
1293                                     struct devlink_rate *parent,
1294                                     void *priv_child, void *priv_parent,
1295                                     struct netlink_ext_ack *extack)
1296{
1297        struct nsim_rate_node *nsim_node = priv_child;
1298
1299        if (parent)
1300                nsim_node->parent_name = parent->name;
1301        else
1302                nsim_node->parent_name = NULL;
1303        return 0;
1304}
1305
1306static int
1307nsim_dev_devlink_trap_drop_counter_get(struct devlink *devlink,
1308                                       const struct devlink_trap *trap,
1309                                       u64 *p_drops)
1310{
1311        struct nsim_dev *nsim_dev = devlink_priv(devlink);
1312        u64 *cnt;
1313
1314        if (nsim_dev->fail_trap_drop_counter_get)
1315                return -EINVAL;
1316
1317        cnt = &nsim_dev->trap_data->trap_pkt_cnt;
1318        *p_drops = (*cnt)++;
1319
1320        return 0;
1321}
1322
1323static const struct devlink_ops nsim_dev_devlink_ops = {
1324        .eswitch_mode_set = nsim_devlink_eswitch_mode_set,
1325        .eswitch_mode_get = nsim_devlink_eswitch_mode_get,
1326        .supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT |
1327                                         DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,
1328        .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
1329        .reload_down = nsim_dev_reload_down,
1330        .reload_up = nsim_dev_reload_up,
1331        .info_get = nsim_dev_info_get,
1332        .flash_update = nsim_dev_flash_update,
1333        .trap_init = nsim_dev_devlink_trap_init,
1334        .trap_action_set = nsim_dev_devlink_trap_action_set,
1335        .trap_group_set = nsim_dev_devlink_trap_group_set,
1336        .trap_policer_set = nsim_dev_devlink_trap_policer_set,
1337        .trap_policer_counter_get = nsim_dev_devlink_trap_policer_counter_get,
1338        .rate_leaf_tx_share_set = nsim_leaf_tx_share_set,
1339        .rate_leaf_tx_max_set = nsim_leaf_tx_max_set,
1340        .rate_node_tx_share_set = nsim_node_tx_share_set,
1341        .rate_node_tx_max_set = nsim_node_tx_max_set,
1342        .rate_node_new = nsim_rate_node_new,
1343        .rate_node_del = nsim_rate_node_del,
1344        .rate_leaf_parent_set = nsim_rate_leaf_parent_set,
1345        .rate_node_parent_set = nsim_rate_node_parent_set,
1346        .trap_drop_counter_get = nsim_dev_devlink_trap_drop_counter_get,
1347};
1348
1349#define NSIM_DEV_MAX_MACS_DEFAULT 32
1350#define NSIM_DEV_TEST1_DEFAULT true
1351
1352static int __nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_type type,
1353                               unsigned int port_index)
1354{
1355        struct devlink_port_attrs attrs = {};
1356        struct nsim_dev_port *nsim_dev_port;
1357        struct devlink_port *devlink_port;
1358        int err;
1359
1360        if (type == NSIM_DEV_PORT_TYPE_VF && !nsim_dev_get_vfs(nsim_dev))
1361                return -EINVAL;
1362
1363        nsim_dev_port = kzalloc(sizeof(*nsim_dev_port), GFP_KERNEL);
1364        if (!nsim_dev_port)
1365                return -ENOMEM;
1366        nsim_dev_port->port_index = nsim_dev_port_index(type, port_index);
1367        nsim_dev_port->port_type = type;
1368
1369        devlink_port = &nsim_dev_port->devlink_port;
1370        if (nsim_dev_port_is_pf(nsim_dev_port)) {
1371                attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
1372                attrs.phys.port_number = port_index + 1;
1373        } else {
1374                attrs.flavour = DEVLINK_PORT_FLAVOUR_PCI_VF;
1375                attrs.pci_vf.pf = 0;
1376                attrs.pci_vf.vf = port_index;
1377        }
1378        memcpy(attrs.switch_id.id, nsim_dev->switch_id.id, nsim_dev->switch_id.id_len);
1379        attrs.switch_id.id_len = nsim_dev->switch_id.id_len;
1380        devlink_port_attrs_set(devlink_port, &attrs);
1381        err = devl_port_register(priv_to_devlink(nsim_dev), devlink_port,
1382                                 nsim_dev_port->port_index);
1383        if (err)
1384                goto err_port_free;
1385
1386        err = nsim_dev_port_debugfs_init(nsim_dev, nsim_dev_port);
1387        if (err)
1388                goto err_dl_port_unregister;
1389
1390        nsim_dev_port->ns = nsim_create(nsim_dev, nsim_dev_port);
1391        if (IS_ERR(nsim_dev_port->ns)) {
1392                err = PTR_ERR(nsim_dev_port->ns);
1393                goto err_port_debugfs_exit;
1394        }
1395
1396        if (nsim_dev_port_is_vf(nsim_dev_port)) {
1397                err = devl_rate_leaf_create(&nsim_dev_port->devlink_port,
1398                                            nsim_dev_port);
1399                if (err)
1400                        goto err_nsim_destroy;
1401        }
1402
1403        devlink_port_type_eth_set(devlink_port, nsim_dev_port->ns->netdev);
1404        list_add(&nsim_dev_port->list, &nsim_dev->port_list);
1405
1406        return 0;
1407
1408err_nsim_destroy:
1409        nsim_destroy(nsim_dev_port->ns);
1410err_port_debugfs_exit:
1411        nsim_dev_port_debugfs_exit(nsim_dev_port);
1412err_dl_port_unregister:
1413        devl_port_unregister(devlink_port);
1414err_port_free:
1415        kfree(nsim_dev_port);
1416        return err;
1417}
1418
1419static void __nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port)
1420{
1421        struct devlink_port *devlink_port = &nsim_dev_port->devlink_port;
1422
1423        list_del(&nsim_dev_port->list);
1424        if (nsim_dev_port_is_vf(nsim_dev_port))
1425                devl_rate_leaf_destroy(&nsim_dev_port->devlink_port);
1426        devlink_port_type_clear(devlink_port);
1427        nsim_destroy(nsim_dev_port->ns);
1428        nsim_dev_port_debugfs_exit(nsim_dev_port);
1429        devl_port_unregister(devlink_port);
1430        kfree(nsim_dev_port);
1431}
1432
1433static void nsim_dev_port_del_all(struct nsim_dev *nsim_dev)
1434{
1435        struct nsim_dev_port *nsim_dev_port, *tmp;
1436
1437        devl_lock(priv_to_devlink(nsim_dev));
1438        list_for_each_entry_safe(nsim_dev_port, tmp,
1439                                 &nsim_dev->port_list, list)
1440                __nsim_dev_port_del(nsim_dev_port);
1441        devl_unlock(priv_to_devlink(nsim_dev));
1442}
1443
1444static int nsim_dev_port_add_all(struct nsim_dev *nsim_dev,
1445                                 unsigned int port_count)
1446{
1447        int i, err;
1448
1449        for (i = 0; i < port_count; i++) {
1450                devl_lock(priv_to_devlink(nsim_dev));
1451                err = __nsim_dev_port_add(nsim_dev, NSIM_DEV_PORT_TYPE_PF, i);
1452                devl_unlock(priv_to_devlink(nsim_dev));
1453                if (err)
1454                        goto err_port_del_all;
1455        }
1456        return 0;
1457
1458err_port_del_all:
1459        nsim_dev_port_del_all(nsim_dev);
1460        return err;
1461}
1462
1463static int nsim_dev_reload_create(struct nsim_dev *nsim_dev,
1464                                  struct netlink_ext_ack *extack)
1465{
1466        struct nsim_bus_dev *nsim_bus_dev = nsim_dev->nsim_bus_dev;
1467        struct devlink *devlink;
1468        int err;
1469
1470        devlink = priv_to_devlink(nsim_dev);
1471        nsim_dev = devlink_priv(devlink);
1472        INIT_LIST_HEAD(&nsim_dev->port_list);
1473        nsim_dev->fw_update_status = true;
1474        nsim_dev->fw_update_overwrite_mask = 0;
1475
1476        nsim_devlink_param_load_driverinit_values(devlink);
1477
1478        err = nsim_dev_dummy_region_init(nsim_dev, devlink);
1479        if (err)
1480                return err;
1481
1482        err = nsim_dev_traps_init(devlink);
1483        if (err)
1484                goto err_dummy_region_exit;
1485
1486        nsim_dev->fib_data = nsim_fib_create(devlink, extack);
1487        if (IS_ERR(nsim_dev->fib_data)) {
1488                err = PTR_ERR(nsim_dev->fib_data);
1489                goto err_traps_exit;
1490        }
1491
1492        err = nsim_dev_health_init(nsim_dev, devlink);
1493        if (err)
1494                goto err_fib_destroy;
1495
1496        err = nsim_dev_psample_init(nsim_dev);
1497        if (err)
1498                goto err_health_exit;
1499
1500        err = nsim_dev_hwstats_init(nsim_dev);
1501        if (err)
1502                goto err_psample_exit;
1503
1504        err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count);
1505        if (err)
1506                goto err_hwstats_exit;
1507
1508        nsim_dev->take_snapshot = debugfs_create_file("take_snapshot",
1509                                                      0200,
1510                                                      nsim_dev->ddir,
1511                                                      nsim_dev,
1512                                                &nsim_dev_take_snapshot_fops);
1513        return 0;
1514
1515err_hwstats_exit:
1516        nsim_dev_hwstats_exit(nsim_dev);
1517err_psample_exit:
1518        nsim_dev_psample_exit(nsim_dev);
1519err_health_exit:
1520        nsim_dev_health_exit(nsim_dev);
1521err_fib_destroy:
1522        nsim_fib_destroy(devlink, nsim_dev->fib_data);
1523err_traps_exit:
1524        nsim_dev_traps_exit(devlink);
1525err_dummy_region_exit:
1526        nsim_dev_dummy_region_exit(nsim_dev);
1527        return err;
1528}
1529
1530int nsim_drv_probe(struct nsim_bus_dev *nsim_bus_dev)
1531{
1532        struct nsim_dev *nsim_dev;
1533        struct devlink *devlink;
1534        int err;
1535
1536        devlink = devlink_alloc_ns(&nsim_dev_devlink_ops, sizeof(*nsim_dev),
1537                                 nsim_bus_dev->initial_net, &nsim_bus_dev->dev);
1538        if (!devlink)
1539                return -ENOMEM;
1540        nsim_dev = devlink_priv(devlink);
1541        nsim_dev->nsim_bus_dev = nsim_bus_dev;
1542        nsim_dev->switch_id.id_len = sizeof(nsim_dev->switch_id.id);
1543        get_random_bytes(nsim_dev->switch_id.id, nsim_dev->switch_id.id_len);
1544        INIT_LIST_HEAD(&nsim_dev->port_list);
1545        nsim_dev->fw_update_status = true;
1546        nsim_dev->fw_update_overwrite_mask = 0;
1547        nsim_dev->max_macs = NSIM_DEV_MAX_MACS_DEFAULT;
1548        nsim_dev->test1 = NSIM_DEV_TEST1_DEFAULT;
1549        spin_lock_init(&nsim_dev->fa_cookie_lock);
1550
1551        dev_set_drvdata(&nsim_bus_dev->dev, nsim_dev);
1552
1553        nsim_dev->vfconfigs = kcalloc(nsim_bus_dev->max_vfs,
1554                                      sizeof(struct nsim_vf_config),
1555                                      GFP_KERNEL | __GFP_NOWARN);
1556        if (!nsim_dev->vfconfigs) {
1557                err = -ENOMEM;
1558                goto err_devlink_free;
1559        }
1560
1561        err = nsim_dev_resources_register(devlink);
1562        if (err)
1563                goto err_vfc_free;
1564
1565        err = devlink_params_register(devlink, nsim_devlink_params,
1566                                      ARRAY_SIZE(nsim_devlink_params));
1567        if (err)
1568                goto err_dl_unregister;
1569        nsim_devlink_set_params_init_values(nsim_dev, devlink);
1570
1571        err = nsim_dev_dummy_region_init(nsim_dev, devlink);
1572        if (err)
1573                goto err_params_unregister;
1574
1575        err = nsim_dev_traps_init(devlink);
1576        if (err)
1577                goto err_dummy_region_exit;
1578
1579        err = nsim_dev_debugfs_init(nsim_dev);
1580        if (err)
1581                goto err_traps_exit;
1582
1583        nsim_dev->fib_data = nsim_fib_create(devlink, NULL);
1584        if (IS_ERR(nsim_dev->fib_data)) {
1585                err = PTR_ERR(nsim_dev->fib_data);
1586                goto err_debugfs_exit;
1587        }
1588
1589        err = nsim_dev_health_init(nsim_dev, devlink);
1590        if (err)
1591                goto err_fib_destroy;
1592
1593        err = nsim_bpf_dev_init(nsim_dev);
1594        if (err)
1595                goto err_health_exit;
1596
1597        err = nsim_dev_psample_init(nsim_dev);
1598        if (err)
1599                goto err_bpf_dev_exit;
1600
1601        err = nsim_dev_hwstats_init(nsim_dev);
1602        if (err)
1603                goto err_psample_exit;
1604
1605        err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count);
1606        if (err)
1607                goto err_hwstats_exit;
1608
1609        nsim_dev->esw_mode = DEVLINK_ESWITCH_MODE_LEGACY;
1610        devlink_set_features(devlink, DEVLINK_F_RELOAD);
1611        devlink_register(devlink);
1612        return 0;
1613
1614err_hwstats_exit:
1615        nsim_dev_hwstats_exit(nsim_dev);
1616err_psample_exit:
1617        nsim_dev_psample_exit(nsim_dev);
1618err_bpf_dev_exit:
1619        nsim_bpf_dev_exit(nsim_dev);
1620err_health_exit:
1621        nsim_dev_health_exit(nsim_dev);
1622err_fib_destroy:
1623        nsim_fib_destroy(devlink, nsim_dev->fib_data);
1624err_debugfs_exit:
1625        nsim_dev_debugfs_exit(nsim_dev);
1626err_traps_exit:
1627        nsim_dev_traps_exit(devlink);
1628err_dummy_region_exit:
1629        nsim_dev_dummy_region_exit(nsim_dev);
1630err_params_unregister:
1631        devlink_params_unregister(devlink, nsim_devlink_params,
1632                                  ARRAY_SIZE(nsim_devlink_params));
1633err_dl_unregister:
1634        devlink_resources_unregister(devlink);
1635err_vfc_free:
1636        kfree(nsim_dev->vfconfigs);
1637err_devlink_free:
1638        devlink_free(devlink);
1639        dev_set_drvdata(&nsim_bus_dev->dev, NULL);
1640        return err;
1641}
1642
1643static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev)
1644{
1645        struct devlink *devlink = priv_to_devlink(nsim_dev);
1646
1647        if (devlink_is_reload_failed(devlink))
1648                return;
1649        debugfs_remove(nsim_dev->take_snapshot);
1650
1651        devl_lock(devlink);
1652        if (nsim_dev_get_vfs(nsim_dev)) {
1653                nsim_bus_dev_set_vfs(nsim_dev->nsim_bus_dev, 0);
1654                if (nsim_esw_mode_is_switchdev(nsim_dev))
1655                        nsim_esw_legacy_enable(nsim_dev, NULL);
1656        }
1657        devl_unlock(devlink);
1658
1659        nsim_dev_port_del_all(nsim_dev);
1660        nsim_dev_hwstats_exit(nsim_dev);
1661        nsim_dev_psample_exit(nsim_dev);
1662        nsim_dev_health_exit(nsim_dev);
1663        nsim_fib_destroy(devlink, nsim_dev->fib_data);
1664        nsim_dev_traps_exit(devlink);
1665        nsim_dev_dummy_region_exit(nsim_dev);
1666}
1667
1668void nsim_drv_remove(struct nsim_bus_dev *nsim_bus_dev)
1669{
1670        struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev);
1671        struct devlink *devlink = priv_to_devlink(nsim_dev);
1672
1673        devlink_unregister(devlink);
1674        nsim_dev_reload_destroy(nsim_dev);
1675
1676        nsim_bpf_dev_exit(nsim_dev);
1677        nsim_dev_debugfs_exit(nsim_dev);
1678        devlink_params_unregister(devlink, nsim_devlink_params,
1679                                  ARRAY_SIZE(nsim_devlink_params));
1680        devlink_resources_unregister(devlink);
1681        kfree(nsim_dev->vfconfigs);
1682        devlink_free(devlink);
1683        dev_set_drvdata(&nsim_bus_dev->dev, NULL);
1684}
1685
1686static struct nsim_dev_port *
1687__nsim_dev_port_lookup(struct nsim_dev *nsim_dev, enum nsim_dev_port_type type,
1688                       unsigned int port_index)
1689{
1690        struct nsim_dev_port *nsim_dev_port;
1691
1692        port_index = nsim_dev_port_index(type, port_index);
1693        list_for_each_entry(nsim_dev_port, &nsim_dev->port_list, list)
1694                if (nsim_dev_port->port_index == port_index)
1695                        return nsim_dev_port;
1696        return NULL;
1697}
1698
1699int nsim_drv_port_add(struct nsim_bus_dev *nsim_bus_dev, enum nsim_dev_port_type type,
1700                      unsigned int port_index)
1701{
1702        struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev);
1703        int err;
1704
1705        devl_lock(priv_to_devlink(nsim_dev));
1706        if (__nsim_dev_port_lookup(nsim_dev, type, port_index))
1707                err = -EEXIST;
1708        else
1709                err = __nsim_dev_port_add(nsim_dev, type, port_index);
1710        devl_unlock(priv_to_devlink(nsim_dev));
1711        return err;
1712}
1713
1714int nsim_drv_port_del(struct nsim_bus_dev *nsim_bus_dev, enum nsim_dev_port_type type,
1715                      unsigned int port_index)
1716{
1717        struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev);
1718        struct nsim_dev_port *nsim_dev_port;
1719        int err = 0;
1720
1721        devl_lock(priv_to_devlink(nsim_dev));
1722        nsim_dev_port = __nsim_dev_port_lookup(nsim_dev, type, port_index);
1723        if (!nsim_dev_port)
1724                err = -ENOENT;
1725        else
1726                __nsim_dev_port_del(nsim_dev_port);
1727        devl_unlock(priv_to_devlink(nsim_dev));
1728        return err;
1729}
1730
1731int nsim_drv_configure_vfs(struct nsim_bus_dev *nsim_bus_dev,
1732                           unsigned int num_vfs)
1733{
1734        struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev);
1735        struct devlink *devlink = priv_to_devlink(nsim_dev);
1736        int ret = 0;
1737
1738        devl_lock(devlink);
1739        if (nsim_bus_dev->num_vfs == num_vfs)
1740                goto exit_unlock;
1741        if (nsim_bus_dev->num_vfs && num_vfs) {
1742                ret = -EBUSY;
1743                goto exit_unlock;
1744        }
1745        if (nsim_bus_dev->max_vfs < num_vfs) {
1746                ret = -ENOMEM;
1747                goto exit_unlock;
1748        }
1749
1750        nsim_bus_dev_set_vfs(nsim_bus_dev, num_vfs);
1751        if (nsim_esw_mode_is_switchdev(nsim_dev)) {
1752                if (num_vfs) {
1753                        ret = nsim_esw_switchdev_enable(nsim_dev, NULL);
1754                        if (ret) {
1755                                nsim_bus_dev_set_vfs(nsim_bus_dev, 0);
1756                                goto exit_unlock;
1757                        }
1758                } else {
1759                        nsim_esw_legacy_enable(nsim_dev, NULL);
1760                }
1761        }
1762
1763exit_unlock:
1764        devl_unlock(devlink);
1765
1766        return ret;
1767}
1768
1769int nsim_dev_init(void)
1770{
1771        nsim_dev_ddir = debugfs_create_dir(DRV_NAME, NULL);
1772        return PTR_ERR_OR_ZERO(nsim_dev_ddir);
1773}
1774
1775void nsim_dev_exit(void)
1776{
1777        debugfs_remove_recursive(nsim_dev_ddir);
1778}
1779