Skip to content

Commit

Permalink
netdevsim: allow port objects to be linked with line cards
Browse files Browse the repository at this point in the history
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 <jiri@nvidia.com>
---
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
  • Loading branch information
Jiri Pirko committed Apr 5, 2022
1 parent a7b9464 commit dfd22c2
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 11 deletions.
6 changes: 4 additions & 2 deletions drivers/net/netdevsim/bus.c
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
46 changes: 37 additions & 9 deletions drivers/net/netdevsim/dev.c
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

Expand Down Expand Up @@ -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 = {};
Expand All @@ -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)) {
Expand Down Expand Up @@ -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);

Expand All @@ -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);
Expand All @@ -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;
Expand 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)
Expand Down Expand Up @@ -1789,41 +1811,47 @@ 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;
return NULL;
}

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);
struct nsim_dev_port *nsim_dev_port;
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
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/netdevsim/netdev.c
Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/netdevsim/netdevsim.h
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
};
Expand All @@ -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);
Expand Down

0 comments on commit dfd22c2

Please sign in to comment.