aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netdevsim/dev.c
diff options
context:
space:
mode:
authorJiri Pirko <jiri@mellanox.com>2019-04-25 15:59:54 +0200
committerDavid S. Miller <davem@davemloft.net>2019-04-26 01:52:03 -0400
commit794b2c05ca1c4ded4a023d11833e3855a0ed6ea8 (patch)
tree5230f4fd38b88f53e70baba251cda58074b1a40f /drivers/net/netdevsim/dev.c
parentnetdevsim: implement dev probe/remove skeleton with port initialization (diff)
downloadlinux-dev-794b2c05ca1c4ded4a023d11833e3855a0ed6ea8.tar.xz
linux-dev-794b2c05ca1c4ded4a023d11833e3855a0ed6ea8.zip
netdevsim: extend device attrs to support port addition and deletion
In order to test flows in core, it is beneficial to maintain previously supported possibility to add and delete ports during netdevsim lifetime. Do it by extending device sysfs attrs by "new_port" and "del_port". Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/netdevsim/dev.c')
-rw-r--r--drivers/net/netdevsim/dev.c55
1 files changed, 51 insertions, 4 deletions
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index 6ee9d43ae252..2fa1b2061370 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -18,6 +18,7 @@
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/list.h>
+#include <linux/mutex.h>
#include <linux/random.h>
#include <linux/rtnetlink.h>
#include <net/devlink.h>
@@ -238,6 +239,7 @@ nsim_dev_create(struct nsim_bus_dev *nsim_bus_dev, unsigned int port_count)
nsim_dev->switch_id.id_len = sizeof(nsim_dev->switch_id.id);
get_random_bytes(nsim_dev->switch_id.id, nsim_dev->switch_id.id_len);
INIT_LIST_HEAD(&nsim_dev->port_list);
+ mutex_init(&nsim_dev->port_list_lock);
nsim_dev->fib_data = nsim_fib_create();
if (IS_ERR(nsim_dev->fib_data)) {
@@ -285,10 +287,12 @@ void nsim_dev_destroy(struct nsim_dev *nsim_dev)
devlink_unregister(devlink);
devlink_resources_unregister(devlink, NULL);
nsim_fib_destroy(nsim_dev->fib_data);
+ mutex_destroy(&nsim_dev->port_list_lock);
devlink_free(devlink);
}
-static int nsim_dev_port_add(struct nsim_dev *nsim_dev, unsigned int port_index)
+static int __nsim_dev_port_add(struct nsim_dev *nsim_dev,
+ unsigned int port_index)
{
struct nsim_dev_port *nsim_dev_port;
struct devlink_port *devlink_port;
@@ -324,7 +328,7 @@ err_port_free:
return err;
}
-static void nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port)
+static void __nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port)
{
struct devlink_port *devlink_port = &nsim_dev_port->devlink_port;
@@ -340,7 +344,7 @@ static void nsim_dev_port_del_all(struct nsim_dev *nsim_dev)
list_for_each_entry_safe(nsim_dev_port, tmp,
&nsim_dev->port_list, list)
- nsim_dev_port_del(nsim_dev_port);
+ __nsim_dev_port_del(nsim_dev_port);
}
int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
@@ -355,7 +359,7 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
dev_set_drvdata(&nsim_bus_dev->dev, nsim_dev);
for (i = 0; i < nsim_bus_dev->port_count; i++) {
- err = nsim_dev_port_add(nsim_dev, i);
+ err = __nsim_dev_port_add(nsim_dev, i);
if (err)
goto err_port_del_all;
}
@@ -375,6 +379,49 @@ void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev)
nsim_dev_destroy(nsim_dev);
}
+static struct nsim_dev_port *
+__nsim_dev_port_lookup(struct nsim_dev *nsim_dev, unsigned int port_index)
+{
+ struct nsim_dev_port *nsim_dev_port;
+
+ list_for_each_entry(nsim_dev_port, &nsim_dev->port_list, list)
+ if (nsim_dev_port->port_index == port_index)
+ return nsim_dev_port;
+ return NULL;
+}
+
+int nsim_dev_port_add(struct nsim_bus_dev *nsim_bus_dev,
+ unsigned int port_index)
+{
+ struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev);
+ int err;
+
+ mutex_lock(&nsim_dev->port_list_lock);
+ if (__nsim_dev_port_lookup(nsim_dev, port_index))
+ err = -EEXIST;
+ else
+ err = __nsim_dev_port_add(nsim_dev, port_index);
+ mutex_unlock(&nsim_dev->port_list_lock);
+ return err;
+}
+
+int nsim_dev_port_del(struct nsim_bus_dev *nsim_bus_dev,
+ unsigned int port_index)
+{
+ struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev);
+ struct nsim_dev_port *nsim_dev_port;
+ int err = 0;
+
+ mutex_lock(&nsim_dev->port_list_lock);
+ nsim_dev_port = __nsim_dev_port_lookup(nsim_dev, port_index);
+ if (!nsim_dev_port)
+ err = -ENOENT;
+ else
+ __nsim_dev_port_del(nsim_dev_port);
+ mutex_unlock(&nsim_dev->port_list_lock);
+ return err;
+}
+
int nsim_dev_init(void)
{
nsim_dev_ddir = debugfs_create_dir(DRV_NAME, NULL);