From 5cfe0dc86bde79b21b5e0097a45355e3a5dbb1cb Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 12 Jan 2021 13:30:54 +0100 Subject: [PATCH] netdevsim: allow port objects to be linked with line cards Line cards contain ports. Allow ports to be places on the line cards. Track the ports that belong under certain line card. Make sure that the line card port carrier is down, as it will be taken up later on during "activation". Signed-off-by: Jiri Pirko --- RFCv2->RFCv3: - rebased on top of dev/drv port_add/dev function rename - rebased on top of rate patchset - rebased on top of Leon's reload protection patch --- drivers/net/netdevsim/bus.c | 6 ++-- drivers/net/netdevsim/dev.c | 46 +++++++++++++++++++++++++------ drivers/net/netdevsim/netdev.c | 2 ++ drivers/net/netdevsim/netdevsim.h | 4 +++ 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/drivers/net/netdevsim/bus.c b/drivers/net/netdevsim/bus.c index c9abf55dfab5c..858ec79fa5733 100644 --- a/drivers/net/netdevsim/bus.c +++ b/drivers/net/netdevsim/bus.c @@ -80,7 +80,8 @@ new_port_store(struct device *dev, struct device_attribute *attr, return -EBUSY; } - ret = nsim_drv_port_add(nsim_bus_dev, NSIM_DEV_PORT_TYPE_PF, port_index); + ret = nsim_drv_port_add(nsim_bus_dev, NSIM_DEV_PORT_TYPE_PF, NULL, + port_index); mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock); return ret ? ret : count; } @@ -110,7 +111,8 @@ del_port_store(struct device *dev, struct device_attribute *attr, return -EBUSY; } - ret = nsim_drv_port_del(nsim_bus_dev, NSIM_DEV_PORT_TYPE_PF, port_index); + ret = nsim_drv_port_del(nsim_bus_dev, NSIM_DEV_PORT_TYPE_PF, NULL, + port_index); mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock); return ret ? ret : count; } diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c index 1f809d42316b6..f0a662fdb4f03 100644 --- a/drivers/net/netdevsim/dev.c +++ b/drivers/net/netdevsim/dev.c @@ -35,14 +35,23 @@ #include "netdevsim.h" +#define NSIM_DEV_LINECARD_PORT_INDEX_BASE 1024 +#define NSIM_DEV_LINECARD_PORT_INDEX_STEP 256 + static unsigned int -nsim_dev_port_index(enum nsim_dev_port_type type, unsigned int port_index) +nsim_dev_port_index(enum nsim_dev_port_type type, + struct nsim_dev_linecard *nsim_dev_linecard, + unsigned int port_index) { switch (type) { case NSIM_DEV_PORT_TYPE_VF: port_index = NSIM_DEV_VF_PORT_INDEX_BASE + port_index; break; case NSIM_DEV_PORT_TYPE_PF: + if (nsim_dev_linecard) + port_index += NSIM_DEV_LINECARD_PORT_INDEX_BASE + + nsim_dev_linecard->linecard_index * + NSIM_DEV_LINECARD_PORT_INDEX_STEP; break; } @@ -625,7 +634,8 @@ static int nsim_esw_switchdev_enable(struct nsim_dev *nsim_dev, int i, err; for (i = 0; i < nsim_dev_get_vfs(nsim_dev); i++) { - err = __nsim_dev_port_add(nsim_dev, NSIM_DEV_PORT_TYPE_VF, i); + err = __nsim_dev_port_add(nsim_dev, NSIM_DEV_PORT_TYPE_VF, + NULL, i); if (err) { NL_SET_ERR_MSG_MOD(extack, "Failed to initialize VFs' netdevsim ports"); pr_err("Failed to initialize VF id=%d. %d.\n", i, err); @@ -638,7 +648,7 @@ static int nsim_esw_switchdev_enable(struct nsim_dev *nsim_dev, err_port_add_vfs: list_for_each_entry_safe(nsim_dev_port, tmp, &nsim_dev->port_list, list) if (nsim_dev_port_is_vf(nsim_dev_port)) - __nsim_dev_port_del(nsim_dev_port); + __nsim_dev_port_del(nsim_dev_port, NULL, i); return err; } @@ -1381,6 +1391,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, enum nsim_dev_port_type type, + struct nsim_dev_linecard *nsim_dev_linecard, unsigned int port_index) { struct devlink_port_attrs attrs = {}; @@ -1394,8 +1405,10 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_typ nsim_dev_port = kzalloc(sizeof(*nsim_dev_port), GFP_KERNEL); if (!nsim_dev_port) return -ENOMEM; - nsim_dev_port->port_index = nsim_dev_port_index(type, port_index); + nsim_dev_port->port_index = nsim_dev_port_index(type, nsim_dev_linecard, + port_index); nsim_dev_port->port_type = type; + nsim_dev_port->linecard = nsim_dev_linecard; devlink_port = &nsim_dev_port->devlink_port; if (nsim_dev_port_is_pf(nsim_dev_port)) { @@ -1431,6 +1444,11 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_typ goto err_nsim_destroy; } + 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); @@ -1454,6 +1472,8 @@ static void __nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port) list_del(&nsim_dev_port->list); if (nsim_dev_port_is_vf(nsim_dev_port)) devl_rate_leaf_destroy(&nsim_dev_port->devlink_port); + 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); @@ -1479,7 +1499,8 @@ static int nsim_dev_port_add_all(struct nsim_dev *nsim_dev, for (i = 0; i < port_count; i++) { devl_lock(priv_to_devlink(nsim_dev)); - err = __nsim_dev_port_add(nsim_dev, NSIM_DEV_PORT_TYPE_PF, i); + err = __nsim_dev_port_add(nsim_dev, NSIM_DEV_PORT_TYPE_PF, + NULL, i); devl_unlock(priv_to_devlink(nsim_dev)); if (err) goto err_port_del_all; @@ -1502,6 +1523,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) @@ -1789,11 +1811,12 @@ void nsim_drv_remove(struct nsim_bus_dev *nsim_bus_dev) static struct nsim_dev_port * __nsim_dev_port_lookup(struct nsim_dev *nsim_dev, enum nsim_dev_port_type type, + struct nsim_dev_linecard *nsim_dev_linecard, unsigned int port_index) { struct nsim_dev_port *nsim_dev_port; - port_index = nsim_dev_port_index(type, port_index); + port_index = nsim_dev_port_index(type, 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; @@ -1801,21 +1824,25 @@ __nsim_dev_port_lookup(struct nsim_dev *nsim_dev, enum nsim_dev_port_type type, } int nsim_drv_port_add(struct nsim_bus_dev *nsim_bus_dev, enum nsim_dev_port_type type, + 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; devl_lock(priv_to_devlink(nsim_dev)); - if (__nsim_dev_port_lookup(nsim_dev, type, port_index)) + if (__nsim_dev_port_lookup(nsim_dev, type, + nsim_dev_linecard, port_index)) err = -EEXIST; else - err = __nsim_dev_port_add(nsim_dev, type, port_index); + err = __nsim_dev_port_add(nsim_dev, type, + nsim_dev_linecard, port_index); devl_unlock(priv_to_devlink(nsim_dev)); return err; } int nsim_drv_port_del(struct nsim_bus_dev *nsim_bus_dev, enum nsim_dev_port_type type, + struct nsim_dev_linecard *nsim_dev_linecard, unsigned int port_index) { struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev); @@ -1823,7 +1850,8 @@ int nsim_drv_port_del(struct nsim_bus_dev *nsim_bus_dev, enum nsim_dev_port_type int err = 0; devl_lock(priv_to_devlink(nsim_dev)); - nsim_dev_port = __nsim_dev_port_lookup(nsim_dev, type, port_index); + nsim_dev_port = __nsim_dev_port_lookup(nsim_dev, type, + nsim_dev_linecard, port_index); if (!nsim_dev_port) err = -ENOENT; else diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c index e470e3398abc2..2bc1cb43e7103 100644 --- a/drivers/net/netdevsim/netdev.c +++ b/drivers/net/netdevsim/netdev.c @@ -314,6 +314,8 @@ static int nsim_init_netdevsim(struct netdevsim *ns) nsim_ipsec_init(ns); + netif_carrier_off(ns->netdev); + err = register_netdevice(ns->netdev); if (err) goto err_ipsec_teardown; diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h index 77a063992d5a9..278039770f54d 100644 --- a/drivers/net/netdevsim/netdevsim.h +++ b/drivers/net/netdevsim/netdevsim.h @@ -232,6 +232,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; @@ -310,6 +311,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; }; @@ -335,9 +337,11 @@ int nsim_drv_probe(struct nsim_bus_dev *nsim_bus_dev); void nsim_drv_remove(struct nsim_bus_dev *nsim_bus_dev); int nsim_drv_port_add(struct nsim_bus_dev *nsim_bus_dev, enum nsim_dev_port_type type, + struct nsim_dev_linecard *nsim_dev_linecard, unsigned int port_index); int nsim_drv_port_del(struct nsim_bus_dev *nsim_bus_dev, enum nsim_dev_port_type type, + struct nsim_dev_linecard *nsim_dev_linecard, unsigned int port_index); int nsim_drv_configure_vfs(struct nsim_bus_dev *nsim_bus_dev, unsigned int num_vfs);