summaryrefslogtreecommitdiff
path: root/drivers/net/netdevsim/dev.c
diff options
context:
space:
mode:
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);