cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dev.c (50067B)


      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}