@@ -113,7 +113,7 @@ new_port_store(struct device *dev, struct device_attribute *attr,
mutex_lock(&nsim_bus_dev->nsim_bus_reload_lock);
devlink_reload_disable(devlink);
- ret = nsim_dev_port_add(nsim_bus_dev, port_index);
+ ret = nsim_dev_port_add(nsim_bus_dev, NULL, port_index);
devlink_reload_enable(devlink);
mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock);
return ret ? ret : count;
@@ -142,7 +142,7 @@ del_port_store(struct device *dev, struct device_attribute *attr,
mutex_lock(&nsim_bus_dev->nsim_bus_reload_lock);
devlink_reload_disable(devlink);
- ret = nsim_dev_port_del(nsim_bus_dev, port_index);
+ ret = nsim_dev_port_del(nsim_bus_dev, NULL, port_index);
devlink_reload_enable(devlink);
mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock);
return ret ? ret : count;
@@ -35,6 +35,21 @@
#include "netdevsim.h"
+#define NSIM_DEV_LINECARD_PORT_INDEX_BASE 1000
+#define NSIM_DEV_LINECARD_PORT_INDEX_STEP 100
+
+static unsigned int
+nsim_dev_port_index(struct nsim_dev_linecard *nsim_dev_linecard,
+ unsigned int port_index)
+{
+ if (!nsim_dev_linecard)
+ return port_index;
+
+ return NSIM_DEV_LINECARD_PORT_INDEX_BASE +
+ nsim_dev_linecard->linecard_index * NSIM_DEV_LINECARD_PORT_INDEX_STEP +
+ port_index;
+}
+
static struct dentry *nsim_dev_ddir;
#define NSIM_DEV_DUMMY_REGION_SIZE (1024 * 32)
@@ -942,6 +957,7 @@ static const struct devlink_ops nsim_dev_devlink_ops = {
#define NSIM_DEV_TEST1_DEFAULT true
static int __nsim_dev_port_add(struct nsim_dev *nsim_dev,
+ struct nsim_dev_linecard *nsim_dev_linecard,
unsigned int port_index)
{
struct devlink_port_attrs attrs = {};
@@ -952,8 +968,9 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev,
nsim_dev_port = kzalloc(sizeof(*nsim_dev_port), GFP_KERNEL);
if (!nsim_dev_port)
return -ENOMEM;
- nsim_dev_port->port_index = port_index;
-
+ nsim_dev_port->port_index = nsim_dev_port_index(nsim_dev_linecard,
+ port_index);
+ nsim_dev_port->linecard = nsim_dev_linecard;
devlink_port = &nsim_dev_port->devlink_port;
attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
attrs.phys.port_number = port_index + 1;
@@ -961,7 +978,7 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev,
attrs.switch_id.id_len = nsim_dev->switch_id.id_len;
devlink_port_attrs_set(devlink_port, &attrs);
err = devlink_port_register(priv_to_devlink(nsim_dev), devlink_port,
- port_index);
+ nsim_dev_port->port_index);
if (err)
goto err_port_free;
@@ -975,6 +992,11 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev,
goto err_port_debugfs_exit;
}
+ if (nsim_dev_linecard)
+ list_add(&nsim_dev_port->list_lc, &nsim_dev_linecard->port_list);
+ else
+ netif_carrier_on(nsim_dev_port->ns->netdev);
+
devlink_port_type_eth_set(devlink_port, nsim_dev_port->ns->netdev);
list_add(&nsim_dev_port->list, &nsim_dev->port_list);
@@ -994,6 +1016,8 @@ static void __nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port)
struct devlink_port *devlink_port = &nsim_dev_port->devlink_port;
list_del(&nsim_dev_port->list);
+ if (nsim_dev_port->linecard)
+ list_del(&nsim_dev_port->list_lc);
devlink_port_type_clear(devlink_port);
nsim_destroy(nsim_dev_port->ns);
nsim_dev_port_debugfs_exit(nsim_dev_port);
@@ -1018,7 +1042,7 @@ static int nsim_dev_port_add_all(struct nsim_dev *nsim_dev,
int i, err;
for (i = 0; i < port_count; i++) {
- err = __nsim_dev_port_add(nsim_dev, i);
+ err = __nsim_dev_port_add(nsim_dev, NULL, i);
if (err)
goto err_port_del_all;
}
@@ -1040,6 +1064,7 @@ static int __nsim_dev_linecard_add(struct nsim_dev *nsim_dev,
return -ENOMEM;
nsim_dev_linecard->nsim_dev = nsim_dev;
nsim_dev_linecard->linecard_index = linecard_index;
+ INIT_LIST_HEAD(&nsim_dev_linecard->port_list);
err = nsim_dev_linecard_debugfs_init(nsim_dev, nsim_dev_linecard);
if (err)
@@ -1286,10 +1311,13 @@ void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev)
}
static struct nsim_dev_port *
-__nsim_dev_port_lookup(struct nsim_dev *nsim_dev, unsigned int port_index)
+__nsim_dev_port_lookup(struct nsim_dev *nsim_dev,
+ struct nsim_dev_linecard *nsim_dev_linecard,
+ unsigned int port_index)
{
struct nsim_dev_port *nsim_dev_port;
+ port_index = nsim_dev_port_index(nsim_dev_linecard, port_index);
list_for_each_entry(nsim_dev_port, &nsim_dev->port_list, list)
if (nsim_dev_port->port_index == port_index)
return nsim_dev_port;
@@ -1297,21 +1325,24 @@ __nsim_dev_port_lookup(struct nsim_dev *nsim_dev, unsigned int port_index)
}
int nsim_dev_port_add(struct nsim_bus_dev *nsim_bus_dev,
+ struct nsim_dev_linecard *nsim_dev_linecard,
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))
+ if (__nsim_dev_port_lookup(nsim_dev, nsim_dev_linecard, port_index))
err = -EEXIST;
else
- err = __nsim_dev_port_add(nsim_dev, port_index);
+ err = __nsim_dev_port_add(nsim_dev, nsim_dev_linecard,
+ port_index);
mutex_unlock(&nsim_dev->port_list_lock);
return err;
}
int nsim_dev_port_del(struct nsim_bus_dev *nsim_bus_dev,
+ struct nsim_dev_linecard *nsim_dev_linecard,
unsigned int port_index)
{
struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev);
@@ -1319,7 +1350,8 @@ int nsim_dev_port_del(struct nsim_bus_dev *nsim_bus_dev,
int err = 0;
mutex_lock(&nsim_dev->port_list_lock);
- nsim_dev_port = __nsim_dev_port_lookup(nsim_dev, port_index);
+ nsim_dev_port = __nsim_dev_port_lookup(nsim_dev, nsim_dev_linecard,
+ port_index);
if (!nsim_dev_port)
err = -ENOENT;
else
@@ -312,6 +312,8 @@ nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port)
nsim_ipsec_init(ns);
+ netif_carrier_off(dev);
+
err = register_netdevice(dev);
if (err)
goto err_ipsec_teardown;
@@ -184,6 +184,7 @@ struct nsim_dev_linecard;
struct nsim_dev_port {
struct list_head list;
+ struct list_head list_lc; /* node in linecard list */
struct devlink_port devlink_port;
struct nsim_dev_linecard *linecard;
unsigned int port_index;
@@ -196,6 +197,7 @@ struct nsim_dev;
struct nsim_dev_linecard {
struct list_head list;
struct nsim_dev *nsim_dev;
+ struct list_head port_list;
unsigned int linecard_index;
struct dentry *ddir;
};
@@ -255,8 +257,10 @@ void nsim_dev_exit(void);
int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev);
void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev);
int nsim_dev_port_add(struct nsim_bus_dev *nsim_bus_dev,
+ struct nsim_dev_linecard *nsim_dev_linecard,
unsigned int port_index);
int nsim_dev_port_del(struct nsim_bus_dev *nsim_bus_dev,
+ struct nsim_dev_linecard *nsim_dev_linecard,
unsigned int port_index);
struct nsim_fib_data *nsim_fib_create(struct devlink *devlink,