[PATCH net-next 0/7] netdevsim port add, delete support

STALE2001d

Revision v1 of 2 in this series.

28 messages, 4 authors, 2021-02-09 · open the first message on its own page

[PATCH net-next 0/7] netdevsim port add, delete support

From: Parav Pandit <hidden>
Date: 2021-02-06 12:57:03

This series simulates one or more PCI PF and SF port addition and function
configuration functionality.

Example sequence:
Create a device with ID=10 and one physical port.
$ echo "10 1" > /sys/bus/netdevsim/new_device

Add PCI PF port:
$ devlink port add netdevsim/netdevsim10 flavour pcipf pfnum 2
netdevsim/netdevsim10/1: type eth netdev eth1 flavour pcipf controller 0 pfnum 2 external false splittable false
  function:
    hw_addr 00:00:00:00:00:00

$ devlink port add netdevsim/netdevsim10 flavour pcisf pfnum 2
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:00:00:00:00:00

Show devlink port:
$ devlink port show netdevsim/netdevsim10/2
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:00:00:00:00:00 state inactive opstate detached

Set the MAC address and activate the function:
$ devlink port function set netdevsim/netdevsim10/2 hw_addr 00:11:22:33:44:55 state active

Show the port and function attributes in JSON format:
$ devlink port show netdevsim/netdevsim10/2 -jp
{
    "port": {
        "netdevsim/netdevsim10/2": {
            "type": "eth",
            "netdev": "eth2",
            "flavour": "pcisf",
            "controller": 0,
            "pfnum": 2,
            "sfnum": 0,
            "splittable": false,
            "function": {
                "hw_addr": "00:11:22:33:44:55",
                "state": "active",
                "opstate": "attached"
            }
        }
    }
}

Delete PCI SF and PF ports:
$ devlink port del netdevsim/netdevsim10/2

Patch summary:
patch-1 adds support for adding/remove PCI PF port
patch-2 adds support for adding/remove PCI SF port
patch-3 simulates MAC address query
patch-4 simulates setting MAC address
patch-5 simulates state query
patch-6 simulates setting state
patch-7 adds tests

Parav Pandit (7):
  netdevsim: Add support for add and delete of a PCI PF port
  netdevsim: Add support for add and delete PCI SF port
  netdevsim: Simulate get hardware address of a PCI port
  netdevsim: Simulate set hardware address of a PCI port
  netdevsim: Simulate port function state for a PCI port
  netdevsim: Simulate port function set state for a PCI port
  netdevsim: Add netdevsim port add test cases

 drivers/net/netdevsim/Makefile                |   2 +-
 drivers/net/netdevsim/dev.c                   |  14 +
 drivers/net/netdevsim/netdevsim.h             |  38 ++
 drivers/net/netdevsim/port_function.c         | 521 ++++++++++++++++++
 .../drivers/net/netdevsim/devlink.sh          |  72 ++-
 5 files changed, 645 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/netdevsim/port_function.c

-- 
2.26.2

[PATCH net-next 1/7] netdevsim: Add support for add and delete of a PCI PF port

From: Parav Pandit <hidden>
Date: 2021-02-06 12:57:03

Simulate PCI PF ports. Allow user to create one or more PCI PF ports.

Examples:

Create a device with ID=10 and one physical port.
$ echo "10 1" > /sys/bus/netdevsim/new_device

Add devlink port of flavour 'pcipf' for PF number 2:

$ devlink port add netdevsim/netdevsim10 flavour pcipf pfnum 2
netdevsim/netdevsim10/4: type eth netdev eth4 flavour pcipf controller 0 pfnum 2 external false splittable false

Show the PCI PF port:
$ devlink port show netdevsim/netdevsim10/4
netdevsim/netdevsim10/4: type eth netdev eth4 flavour pcipf controller 0 pfnum 2 external false splittable false

Delete newly added devlink port:
$ devlink port del netdevsim/netdevsim10/4

Signed-off-by: Parav Pandit <redacted>
---
 drivers/net/netdevsim/Makefile        |   2 +-
 drivers/net/netdevsim/dev.c           |  10 +
 drivers/net/netdevsim/netdevsim.h     |  20 ++
 drivers/net/netdevsim/port_function.c | 340 ++++++++++++++++++++++++++
 4 files changed, 371 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/netdevsim/port_function.c
diff --git a/drivers/net/netdevsim/Makefile b/drivers/net/netdevsim/Makefile
index ade086eed955..be2aefafc498 100644
--- a/drivers/net/netdevsim/Makefile
+++ b/drivers/net/netdevsim/Makefile
@@ -3,7 +3,7 @@
 obj-$(CONFIG_NETDEVSIM) += netdevsim.o
 
 netdevsim-objs := \
-	netdev.o dev.o ethtool.o fib.o bus.o health.o udp_tunnels.o
+	netdev.o dev.o ethtool.o fib.o bus.o health.o udp_tunnels.o port_function.o
 
 ifeq ($(CONFIG_BPF_SYSCALL),y)
 netdevsim-objs += \
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index 816af1f55e2c..806e387918fe 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -905,6 +905,8 @@ static const struct devlink_ops nsim_dev_devlink_ops = {
 	.trap_group_set = nsim_dev_devlink_trap_group_set,
 	.trap_policer_set = nsim_dev_devlink_trap_policer_set,
 	.trap_policer_counter_get = nsim_dev_devlink_trap_policer_counter_get,
+	.port_new = nsim_dev_devlink_port_new,
+	.port_del = nsim_dev_devlink_port_del,
 };
 
 #define NSIM_DEV_MAX_MACS_DEFAULT 32
@@ -1039,6 +1041,8 @@ static int nsim_dev_reload_create(struct nsim_dev *nsim_dev,
 						      nsim_dev->ddir,
 						      nsim_dev,
 						&nsim_dev_take_snapshot_fops);
+
+	nsim_dev_port_fn_enable(nsim_dev);
 	return 0;
 
 err_health_exit:
@@ -1073,6 +1077,7 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
 	nsim_dev->max_macs = NSIM_DEV_MAX_MACS_DEFAULT;
 	nsim_dev->test1 = NSIM_DEV_TEST1_DEFAULT;
 	spin_lock_init(&nsim_dev->fa_cookie_lock);
+	nsim_dev_port_fn_init(nsim_dev);
 
 	dev_set_drvdata(&nsim_bus_dev->dev, nsim_dev);
 
@@ -1120,6 +1125,7 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
 	if (err)
 		goto err_bpf_dev_exit;
 
+	nsim_dev_port_fn_enable(nsim_dev);
 	devlink_params_publish(devlink);
 	devlink_reload_enable(devlink);
 	return 0;
@@ -1154,6 +1160,9 @@ static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev)
 
 	if (devlink_is_reload_failed(devlink))
 		return;
+
+	/* Disable and destroy any user created devlink ports */
+	nsim_dev_port_fn_disable(nsim_dev);
 	debugfs_remove(nsim_dev->take_snapshot);
 	nsim_dev_port_del_all(nsim_dev);
 	nsim_dev_health_exit(nsim_dev);
@@ -1178,6 +1187,7 @@ void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev)
 				  ARRAY_SIZE(nsim_devlink_params));
 	devlink_unregister(devlink);
 	devlink_resources_unregister(devlink, NULL);
+	nsim_dev_port_fn_exit(nsim_dev);
 	devlink_free(devlink);
 }
 
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index 48163c5f2ec9..31beddede0f2 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -229,6 +229,15 @@ struct nsim_dev {
 		bool static_iana_vxlan;
 		u32 sleep;
 	} udp_ports;
+	struct {
+		struct list_head head;
+		struct ida ida;
+		struct ida pfnum_ida;
+		struct mutex disable_mutex; /* protects port deletion
+					     * by driver unload context
+					     */
+		bool enabled;
+	} port_functions;
 };
 
 static inline struct net *nsim_dev_net(struct nsim_dev *nsim_dev)
@@ -299,3 +308,14 @@ struct nsim_bus_dev {
 
 int nsim_bus_init(void);
 void nsim_bus_exit(void);
+
+void nsim_dev_port_fn_init(struct nsim_dev *nsim_dev);
+void nsim_dev_port_fn_exit(struct nsim_dev *nsim_dev);
+void nsim_dev_port_fn_enable(struct nsim_dev *nsim_dev);
+void nsim_dev_port_fn_disable(struct nsim_dev *nsim_dev);
+int nsim_dev_devlink_port_new(struct devlink *devlink,
+			      const struct devlink_port_new_attrs *attrs,
+			      struct netlink_ext_ack *extack,
+			      unsigned int *new_port_index);
+int nsim_dev_devlink_port_del(struct devlink *devlink, unsigned int port_index,
+			      struct netlink_ext_ack *extack);
diff --git a/drivers/net/netdevsim/port_function.c b/drivers/net/netdevsim/port_function.c
new file mode 100644
index 000000000000..a957b754ef92
--- /dev/null
+++ b/drivers/net/netdevsim/port_function.c
@@ -0,0 +1,340 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+/* Copyright (c) 2020 Mellanox Technologies Ltd. */
+
+#include <linux/etherdevice.h>
+#include <uapi/linux/devlink.h>
+
+#include "netdevsim.h"
+
+struct nsim_port_fn {
+	struct devlink_port dl_port;
+	struct net_device *netdev;
+	struct list_head list;
+	unsigned int port_index;
+	enum devlink_port_flavour flavour;
+	u16 pfnum;
+};
+
+static struct devlink_port *
+nsim_dev_port_fn_get_devlink_port(struct net_device *dev)
+{
+	struct nsim_port_fn *port = netdev_priv(dev);
+
+	return &port->dl_port;
+}
+
+static netdev_tx_t
+nsim_dev_port_fn_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
+}
+
+static const struct net_device_ops nsim_netdev_ops = {
+	.ndo_start_xmit = nsim_dev_port_fn_start_xmit,
+	.ndo_get_devlink_port = nsim_dev_port_fn_get_devlink_port,
+};
+
+static void nsim_port_fn_ndev_setup(struct net_device *dev)
+{
+	ether_setup(dev);
+	eth_hw_addr_random(dev);
+
+	dev->tx_queue_len = 0;
+	dev->flags |= IFF_NOARP;
+	dev->flags &= ~IFF_MULTICAST;
+	dev->max_mtu = ETH_MAX_MTU;
+}
+
+static struct nsim_port_fn *
+nsim_devlink_port_fn_alloc(struct nsim_dev *dev,
+			   const struct devlink_port_new_attrs *attrs)
+{
+	struct nsim_bus_dev *nsim_bus_dev = dev->nsim_bus_dev;
+	struct nsim_port_fn *port;
+	struct net_device *netdev;
+	int ret;
+
+	netdev = alloc_netdev(sizeof(*port), "eth%d", NET_NAME_UNKNOWN,
+			      nsim_port_fn_ndev_setup);
+	if (!netdev)
+		return ERR_PTR(-ENOMEM);
+
+	dev_net_set(netdev, nsim_dev_net(dev));
+	netdev->netdev_ops = &nsim_netdev_ops;
+	nsim_bus_dev = dev->nsim_bus_dev;
+	SET_NETDEV_DEV(netdev, &nsim_bus_dev->dev);
+
+	port = netdev_priv(netdev);
+	memset(port, 0, sizeof(*port));
+	port->netdev = netdev;
+	port->flavour = attrs->flavour;
+
+	if (attrs->port_index_valid)
+		ret = ida_alloc_range(&dev->port_functions.ida,
+				      attrs->port_index,
+				      attrs->port_index, GFP_KERNEL);
+	else
+		ret = ida_alloc_min(&dev->port_functions.ida,
+				    nsim_bus_dev->port_count, GFP_KERNEL);
+	if (ret < 0)
+		goto port_ida_err;
+
+	port->port_index = ret;
+
+	switch (port->flavour) {
+	case DEVLINK_PORT_FLAVOUR_PCI_PF:
+		ret = ida_alloc_range(&dev->port_functions.pfnum_ida,
+				      attrs->pfnum, attrs->pfnum,
+				      GFP_KERNEL);
+		if (ret < 0)
+			goto fn_ida_err;
+		port->pfnum = ret;
+		break;
+	default:
+		break;
+	}
+	return port;
+
+fn_ida_err:
+	ida_simple_remove(&dev->port_functions.ida, port->port_index);
+port_ida_err:
+	free_netdev(netdev);
+	return ERR_PTR(ret);
+}
+
+static void
+nsim_devlink_port_fn_free(struct nsim_dev *dev, struct nsim_port_fn *port)
+{
+	switch (port->flavour) {
+	case DEVLINK_PORT_FLAVOUR_PCI_PF:
+		ida_simple_remove(&dev->port_functions.pfnum_ida, port->pfnum);
+		break;
+	default:
+		break;
+	}
+	ida_simple_remove(&dev->port_functions.ida, port->port_index);
+	free_netdev(port->netdev);
+}
+
+static bool
+nsim_dev_port_index_internal(struct nsim_dev *nsim_dev, unsigned int port_index)
+{
+	struct nsim_bus_dev *nsim_bus_dev = nsim_dev->nsim_bus_dev;
+
+	return (port_index < nsim_bus_dev->port_count) ? true : false;
+}
+
+static bool
+nsim_dev_port_port_exists(struct nsim_dev *nsim_dev,
+			  const struct devlink_port_new_attrs *attrs)
+{
+	struct nsim_port_fn *tmp;
+
+	list_for_each_entry(tmp, &nsim_dev->port_functions.head, list) {
+		if (attrs->port_index_valid &&
+		    tmp->port_index == attrs->port_index)
+			return true;
+		if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF &&
+		    tmp->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF &&
+		    tmp->pfnum == attrs->pfnum)
+			return true;
+	}
+	return false;
+}
+
+static struct nsim_port_fn *
+nsim_dev_devlink_port_index_lookup(const struct nsim_dev *nsim_dev,
+				   unsigned int port_index,
+				   struct netlink_ext_ack *extack)
+{
+	struct nsim_port_fn *port;
+
+	list_for_each_entry(port, &nsim_dev->port_functions.head, list) {
+		if (port->port_index != port_index)
+			continue;
+		return port;
+	}
+	NL_SET_ERR_MSG_MOD(extack, "User created port not found");
+	return ERR_PTR(-ENOENT);
+}
+
+static int nsim_devlink_port_fn_add(struct devlink *devlink,
+				    struct nsim_dev *nsim_dev,
+				    struct nsim_port_fn *port,
+				    struct netlink_ext_ack *extack)
+{
+	int err;
+
+	list_add(&port->list, &nsim_dev->port_functions.head);
+
+	err = devlink_port_register(devlink, &port->dl_port, port->port_index);
+	if (err)
+		goto reg_err;
+
+	err = register_netdev(port->netdev);
+	if (err)
+		goto netdev_err;
+
+	devlink_port_type_eth_set(&port->dl_port, port->netdev);
+	return 0;
+
+netdev_err:
+	devlink_port_type_clear(&port->dl_port);
+	devlink_port_unregister(&port->dl_port);
+reg_err:
+	list_del(&port->list);
+	return err;
+}
+
+static void nsim_devlink_port_fn_del(struct nsim_dev *nsim_dev,
+				     struct nsim_port_fn *port)
+{
+	devlink_port_type_clear(&port->dl_port);
+	unregister_netdev(port->netdev);
+	devlink_port_unregister(&port->dl_port);
+	list_del(&port->list);
+}
+
+static bool
+nsim_dev_port_flavour_supported(const struct nsim_dev *nsim_dev,
+				const struct devlink_port_new_attrs *attrs)
+{
+	return attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF;
+}
+
+int nsim_dev_devlink_port_new(struct devlink *devlink,
+			      const struct devlink_port_new_attrs *attrs,
+			      struct netlink_ext_ack *extack,
+			      unsigned int *new_port_index)
+{
+	struct nsim_dev *nsim_dev = devlink_priv(devlink);
+	struct nsim_bus_dev *nsim_bus_dev;
+	struct nsim_port_fn *port;
+	int err;
+
+	nsim_bus_dev = nsim_dev->nsim_bus_dev;
+	if (attrs->port_index_valid &&
+	    attrs->port_index < nsim_bus_dev->port_count) {
+		NL_SET_ERR_MSG_MOD(extack,
+				   "Port with given port index already exist");
+		return -EEXIST;
+	}
+	if (!nsim_dev_port_flavour_supported(nsim_dev, attrs)) {
+		NL_SET_ERR_MSG_MOD(extack, "Unsupported port flavour specified");
+		return -EOPNOTSUPP;
+	}
+	mutex_lock(&nsim_dev->port_functions.disable_mutex);
+	if (!nsim_dev->port_functions.enabled) {
+		err = -ENODEV;
+		goto alloc_err;
+	}
+	if (nsim_dev_port_port_exists(nsim_dev, attrs)) {
+		NL_SET_ERR_MSG_MOD(extack,
+				   "Port with given attributes already exists");
+		err = -EEXIST;
+		goto alloc_err;
+	}
+	port = nsim_devlink_port_fn_alloc(nsim_dev, attrs);
+	if (IS_ERR(port)) {
+		NL_SET_ERR_MSG_MOD(extack, "Fail to allocate port");
+		err = PTR_ERR(port);
+		goto alloc_err;
+	}
+	memcpy(port->dl_port.attrs.switch_id.id, nsim_dev->switch_id.id,
+	       nsim_dev->switch_id.id_len);
+	port->dl_port.attrs.switch_id.id_len = nsim_dev->switch_id.id_len;
+
+	devlink_port_attrs_pci_pf_set(&port->dl_port, 0, port->pfnum, false);
+
+	err = nsim_devlink_port_fn_add(devlink, nsim_dev, port, extack);
+	if (err)
+		goto add_err;
+	*new_port_index = port->port_index;
+	mutex_unlock(&nsim_dev->port_functions.disable_mutex);
+	return 0;
+
+add_err:
+	nsim_devlink_port_fn_free(nsim_dev, port);
+alloc_err:
+	mutex_unlock(&nsim_dev->port_functions.disable_mutex);
+	return err;
+}
+
+int nsim_dev_devlink_port_del(struct devlink *devlink, unsigned int port_index,
+			      struct netlink_ext_ack *extack)
+{
+	struct nsim_dev *nsim_dev = devlink_priv(devlink);
+	struct nsim_port_fn *port;
+	int err = 0;
+
+	if (nsim_dev_port_index_internal(nsim_dev, port_index)) {
+		NL_SET_ERR_MSG_MOD(extack, "Port index doesn't belong to user created port");
+		return -EINVAL;
+	}
+
+	mutex_lock(&nsim_dev->port_functions.disable_mutex);
+	if (!nsim_dev->port_functions.enabled) {
+		err = -ENODEV;
+		goto err;
+	}
+
+	port = nsim_dev_devlink_port_index_lookup(nsim_dev, port_index, extack);
+	if (IS_ERR(port)) {
+		err = PTR_ERR(port);
+		goto err;
+	}
+	nsim_devlink_port_fn_del(nsim_dev, port);
+	nsim_devlink_port_fn_free(nsim_dev, port);
+	mutex_unlock(&nsim_dev->port_functions.disable_mutex);
+	return 0;
+
+err:
+	mutex_unlock(&nsim_dev->port_functions.disable_mutex);
+	return PTR_ERR(port);
+}
+
+void nsim_dev_port_fn_init(struct nsim_dev *nsim_dev)
+{
+	mutex_init(&nsim_dev->port_functions.disable_mutex);
+	INIT_LIST_HEAD(&nsim_dev->port_functions.head);
+	ida_init(&nsim_dev->port_functions.ida);
+	ida_init(&nsim_dev->port_functions.pfnum_ida);
+}
+
+void nsim_dev_port_fn_exit(struct nsim_dev *nsim_dev)
+{
+	WARN_ON(!ida_is_empty(&nsim_dev->port_functions.pfnum_ida));
+	ida_destroy(&nsim_dev->port_functions.pfnum_ida);
+	WARN_ON(!ida_is_empty(&nsim_dev->port_functions.ida));
+	ida_destroy(&nsim_dev->port_functions.ida);
+	WARN_ON(!list_empty(&nsim_dev->port_functions.head));
+	mutex_destroy(&nsim_dev->port_functions.disable_mutex);
+}
+
+void nsim_dev_port_fn_enable(struct nsim_dev *nsim_dev)
+{
+	mutex_lock(&nsim_dev->port_functions.disable_mutex);
+	nsim_dev->port_functions.enabled = true;
+	mutex_unlock(&nsim_dev->port_functions.disable_mutex);
+}
+
+void nsim_dev_port_fn_disable(struct nsim_dev *nsim_dev)
+{
+	struct nsim_port_fn *port;
+	struct nsim_port_fn *tmp;
+
+	mutex_lock(&nsim_dev->port_functions.disable_mutex);
+	nsim_dev->port_functions.enabled = false;
+	mutex_unlock(&nsim_dev->port_functions.disable_mutex);
+
+	/* At this point, no new user commands can start and any ongoing
+	 * commands have completed, so it is safe to delete all user created
+	 * ports.
+	 */
+	list_for_each_entry_safe_reverse(port, tmp,
+					 &nsim_dev->port_functions.head, list) {
+		nsim_devlink_port_fn_del(nsim_dev, port);
+		nsim_devlink_port_fn_free(nsim_dev, port);
+	}
+}
-- 
2.26.2

[PATCH net-next 4/7] netdevsim: Simulate set hardware address of a PCI port

From: Parav Pandit <hidden>
Date: 2021-02-06 12:57:04

Allow users to get/set hardware address for the PCI port.

Below example creates one devlink port, queries a port, sets a
hardware address.

Example of a PCI SF port which supports a port function hw_addr set:
Create a device with ID=10 and one physical port.
$ echo "10 1" > /sys/bus/netdevsim/new_device

Add PCI PF port:
$ devlink port add netdevsim/netdevsim10 flavour pcipf pfnum 2
netdevsim/netdevsim10/1: type eth netdev eth1 flavour pcipf controller 0 pfnum 2 external false splittable false
  function:
    hw_addr 00:00:00:00:00:00

$ devlink port add netdevsim/netdevsim10 flavour pcisf pfnum 2
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:00:00:00:00:00

Set the MAC address:
$ devlink port function set netdevsim/netdevsim10/2 hw_addr 00:11:22:33:44:55

Show devlink ports:
$ devlink port show
netdevsim/netdevsim10/0: type eth netdev eth0 flavour physical port 1 splittable false
netdevsim/netdevsim10/1: type eth netdev eth1 flavour pcipf controller 0 pfnum 2 external false splittable false
  function:
    hw_addr 00:00:00:00:00:00
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:11:22:33:44:55

Show the port and function attributes in JSON format:
$ devlink port show netdevsim/netdevsim10/2 -jp
{
    "port": {
        "netdevsim/netdevsim10/2": {
            "type": "eth",
            "netdev": "eth2",
            "flavour": "pcisf",
            "controller": 0,
            "pfnum": 2,
            "sfnum": 0,
            "splittable": false,
            "function": {
                "hw_addr": "00:11:22:33:44:55"
            }
        }
    }
}

Signed-off-by: Parav Pandit <redacted>
---
 drivers/net/netdevsim/dev.c           |  1 +
 drivers/net/netdevsim/netdevsim.h     |  4 ++++
 drivers/net/netdevsim/port_function.c | 21 +++++++++++++++++++++
 3 files changed, 26 insertions(+)
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index 6046906d6b85..ab15b5f7e955 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -908,6 +908,7 @@ static const struct devlink_ops nsim_dev_devlink_ops = {
 	.port_new = nsim_dev_devlink_port_new,
 	.port_del = nsim_dev_devlink_port_del,
 	.port_function_hw_addr_get = nsim_dev_port_fn_hw_addr_get,
+	.port_function_hw_addr_set = nsim_dev_port_fn_hw_addr_set,
 };
 
 #define NSIM_DEV_MAX_MACS_DEFAULT 32
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index e910c3cf480d..aafe2027a112 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -324,3 +324,7 @@ int nsim_dev_port_fn_hw_addr_get(struct devlink *devlink,
 				 struct devlink_port *port,
 				 u8 *hw_addr, int *hw_addr_len,
 				 struct netlink_ext_ack *extack);
+int nsim_dev_port_fn_hw_addr_set(struct devlink *devlink,
+				 struct devlink_port *port,
+				 const u8 *hw_addr, int hw_addr_len,
+				 struct netlink_ext_ack *extack);
diff --git a/drivers/net/netdevsim/port_function.c b/drivers/net/netdevsim/port_function.c
index 4031598e2076..d47cdf44770a 100644
--- a/drivers/net/netdevsim/port_function.c
+++ b/drivers/net/netdevsim/port_function.c
@@ -461,3 +461,24 @@ int nsim_dev_port_fn_hw_addr_get(struct devlink *devlink,
 	*hw_addr_len = ETH_ALEN;
 	return 0;
 }
+
+int nsim_dev_port_fn_hw_addr_set(struct devlink *devlink,
+				 struct devlink_port *dl_port,
+				 const u8 *hw_addr, int hw_addr_len,
+				 struct netlink_ext_ack *extack)
+{
+	struct nsim_dev *nsim_dev = devlink_priv(devlink);
+	struct nsim_port_fn *port;
+
+	if (hw_addr_len != ETH_ALEN) {
+		NL_SET_ERR_MSG_MOD(extack,
+				   "Hardware address must be 6 bytes long");
+		return -EOPNOTSUPP;
+	}
+	port = nsim_dev_to_port_fn(nsim_dev, dl_port, extack);
+	if (IS_ERR(port))
+		return PTR_ERR(port);
+
+	memcpy(port->hw_addr, hw_addr, ETH_ALEN);
+	return 0;
+}
-- 
2.26.2

[PATCH net-next 3/7] netdevsim: Simulate get hardware address of a PCI port

From: Parav Pandit <hidden>
Date: 2021-02-06 12:57:04

Allow users to get hardware address for the PCI port.

Below example creates one devlink port, queries a port and its hardware
address.

Example of a PCI SF port which supports a port function hw_addr set:
Create a device with ID=10 and one physical port.
$ echo "10 1" > /sys/bus/netdevsim/new_device

Add PCI PF port:
$ devlink port add netdevsim/netdevsim10 flavour pcipf pfnum 2
netdevsim/netdevsim10/1: type eth netdev eth1 flavour pcipf controller 0 pfnum 2 external false splittable false
  function:
    hw_addr 00:00:00:00:00:00

$ devlink port add netdevsim/netdevsim10 flavour pcisf pfnum 2
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:00:00:00:00:00

Show devlink ports:
$ devlink port show
netdevsim/netdevsim10/0: type eth netdev eth0 flavour physical port 1 splittable false
netdevsim/netdevsim10/1: type eth netdev eth1 flavour pcipf controller 0 pfnum 2 external false splittable false
  function:
    hw_addr 00:00:00:00:00:00
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:00:00:00:00:00

Show the port and function attributes in JSON format:
$ devlink port show netdevsim/netdevsim10/2 -jp
{
    "port": {
        "netdevsim/netdevsim10/2": {
            "type": "eth",
            "netdev": "eth2",
            "flavour": "pcisf",
            "controller": 0,
            "pfnum": 2,
            "sfnum": 0,
            "splittable": false,
            "function": {
                "hw_addr": "00:00:00:00:00:00"
            }
        }
    }
}

Signed-off-by: Parav Pandit <redacted>
---
 drivers/net/netdevsim/dev.c           |  1 +
 drivers/net/netdevsim/netdevsim.h     |  4 ++++
 drivers/net/netdevsim/port_function.c | 30 +++++++++++++++++++++++++++
 3 files changed, 35 insertions(+)
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index 806e387918fe..6046906d6b85 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -907,6 +907,7 @@ static const struct devlink_ops nsim_dev_devlink_ops = {
 	.trap_policer_counter_get = nsim_dev_devlink_trap_policer_counter_get,
 	.port_new = nsim_dev_devlink_port_new,
 	.port_del = nsim_dev_devlink_port_del,
+	.port_function_hw_addr_get = nsim_dev_port_fn_hw_addr_get,
 };
 
 #define NSIM_DEV_MAX_MACS_DEFAULT 32
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index efa7c08d842a..e910c3cf480d 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -320,3 +320,7 @@ int nsim_dev_devlink_port_new(struct devlink *devlink,
 			      unsigned int *new_port_index);
 int nsim_dev_devlink_port_del(struct devlink *devlink, unsigned int port_index,
 			      struct netlink_ext_ack *extack);
+int nsim_dev_port_fn_hw_addr_get(struct devlink *devlink,
+				 struct devlink_port *port,
+				 u8 *hw_addr, int *hw_addr_len,
+				 struct netlink_ext_ack *extack);
diff --git a/drivers/net/netdevsim/port_function.c b/drivers/net/netdevsim/port_function.c
index a2f62a609e9b..4031598e2076 100644
--- a/drivers/net/netdevsim/port_function.c
+++ b/drivers/net/netdevsim/port_function.c
@@ -16,6 +16,7 @@ struct nsim_port_fn {
 	int refcount; /* Counts how many sf ports are bound attached to this pf port. */
 	u32 sfnum;
 	u16 pfnum;
+	u8 hw_addr[ETH_ALEN];
 };
 
 static struct devlink_port *
@@ -431,3 +432,32 @@ void nsim_dev_port_fn_disable(struct nsim_dev *nsim_dev)
 		nsim_devlink_port_fn_free(nsim_dev, port);
 	}
 }
+
+static struct nsim_port_fn *
+nsim_dev_to_port_fn(struct nsim_dev *nsim_dev, struct devlink_port *dl_port,
+		    struct netlink_ext_ack *extack)
+{
+	if (nsim_dev_port_index_internal(nsim_dev, dl_port->index)) {
+		NL_SET_ERR_MSG_MOD(extack,
+				   "Port index doesn't belong to user created port");
+		return ERR_PTR(-EOPNOTSUPP);
+	}
+	return container_of(dl_port, struct nsim_port_fn, dl_port);
+}
+
+int nsim_dev_port_fn_hw_addr_get(struct devlink *devlink,
+				 struct devlink_port *dl_port,
+				 u8 *hw_addr, int *hw_addr_len,
+				 struct netlink_ext_ack *extack)
+{
+	struct nsim_dev *nsim_dev = devlink_priv(devlink);
+	struct nsim_port_fn *port;
+
+	port = nsim_dev_to_port_fn(nsim_dev, dl_port, extack);
+	if (IS_ERR(port))
+		return PTR_ERR(port);
+
+	memcpy(hw_addr, port->hw_addr, ETH_ALEN);
+	*hw_addr_len = ETH_ALEN;
+	return 0;
+}
-- 
2.26.2

[PATCH net-next 2/7] netdevsim: Add support for add and delete PCI SF port

From: Parav Pandit <hidden>
Date: 2021-02-06 12:57:05

Simulate PCI SF ports. Allow user to create one or more PCI SF ports.

Examples:

echo "10 1" > /sys/bus/netdevsim/new_device

Add PCI PF port:
$ devlink port add netdevsim/netdevsim10 flavour pcipf pfnum 2
netdevsim/netdevsim10/1: type eth netdev eth1 flavour pcipf controller 0 pfnum 2 external false splittable false

Add PCI SF port where port index and sfnum are auto assigned by driver.

$ devlink port add netdevsim/netdevsim10 flavour pcisf pfnum 2
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false

Show devlink ports:
$ devlink port show
netdevsim/netdevsim10/0: type eth netdev eth0 flavour physical port 1 splittable false
netdevsim/netdevsim10/1: type eth netdev eth1 flavour pcipf controller 0 pfnum 2 external false splittable false
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false

Create a PCI SF port whose port index and SF number are assigned by
the user.

$ devlink port add netdevsim/netdevsim10/66 flavour pcisf pfnum 2 sfnum 66
netdevsim/netdevsim10/66: type eth netdev eth3 flavour pcisf controller 0 pfnum 2 sfnum 66 splittable false

Delete PCI SF and PF ports:
$ devlink port del netdevsim/netdevsim10/66
$ devlink port del netdevsim/netdevsim10/2
$ devlink port del netdevsim/netdevsim10/1

Signed-off-by: Parav Pandit <redacted>
Reviewed-by: Jiri Pirko <redacted>
---
 drivers/net/netdevsim/netdevsim.h     |  1 +
 drivers/net/netdevsim/port_function.c | 99 ++++++++++++++++++++++++++-
 2 files changed, 97 insertions(+), 3 deletions(-)
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index 31beddede0f2..efa7c08d842a 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -233,6 +233,7 @@ struct nsim_dev {
 		struct list_head head;
 		struct ida ida;
 		struct ida pfnum_ida;
+		struct ida sfnum_ida;
 		struct mutex disable_mutex; /* protects port deletion
 					     * by driver unload context
 					     */
diff --git a/drivers/net/netdevsim/port_function.c b/drivers/net/netdevsim/port_function.c
index a957b754ef92..a2f62a609e9b 100644
--- a/drivers/net/netdevsim/port_function.c
+++ b/drivers/net/netdevsim/port_function.c
@@ -9,9 +9,12 @@
 struct nsim_port_fn {
 	struct devlink_port dl_port;
 	struct net_device *netdev;
+	struct nsim_port_fn *pf_pfn;
 	struct list_head list;
 	unsigned int port_index;
 	enum devlink_port_flavour flavour;
+	int refcount; /* Counts how many sf ports are bound attached to this pf port. */
+	u32 sfnum;
 	u16 pfnum;
 };
 
@@ -91,9 +94,24 @@ nsim_devlink_port_fn_alloc(struct nsim_dev *dev,
 			goto fn_ida_err;
 		port->pfnum = ret;
 		break;
+	case DEVLINK_PORT_FLAVOUR_PCI_SF:
+		if (attrs->sfnum_valid)
+			ret = ida_alloc_range(&dev->port_functions.sfnum_ida, attrs->sfnum,
+					      attrs->sfnum, GFP_KERNEL);
+		else
+			ret = ida_alloc(&dev->port_functions.sfnum_ida, GFP_KERNEL);
+		if (ret < 0)
+			goto fn_ida_err;
+		port->sfnum = ret;
+		port->pfnum = attrs->pfnum;
+		break;
 	default:
 		break;
 	}
+	/* refcount_t is not needed as port is protected by port_functions.mutex.
+	 * This count is to keep track of how many SF ports are attached a PF port.
+	 */
+	port->refcount = 1;
 	return port;
 
 fn_ida_err:
@@ -110,6 +128,9 @@ nsim_devlink_port_fn_free(struct nsim_dev *dev, struct nsim_port_fn *port)
 	case DEVLINK_PORT_FLAVOUR_PCI_PF:
 		ida_simple_remove(&dev->port_functions.pfnum_ida, port->pfnum);
 		break;
+	case DEVLINK_PORT_FLAVOUR_PCI_SF:
+		ida_simple_remove(&dev->port_functions.sfnum_ida, port->sfnum);
+		break;
 	default:
 		break;
 	}
@@ -139,6 +160,12 @@ nsim_dev_port_port_exists(struct nsim_dev *nsim_dev,
 		    tmp->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF &&
 		    tmp->pfnum == attrs->pfnum)
 			return true;
+
+		if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_SF &&
+		    tmp->flavour == DEVLINK_PORT_FLAVOUR_PCI_SF &&
+		    attrs->sfnum_valid &&
+		    tmp->sfnum == attrs->sfnum && tmp->pfnum == attrs->pfnum)
+			return true;
 	}
 	return false;
 }
@@ -153,20 +180,72 @@ nsim_dev_devlink_port_index_lookup(const struct nsim_dev *nsim_dev,
 	list_for_each_entry(port, &nsim_dev->port_functions.head, list) {
 		if (port->port_index != port_index)
 			continue;
+		if (port->refcount > 1) {
+			NL_SET_ERR_MSG_MOD(extack, "Port is in use");
+			return ERR_PTR(-EBUSY);
+		}
 		return port;
 	}
 	NL_SET_ERR_MSG_MOD(extack, "User created port not found");
 	return ERR_PTR(-ENOENT);
 }
 
+static struct nsim_port_fn *
+pf_port_get(struct nsim_dev *nsim_dev, struct nsim_port_fn *port)
+{
+	struct nsim_port_fn *tmp;
+
+	/* PF port addition doesn't need a parent. */
+	if (port->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF)
+		return NULL;
+
+	list_for_each_entry(tmp, &nsim_dev->port_functions.head, list) {
+		if (tmp->flavour != DEVLINK_PORT_FLAVOUR_PCI_PF ||
+		    tmp->pfnum != port->pfnum)
+			continue;
+
+		if (tmp->refcount + 1 == INT_MAX)
+			return ERR_PTR(-ENOSPC);
+
+		port->pf_pfn = tmp;
+		tmp->refcount++;
+		return tmp;
+	}
+	return ERR_PTR(-ENOENT);
+}
+
+static void pf_port_put(struct nsim_port_fn *port)
+{
+	if (port->pf_pfn) {
+		port->pf_pfn->refcount--;
+		WARN_ON(port->pf_pfn->refcount < 0);
+	}
+	port->refcount--;
+	WARN_ON(port->refcount != 0);
+}
+
 static int nsim_devlink_port_fn_add(struct devlink *devlink,
 				    struct nsim_dev *nsim_dev,
 				    struct nsim_port_fn *port,
 				    struct netlink_ext_ack *extack)
 {
+	struct nsim_port_fn *pf_pfn;
 	int err;
 
-	list_add(&port->list, &nsim_dev->port_functions.head);
+	/* Keep all PF ports at the start, so that when driver is unloaded
+	 * All SF ports from the end of the list can be removed first.
+	 */
+	if (port->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF)
+		list_add(&port->list, &nsim_dev->port_functions.head);
+	else
+		list_add_tail(&port->list, &nsim_dev->port_functions.head);
+
+	pf_pfn = pf_port_get(nsim_dev, port);
+	if (IS_ERR(pf_pfn)) {
+		NL_SET_ERR_MSG_MOD(extack, "Fail to get pf port");
+		err = PTR_ERR(pf_pfn);
+		goto pf_err;
+	}
 
 	err = devlink_port_register(devlink, &port->dl_port, port->port_index);
 	if (err)
@@ -183,6 +262,8 @@ static int nsim_devlink_port_fn_add(struct devlink *devlink,
 	devlink_port_type_clear(&port->dl_port);
 	devlink_port_unregister(&port->dl_port);
 reg_err:
+	pf_port_put(port);
+pf_err:
 	list_del(&port->list);
 	return err;
 }
@@ -194,13 +275,15 @@ static void nsim_devlink_port_fn_del(struct nsim_dev *nsim_dev,
 	unregister_netdev(port->netdev);
 	devlink_port_unregister(&port->dl_port);
 	list_del(&port->list);
+	pf_port_put(port);
 }
 
 static bool
 nsim_dev_port_flavour_supported(const struct nsim_dev *nsim_dev,
 				const struct devlink_port_new_attrs *attrs)
 {
-	return attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF;
+	return attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF ||
+	       attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_SF;
 }
 
 int nsim_dev_devlink_port_new(struct devlink *devlink,
@@ -245,7 +328,12 @@ int nsim_dev_devlink_port_new(struct devlink *devlink,
 	       nsim_dev->switch_id.id_len);
 	port->dl_port.attrs.switch_id.id_len = nsim_dev->switch_id.id_len;
 
-	devlink_port_attrs_pci_pf_set(&port->dl_port, 0, port->pfnum, false);
+	if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF)
+		devlink_port_attrs_pci_pf_set(&port->dl_port, 0,
+					      port->pfnum, false);
+	else
+		devlink_port_attrs_pci_sf_set(&port->dl_port, 0, port->pfnum,
+					      port->sfnum);
 
 	err = nsim_devlink_port_fn_add(devlink, nsim_dev, port, extack);
 	if (err)
@@ -300,10 +388,13 @@ void nsim_dev_port_fn_init(struct nsim_dev *nsim_dev)
 	INIT_LIST_HEAD(&nsim_dev->port_functions.head);
 	ida_init(&nsim_dev->port_functions.ida);
 	ida_init(&nsim_dev->port_functions.pfnum_ida);
+	ida_init(&nsim_dev->port_functions.sfnum_ida);
 }
 
 void nsim_dev_port_fn_exit(struct nsim_dev *nsim_dev)
 {
+	WARN_ON(!ida_is_empty(&nsim_dev->port_functions.sfnum_ida));
+	ida_destroy(&nsim_dev->port_functions.sfnum_ida);
 	WARN_ON(!ida_is_empty(&nsim_dev->port_functions.pfnum_ida));
 	ida_destroy(&nsim_dev->port_functions.pfnum_ida);
 	WARN_ON(!ida_is_empty(&nsim_dev->port_functions.ida));
@@ -332,6 +423,8 @@ void nsim_dev_port_fn_disable(struct nsim_dev *nsim_dev)
 	 * commands have completed, so it is safe to delete all user created
 	 * ports.
 	 */
+
+	/* Remove SF ports first, followed by PF ports. */
 	list_for_each_entry_safe_reverse(port, tmp,
 					 &nsim_dev->port_functions.head, list) {
 		nsim_devlink_port_fn_del(nsim_dev, port);
-- 
2.26.2

[PATCH net-next 5/7] netdevsim: Simulate port function state for a PCI port

From: Parav Pandit <hidden>
Date: 2021-02-06 12:57:09

Simulate port function state of a PCI port.
This enables users to get the state of the PCI port function.

Example of a PCI SF port which supports a port function hw_addr set:
Create a device with ID=10 and one physical port.
$ echo "10 1" > /sys/bus/netdevsim/new_device

Add PCI PF port:
$ devlink port add netdevsim/netdevsim10 flavour pcipf pfnum 2
netdevsim/netdevsim10/1: type eth netdev eth1 flavour pcipf controller 0 pfnum 2 external false splittable false
  function:
    hw_addr 00:00:00:00:00:00

$ devlink port add netdevsim/netdevsim10 flavour pcisf pfnum 2
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:00:00:00:00:00

Show devlink port:
$ devlink port show netdevsim/netdevsim10/2
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:00:00:00:00:00 state inactive opstate detached

Show the port and function attributes in JSON format:
$ devlink port show netdevsim/netdevsim10/2 -jp
{
    "port": {
        "netdevsim/netdevsim10/2": {
            "type": "eth",
            "netdev": "eth2",
            "flavour": "pcisf",
            "controller": 0,
            "pfnum": 2,
            "sfnum": 0,
            "splittable": false,
            "function": {
                "hw_addr": "00:00:00:00:00:00",
                "state": "inactive",
                "opstate": "detached"
            }
        }
    }
}

Signed-off-by: Parav Pandit <redacted>
---
 drivers/net/netdevsim/dev.c           |  1 +
 drivers/net/netdevsim/netdevsim.h     |  5 +++++
 drivers/net/netdevsim/port_function.c | 22 ++++++++++++++++++++++
 3 files changed, 28 insertions(+)
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index ab15b5f7e955..9f2164ea89cd 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -909,6 +909,7 @@ static const struct devlink_ops nsim_dev_devlink_ops = {
 	.port_del = nsim_dev_devlink_port_del,
 	.port_function_hw_addr_get = nsim_dev_port_fn_hw_addr_get,
 	.port_function_hw_addr_set = nsim_dev_port_fn_hw_addr_set,
+	.port_fn_state_get = nsim_dev_port_fn_state_get,
 };
 
 #define NSIM_DEV_MAX_MACS_DEFAULT 32
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index aafe2027a112..c0544d93e1e8 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -328,3 +328,8 @@ int nsim_dev_port_fn_hw_addr_set(struct devlink *devlink,
 				 struct devlink_port *port,
 				 const u8 *hw_addr, int hw_addr_len,
 				 struct netlink_ext_ack *extack);
+int nsim_dev_port_fn_state_get(struct devlink *devlink,
+			       struct devlink_port *port,
+			       enum devlink_port_fn_state *state,
+			       enum devlink_port_fn_opstate *opstate,
+			       struct netlink_ext_ack *extack);
diff --git a/drivers/net/netdevsim/port_function.c b/drivers/net/netdevsim/port_function.c
index d47cdf44770a..10c692b8aea2 100644
--- a/drivers/net/netdevsim/port_function.c
+++ b/drivers/net/netdevsim/port_function.c
@@ -17,6 +17,7 @@ struct nsim_port_fn {
 	u32 sfnum;
 	u16 pfnum;
 	u8 hw_addr[ETH_ALEN];
+	u8 state; /* enum devlink_port_fn_state */
 };
 
 static struct devlink_port *
@@ -248,6 +249,7 @@ static int nsim_devlink_port_fn_add(struct devlink *devlink,
 		goto pf_err;
 	}
 
+	port->state = DEVLINK_PORT_FN_STATE_INACTIVE;
 	err = devlink_port_register(devlink, &port->dl_port, port->port_index);
 	if (err)
 		goto reg_err;
@@ -482,3 +484,23 @@ int nsim_dev_port_fn_hw_addr_set(struct devlink *devlink,
 	memcpy(port->hw_addr, hw_addr, ETH_ALEN);
 	return 0;
 }
+
+int nsim_dev_port_fn_state_get(struct devlink *devlink,
+			       struct devlink_port *dl_port,
+			       enum devlink_port_fn_state *state,
+			       enum devlink_port_fn_opstate *opstate,
+			       struct netlink_ext_ack *extack)
+{
+	struct nsim_dev *nsim_dev = devlink_priv(devlink);
+	struct nsim_port_fn *port;
+
+	port = nsim_dev_to_port_fn(nsim_dev, dl_port, extack);
+	if (IS_ERR(port))
+		return PTR_ERR(port);
+	*state = port->state;
+	if (port->state == DEVLINK_PORT_FN_STATE_INACTIVE)
+		*opstate = DEVLINK_PORT_FN_OPSTATE_DETACHED;
+	else
+		*opstate = DEVLINK_PORT_FN_OPSTATE_ATTACHED;
+	return 0;
+}
-- 
2.26.2

[PATCH net-next 6/7] netdevsim: Simulate port function set state for a PCI port

From: Parav Pandit <hidden>
Date: 2021-02-06 12:57:18

Simulate port function state of a PCI port.
This enables users to get and set the state of the PCI port function.

Example of a PCI SF port which supports a port function:

Create a device with ID=10 and one physical port.
$ echo "10 1" > /sys/bus/netdevsim/new_device

Add PCI PF port:
$ devlink port add netdevsim/netdevsim10 flavour pcipf pfnum 2
netdevsim/netdevsim10/1: type eth netdev eth1 flavour pcipf controller 0 pfnum 2 external false splittable false
  function:
    hw_addr 00:00:00:00:00:00

$ devlink port add netdevsim/netdevsim10 flavour pcisf pfnum 2
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:00:00:00:00:00

Show devlink port:
$ devlink port show netdevsim/netdevsim10/2
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:00:00:00:00:00 state inactive opstate detached

Set the MAC address and activate the function:
$ devlink port function set netdevsim/netdevsim10/2 hw_addr 00:11:22:33:44:55 state active

Show the port and function attributes in JSON format:
$ devlink port show netdevsim/netdevsim10/2 -jp
{
    "port": {
        "netdevsim/netdevsim10/2": {
            "type": "eth",
            "netdev": "eth2",
            "flavour": "pcisf",
            "controller": 0,
            "pfnum": 2,
            "sfnum": 0,
            "splittable": false,
            "function": {
                "hw_addr": "00:11:22:33:44:55",
                "state": "active",
                "opstate": "attached"
            }
        }
    }
}

Signed-off-by: Parav Pandit <redacted>
---
 drivers/net/netdevsim/dev.c           |  1 +
 drivers/net/netdevsim/netdevsim.h     |  4 ++++
 drivers/net/netdevsim/port_function.c | 15 +++++++++++++++
 3 files changed, 20 insertions(+)
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index 9f2164ea89cd..e8b6bd22fb1f 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -910,6 +910,7 @@ static const struct devlink_ops nsim_dev_devlink_ops = {
 	.port_function_hw_addr_get = nsim_dev_port_fn_hw_addr_get,
 	.port_function_hw_addr_set = nsim_dev_port_fn_hw_addr_set,
 	.port_fn_state_get = nsim_dev_port_fn_state_get,
+	.port_fn_state_set = nsim_dev_port_fn_state_set,
 };
 
 #define NSIM_DEV_MAX_MACS_DEFAULT 32
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index c0544d93e1e8..93bfa3e946b2 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -333,3 +333,7 @@ int nsim_dev_port_fn_state_get(struct devlink *devlink,
 			       enum devlink_port_fn_state *state,
 			       enum devlink_port_fn_opstate *opstate,
 			       struct netlink_ext_ack *extack);
+int nsim_dev_port_fn_state_set(struct devlink *devlink,
+			       struct devlink_port *port,
+			       enum devlink_port_fn_state state,
+			       struct netlink_ext_ack *extack);
diff --git a/drivers/net/netdevsim/port_function.c b/drivers/net/netdevsim/port_function.c
index 10c692b8aea2..8e8e7d6df8a1 100644
--- a/drivers/net/netdevsim/port_function.c
+++ b/drivers/net/netdevsim/port_function.c
@@ -504,3 +504,18 @@ int nsim_dev_port_fn_state_get(struct devlink *devlink,
 		*opstate = DEVLINK_PORT_FN_OPSTATE_ATTACHED;
 	return 0;
 }
+
+int nsim_dev_port_fn_state_set(struct devlink *devlink,
+			       struct devlink_port *dl_port,
+			       enum devlink_port_fn_state state,
+			       struct netlink_ext_ack *extack)
+{
+	struct nsim_dev *nsim_dev = devlink_priv(devlink);
+	struct nsim_port_fn *port;
+
+	port = nsim_dev_to_port_fn(nsim_dev, dl_port, extack);
+	if (IS_ERR(port))
+		return PTR_ERR(port);
+	port->state = state;
+	return 0;
+}
-- 
2.26.2

[PATCH net-next 7/7] netdevsim: Add netdevsim port add test cases

From: Parav Pandit <hidden>
Date: 2021-02-06 12:58:14

Add tests for PCI PF and SF port add, configure and delete using user
specified port index and sfumber; and also using auto generated port
index.

Signed-off-by: Parav Pandit <redacted>
---
 .../drivers/net/netdevsim/devlink.sh          | 72 ++++++++++++++++++-
 1 file changed, 71 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
index 40909c254365..ba349909a37e 100755
--- a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
+++ b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
@@ -5,7 +5,7 @@ lib_dir=$(dirname $0)/../../../net/forwarding
 
 ALL_TESTS="fw_flash_test params_test regions_test reload_test \
 	   netns_reload_test resource_test dev_info_test \
-	   empty_reporter_test dummy_reporter_test"
+	   empty_reporter_test dummy_reporter_test devlink_port_add_test"
 NUM_NETIFS=0
 source $lib_dir/lib.sh
 
@@ -507,6 +507,76 @@ dummy_reporter_test()
 	log_test "dummy reporter test"
 }
 
+function_state_get()
+{
+	local name=$1
+
+	cmd_jq "devlink port show $DL_HANDLE/$USR_SF_PORT_INDEX -j" \
+		" .[][].function.$1"
+}
+
+devlink_port_add_test()
+{
+	RET=0
+	USR_PF_PORT_INDEX=600
+	USR_PFNUM_A=2
+	USR_PFNUM_B=3
+	USR_SF_PORT_INDEX=601
+	USR_SFNUM_A=44
+	USR_SFNUM_B=55
+
+	devlink port add $DL_HANDLE flavour pcipf pfnum $USR_PFNUM_A
+	check_err $? "Failed PF port addition"
+
+	devlink port show
+	check_err $? "Failed PF port show"
+
+	devlink port add $DL_HANDLE flavour pcisf pfnum $USR_PFNUM_A
+	check_err $? "Failed SF port addition"
+
+	devlink port add $DL_HANDLE flavour pcisf pfnum $USR_PFNUM_A \
+			sfnum $USR_SFNUM_A
+	check_err $? "Failed SF port addition"
+
+	devlink port add $DL_HANDLE flavour pcipf pfnum $USR_PFNUM_B
+	check_err $? "Failed second PF port addition"
+
+	devlink port add $DL_HANDLE/$USR_SF_PORT_INDEX flavour pcisf \
+			pfnum $USR_PFNUM_B sfnum $USR_SFNUM_B
+	check_err $? "Failed SF port addition"
+
+	devlink port show
+	check_err $? "Failed PF port show"
+
+	state=$(function_state_get "state")
+	check_err $? "Failed to get function state"
+	[ "$state" == "inactive" ]
+	check_err $? "Unexpected function state $state"
+
+	state=$(function_state_get "opstate")
+	check_err $? "Failed to get operational state"
+	[ "$state" == "detached" ]
+	check_err $? "Unexpected function opstate $opstate"
+
+	devlink port function set $DL_HANDLE/$USR_SF_PORT_INDEX state active
+	check_err $? "Failed to set state"
+
+	state=$(function_state_get "state")
+	check_err $? "Failed to get function state"
+	[ "$state" == "active" ]
+	check_err $? "Unexpected function state $state"
+
+	state=$(function_state_get "opstate")
+	check_err $? "Failed to get operational state"
+	[ "$state" == "attached" ]
+	check_err $? "Unexpected function opstate $opstate"
+
+	devlink port del $DL_HANDLE/$USR_SF_PORT_INDEX
+	check_err $? "Failed SF port deletion"
+
+	log_test "port_add test"
+}
+
 setup_prepare()
 {
 	modprobe netdevsim
-- 
2.26.2

Re: [PATCH net-next 1/7] netdevsim: Add support for add and delete of a PCI PF port

From: kernel test robot <hidden>
Date: 2021-02-06 14:35:51

Hi Parav,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Parav-Pandit/netdevsim-port-add-delete-support/20210206-210153
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 6626a0266566c5aea16178c5e6cd7fc4db3f2f56
config: x86_64-allyesconfig (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/4234edd1adbb2da7f6f156c2bfdac5170eb97dbb
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Parav-Pandit/netdevsim-port-add-delete-support/20210206-210153
        git checkout 4234edd1adbb2da7f6f156c2bfdac5170eb97dbb
        # save the attached .config to linux build tree
        make W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <redacted>

All warnings (new ones prefixed by >>):

   In file included from drivers/net/netdevsim/netdev.c:27:
quoted
drivers/net/netdevsim/netdevsim.h:317:23: warning: 'struct devlink_port_new_attrs' declared inside parameter list will not be visible outside of this definition or declaration
     317 |          const struct devlink_port_new_attrs *attrs,
         |                       ^~~~~~~~~~~~~~~~~~~~~~
--
   In file included from drivers/net/netdevsim/dev.c:36:
quoted
drivers/net/netdevsim/netdevsim.h:317:23: warning: 'struct devlink_port_new_attrs' declared inside parameter list will not be visible outside of this definition or declaration
     317 |          const struct devlink_port_new_attrs *attrs,
         |                       ^~~~~~~~~~~~~~~~~~~~~~
   drivers/net/netdevsim/dev.c:908:3: error: 'const struct devlink_ops' has no member named 'port_new'
     908 |  .port_new = nsim_dev_devlink_port_new,
         |   ^~~~~~~~
   drivers/net/netdevsim/dev.c:908:14: error: initialization of 'int (*)(struct devlink *, struct devlink_port *, u8 *, int *, struct netlink_ext_ack *)' {aka 'int (*)(struct devlink *, struct devlink_port *, unsigned char *, int *, struct netlink_ext_ack *)'} from incompatible pointer type 'int (*)(struct devlink *, const struct devlink_port_new_attrs *, struct netlink_ext_ack *, unsigned int *)' [-Werror=incompatible-pointer-types]
     908 |  .port_new = nsim_dev_devlink_port_new,
         |              ^~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/netdevsim/dev.c:908:14: note: (near initialization for 'nsim_dev_devlink_ops.port_function_hw_addr_get')
   drivers/net/netdevsim/dev.c:909:3: error: 'const struct devlink_ops' has no member named 'port_del'; did you mean 'port_split'?
     909 |  .port_del = nsim_dev_devlink_port_del,
         |   ^~~~~~~~
         |   port_split
   drivers/net/netdevsim/dev.c:909:14: error: initialization of 'int (*)(struct devlink *, struct devlink_port *, const u8 *, int,  struct netlink_ext_ack *)' {aka 'int (*)(struct devlink *, struct devlink_port *, const unsigned char *, int,  struct netlink_ext_ack *)'} from incompatible pointer type 'int (*)(struct devlink *, unsigned int,  struct netlink_ext_ack *)' [-Werror=incompatible-pointer-types]
     909 |  .port_del = nsim_dev_devlink_port_del,
         |              ^~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/netdevsim/dev.c:909:14: note: (near initialization for 'nsim_dev_devlink_ops.port_function_hw_addr_set')
   cc1: some warnings being treated as errors
--
   In file included from drivers/net/netdevsim/port_function.c:7:
quoted
drivers/net/netdevsim/netdevsim.h:317:23: warning: 'struct devlink_port_new_attrs' declared inside parameter list will not be visible outside of this definition or declaration
     317 |          const struct devlink_port_new_attrs *attrs,
         |                       ^~~~~~~~~~~~~~~~~~~~~~
   drivers/net/netdevsim/port_function.c:51:20: warning: 'struct devlink_port_new_attrs' declared inside parameter list will not be visible outside of this definition or declaration
      51 |       const struct devlink_port_new_attrs *attrs)
         |                    ^~~~~~~~~~~~~~~~~~~~~~
   drivers/net/netdevsim/port_function.c: In function 'nsim_devlink_port_fn_alloc':
   drivers/net/netdevsim/port_function.c:71:23: error: dereferencing pointer to incomplete type 'const struct devlink_port_new_attrs'
      71 |  port->flavour = attrs->flavour;
         |                       ^~
   drivers/net/netdevsim/port_function.c: At top level:
   drivers/net/netdevsim/port_function.c:130:19: warning: 'struct devlink_port_new_attrs' declared inside parameter list will not be visible outside of this definition or declaration
     130 |      const struct devlink_port_new_attrs *attrs)
         |                   ^~~~~~~~~~~~~~~~~~~~~~
   drivers/net/netdevsim/port_function.c: In function 'nsim_dev_port_port_exists':
   drivers/net/netdevsim/port_function.c:135:12: error: dereferencing pointer to incomplete type 'const struct devlink_port_new_attrs'
     135 |   if (attrs->port_index_valid &&
         |            ^~
   drivers/net/netdevsim/port_function.c: At top level:
   drivers/net/netdevsim/port_function.c:201:18: warning: 'struct devlink_port_new_attrs' declared inside parameter list will not be visible outside of this definition or declaration
     201 |     const struct devlink_port_new_attrs *attrs)
         |                  ^~~~~~~~~~~~~~~~~~~~~~
   drivers/net/netdevsim/port_function.c: In function 'nsim_dev_port_flavour_supported':
   drivers/net/netdevsim/port_function.c:203:14: error: dereferencing pointer to incomplete type 'const struct devlink_port_new_attrs'
     203 |  return attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF;
         |              ^~
   drivers/net/netdevsim/port_function.c: At top level:
   drivers/net/netdevsim/port_function.c:207:23: warning: 'struct devlink_port_new_attrs' declared inside parameter list will not be visible outside of this definition or declaration
     207 |          const struct devlink_port_new_attrs *attrs,
         |                       ^~~~~~~~~~~~~~~~~~~~~~
   drivers/net/netdevsim/port_function.c:206:5: error: conflicting types for 'nsim_dev_devlink_port_new'
     206 | int nsim_dev_devlink_port_new(struct devlink *devlink,
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~
   In file included from drivers/net/netdevsim/port_function.c:7:
   drivers/net/netdevsim/netdevsim.h:316:5: note: previous declaration of 'nsim_dev_devlink_port_new' was here
     316 | int nsim_dev_devlink_port_new(struct devlink *devlink,
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/netdevsim/port_function.c: In function 'nsim_dev_devlink_port_new':
   drivers/net/netdevsim/port_function.c:217:11: error: dereferencing pointer to incomplete type 'const struct devlink_port_new_attrs'
     217 |  if (attrs->port_index_valid &&
         |           ^~
   drivers/net/netdevsim/port_function.c:223:49: error: passing argument 2 of 'nsim_dev_port_flavour_supported' from incompatible pointer type [-Werror=incompatible-pointer-types]
     223 |  if (!nsim_dev_port_flavour_supported(nsim_dev, attrs)) {
         |                                                 ^~~~~
         |                                                 |
         |                                                 const struct devlink_port_new_attrs *
   drivers/net/netdevsim/port_function.c:201:42: note: expected 'const struct devlink_port_new_attrs *' but argument is of type 'const struct devlink_port_new_attrs *'
     201 |     const struct devlink_port_new_attrs *attrs)
         |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
   drivers/net/netdevsim/port_function.c:232:42: error: passing argument 2 of 'nsim_dev_port_port_exists' from incompatible pointer type [-Werror=incompatible-pointer-types]
     232 |  if (nsim_dev_port_port_exists(nsim_dev, attrs)) {
         |                                          ^~~~~
         |                                          |
         |                                          const struct devlink_port_new_attrs *
   drivers/net/netdevsim/port_function.c:130:43: note: expected 'const struct devlink_port_new_attrs *' but argument is of type 'const struct devlink_port_new_attrs *'
     130 |      const struct devlink_port_new_attrs *attrs)
         |      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
   drivers/net/netdevsim/port_function.c:238:46: error: passing argument 2 of 'nsim_devlink_port_fn_alloc' from incompatible pointer type [-Werror=incompatible-pointer-types]
     238 |  port = nsim_devlink_port_fn_alloc(nsim_dev, attrs);
         |                                              ^~~~~
         |                                              |
         |                                              const struct devlink_port_new_attrs *
   drivers/net/netdevsim/port_function.c:51:44: note: expected 'const struct devlink_port_new_attrs *' but argument is of type 'const struct devlink_port_new_attrs *'
      51 |       const struct devlink_port_new_attrs *attrs)
         |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
   drivers/net/netdevsim/port_function.c: In function 'nsim_dev_devlink_port_del':
   drivers/net/netdevsim/port_function.c:269:6: warning: variable 'err' set but not used [-Wunused-but-set-variable]
     269 |  int err = 0;
         |      ^~~
   drivers/net/netdevsim/port_function.c: In function 'nsim_dev_port_flavour_supported':
   drivers/net/netdevsim/port_function.c:204:1: error: control reaches end of non-void function [-Werror=return-type]
     204 | }
         | ^
   cc1: some warnings being treated as errors


vim +317 drivers/net/netdevsim/netdevsim.h

   311	
   312	void nsim_dev_port_fn_init(struct nsim_dev *nsim_dev);
   313	void nsim_dev_port_fn_exit(struct nsim_dev *nsim_dev);
   314	void nsim_dev_port_fn_enable(struct nsim_dev *nsim_dev);
   315	void nsim_dev_port_fn_disable(struct nsim_dev *nsim_dev);
   316	int nsim_dev_devlink_port_new(struct devlink *devlink,
 > 317				      const struct devlink_port_new_attrs *attrs,

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

Re: [PATCH net-next 1/7] netdevsim: Add support for add and delete of a PCI PF port

From: kernel test robot <hidden>
Date: 2021-02-06 16:25:43

Hi Parav,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Parav-Pandit/netdevsim-port-add-delete-support/20210206-210153
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 6626a0266566c5aea16178c5e6cd7fc4db3f2f56
config: x86_64-randconfig-a004-20210206 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project c9439ca36342fb6013187d0a69aef92736951476)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install x86_64 cross compiling tool for clang build
        # apt-get install binutils-x86-64-linux-gnu
        # https://github.com/0day-ci/linux/commit/4234edd1adbb2da7f6f156c2bfdac5170eb97dbb
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Parav-Pandit/netdevsim-port-add-delete-support/20210206-210153
        git checkout 4234edd1adbb2da7f6f156c2bfdac5170eb97dbb
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <redacted>

All error/warnings (new ones prefixed by >>):

   In file included from drivers/net/netdevsim/netdev.c:27:
quoted
drivers/net/netdevsim/netdevsim.h:317:23: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
   1 warning generated.
--
   In file included from drivers/net/netdevsim/dev.c:36:
quoted
drivers/net/netdevsim/netdevsim.h:317:23: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
quoted
drivers/net/netdevsim/dev.c:908:3: error: field designator 'port_new' does not refer to any field in type 'const struct devlink_ops'
           .port_new = nsim_dev_devlink_port_new,
            ^
quoted
drivers/net/netdevsim/dev.c:909:3: error: field designator 'port_del' does not refer to any field in type 'const struct devlink_ops'
           .port_del = nsim_dev_devlink_port_del,
            ^
   1 warning and 2 errors generated.
--
   In file included from drivers/net/netdevsim/port_function.c:7:
quoted
drivers/net/netdevsim/netdevsim.h:317:23: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
quoted
drivers/net/netdevsim/port_function.c:51:20: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                              const struct devlink_port_new_attrs *attrs)
                                           ^
quoted
drivers/net/netdevsim/port_function.c:71:23: error: incomplete definition of type 'struct devlink_port_new_attrs'
           port->flavour = attrs->flavour;
                           ~~~~~^
   drivers/net/netdevsim/port_function.c:51:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:73:11: error: incomplete definition of type 'struct devlink_port_new_attrs'
           if (attrs->port_index_valid)
               ~~~~~^
   drivers/net/netdevsim/port_function.c:51:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:75:16: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->port_index,
                                         ~~~~~^
   drivers/net/netdevsim/port_function.c:51:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:76:16: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->port_index, GFP_KERNEL);
                                         ~~~~~^
   drivers/net/netdevsim/port_function.c:51:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:88:16: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->pfnum, attrs->pfnum,
                                         ~~~~~^
   drivers/net/netdevsim/port_function.c:51:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:88:30: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->pfnum, attrs->pfnum,
                                                       ~~~~~^
   drivers/net/netdevsim/port_function.c:51:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:130:19: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:135:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->port_index_valid &&
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:130:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:136:31: error: incomplete definition of type 'struct devlink_port_new_attrs'
                       tmp->port_index == attrs->port_index)
                                          ~~~~~^
   drivers/net/netdevsim/port_function.c:130:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:138:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF &&
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:130:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:140:26: error: incomplete definition of type 'struct devlink_port_new_attrs'
                       tmp->pfnum == attrs->pfnum)
                                     ~~~~~^
   drivers/net/netdevsim/port_function.c:130:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:201:18: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                                   const struct devlink_port_new_attrs *attrs)
                                                ^
   drivers/net/netdevsim/port_function.c:203:14: error: incomplete definition of type 'struct devlink_port_new_attrs'
           return attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF;
                  ~~~~~^
   drivers/net/netdevsim/port_function.c:201:18: note: forward declaration of 'struct devlink_port_new_attrs'
                                   const struct devlink_port_new_attrs *attrs)
                                                ^
   drivers/net/netdevsim/port_function.c:207:23: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
   drivers/net/netdevsim/port_function.c:206:5: error: conflicting types for 'nsim_dev_devlink_port_new'
   int nsim_dev_devlink_port_new(struct devlink *devlink,
       ^
   drivers/net/netdevsim/netdevsim.h:316:5: note: previous declaration is here
   int nsim_dev_devlink_port_new(struct devlink *devlink,
       ^
   drivers/net/netdevsim/port_function.c:217:11: error: incomplete definition of type 'struct devlink_port_new_attrs'
           if (attrs->port_index_valid &&
               ~~~~~^
   drivers/net/netdevsim/port_function.c:207:23: note: forward declaration of 'struct devlink_port_new_attrs'
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
   drivers/net/netdevsim/port_function.c:218:11: error: incomplete definition of type 'struct devlink_port_new_attrs'
               attrs->port_index < nsim_bus_dev->port_count) {
               ~~~~~^
   drivers/net/netdevsim/port_function.c:207:23: note: forward declaration of 'struct devlink_port_new_attrs'
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
   drivers/net/netdevsim/port_function.c:223:49: error: incompatible pointer types passing 'const struct devlink_port_new_attrs *' to parameter of type 'const struct devlink_port_new_attrs *' [-Werror,-Wincompatible-pointer-types]
           if (!nsim_dev_port_flavour_supported(nsim_dev, attrs)) {
                                                          ^~~~~
   drivers/net/netdevsim/port_function.c:201:42: note: passing argument to parameter 'attrs' here
                                   const struct devlink_port_new_attrs *attrs)
                                                                        ^
   drivers/net/netdevsim/port_function.c:232:42: error: incompatible pointer types passing 'const struct devlink_port_new_attrs *' to parameter of type 'const struct devlink_port_new_attrs *' [-Werror,-Wincompatible-pointer-types]
           if (nsim_dev_port_port_exists(nsim_dev, attrs)) {


vim +908 drivers/net/netdevsim/dev.c

   894	
   895	static const struct devlink_ops nsim_dev_devlink_ops = {
   896		.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT |
   897						 DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,
   898		.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
   899		.reload_down = nsim_dev_reload_down,
   900		.reload_up = nsim_dev_reload_up,
   901		.info_get = nsim_dev_info_get,
   902		.flash_update = nsim_dev_flash_update,
   903		.trap_init = nsim_dev_devlink_trap_init,
   904		.trap_action_set = nsim_dev_devlink_trap_action_set,
   905		.trap_group_set = nsim_dev_devlink_trap_group_set,
   906		.trap_policer_set = nsim_dev_devlink_trap_policer_set,
   907		.trap_policer_counter_get = nsim_dev_devlink_trap_policer_counter_get,
 > 908		.port_new = nsim_dev_devlink_port_new,
 > 909		.port_del = nsim_dev_devlink_port_del,
   910	};
   911	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

Re: [PATCH net-next 2/7] netdevsim: Add support for add and delete PCI SF port

From: kernel test robot <hidden>
Date: 2021-02-06 17:44:26

Hi Parav,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Parav-Pandit/netdevsim-port-add-delete-support/20210206-210153
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 6626a0266566c5aea16178c5e6cd7fc4db3f2f56
config: x86_64-randconfig-a004-20210206 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project c9439ca36342fb6013187d0a69aef92736951476)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install x86_64 cross compiling tool for clang build
        # apt-get install binutils-x86-64-linux-gnu
        # https://github.com/0day-ci/linux/commit/980b8cbe1c29602278397d53732cc258b1d62416
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Parav-Pandit/netdevsim-port-add-delete-support/20210206-210153
        git checkout 980b8cbe1c29602278397d53732cc258b1d62416
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <redacted>

All errors (new ones prefixed by >>):

   In file included from drivers/net/netdevsim/port_function.c:7:
   drivers/net/netdevsim/netdevsim.h:318:23: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
   drivers/net/netdevsim/port_function.c:54:20: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:74:23: error: incomplete definition of type 'struct devlink_port_new_attrs'
           port->flavour = attrs->flavour;
                           ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:76:11: error: incomplete definition of type 'struct devlink_port_new_attrs'
           if (attrs->port_index_valid)
               ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:78:16: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->port_index,
                                         ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:79:16: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->port_index, GFP_KERNEL);
                                         ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:91:16: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->pfnum, attrs->pfnum,
                                         ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:91:30: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->pfnum, attrs->pfnum,
                                                       ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
quoted
drivers/net/netdevsim/port_function.c:97:7: error: use of undeclared identifier 'DEVLINK_PORT_FLAVOUR_PCI_SF'
           case DEVLINK_PORT_FLAVOUR_PCI_SF:
                ^
   drivers/net/netdevsim/port_function.c:98:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->sfnum_valid)
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:99:63: error: incomplete definition of type 'struct devlink_port_new_attrs'
                           ret = ida_alloc_range(&dev->port_functions.sfnum_ida, attrs->sfnum,
                                                                                 ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:100:17: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                                 attrs->sfnum, GFP_KERNEL);
                                                 ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:106:22: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   port->pfnum = attrs->pfnum;
                                 ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:131:7: error: use of undeclared identifier 'DEVLINK_PORT_FLAVOUR_PCI_SF'
           case DEVLINK_PORT_FLAVOUR_PCI_SF:
                ^
   drivers/net/netdevsim/port_function.c:151:19: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:156:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->port_index_valid &&
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:157:31: error: incomplete definition of type 'struct devlink_port_new_attrs'
                       tmp->port_index == attrs->port_index)
                                          ~~~~~^
   drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:159:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF &&
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:161:26: error: incomplete definition of type 'struct devlink_port_new_attrs'
                       tmp->pfnum == attrs->pfnum)
                                     ~~~~~^
   drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:164:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_SF &&
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:166:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                       attrs->sfnum_valid &&
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:167:26: error: incomplete definition of type 'struct devlink_port_new_attrs'
                       tmp->sfnum == attrs->sfnum && tmp->pfnum == attrs->pfnum)
                                     ~~~~~^
   drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   fatal error: too many errors emitted, stopping now [-ferror-limit=]
   3 warnings and 20 errors generated.


vim +/DEVLINK_PORT_FLAVOUR_PCI_SF +97 drivers/net/netdevsim/port_function.c

    51	
    52	static struct nsim_port_fn *
    53	nsim_devlink_port_fn_alloc(struct nsim_dev *dev,
    54				   const struct devlink_port_new_attrs *attrs)
    55	{
    56		struct nsim_bus_dev *nsim_bus_dev = dev->nsim_bus_dev;
    57		struct nsim_port_fn *port;
    58		struct net_device *netdev;
    59		int ret;
    60	
    61		netdev = alloc_netdev(sizeof(*port), "eth%d", NET_NAME_UNKNOWN,
    62				      nsim_port_fn_ndev_setup);
    63		if (!netdev)
    64			return ERR_PTR(-ENOMEM);
    65	
    66		dev_net_set(netdev, nsim_dev_net(dev));
    67		netdev->netdev_ops = &nsim_netdev_ops;
    68		nsim_bus_dev = dev->nsim_bus_dev;
    69		SET_NETDEV_DEV(netdev, &nsim_bus_dev->dev);
    70	
    71		port = netdev_priv(netdev);
    72		memset(port, 0, sizeof(*port));
    73		port->netdev = netdev;
    74		port->flavour = attrs->flavour;
    75	
    76		if (attrs->port_index_valid)
    77			ret = ida_alloc_range(&dev->port_functions.ida,
    78					      attrs->port_index,
    79					      attrs->port_index, GFP_KERNEL);
    80		else
    81			ret = ida_alloc_min(&dev->port_functions.ida,
    82					    nsim_bus_dev->port_count, GFP_KERNEL);
    83		if (ret < 0)
    84			goto port_ida_err;
    85	
    86		port->port_index = ret;
    87	
    88		switch (port->flavour) {
    89		case DEVLINK_PORT_FLAVOUR_PCI_PF:
    90			ret = ida_alloc_range(&dev->port_functions.pfnum_ida,
    91					      attrs->pfnum, attrs->pfnum,
    92					      GFP_KERNEL);
    93			if (ret < 0)
    94				goto fn_ida_err;
    95			port->pfnum = ret;
    96			break;
  > 97		case DEVLINK_PORT_FLAVOUR_PCI_SF:
    98			if (attrs->sfnum_valid)
    99				ret = ida_alloc_range(&dev->port_functions.sfnum_ida, attrs->sfnum,
   100						      attrs->sfnum, GFP_KERNEL);
   101			else
   102				ret = ida_alloc(&dev->port_functions.sfnum_ida, GFP_KERNEL);
   103			if (ret < 0)
   104				goto fn_ida_err;
   105			port->sfnum = ret;
   106			port->pfnum = attrs->pfnum;
   107			break;
   108		default:
   109			break;
   110		}
   111		/* refcount_t is not needed as port is protected by port_functions.mutex.
   112		 * This count is to keep track of how many SF ports are attached a PF port.
   113		 */
   114		port->refcount = 1;
   115		return port;
   116	
   117	fn_ida_err:
   118		ida_simple_remove(&dev->port_functions.ida, port->port_index);
   119	port_ida_err:
   120		free_netdev(netdev);
   121		return ERR_PTR(ret);
   122	}
   123	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

Re: [PATCH net-next 1/7] netdevsim: Add support for add and delete of a PCI PF port

From: kernel test robot <hidden>
Date: 2021-02-06 18:31:02

Hi Parav,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Parav-Pandit/netdevsim-port-add-delete-support/20210206-210153
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 6626a0266566c5aea16178c5e6cd7fc4db3f2f56
config: x86_64-allyesconfig (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/4234edd1adbb2da7f6f156c2bfdac5170eb97dbb
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Parav-Pandit/netdevsim-port-add-delete-support/20210206-210153
        git checkout 4234edd1adbb2da7f6f156c2bfdac5170eb97dbb
        # save the attached .config to linux build tree
        make W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <redacted>

All errors (new ones prefixed by >>):

   In file included from drivers/net/netdevsim/dev.c:36:
   drivers/net/netdevsim/netdevsim.h:317:23: warning: 'struct devlink_port_new_attrs' declared inside parameter list will not be visible outside of this definition or declaration
     317 |          const struct devlink_port_new_attrs *attrs,
         |                       ^~~~~~~~~~~~~~~~~~~~~~
quoted
drivers/net/netdevsim/dev.c:908:3: error: 'const struct devlink_ops' has no member named 'port_new'
     908 |  .port_new = nsim_dev_devlink_port_new,
         |   ^~~~~~~~
quoted
drivers/net/netdevsim/dev.c:908:14: error: initialization of 'int (*)(struct devlink *, struct devlink_port *, u8 *, int *, struct netlink_ext_ack *)' {aka 'int (*)(struct devlink *, struct devlink_port *, unsigned char *, int *, struct netlink_ext_ack *)'} from incompatible pointer type 'int (*)(struct devlink *, const struct devlink_port_new_attrs *, struct netlink_ext_ack *, unsigned int *)' [-Werror=incompatible-pointer-types]
     908 |  .port_new = nsim_dev_devlink_port_new,
         |              ^~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/netdevsim/dev.c:908:14: note: (near initialization for 'nsim_dev_devlink_ops.port_function_hw_addr_get')
quoted
drivers/net/netdevsim/dev.c:909:3: error: 'const struct devlink_ops' has no member named 'port_del'; did you mean 'port_split'?
     909 |  .port_del = nsim_dev_devlink_port_del,
         |   ^~~~~~~~
         |   port_split
quoted
drivers/net/netdevsim/dev.c:909:14: error: initialization of 'int (*)(struct devlink *, struct devlink_port *, const u8 *, int,  struct netlink_ext_ack *)' {aka 'int (*)(struct devlink *, struct devlink_port *, const unsigned char *, int,  struct netlink_ext_ack *)'} from incompatible pointer type 'int (*)(struct devlink *, unsigned int,  struct netlink_ext_ack *)' [-Werror=incompatible-pointer-types]
     909 |  .port_del = nsim_dev_devlink_port_del,
         |              ^~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/netdevsim/dev.c:909:14: note: (near initialization for 'nsim_dev_devlink_ops.port_function_hw_addr_set')
   cc1: some warnings being treated as errors


vim +908 drivers/net/netdevsim/dev.c

   894	
   895	static const struct devlink_ops nsim_dev_devlink_ops = {
   896		.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT |
   897						 DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,
   898		.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
   899		.reload_down = nsim_dev_reload_down,
   900		.reload_up = nsim_dev_reload_up,
   901		.info_get = nsim_dev_info_get,
   902		.flash_update = nsim_dev_flash_update,
   903		.trap_init = nsim_dev_devlink_trap_init,
   904		.trap_action_set = nsim_dev_devlink_trap_action_set,
   905		.trap_group_set = nsim_dev_devlink_trap_group_set,
   906		.trap_policer_set = nsim_dev_devlink_trap_policer_set,
   907		.trap_policer_counter_get = nsim_dev_devlink_trap_policer_counter_get,
 > 908		.port_new = nsim_dev_devlink_port_new,
 > 909		.port_del = nsim_dev_devlink_port_del,
   910	};
   911	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

Re: [PATCH net-next 5/7] netdevsim: Simulate port function state for a PCI port

From: kernel test robot <hidden>
Date: 2021-02-06 18:32:21

Hi Parav,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Parav-Pandit/netdevsim-port-add-delete-support/20210206-210153
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 6626a0266566c5aea16178c5e6cd7fc4db3f2f56
config: x86_64-randconfig-a004-20210206 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project c9439ca36342fb6013187d0a69aef92736951476)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install x86_64 cross compiling tool for clang build
        # apt-get install binutils-x86-64-linux-gnu
        # https://github.com/0day-ci/linux/commit/9949947ea5985420405ec8649676757144240a7a
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Parav-Pandit/netdevsim-port-add-delete-support/20210206-210153
        git checkout 9949947ea5985420405ec8649676757144240a7a
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <redacted>

All error/warnings (new ones prefixed by >>):

   In file included from drivers/net/netdevsim/netdev.c:27:
   drivers/net/netdevsim/netdevsim.h:318:23: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
quoted
drivers/net/netdevsim/netdevsim.h:333:16: warning: declaration of 'enum devlink_port_fn_state' will not be visible outside of this function [-Wvisibility]
                                  enum devlink_port_fn_state *state,
                                       ^
quoted
drivers/net/netdevsim/netdevsim.h:334:16: warning: declaration of 'enum devlink_port_fn_opstate' will not be visible outside of this function [-Wvisibility]
                                  enum devlink_port_fn_opstate *opstate,
                                       ^
   3 warnings generated.
--
   In file included from drivers/net/netdevsim/dev.c:36:
   drivers/net/netdevsim/netdevsim.h:318:23: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
quoted
drivers/net/netdevsim/netdevsim.h:333:16: warning: declaration of 'enum devlink_port_fn_state' will not be visible outside of this function [-Wvisibility]
                                  enum devlink_port_fn_state *state,
                                       ^
quoted
drivers/net/netdevsim/netdevsim.h:334:16: warning: declaration of 'enum devlink_port_fn_opstate' will not be visible outside of this function [-Wvisibility]
                                  enum devlink_port_fn_opstate *opstate,
                                       ^
   drivers/net/netdevsim/dev.c:908:3: error: field designator 'port_new' does not refer to any field in type 'const struct devlink_ops'
           .port_new = nsim_dev_devlink_port_new,
            ^
   drivers/net/netdevsim/dev.c:909:3: error: field designator 'port_del' does not refer to any field in type 'const struct devlink_ops'
           .port_del = nsim_dev_devlink_port_del,
            ^
quoted
drivers/net/netdevsim/dev.c:912:3: error: field designator 'port_fn_state_get' does not refer to any field in type 'const struct devlink_ops'
           .port_fn_state_get = nsim_dev_port_fn_state_get,
            ^
   3 warnings and 3 errors generated.
--
   In file included from drivers/net/netdevsim/port_function.c:7:
   drivers/net/netdevsim/netdevsim.h:318:23: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
quoted
drivers/net/netdevsim/netdevsim.h:333:16: warning: declaration of 'enum devlink_port_fn_state' will not be visible outside of this function [-Wvisibility]
                                  enum devlink_port_fn_state *state,
                                       ^
quoted
drivers/net/netdevsim/netdevsim.h:334:16: warning: declaration of 'enum devlink_port_fn_opstate' will not be visible outside of this function [-Wvisibility]
                                  enum devlink_port_fn_opstate *opstate,
                                       ^
   drivers/net/netdevsim/port_function.c:56:20: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:76:23: error: incomplete definition of type 'struct devlink_port_new_attrs'
           port->flavour = attrs->flavour;
                           ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:78:11: error: incomplete definition of type 'struct devlink_port_new_attrs'
           if (attrs->port_index_valid)
               ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:80:16: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->port_index,
                                         ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:81:16: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->port_index, GFP_KERNEL);
                                         ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:93:16: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->pfnum, attrs->pfnum,
                                         ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:93:30: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->pfnum, attrs->pfnum,
                                                       ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:99:7: error: use of undeclared identifier 'DEVLINK_PORT_FLAVOUR_PCI_SF'
           case DEVLINK_PORT_FLAVOUR_PCI_SF:
                ^
   drivers/net/netdevsim/port_function.c:100:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->sfnum_valid)
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:101:63: error: incomplete definition of type 'struct devlink_port_new_attrs'
                           ret = ida_alloc_range(&dev->port_functions.sfnum_ida, attrs->sfnum,
                                                                                 ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:102:17: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                                 attrs->sfnum, GFP_KERNEL);
                                                 ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:108:22: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   port->pfnum = attrs->pfnum;
                                 ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:133:7: error: use of undeclared identifier 'DEVLINK_PORT_FLAVOUR_PCI_SF'
           case DEVLINK_PORT_FLAVOUR_PCI_SF:
                ^
   drivers/net/netdevsim/port_function.c:153:19: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:158:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->port_index_valid &&
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:153:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:159:31: error: incomplete definition of type 'struct devlink_port_new_attrs'
                       tmp->port_index == attrs->port_index)
                                          ~~~~~^
   drivers/net/netdevsim/port_function.c:153:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:161:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF &&
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:153:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:163:26: error: incomplete definition of type 'struct devlink_port_new_attrs'
                       tmp->pfnum == attrs->pfnum)
                                     ~~~~~^
   drivers/net/netdevsim/port_function.c:153:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:166:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_SF &&


vim +912 drivers/net/netdevsim/dev.c

   894	
   895	static const struct devlink_ops nsim_dev_devlink_ops = {
   896		.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT |
   897						 DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,
   898		.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
   899		.reload_down = nsim_dev_reload_down,
   900		.reload_up = nsim_dev_reload_up,
   901		.info_get = nsim_dev_info_get,
   902		.flash_update = nsim_dev_flash_update,
   903		.trap_init = nsim_dev_devlink_trap_init,
   904		.trap_action_set = nsim_dev_devlink_trap_action_set,
   905		.trap_group_set = nsim_dev_devlink_trap_group_set,
   906		.trap_policer_set = nsim_dev_devlink_trap_policer_set,
   907		.trap_policer_counter_get = nsim_dev_devlink_trap_policer_counter_get,
   908		.port_new = nsim_dev_devlink_port_new,
   909		.port_del = nsim_dev_devlink_port_del,
   910		.port_function_hw_addr_get = nsim_dev_port_fn_hw_addr_get,
   911		.port_function_hw_addr_set = nsim_dev_port_fn_hw_addr_set,
 > 912		.port_fn_state_get = nsim_dev_port_fn_state_get,
   913	};
   914	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

RE: [PATCH net-next 1/7] netdevsim: Add support for add and delete of a PCI PF port

From: Parav Pandit <hidden>
Date: 2021-02-07 08:00:48

From: kernel test robot <redacted>
Sent: Saturday, February 6, 2021 8:05 PM

Hi Parav,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Parav-Pandit/netdevsim-
port-add-delete-support/20210206-210153
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
6626a0266566c5aea16178c5e6cd7fc4db3f2f56
This commit tag doesn't contain the devlink patches required upto commit 142d93d12dc1.
Can you please update the 0day-ci to move to at least commit 142d93d12dc1?
   drivers/net/netdevsim/port_function.c:269:6: warning: variable 'err' set
but not used [-Wunused-but-set-variable]
     269 |  int err = 0;
         |      ^~~
Sending v2 to fix this warning.

Re: [kbuild-all] Re: [PATCH net-next 1/7] netdevsim: Add support for add and delete of a PCI PF port

From: Rong Chen <hidden>
Date: 2021-02-07 08:05:38


On 2/7/21 3:59 PM, Parav Pandit wrote:
quoted
From: kernel test robot <redacted>
Sent: Saturday, February 6, 2021 8:05 PM

Hi Parav,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Parav-Pandit/netdevsim-
port-add-delete-support/20210206-210153
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
6626a0266566c5aea16178c5e6cd7fc4db3f2f56
This commit tag doesn't contain the devlink patches required upto commit 142d93d12dc1.
Can you please update the 0day-ci to move to at least commit 142d93d12dc1?
Thanks for the feedback, we'll take a look.

Best Regards,
Rong Chen
quoted
    drivers/net/netdevsim/port_function.c:269:6: warning: variable 'err' set
but not used [-Wunused-but-set-variable]
      269 |  int err = 0;
          |      ^~~
Sending v2 to fix this warning.
_______________________________________________
kbuild-all mailing list -- kbuild-all@lists.01.org
To unsubscribe send an email to kbuild-all-leave@lists.01.org

[PATCH net-next v2 0/7] netdevsim port add, delete support

From: Parav Pandit <hidden>
Date: 2021-02-07 08:45:23

This series simulates one or more PCI PF and SF port addition and function
configuration functionality.

Example sequence:
Create a device with ID=10 and one physical port.
$ echo "10 1" > /sys/bus/netdevsim/new_device

Add PCI PF port:
$ devlink port add netdevsim/netdevsim10 flavour pcipf pfnum 2
netdevsim/netdevsim10/1: type eth netdev eth1 flavour pcipf controller 0 pfnum 2 external false splittable false
  function:
    hw_addr 00:00:00:00:00:00

$ devlink port add netdevsim/netdevsim10 flavour pcisf pfnum 2
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:00:00:00:00:00

Show devlink port:
$ devlink port show netdevsim/netdevsim10/2
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:00:00:00:00:00 state inactive opstate detached

Set the MAC address and activate the function:
$ devlink port function set netdevsim/netdevsim10/2 hw_addr 00:11:22:33:44:55 state active

Show the port and function attributes in JSON format:
$ devlink port show netdevsim/netdevsim10/2 -jp
{
    "port": {
        "netdevsim/netdevsim10/2": {
            "type": "eth",
            "netdev": "eth2",
            "flavour": "pcisf",
            "controller": 0,
            "pfnum": 2,
            "sfnum": 0,
            "splittable": false,
            "function": {
                "hw_addr": "00:11:22:33:44:55",
                "state": "active",
                "opstate": "attached"
            }
        }
    }
}

Delete PCI SF and PF ports:
$ devlink port del netdevsim/netdevsim10/2

Patch summary:
patch-1 adds support for adding/remove PCI PF port
patch-2 adds support for adding/remove PCI SF port
patch-3 simulates MAC address query
patch-4 simulates setting MAC address
patch-5 simulates state query
patch-6 simulates setting state
patch-7 adds tests

Parav Pandit (7):
  netdevsim: Add support for add and delete of a PCI PF port
  netdevsim: Add support for add and delete PCI SF port
  netdevsim: Simulate get hardware address of a PCI port
  netdevsim: Simulate set hardware address of a PCI port
  netdevsim: Simulate port function state for a PCI port
  netdevsim: Simulate port function set state for a PCI port
  netdevsim: Add netdevsim port add test cases

 drivers/net/netdevsim/Makefile                |   2 +-
 drivers/net/netdevsim/dev.c                   |  14 +
 drivers/net/netdevsim/netdevsim.h             |  38 ++
 drivers/net/netdevsim/port_function.c         | 521 ++++++++++++++++++
 .../drivers/net/netdevsim/devlink.sh          |  72 ++-
 5 files changed, 645 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/netdevsim/port_function.c

-- 
2.26.2

[PATCH net-next v2 1/7] netdevsim: Add support for add and delete of a PCI PF port

From: Parav Pandit <hidden>
Date: 2021-02-07 08:45:23

Simulate PCI PF ports. Allow user to create one or more PCI PF ports.

Examples:

Create a device with ID=10 and one physical port.
$ echo "10 1" > /sys/bus/netdevsim/new_device

Add devlink port of flavour 'pcipf' for PF number 2:

$ devlink port add netdevsim/netdevsim10 flavour pcipf pfnum 2
netdevsim/netdevsim10/4: type eth netdev eth4 flavour pcipf controller 0 pfnum 2 external false splittable false

Show the PCI PF port:
$ devlink port show netdevsim/netdevsim10/4
netdevsim/netdevsim10/4: type eth netdev eth4 flavour pcipf controller 0 pfnum 2 external false splittable false

Delete newly added devlink port:
$ devlink port del netdevsim/netdevsim10/4

issue: 2241444
Signed-off-by: Parav Pandit <redacted>
---
changelog:
v1->v2:
 - fixed warning for unused err value

---
 drivers/net/netdevsim/Makefile        |   2 +-
 drivers/net/netdevsim/dev.c           |  10 +
 drivers/net/netdevsim/netdevsim.h     |  20 ++
 drivers/net/netdevsim/port_function.c | 340 ++++++++++++++++++++++++++
 4 files changed, 371 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/netdevsim/port_function.c
diff --git a/drivers/net/netdevsim/Makefile b/drivers/net/netdevsim/Makefile
index ade086eed955..be2aefafc498 100644
--- a/drivers/net/netdevsim/Makefile
+++ b/drivers/net/netdevsim/Makefile
@@ -3,7 +3,7 @@
 obj-$(CONFIG_NETDEVSIM) += netdevsim.o
 
 netdevsim-objs := \
-	netdev.o dev.o ethtool.o fib.o bus.o health.o udp_tunnels.o
+	netdev.o dev.o ethtool.o fib.o bus.o health.o udp_tunnels.o port_function.o
 
 ifeq ($(CONFIG_BPF_SYSCALL),y)
 netdevsim-objs += \
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index 816af1f55e2c..806e387918fe 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -905,6 +905,8 @@ static const struct devlink_ops nsim_dev_devlink_ops = {
 	.trap_group_set = nsim_dev_devlink_trap_group_set,
 	.trap_policer_set = nsim_dev_devlink_trap_policer_set,
 	.trap_policer_counter_get = nsim_dev_devlink_trap_policer_counter_get,
+	.port_new = nsim_dev_devlink_port_new,
+	.port_del = nsim_dev_devlink_port_del,
 };
 
 #define NSIM_DEV_MAX_MACS_DEFAULT 32
@@ -1039,6 +1041,8 @@ static int nsim_dev_reload_create(struct nsim_dev *nsim_dev,
 						      nsim_dev->ddir,
 						      nsim_dev,
 						&nsim_dev_take_snapshot_fops);
+
+	nsim_dev_port_fn_enable(nsim_dev);
 	return 0;
 
 err_health_exit:
@@ -1073,6 +1077,7 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
 	nsim_dev->max_macs = NSIM_DEV_MAX_MACS_DEFAULT;
 	nsim_dev->test1 = NSIM_DEV_TEST1_DEFAULT;
 	spin_lock_init(&nsim_dev->fa_cookie_lock);
+	nsim_dev_port_fn_init(nsim_dev);
 
 	dev_set_drvdata(&nsim_bus_dev->dev, nsim_dev);
 
@@ -1120,6 +1125,7 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
 	if (err)
 		goto err_bpf_dev_exit;
 
+	nsim_dev_port_fn_enable(nsim_dev);
 	devlink_params_publish(devlink);
 	devlink_reload_enable(devlink);
 	return 0;
@@ -1154,6 +1160,9 @@ static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev)
 
 	if (devlink_is_reload_failed(devlink))
 		return;
+
+	/* Disable and destroy any user created devlink ports */
+	nsim_dev_port_fn_disable(nsim_dev);
 	debugfs_remove(nsim_dev->take_snapshot);
 	nsim_dev_port_del_all(nsim_dev);
 	nsim_dev_health_exit(nsim_dev);
@@ -1178,6 +1187,7 @@ void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev)
 				  ARRAY_SIZE(nsim_devlink_params));
 	devlink_unregister(devlink);
 	devlink_resources_unregister(devlink, NULL);
+	nsim_dev_port_fn_exit(nsim_dev);
 	devlink_free(devlink);
 }
 
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index 48163c5f2ec9..31beddede0f2 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -229,6 +229,15 @@ struct nsim_dev {
 		bool static_iana_vxlan;
 		u32 sleep;
 	} udp_ports;
+	struct {
+		struct list_head head;
+		struct ida ida;
+		struct ida pfnum_ida;
+		struct mutex disable_mutex; /* protects port deletion
+					     * by driver unload context
+					     */
+		bool enabled;
+	} port_functions;
 };
 
 static inline struct net *nsim_dev_net(struct nsim_dev *nsim_dev)
@@ -299,3 +308,14 @@ struct nsim_bus_dev {
 
 int nsim_bus_init(void);
 void nsim_bus_exit(void);
+
+void nsim_dev_port_fn_init(struct nsim_dev *nsim_dev);
+void nsim_dev_port_fn_exit(struct nsim_dev *nsim_dev);
+void nsim_dev_port_fn_enable(struct nsim_dev *nsim_dev);
+void nsim_dev_port_fn_disable(struct nsim_dev *nsim_dev);
+int nsim_dev_devlink_port_new(struct devlink *devlink,
+			      const struct devlink_port_new_attrs *attrs,
+			      struct netlink_ext_ack *extack,
+			      unsigned int *new_port_index);
+int nsim_dev_devlink_port_del(struct devlink *devlink, unsigned int port_index,
+			      struct netlink_ext_ack *extack);
diff --git a/drivers/net/netdevsim/port_function.c b/drivers/net/netdevsim/port_function.c
new file mode 100644
index 000000000000..7df1ca5ad7b8
--- /dev/null
+++ b/drivers/net/netdevsim/port_function.c
@@ -0,0 +1,340 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+/* Copyright (c) 2020 Mellanox Technologies Ltd. */
+
+#include <linux/etherdevice.h>
+#include <uapi/linux/devlink.h>
+
+#include "netdevsim.h"
+
+struct nsim_port_fn {
+	struct devlink_port dl_port;
+	struct net_device *netdev;
+	struct list_head list;
+	unsigned int port_index;
+	enum devlink_port_flavour flavour;
+	u16 pfnum;
+};
+
+static struct devlink_port *
+nsim_dev_port_fn_get_devlink_port(struct net_device *dev)
+{
+	struct nsim_port_fn *port = netdev_priv(dev);
+
+	return &port->dl_port;
+}
+
+static netdev_tx_t
+nsim_dev_port_fn_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
+}
+
+static const struct net_device_ops nsim_netdev_ops = {
+	.ndo_start_xmit = nsim_dev_port_fn_start_xmit,
+	.ndo_get_devlink_port = nsim_dev_port_fn_get_devlink_port,
+};
+
+static void nsim_port_fn_ndev_setup(struct net_device *dev)
+{
+	ether_setup(dev);
+	eth_hw_addr_random(dev);
+
+	dev->tx_queue_len = 0;
+	dev->flags |= IFF_NOARP;
+	dev->flags &= ~IFF_MULTICAST;
+	dev->max_mtu = ETH_MAX_MTU;
+}
+
+static struct nsim_port_fn *
+nsim_devlink_port_fn_alloc(struct nsim_dev *dev,
+			   const struct devlink_port_new_attrs *attrs)
+{
+	struct nsim_bus_dev *nsim_bus_dev = dev->nsim_bus_dev;
+	struct nsim_port_fn *port;
+	struct net_device *netdev;
+	int ret;
+
+	netdev = alloc_netdev(sizeof(*port), "eth%d", NET_NAME_UNKNOWN,
+			      nsim_port_fn_ndev_setup);
+	if (!netdev)
+		return ERR_PTR(-ENOMEM);
+
+	dev_net_set(netdev, nsim_dev_net(dev));
+	netdev->netdev_ops = &nsim_netdev_ops;
+	nsim_bus_dev = dev->nsim_bus_dev;
+	SET_NETDEV_DEV(netdev, &nsim_bus_dev->dev);
+
+	port = netdev_priv(netdev);
+	memset(port, 0, sizeof(*port));
+	port->netdev = netdev;
+	port->flavour = attrs->flavour;
+
+	if (attrs->port_index_valid)
+		ret = ida_alloc_range(&dev->port_functions.ida,
+				      attrs->port_index,
+				      attrs->port_index, GFP_KERNEL);
+	else
+		ret = ida_alloc_min(&dev->port_functions.ida,
+				    nsim_bus_dev->port_count, GFP_KERNEL);
+	if (ret < 0)
+		goto port_ida_err;
+
+	port->port_index = ret;
+
+	switch (port->flavour) {
+	case DEVLINK_PORT_FLAVOUR_PCI_PF:
+		ret = ida_alloc_range(&dev->port_functions.pfnum_ida,
+				      attrs->pfnum, attrs->pfnum,
+				      GFP_KERNEL);
+		if (ret < 0)
+			goto fn_ida_err;
+		port->pfnum = ret;
+		break;
+	default:
+		break;
+	}
+	return port;
+
+fn_ida_err:
+	ida_simple_remove(&dev->port_functions.ida, port->port_index);
+port_ida_err:
+	free_netdev(netdev);
+	return ERR_PTR(ret);
+}
+
+static void
+nsim_devlink_port_fn_free(struct nsim_dev *dev, struct nsim_port_fn *port)
+{
+	switch (port->flavour) {
+	case DEVLINK_PORT_FLAVOUR_PCI_PF:
+		ida_simple_remove(&dev->port_functions.pfnum_ida, port->pfnum);
+		break;
+	default:
+		break;
+	}
+	ida_simple_remove(&dev->port_functions.ida, port->port_index);
+	free_netdev(port->netdev);
+}
+
+static bool
+nsim_dev_port_index_internal(struct nsim_dev *nsim_dev, unsigned int port_index)
+{
+	struct nsim_bus_dev *nsim_bus_dev = nsim_dev->nsim_bus_dev;
+
+	return (port_index < nsim_bus_dev->port_count) ? true : false;
+}
+
+static bool
+nsim_dev_port_port_exists(struct nsim_dev *nsim_dev,
+			  const struct devlink_port_new_attrs *attrs)
+{
+	struct nsim_port_fn *tmp;
+
+	list_for_each_entry(tmp, &nsim_dev->port_functions.head, list) {
+		if (attrs->port_index_valid &&
+		    tmp->port_index == attrs->port_index)
+			return true;
+		if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF &&
+		    tmp->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF &&
+		    tmp->pfnum == attrs->pfnum)
+			return true;
+	}
+	return false;
+}
+
+static struct nsim_port_fn *
+nsim_dev_devlink_port_index_lookup(const struct nsim_dev *nsim_dev,
+				   unsigned int port_index,
+				   struct netlink_ext_ack *extack)
+{
+	struct nsim_port_fn *port;
+
+	list_for_each_entry(port, &nsim_dev->port_functions.head, list) {
+		if (port->port_index != port_index)
+			continue;
+		return port;
+	}
+	NL_SET_ERR_MSG_MOD(extack, "User created port not found");
+	return ERR_PTR(-ENOENT);
+}
+
+static int nsim_devlink_port_fn_add(struct devlink *devlink,
+				    struct nsim_dev *nsim_dev,
+				    struct nsim_port_fn *port,
+				    struct netlink_ext_ack *extack)
+{
+	int err;
+
+	list_add(&port->list, &nsim_dev->port_functions.head);
+
+	err = devlink_port_register(devlink, &port->dl_port, port->port_index);
+	if (err)
+		goto reg_err;
+
+	err = register_netdev(port->netdev);
+	if (err)
+		goto netdev_err;
+
+	devlink_port_type_eth_set(&port->dl_port, port->netdev);
+	return 0;
+
+netdev_err:
+	devlink_port_type_clear(&port->dl_port);
+	devlink_port_unregister(&port->dl_port);
+reg_err:
+	list_del(&port->list);
+	return err;
+}
+
+static void nsim_devlink_port_fn_del(struct nsim_dev *nsim_dev,
+				     struct nsim_port_fn *port)
+{
+	devlink_port_type_clear(&port->dl_port);
+	unregister_netdev(port->netdev);
+	devlink_port_unregister(&port->dl_port);
+	list_del(&port->list);
+}
+
+static bool
+nsim_dev_port_flavour_supported(const struct nsim_dev *nsim_dev,
+				const struct devlink_port_new_attrs *attrs)
+{
+	return attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF;
+}
+
+int nsim_dev_devlink_port_new(struct devlink *devlink,
+			      const struct devlink_port_new_attrs *attrs,
+			      struct netlink_ext_ack *extack,
+			      unsigned int *new_port_index)
+{
+	struct nsim_dev *nsim_dev = devlink_priv(devlink);
+	struct nsim_bus_dev *nsim_bus_dev;
+	struct nsim_port_fn *port;
+	int err;
+
+	nsim_bus_dev = nsim_dev->nsim_bus_dev;
+	if (attrs->port_index_valid &&
+	    attrs->port_index < nsim_bus_dev->port_count) {
+		NL_SET_ERR_MSG_MOD(extack,
+				   "Port with given port index already exist");
+		return -EEXIST;
+	}
+	if (!nsim_dev_port_flavour_supported(nsim_dev, attrs)) {
+		NL_SET_ERR_MSG_MOD(extack, "Unsupported port flavour specified");
+		return -EOPNOTSUPP;
+	}
+	mutex_lock(&nsim_dev->port_functions.disable_mutex);
+	if (!nsim_dev->port_functions.enabled) {
+		err = -ENODEV;
+		goto alloc_err;
+	}
+	if (nsim_dev_port_port_exists(nsim_dev, attrs)) {
+		NL_SET_ERR_MSG_MOD(extack,
+				   "Port with given attributes already exists");
+		err = -EEXIST;
+		goto alloc_err;
+	}
+	port = nsim_devlink_port_fn_alloc(nsim_dev, attrs);
+	if (IS_ERR(port)) {
+		NL_SET_ERR_MSG_MOD(extack, "Fail to allocate port");
+		err = PTR_ERR(port);
+		goto alloc_err;
+	}
+	memcpy(port->dl_port.attrs.switch_id.id, nsim_dev->switch_id.id,
+	       nsim_dev->switch_id.id_len);
+	port->dl_port.attrs.switch_id.id_len = nsim_dev->switch_id.id_len;
+
+	devlink_port_attrs_pci_pf_set(&port->dl_port, 0, port->pfnum, false);
+
+	err = nsim_devlink_port_fn_add(devlink, nsim_dev, port, extack);
+	if (err)
+		goto add_err;
+	*new_port_index = port->port_index;
+	mutex_unlock(&nsim_dev->port_functions.disable_mutex);
+	return 0;
+
+add_err:
+	nsim_devlink_port_fn_free(nsim_dev, port);
+alloc_err:
+	mutex_unlock(&nsim_dev->port_functions.disable_mutex);
+	return err;
+}
+
+int nsim_dev_devlink_port_del(struct devlink *devlink, unsigned int port_index,
+			      struct netlink_ext_ack *extack)
+{
+	struct nsim_dev *nsim_dev = devlink_priv(devlink);
+	struct nsim_port_fn *port;
+	int err;
+
+	if (nsim_dev_port_index_internal(nsim_dev, port_index)) {
+		NL_SET_ERR_MSG_MOD(extack, "Port index doesn't belong to user created port");
+		return -EINVAL;
+	}
+
+	mutex_lock(&nsim_dev->port_functions.disable_mutex);
+	if (!nsim_dev->port_functions.enabled) {
+		err = -ENODEV;
+		goto err;
+	}
+
+	port = nsim_dev_devlink_port_index_lookup(nsim_dev, port_index, extack);
+	if (IS_ERR(port)) {
+		err = PTR_ERR(port);
+		goto err;
+	}
+	nsim_devlink_port_fn_del(nsim_dev, port);
+	nsim_devlink_port_fn_free(nsim_dev, port);
+	mutex_unlock(&nsim_dev->port_functions.disable_mutex);
+	return 0;
+
+err:
+	mutex_unlock(&nsim_dev->port_functions.disable_mutex);
+	return err;
+}
+
+void nsim_dev_port_fn_init(struct nsim_dev *nsim_dev)
+{
+	mutex_init(&nsim_dev->port_functions.disable_mutex);
+	INIT_LIST_HEAD(&nsim_dev->port_functions.head);
+	ida_init(&nsim_dev->port_functions.ida);
+	ida_init(&nsim_dev->port_functions.pfnum_ida);
+}
+
+void nsim_dev_port_fn_exit(struct nsim_dev *nsim_dev)
+{
+	WARN_ON(!ida_is_empty(&nsim_dev->port_functions.pfnum_ida));
+	ida_destroy(&nsim_dev->port_functions.pfnum_ida);
+	WARN_ON(!ida_is_empty(&nsim_dev->port_functions.ida));
+	ida_destroy(&nsim_dev->port_functions.ida);
+	WARN_ON(!list_empty(&nsim_dev->port_functions.head));
+	mutex_destroy(&nsim_dev->port_functions.disable_mutex);
+}
+
+void nsim_dev_port_fn_enable(struct nsim_dev *nsim_dev)
+{
+	mutex_lock(&nsim_dev->port_functions.disable_mutex);
+	nsim_dev->port_functions.enabled = true;
+	mutex_unlock(&nsim_dev->port_functions.disable_mutex);
+}
+
+void nsim_dev_port_fn_disable(struct nsim_dev *nsim_dev)
+{
+	struct nsim_port_fn *port;
+	struct nsim_port_fn *tmp;
+
+	mutex_lock(&nsim_dev->port_functions.disable_mutex);
+	nsim_dev->port_functions.enabled = false;
+	mutex_unlock(&nsim_dev->port_functions.disable_mutex);
+
+	/* At this point, no new user commands can start and any ongoing
+	 * commands have completed, so it is safe to delete all user created
+	 * ports.
+	 */
+	list_for_each_entry_safe_reverse(port, tmp,
+					 &nsim_dev->port_functions.head, list) {
+		nsim_devlink_port_fn_del(nsim_dev, port);
+		nsim_devlink_port_fn_free(nsim_dev, port);
+	}
+}
-- 
2.26.2

[PATCH net-next v2 3/7] netdevsim: Simulate get hardware address of a PCI port

From: Parav Pandit <hidden>
Date: 2021-02-07 08:45:24

Allow users to get hardware address for the PCI port.

Below example creates one devlink port, queries a port and its hardware
address.

Example of a PCI SF port which supports a port function hw_addr set:
Create a device with ID=10 and one physical port.
$ echo "10 1" > /sys/bus/netdevsim/new_device

Add PCI PF port:
$ devlink port add netdevsim/netdevsim10 flavour pcipf pfnum 2
netdevsim/netdevsim10/1: type eth netdev eth1 flavour pcipf controller 0 pfnum 2 external false splittable false
  function:
    hw_addr 00:00:00:00:00:00

$ devlink port add netdevsim/netdevsim10 flavour pcisf pfnum 2
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:00:00:00:00:00

Show devlink ports:
$ devlink port show
netdevsim/netdevsim10/0: type eth netdev eth0 flavour physical port 1 splittable false
netdevsim/netdevsim10/1: type eth netdev eth1 flavour pcipf controller 0 pfnum 2 external false splittable false
  function:
    hw_addr 00:00:00:00:00:00
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:00:00:00:00:00

Show the port and function attributes in JSON format:
$ devlink port show netdevsim/netdevsim10/2 -jp
{
    "port": {
        "netdevsim/netdevsim10/2": {
            "type": "eth",
            "netdev": "eth2",
            "flavour": "pcisf",
            "controller": 0,
            "pfnum": 2,
            "sfnum": 0,
            "splittable": false,
            "function": {
                "hw_addr": "00:00:00:00:00:00"
            }
        }
    }
}

Signed-off-by: Parav Pandit <redacted>
---
 drivers/net/netdevsim/dev.c           |  1 +
 drivers/net/netdevsim/netdevsim.h     |  4 ++++
 drivers/net/netdevsim/port_function.c | 30 +++++++++++++++++++++++++++
 3 files changed, 35 insertions(+)
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index 806e387918fe..6046906d6b85 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -907,6 +907,7 @@ static const struct devlink_ops nsim_dev_devlink_ops = {
 	.trap_policer_counter_get = nsim_dev_devlink_trap_policer_counter_get,
 	.port_new = nsim_dev_devlink_port_new,
 	.port_del = nsim_dev_devlink_port_del,
+	.port_function_hw_addr_get = nsim_dev_port_fn_hw_addr_get,
 };
 
 #define NSIM_DEV_MAX_MACS_DEFAULT 32
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index efa7c08d842a..e910c3cf480d 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -320,3 +320,7 @@ int nsim_dev_devlink_port_new(struct devlink *devlink,
 			      unsigned int *new_port_index);
 int nsim_dev_devlink_port_del(struct devlink *devlink, unsigned int port_index,
 			      struct netlink_ext_ack *extack);
+int nsim_dev_port_fn_hw_addr_get(struct devlink *devlink,
+				 struct devlink_port *port,
+				 u8 *hw_addr, int *hw_addr_len,
+				 struct netlink_ext_ack *extack);
diff --git a/drivers/net/netdevsim/port_function.c b/drivers/net/netdevsim/port_function.c
index 86607d574930..882d1bdbfcf5 100644
--- a/drivers/net/netdevsim/port_function.c
+++ b/drivers/net/netdevsim/port_function.c
@@ -16,6 +16,7 @@ struct nsim_port_fn {
 	int refcount; /* Counts how many sf ports are bound attached to this pf port. */
 	u32 sfnum;
 	u16 pfnum;
+	u8 hw_addr[ETH_ALEN];
 };
 
 static struct devlink_port *
@@ -431,3 +432,32 @@ void nsim_dev_port_fn_disable(struct nsim_dev *nsim_dev)
 		nsim_devlink_port_fn_free(nsim_dev, port);
 	}
 }
+
+static struct nsim_port_fn *
+nsim_dev_to_port_fn(struct nsim_dev *nsim_dev, struct devlink_port *dl_port,
+		    struct netlink_ext_ack *extack)
+{
+	if (nsim_dev_port_index_internal(nsim_dev, dl_port->index)) {
+		NL_SET_ERR_MSG_MOD(extack,
+				   "Port index doesn't belong to user created port");
+		return ERR_PTR(-EOPNOTSUPP);
+	}
+	return container_of(dl_port, struct nsim_port_fn, dl_port);
+}
+
+int nsim_dev_port_fn_hw_addr_get(struct devlink *devlink,
+				 struct devlink_port *dl_port,
+				 u8 *hw_addr, int *hw_addr_len,
+				 struct netlink_ext_ack *extack)
+{
+	struct nsim_dev *nsim_dev = devlink_priv(devlink);
+	struct nsim_port_fn *port;
+
+	port = nsim_dev_to_port_fn(nsim_dev, dl_port, extack);
+	if (IS_ERR(port))
+		return PTR_ERR(port);
+
+	memcpy(hw_addr, port->hw_addr, ETH_ALEN);
+	*hw_addr_len = ETH_ALEN;
+	return 0;
+}
-- 
2.26.2

[PATCH net-next v2 4/7] netdevsim: Simulate set hardware address of a PCI port

From: Parav Pandit <hidden>
Date: 2021-02-07 08:45:24

Allow users to get/set hardware address for the PCI port.

Below example creates one devlink port, queries a port, sets a
hardware address.

Example of a PCI SF port which supports a port function hw_addr set:
Create a device with ID=10 and one physical port.
$ echo "10 1" > /sys/bus/netdevsim/new_device

Add PCI PF port:
$ devlink port add netdevsim/netdevsim10 flavour pcipf pfnum 2
netdevsim/netdevsim10/1: type eth netdev eth1 flavour pcipf controller 0 pfnum 2 external false splittable false
  function:
    hw_addr 00:00:00:00:00:00

$ devlink port add netdevsim/netdevsim10 flavour pcisf pfnum 2
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:00:00:00:00:00

Set the MAC address:
$ devlink port function set netdevsim/netdevsim10/2 hw_addr 00:11:22:33:44:55

Show devlink ports:
$ devlink port show
netdevsim/netdevsim10/0: type eth netdev eth0 flavour physical port 1 splittable false
netdevsim/netdevsim10/1: type eth netdev eth1 flavour pcipf controller 0 pfnum 2 external false splittable false
  function:
    hw_addr 00:00:00:00:00:00
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:11:22:33:44:55

Show the port and function attributes in JSON format:
$ devlink port show netdevsim/netdevsim10/2 -jp
{
    "port": {
        "netdevsim/netdevsim10/2": {
            "type": "eth",
            "netdev": "eth2",
            "flavour": "pcisf",
            "controller": 0,
            "pfnum": 2,
            "sfnum": 0,
            "splittable": false,
            "function": {
                "hw_addr": "00:11:22:33:44:55"
            }
        }
    }
}

Signed-off-by: Parav Pandit <redacted>
---
 drivers/net/netdevsim/dev.c           |  1 +
 drivers/net/netdevsim/netdevsim.h     |  4 ++++
 drivers/net/netdevsim/port_function.c | 21 +++++++++++++++++++++
 3 files changed, 26 insertions(+)
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index 6046906d6b85..ab15b5f7e955 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -908,6 +908,7 @@ static const struct devlink_ops nsim_dev_devlink_ops = {
 	.port_new = nsim_dev_devlink_port_new,
 	.port_del = nsim_dev_devlink_port_del,
 	.port_function_hw_addr_get = nsim_dev_port_fn_hw_addr_get,
+	.port_function_hw_addr_set = nsim_dev_port_fn_hw_addr_set,
 };
 
 #define NSIM_DEV_MAX_MACS_DEFAULT 32
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index e910c3cf480d..aafe2027a112 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -324,3 +324,7 @@ int nsim_dev_port_fn_hw_addr_get(struct devlink *devlink,
 				 struct devlink_port *port,
 				 u8 *hw_addr, int *hw_addr_len,
 				 struct netlink_ext_ack *extack);
+int nsim_dev_port_fn_hw_addr_set(struct devlink *devlink,
+				 struct devlink_port *port,
+				 const u8 *hw_addr, int hw_addr_len,
+				 struct netlink_ext_ack *extack);
diff --git a/drivers/net/netdevsim/port_function.c b/drivers/net/netdevsim/port_function.c
index 882d1bdbfcf5..5d6c5a732546 100644
--- a/drivers/net/netdevsim/port_function.c
+++ b/drivers/net/netdevsim/port_function.c
@@ -461,3 +461,24 @@ int nsim_dev_port_fn_hw_addr_get(struct devlink *devlink,
 	*hw_addr_len = ETH_ALEN;
 	return 0;
 }
+
+int nsim_dev_port_fn_hw_addr_set(struct devlink *devlink,
+				 struct devlink_port *dl_port,
+				 const u8 *hw_addr, int hw_addr_len,
+				 struct netlink_ext_ack *extack)
+{
+	struct nsim_dev *nsim_dev = devlink_priv(devlink);
+	struct nsim_port_fn *port;
+
+	if (hw_addr_len != ETH_ALEN) {
+		NL_SET_ERR_MSG_MOD(extack,
+				   "Hardware address must be 6 bytes long");
+		return -EOPNOTSUPP;
+	}
+	port = nsim_dev_to_port_fn(nsim_dev, dl_port, extack);
+	if (IS_ERR(port))
+		return PTR_ERR(port);
+
+	memcpy(port->hw_addr, hw_addr, ETH_ALEN);
+	return 0;
+}
-- 
2.26.2

[PATCH net-next v2 2/7] netdevsim: Add support for add and delete PCI SF port

From: Parav Pandit <hidden>
Date: 2021-02-07 08:45:24

Simulate PCI SF ports. Allow user to create one or more PCI SF ports.

Examples:

echo "10 1" > /sys/bus/netdevsim/new_device

Add PCI PF port:
$ devlink port add netdevsim/netdevsim10 flavour pcipf pfnum 2
netdevsim/netdevsim10/1: type eth netdev eth1 flavour pcipf controller 0 pfnum 2 external false splittable false

Add PCI SF port where port index and sfnum are auto assigned by driver.

$ devlink port add netdevsim/netdevsim10 flavour pcisf pfnum 2
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false

Show devlink ports:
$ devlink port show
netdevsim/netdevsim10/0: type eth netdev eth0 flavour physical port 1 splittable false
netdevsim/netdevsim10/1: type eth netdev eth1 flavour pcipf controller 0 pfnum 2 external false splittable false
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false

Create a PCI SF port whose port index and SF number are assigned by
the user.

$ devlink port add netdevsim/netdevsim10/66 flavour pcisf pfnum 2 sfnum 66
netdevsim/netdevsim10/66: type eth netdev eth3 flavour pcisf controller 0 pfnum 2 sfnum 66 splittable false

Delete PCI SF and PF ports:
$ devlink port del netdevsim/netdevsim10/66
$ devlink port del netdevsim/netdevsim10/2
$ devlink port del netdevsim/netdevsim10/1

Signed-off-by: Parav Pandit <redacted>
Reviewed-by: Jiri Pirko <redacted>
---
 drivers/net/netdevsim/netdevsim.h     |  1 +
 drivers/net/netdevsim/port_function.c | 99 ++++++++++++++++++++++++++-
 2 files changed, 97 insertions(+), 3 deletions(-)
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index 31beddede0f2..efa7c08d842a 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -233,6 +233,7 @@ struct nsim_dev {
 		struct list_head head;
 		struct ida ida;
 		struct ida pfnum_ida;
+		struct ida sfnum_ida;
 		struct mutex disable_mutex; /* protects port deletion
 					     * by driver unload context
 					     */
diff --git a/drivers/net/netdevsim/port_function.c b/drivers/net/netdevsim/port_function.c
index 7df1ca5ad7b8..86607d574930 100644
--- a/drivers/net/netdevsim/port_function.c
+++ b/drivers/net/netdevsim/port_function.c
@@ -9,9 +9,12 @@
 struct nsim_port_fn {
 	struct devlink_port dl_port;
 	struct net_device *netdev;
+	struct nsim_port_fn *pf_pfn;
 	struct list_head list;
 	unsigned int port_index;
 	enum devlink_port_flavour flavour;
+	int refcount; /* Counts how many sf ports are bound attached to this pf port. */
+	u32 sfnum;
 	u16 pfnum;
 };
 
@@ -91,9 +94,24 @@ nsim_devlink_port_fn_alloc(struct nsim_dev *dev,
 			goto fn_ida_err;
 		port->pfnum = ret;
 		break;
+	case DEVLINK_PORT_FLAVOUR_PCI_SF:
+		if (attrs->sfnum_valid)
+			ret = ida_alloc_range(&dev->port_functions.sfnum_ida, attrs->sfnum,
+					      attrs->sfnum, GFP_KERNEL);
+		else
+			ret = ida_alloc(&dev->port_functions.sfnum_ida, GFP_KERNEL);
+		if (ret < 0)
+			goto fn_ida_err;
+		port->sfnum = ret;
+		port->pfnum = attrs->pfnum;
+		break;
 	default:
 		break;
 	}
+	/* refcount_t is not needed as port is protected by port_functions.mutex.
+	 * This count is to keep track of how many SF ports are attached a PF port.
+	 */
+	port->refcount = 1;
 	return port;
 
 fn_ida_err:
@@ -110,6 +128,9 @@ nsim_devlink_port_fn_free(struct nsim_dev *dev, struct nsim_port_fn *port)
 	case DEVLINK_PORT_FLAVOUR_PCI_PF:
 		ida_simple_remove(&dev->port_functions.pfnum_ida, port->pfnum);
 		break;
+	case DEVLINK_PORT_FLAVOUR_PCI_SF:
+		ida_simple_remove(&dev->port_functions.sfnum_ida, port->sfnum);
+		break;
 	default:
 		break;
 	}
@@ -139,6 +160,12 @@ nsim_dev_port_port_exists(struct nsim_dev *nsim_dev,
 		    tmp->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF &&
 		    tmp->pfnum == attrs->pfnum)
 			return true;
+
+		if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_SF &&
+		    tmp->flavour == DEVLINK_PORT_FLAVOUR_PCI_SF &&
+		    attrs->sfnum_valid &&
+		    tmp->sfnum == attrs->sfnum && tmp->pfnum == attrs->pfnum)
+			return true;
 	}
 	return false;
 }
@@ -153,20 +180,72 @@ nsim_dev_devlink_port_index_lookup(const struct nsim_dev *nsim_dev,
 	list_for_each_entry(port, &nsim_dev->port_functions.head, list) {
 		if (port->port_index != port_index)
 			continue;
+		if (port->refcount > 1) {
+			NL_SET_ERR_MSG_MOD(extack, "Port is in use");
+			return ERR_PTR(-EBUSY);
+		}
 		return port;
 	}
 	NL_SET_ERR_MSG_MOD(extack, "User created port not found");
 	return ERR_PTR(-ENOENT);
 }
 
+static struct nsim_port_fn *
+pf_port_get(struct nsim_dev *nsim_dev, struct nsim_port_fn *port)
+{
+	struct nsim_port_fn *tmp;
+
+	/* PF port addition doesn't need a parent. */
+	if (port->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF)
+		return NULL;
+
+	list_for_each_entry(tmp, &nsim_dev->port_functions.head, list) {
+		if (tmp->flavour != DEVLINK_PORT_FLAVOUR_PCI_PF ||
+		    tmp->pfnum != port->pfnum)
+			continue;
+
+		if (tmp->refcount + 1 == INT_MAX)
+			return ERR_PTR(-ENOSPC);
+
+		port->pf_pfn = tmp;
+		tmp->refcount++;
+		return tmp;
+	}
+	return ERR_PTR(-ENOENT);
+}
+
+static void pf_port_put(struct nsim_port_fn *port)
+{
+	if (port->pf_pfn) {
+		port->pf_pfn->refcount--;
+		WARN_ON(port->pf_pfn->refcount < 0);
+	}
+	port->refcount--;
+	WARN_ON(port->refcount != 0);
+}
+
 static int nsim_devlink_port_fn_add(struct devlink *devlink,
 				    struct nsim_dev *nsim_dev,
 				    struct nsim_port_fn *port,
 				    struct netlink_ext_ack *extack)
 {
+	struct nsim_port_fn *pf_pfn;
 	int err;
 
-	list_add(&port->list, &nsim_dev->port_functions.head);
+	/* Keep all PF ports at the start, so that when driver is unloaded
+	 * All SF ports from the end of the list can be removed first.
+	 */
+	if (port->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF)
+		list_add(&port->list, &nsim_dev->port_functions.head);
+	else
+		list_add_tail(&port->list, &nsim_dev->port_functions.head);
+
+	pf_pfn = pf_port_get(nsim_dev, port);
+	if (IS_ERR(pf_pfn)) {
+		NL_SET_ERR_MSG_MOD(extack, "Fail to get pf port");
+		err = PTR_ERR(pf_pfn);
+		goto pf_err;
+	}
 
 	err = devlink_port_register(devlink, &port->dl_port, port->port_index);
 	if (err)
@@ -183,6 +262,8 @@ static int nsim_devlink_port_fn_add(struct devlink *devlink,
 	devlink_port_type_clear(&port->dl_port);
 	devlink_port_unregister(&port->dl_port);
 reg_err:
+	pf_port_put(port);
+pf_err:
 	list_del(&port->list);
 	return err;
 }
@@ -194,13 +275,15 @@ static void nsim_devlink_port_fn_del(struct nsim_dev *nsim_dev,
 	unregister_netdev(port->netdev);
 	devlink_port_unregister(&port->dl_port);
 	list_del(&port->list);
+	pf_port_put(port);
 }
 
 static bool
 nsim_dev_port_flavour_supported(const struct nsim_dev *nsim_dev,
 				const struct devlink_port_new_attrs *attrs)
 {
-	return attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF;
+	return attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF ||
+	       attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_SF;
 }
 
 int nsim_dev_devlink_port_new(struct devlink *devlink,
@@ -245,7 +328,12 @@ int nsim_dev_devlink_port_new(struct devlink *devlink,
 	       nsim_dev->switch_id.id_len);
 	port->dl_port.attrs.switch_id.id_len = nsim_dev->switch_id.id_len;
 
-	devlink_port_attrs_pci_pf_set(&port->dl_port, 0, port->pfnum, false);
+	if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF)
+		devlink_port_attrs_pci_pf_set(&port->dl_port, 0,
+					      port->pfnum, false);
+	else
+		devlink_port_attrs_pci_sf_set(&port->dl_port, 0, port->pfnum,
+					      port->sfnum);
 
 	err = nsim_devlink_port_fn_add(devlink, nsim_dev, port, extack);
 	if (err)
@@ -300,10 +388,13 @@ void nsim_dev_port_fn_init(struct nsim_dev *nsim_dev)
 	INIT_LIST_HEAD(&nsim_dev->port_functions.head);
 	ida_init(&nsim_dev->port_functions.ida);
 	ida_init(&nsim_dev->port_functions.pfnum_ida);
+	ida_init(&nsim_dev->port_functions.sfnum_ida);
 }
 
 void nsim_dev_port_fn_exit(struct nsim_dev *nsim_dev)
 {
+	WARN_ON(!ida_is_empty(&nsim_dev->port_functions.sfnum_ida));
+	ida_destroy(&nsim_dev->port_functions.sfnum_ida);
 	WARN_ON(!ida_is_empty(&nsim_dev->port_functions.pfnum_ida));
 	ida_destroy(&nsim_dev->port_functions.pfnum_ida);
 	WARN_ON(!ida_is_empty(&nsim_dev->port_functions.ida));
@@ -332,6 +423,8 @@ void nsim_dev_port_fn_disable(struct nsim_dev *nsim_dev)
 	 * commands have completed, so it is safe to delete all user created
 	 * ports.
 	 */
+
+	/* Remove SF ports first, followed by PF ports. */
 	list_for_each_entry_safe_reverse(port, tmp,
 					 &nsim_dev->port_functions.head, list) {
 		nsim_devlink_port_fn_del(nsim_dev, port);
-- 
2.26.2

[PATCH net-next v2 5/7] netdevsim: Simulate port function state for a PCI port

From: Parav Pandit <hidden>
Date: 2021-02-07 08:45:25

Simulate port function state of a PCI port.
This enables users to get the state of the PCI port function.

Example of a PCI SF port which supports a port function hw_addr set:
Create a device with ID=10 and one physical port.
$ echo "10 1" > /sys/bus/netdevsim/new_device

Add PCI PF port:
$ devlink port add netdevsim/netdevsim10 flavour pcipf pfnum 2
netdevsim/netdevsim10/1: type eth netdev eth1 flavour pcipf controller 0 pfnum 2 external false splittable false
  function:
    hw_addr 00:00:00:00:00:00

$ devlink port add netdevsim/netdevsim10 flavour pcisf pfnum 2
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:00:00:00:00:00

Show devlink port:
$ devlink port show netdevsim/netdevsim10/2
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:00:00:00:00:00 state inactive opstate detached

Show the port and function attributes in JSON format:
$ devlink port show netdevsim/netdevsim10/2 -jp
{
    "port": {
        "netdevsim/netdevsim10/2": {
            "type": "eth",
            "netdev": "eth2",
            "flavour": "pcisf",
            "controller": 0,
            "pfnum": 2,
            "sfnum": 0,
            "splittable": false,
            "function": {
                "hw_addr": "00:00:00:00:00:00",
                "state": "inactive",
                "opstate": "detached"
            }
        }
    }
}

Signed-off-by: Parav Pandit <redacted>
---
 drivers/net/netdevsim/dev.c           |  1 +
 drivers/net/netdevsim/netdevsim.h     |  5 +++++
 drivers/net/netdevsim/port_function.c | 22 ++++++++++++++++++++++
 3 files changed, 28 insertions(+)
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index ab15b5f7e955..9f2164ea89cd 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -909,6 +909,7 @@ static const struct devlink_ops nsim_dev_devlink_ops = {
 	.port_del = nsim_dev_devlink_port_del,
 	.port_function_hw_addr_get = nsim_dev_port_fn_hw_addr_get,
 	.port_function_hw_addr_set = nsim_dev_port_fn_hw_addr_set,
+	.port_fn_state_get = nsim_dev_port_fn_state_get,
 };
 
 #define NSIM_DEV_MAX_MACS_DEFAULT 32
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index aafe2027a112..c0544d93e1e8 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -328,3 +328,8 @@ int nsim_dev_port_fn_hw_addr_set(struct devlink *devlink,
 				 struct devlink_port *port,
 				 const u8 *hw_addr, int hw_addr_len,
 				 struct netlink_ext_ack *extack);
+int nsim_dev_port_fn_state_get(struct devlink *devlink,
+			       struct devlink_port *port,
+			       enum devlink_port_fn_state *state,
+			       enum devlink_port_fn_opstate *opstate,
+			       struct netlink_ext_ack *extack);
diff --git a/drivers/net/netdevsim/port_function.c b/drivers/net/netdevsim/port_function.c
index 5d6c5a732546..a25c449e4559 100644
--- a/drivers/net/netdevsim/port_function.c
+++ b/drivers/net/netdevsim/port_function.c
@@ -17,6 +17,7 @@ struct nsim_port_fn {
 	u32 sfnum;
 	u16 pfnum;
 	u8 hw_addr[ETH_ALEN];
+	u8 state; /* enum devlink_port_fn_state */
 };
 
 static struct devlink_port *
@@ -248,6 +249,7 @@ static int nsim_devlink_port_fn_add(struct devlink *devlink,
 		goto pf_err;
 	}
 
+	port->state = DEVLINK_PORT_FN_STATE_INACTIVE;
 	err = devlink_port_register(devlink, &port->dl_port, port->port_index);
 	if (err)
 		goto reg_err;
@@ -482,3 +484,23 @@ int nsim_dev_port_fn_hw_addr_set(struct devlink *devlink,
 	memcpy(port->hw_addr, hw_addr, ETH_ALEN);
 	return 0;
 }
+
+int nsim_dev_port_fn_state_get(struct devlink *devlink,
+			       struct devlink_port *dl_port,
+			       enum devlink_port_fn_state *state,
+			       enum devlink_port_fn_opstate *opstate,
+			       struct netlink_ext_ack *extack)
+{
+	struct nsim_dev *nsim_dev = devlink_priv(devlink);
+	struct nsim_port_fn *port;
+
+	port = nsim_dev_to_port_fn(nsim_dev, dl_port, extack);
+	if (IS_ERR(port))
+		return PTR_ERR(port);
+	*state = port->state;
+	if (port->state == DEVLINK_PORT_FN_STATE_INACTIVE)
+		*opstate = DEVLINK_PORT_FN_OPSTATE_DETACHED;
+	else
+		*opstate = DEVLINK_PORT_FN_OPSTATE_ATTACHED;
+	return 0;
+}
-- 
2.26.2

[PATCH net-next v2 6/7] netdevsim: Simulate port function set state for a PCI port

From: Parav Pandit <hidden>
Date: 2021-02-07 08:45:30

Simulate port function state of a PCI port.
This enables users to get and set the state of the PCI port function.

Example of a PCI SF port which supports a port function:

Create a device with ID=10 and one physical port.
$ echo "10 1" > /sys/bus/netdevsim/new_device

Add PCI PF port:
$ devlink port add netdevsim/netdevsim10 flavour pcipf pfnum 2
netdevsim/netdevsim10/1: type eth netdev eth1 flavour pcipf controller 0 pfnum 2 external false splittable false
  function:
    hw_addr 00:00:00:00:00:00

$ devlink port add netdevsim/netdevsim10 flavour pcisf pfnum 2
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:00:00:00:00:00

Show devlink port:
$ devlink port show netdevsim/netdevsim10/2
netdevsim/netdevsim10/2: type eth netdev eth2 flavour pcisf controller 0 pfnum 2 sfnum 0 splittable false
  function:
    hw_addr 00:00:00:00:00:00 state inactive opstate detached

Set the MAC address and activate the function:
$ devlink port function set netdevsim/netdevsim10/2 hw_addr 00:11:22:33:44:55 state active

Show the port and function attributes in JSON format:
$ devlink port show netdevsim/netdevsim10/2 -jp
{
    "port": {
        "netdevsim/netdevsim10/2": {
            "type": "eth",
            "netdev": "eth2",
            "flavour": "pcisf",
            "controller": 0,
            "pfnum": 2,
            "sfnum": 0,
            "splittable": false,
            "function": {
                "hw_addr": "00:11:22:33:44:55",
                "state": "active",
                "opstate": "attached"
            }
        }
    }
}

Signed-off-by: Parav Pandit <redacted>
---
 drivers/net/netdevsim/dev.c           |  1 +
 drivers/net/netdevsim/netdevsim.h     |  4 ++++
 drivers/net/netdevsim/port_function.c | 15 +++++++++++++++
 3 files changed, 20 insertions(+)
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index 9f2164ea89cd..e8b6bd22fb1f 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -910,6 +910,7 @@ static const struct devlink_ops nsim_dev_devlink_ops = {
 	.port_function_hw_addr_get = nsim_dev_port_fn_hw_addr_get,
 	.port_function_hw_addr_set = nsim_dev_port_fn_hw_addr_set,
 	.port_fn_state_get = nsim_dev_port_fn_state_get,
+	.port_fn_state_set = nsim_dev_port_fn_state_set,
 };
 
 #define NSIM_DEV_MAX_MACS_DEFAULT 32
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index c0544d93e1e8..93bfa3e946b2 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -333,3 +333,7 @@ int nsim_dev_port_fn_state_get(struct devlink *devlink,
 			       enum devlink_port_fn_state *state,
 			       enum devlink_port_fn_opstate *opstate,
 			       struct netlink_ext_ack *extack);
+int nsim_dev_port_fn_state_set(struct devlink *devlink,
+			       struct devlink_port *port,
+			       enum devlink_port_fn_state state,
+			       struct netlink_ext_ack *extack);
diff --git a/drivers/net/netdevsim/port_function.c b/drivers/net/netdevsim/port_function.c
index a25c449e4559..5be66ffa8d77 100644
--- a/drivers/net/netdevsim/port_function.c
+++ b/drivers/net/netdevsim/port_function.c
@@ -504,3 +504,18 @@ int nsim_dev_port_fn_state_get(struct devlink *devlink,
 		*opstate = DEVLINK_PORT_FN_OPSTATE_ATTACHED;
 	return 0;
 }
+
+int nsim_dev_port_fn_state_set(struct devlink *devlink,
+			       struct devlink_port *dl_port,
+			       enum devlink_port_fn_state state,
+			       struct netlink_ext_ack *extack)
+{
+	struct nsim_dev *nsim_dev = devlink_priv(devlink);
+	struct nsim_port_fn *port;
+
+	port = nsim_dev_to_port_fn(nsim_dev, dl_port, extack);
+	if (IS_ERR(port))
+		return PTR_ERR(port);
+	port->state = state;
+	return 0;
+}
-- 
2.26.2

[PATCH net-next v2 7/7] netdevsim: Add netdevsim port add test cases

From: Parav Pandit <hidden>
Date: 2021-02-07 08:45:57

Add tests for PCI PF and SF port add, configure and delete.

Signed-off-by: Parav Pandit <redacted>
---
 .../drivers/net/netdevsim/devlink.sh          | 72 ++++++++++++++++++-
 1 file changed, 71 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
index 40909c254365..ba349909a37e 100755
--- a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
+++ b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
@@ -5,7 +5,7 @@ lib_dir=$(dirname $0)/../../../net/forwarding
 
 ALL_TESTS="fw_flash_test params_test regions_test reload_test \
 	   netns_reload_test resource_test dev_info_test \
-	   empty_reporter_test dummy_reporter_test"
+	   empty_reporter_test dummy_reporter_test devlink_port_add_test"
 NUM_NETIFS=0
 source $lib_dir/lib.sh
 
@@ -507,6 +507,76 @@ dummy_reporter_test()
 	log_test "dummy reporter test"
 }
 
+function_state_get()
+{
+	local name=$1
+
+	cmd_jq "devlink port show $DL_HANDLE/$USR_SF_PORT_INDEX -j" \
+		" .[][].function.$1"
+}
+
+devlink_port_add_test()
+{
+	RET=0
+	USR_PF_PORT_INDEX=600
+	USR_PFNUM_A=2
+	USR_PFNUM_B=3
+	USR_SF_PORT_INDEX=601
+	USR_SFNUM_A=44
+	USR_SFNUM_B=55
+
+	devlink port add $DL_HANDLE flavour pcipf pfnum $USR_PFNUM_A
+	check_err $? "Failed PF port addition"
+
+	devlink port show
+	check_err $? "Failed PF port show"
+
+	devlink port add $DL_HANDLE flavour pcisf pfnum $USR_PFNUM_A
+	check_err $? "Failed SF port addition"
+
+	devlink port add $DL_HANDLE flavour pcisf pfnum $USR_PFNUM_A \
+			sfnum $USR_SFNUM_A
+	check_err $? "Failed SF port addition"
+
+	devlink port add $DL_HANDLE flavour pcipf pfnum $USR_PFNUM_B
+	check_err $? "Failed second PF port addition"
+
+	devlink port add $DL_HANDLE/$USR_SF_PORT_INDEX flavour pcisf \
+			pfnum $USR_PFNUM_B sfnum $USR_SFNUM_B
+	check_err $? "Failed SF port addition"
+
+	devlink port show
+	check_err $? "Failed PF port show"
+
+	state=$(function_state_get "state")
+	check_err $? "Failed to get function state"
+	[ "$state" == "inactive" ]
+	check_err $? "Unexpected function state $state"
+
+	state=$(function_state_get "opstate")
+	check_err $? "Failed to get operational state"
+	[ "$state" == "detached" ]
+	check_err $? "Unexpected function opstate $opstate"
+
+	devlink port function set $DL_HANDLE/$USR_SF_PORT_INDEX state active
+	check_err $? "Failed to set state"
+
+	state=$(function_state_get "state")
+	check_err $? "Failed to get function state"
+	[ "$state" == "active" ]
+	check_err $? "Unexpected function state $state"
+
+	state=$(function_state_get "opstate")
+	check_err $? "Failed to get operational state"
+	[ "$state" == "attached" ]
+	check_err $? "Unexpected function opstate $opstate"
+
+	devlink port del $DL_HANDLE/$USR_SF_PORT_INDEX
+	check_err $? "Failed SF port deletion"
+
+	log_test "port_add test"
+}
+
 setup_prepare()
 {
 	modprobe netdevsim
-- 
2.26.2

Re: [PATCH net-next v2 1/7] netdevsim: Add support for add and delete of a PCI PF port

From: kernel test robot <hidden>
Date: 2021-02-07 12:02:07

Hi Parav,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Parav-Pandit/netdevsim-Add-support-for-add-and-delete-of-a-PCI-PF-port/20210207-174501
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 6626a0266566c5aea16178c5e6cd7fc4db3f2f56
config: arm-randconfig-r004-20210207 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project c9439ca36342fb6013187d0a69aef92736951476)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm cross compiling tool for clang build
        # apt-get install binutils-arm-linux-gnueabi
        # https://github.com/0day-ci/linux/commit/27c3dd62beaaa376fb7a81543a712ca99e315b81
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Parav-Pandit/netdevsim-Add-support-for-add-and-delete-of-a-PCI-PF-port/20210207-174501
        git checkout 27c3dd62beaaa376fb7a81543a712ca99e315b81
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <redacted>

All error/warnings (new ones prefixed by >>):

   In file included from drivers/net/netdevsim/netdev.c:27:
quoted
drivers/net/netdevsim/netdevsim.h:317:23: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
   1 warning generated.
--
   In file included from drivers/net/netdevsim/dev.c:36:
quoted
drivers/net/netdevsim/netdevsim.h:317:23: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
quoted
drivers/net/netdevsim/dev.c:908:3: error: field designator 'port_new' does not refer to any field in type 'const struct devlink_ops'
           .port_new = nsim_dev_devlink_port_new,
            ^
quoted
drivers/net/netdevsim/dev.c:909:3: error: field designator 'port_del' does not refer to any field in type 'const struct devlink_ops'
           .port_del = nsim_dev_devlink_port_del,
            ^
   1 warning and 2 errors generated.
--
   In file included from drivers/net/netdevsim/port_function.c:7:
quoted
drivers/net/netdevsim/netdevsim.h:317:23: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
quoted
drivers/net/netdevsim/port_function.c:51:20: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                              const struct devlink_port_new_attrs *attrs)
                                           ^
quoted
drivers/net/netdevsim/port_function.c:71:23: error: incomplete definition of type 'struct devlink_port_new_attrs'
           port->flavour = attrs->flavour;
                           ~~~~~^
   drivers/net/netdevsim/port_function.c:51:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:73:11: error: incomplete definition of type 'struct devlink_port_new_attrs'
           if (attrs->port_index_valid)
               ~~~~~^
   drivers/net/netdevsim/port_function.c:51:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:75:16: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->port_index,
                                         ~~~~~^
   drivers/net/netdevsim/port_function.c:51:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:76:16: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->port_index, GFP_KERNEL);
                                         ~~~~~^
   drivers/net/netdevsim/port_function.c:51:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:88:16: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->pfnum, attrs->pfnum,
                                         ~~~~~^
   drivers/net/netdevsim/port_function.c:51:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:88:30: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->pfnum, attrs->pfnum,
                                                       ~~~~~^
   drivers/net/netdevsim/port_function.c:51:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:130:19: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:135:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->port_index_valid &&
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:130:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:136:31: error: incomplete definition of type 'struct devlink_port_new_attrs'
                       tmp->port_index == attrs->port_index)
                                          ~~~~~^
   drivers/net/netdevsim/port_function.c:130:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:138:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF &&
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:130:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:140:26: error: incomplete definition of type 'struct devlink_port_new_attrs'
                       tmp->pfnum == attrs->pfnum)
                                     ~~~~~^
   drivers/net/netdevsim/port_function.c:130:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:201:18: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                                   const struct devlink_port_new_attrs *attrs)
                                                ^
   drivers/net/netdevsim/port_function.c:203:14: error: incomplete definition of type 'struct devlink_port_new_attrs'
           return attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF;
                  ~~~~~^
   drivers/net/netdevsim/port_function.c:201:18: note: forward declaration of 'struct devlink_port_new_attrs'
                                   const struct devlink_port_new_attrs *attrs)
                                                ^
   drivers/net/netdevsim/port_function.c:207:23: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
   drivers/net/netdevsim/port_function.c:206:5: error: conflicting types for 'nsim_dev_devlink_port_new'
   int nsim_dev_devlink_port_new(struct devlink *devlink,
       ^
   drivers/net/netdevsim/netdevsim.h:316:5: note: previous declaration is here
   int nsim_dev_devlink_port_new(struct devlink *devlink,
       ^
   drivers/net/netdevsim/port_function.c:217:11: error: incomplete definition of type 'struct devlink_port_new_attrs'
           if (attrs->port_index_valid &&
               ~~~~~^
   drivers/net/netdevsim/port_function.c:207:23: note: forward declaration of 'struct devlink_port_new_attrs'
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
   drivers/net/netdevsim/port_function.c:218:11: error: incomplete definition of type 'struct devlink_port_new_attrs'
               attrs->port_index < nsim_bus_dev->port_count) {
               ~~~~~^
   drivers/net/netdevsim/port_function.c:207:23: note: forward declaration of 'struct devlink_port_new_attrs'
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
   drivers/net/netdevsim/port_function.c:223:49: error: incompatible pointer types passing 'const struct devlink_port_new_attrs *' to parameter of type 'const struct devlink_port_new_attrs *' [-Werror,-Wincompatible-pointer-types]
           if (!nsim_dev_port_flavour_supported(nsim_dev, attrs)) {
                                                          ^~~~~
   drivers/net/netdevsim/port_function.c:201:42: note: passing argument to parameter 'attrs' here
                                   const struct devlink_port_new_attrs *attrs)
                                                                        ^
   drivers/net/netdevsim/port_function.c:232:42: error: incompatible pointer types passing 'const struct devlink_port_new_attrs *' to parameter of type 'const struct devlink_port_new_attrs *' [-Werror,-Wincompatible-pointer-types]
           if (nsim_dev_port_port_exists(nsim_dev, attrs)) {


vim +908 drivers/net/netdevsim/dev.c

   894	
   895	static const struct devlink_ops nsim_dev_devlink_ops = {
   896		.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT |
   897						 DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,
   898		.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
   899		.reload_down = nsim_dev_reload_down,
   900		.reload_up = nsim_dev_reload_up,
   901		.info_get = nsim_dev_info_get,
   902		.flash_update = nsim_dev_flash_update,
   903		.trap_init = nsim_dev_devlink_trap_init,
   904		.trap_action_set = nsim_dev_devlink_trap_action_set,
   905		.trap_group_set = nsim_dev_devlink_trap_group_set,
   906		.trap_policer_set = nsim_dev_devlink_trap_policer_set,
   907		.trap_policer_counter_get = nsim_dev_devlink_trap_policer_counter_get,
 > 908		.port_new = nsim_dev_devlink_port_new,
 > 909		.port_del = nsim_dev_devlink_port_del,
   910	};
   911	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

Re: [PATCH net-next v2 2/7] netdevsim: Add support for add and delete PCI SF port

From: kernel test robot <hidden>
Date: 2021-02-07 12:29:56

Hi Parav,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Parav-Pandit/netdevsim-Add-support-for-add-and-delete-of-a-PCI-PF-port/20210207-174501
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 6626a0266566c5aea16178c5e6cd7fc4db3f2f56
config: arm-randconfig-r004-20210207 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project c9439ca36342fb6013187d0a69aef92736951476)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm cross compiling tool for clang build
        # apt-get install binutils-arm-linux-gnueabi
        # https://github.com/0day-ci/linux/commit/9cd1b543da8076288ba231ed010e8a610e238bae
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Parav-Pandit/netdevsim-Add-support-for-add-and-delete-of-a-PCI-PF-port/20210207-174501
        git checkout 9cd1b543da8076288ba231ed010e8a610e238bae
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <redacted>

All errors (new ones prefixed by >>):

   In file included from drivers/net/netdevsim/port_function.c:7:
   drivers/net/netdevsim/netdevsim.h:318:23: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
   drivers/net/netdevsim/port_function.c:54:20: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:74:23: error: incomplete definition of type 'struct devlink_port_new_attrs'
           port->flavour = attrs->flavour;
                           ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:76:11: error: incomplete definition of type 'struct devlink_port_new_attrs'
           if (attrs->port_index_valid)
               ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:78:16: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->port_index,
                                         ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:79:16: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->port_index, GFP_KERNEL);
                                         ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:91:16: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->pfnum, attrs->pfnum,
                                         ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:91:30: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->pfnum, attrs->pfnum,
                                                       ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
quoted
drivers/net/netdevsim/port_function.c:97:7: error: use of undeclared identifier 'DEVLINK_PORT_FLAVOUR_PCI_SF'
           case DEVLINK_PORT_FLAVOUR_PCI_SF:
                ^
   drivers/net/netdevsim/port_function.c:98:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->sfnum_valid)
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:99:63: error: incomplete definition of type 'struct devlink_port_new_attrs'
                           ret = ida_alloc_range(&dev->port_functions.sfnum_ida, attrs->sfnum,
                                                                                 ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:100:17: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                                 attrs->sfnum, GFP_KERNEL);
                                                 ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:106:22: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   port->pfnum = attrs->pfnum;
                                 ~~~~~^
   drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:131:7: error: use of undeclared identifier 'DEVLINK_PORT_FLAVOUR_PCI_SF'
           case DEVLINK_PORT_FLAVOUR_PCI_SF:
                ^
   drivers/net/netdevsim/port_function.c:151:19: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:156:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->port_index_valid &&
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:157:31: error: incomplete definition of type 'struct devlink_port_new_attrs'
                       tmp->port_index == attrs->port_index)
                                          ~~~~~^
   drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:159:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF &&
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:161:26: error: incomplete definition of type 'struct devlink_port_new_attrs'
                       tmp->pfnum == attrs->pfnum)
                                     ~~~~~^
   drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:164:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_SF &&
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:166:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                       attrs->sfnum_valid &&
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:167:26: error: incomplete definition of type 'struct devlink_port_new_attrs'
                       tmp->sfnum == attrs->sfnum && tmp->pfnum == attrs->pfnum)
                                     ~~~~~^
   drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   fatal error: too many errors emitted, stopping now [-ferror-limit=]
   3 warnings and 20 errors generated.


vim +/DEVLINK_PORT_FLAVOUR_PCI_SF +97 drivers/net/netdevsim/port_function.c

    51	
    52	static struct nsim_port_fn *
    53	nsim_devlink_port_fn_alloc(struct nsim_dev *dev,
    54				   const struct devlink_port_new_attrs *attrs)
    55	{
    56		struct nsim_bus_dev *nsim_bus_dev = dev->nsim_bus_dev;
    57		struct nsim_port_fn *port;
    58		struct net_device *netdev;
    59		int ret;
    60	
    61		netdev = alloc_netdev(sizeof(*port), "eth%d", NET_NAME_UNKNOWN,
    62				      nsim_port_fn_ndev_setup);
    63		if (!netdev)
    64			return ERR_PTR(-ENOMEM);
    65	
    66		dev_net_set(netdev, nsim_dev_net(dev));
    67		netdev->netdev_ops = &nsim_netdev_ops;
    68		nsim_bus_dev = dev->nsim_bus_dev;
    69		SET_NETDEV_DEV(netdev, &nsim_bus_dev->dev);
    70	
    71		port = netdev_priv(netdev);
    72		memset(port, 0, sizeof(*port));
    73		port->netdev = netdev;
    74		port->flavour = attrs->flavour;
    75	
    76		if (attrs->port_index_valid)
    77			ret = ida_alloc_range(&dev->port_functions.ida,
    78					      attrs->port_index,
    79					      attrs->port_index, GFP_KERNEL);
    80		else
    81			ret = ida_alloc_min(&dev->port_functions.ida,
    82					    nsim_bus_dev->port_count, GFP_KERNEL);
    83		if (ret < 0)
    84			goto port_ida_err;
    85	
    86		port->port_index = ret;
    87	
    88		switch (port->flavour) {
    89		case DEVLINK_PORT_FLAVOUR_PCI_PF:
    90			ret = ida_alloc_range(&dev->port_functions.pfnum_ida,
    91					      attrs->pfnum, attrs->pfnum,
    92					      GFP_KERNEL);
    93			if (ret < 0)
    94				goto fn_ida_err;
    95			port->pfnum = ret;
    96			break;
  > 97		case DEVLINK_PORT_FLAVOUR_PCI_SF:
    98			if (attrs->sfnum_valid)
    99				ret = ida_alloc_range(&dev->port_functions.sfnum_ida, attrs->sfnum,
   100						      attrs->sfnum, GFP_KERNEL);
   101			else
   102				ret = ida_alloc(&dev->port_functions.sfnum_ida, GFP_KERNEL);
   103			if (ret < 0)
   104				goto fn_ida_err;
   105			port->sfnum = ret;
   106			port->pfnum = attrs->pfnum;
   107			break;
   108		default:
   109			break;
   110		}
   111		/* refcount_t is not needed as port is protected by port_functions.mutex.
   112		 * This count is to keep track of how many SF ports are attached a PF port.
   113		 */
   114		port->refcount = 1;
   115		return port;
   116	
   117	fn_ida_err:
   118		ida_simple_remove(&dev->port_functions.ida, port->port_index);
   119	port_ida_err:
   120		free_netdev(netdev);
   121		return ERR_PTR(ret);
   122	}
   123	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

Re: [PATCH net-next v2 5/7] netdevsim: Simulate port function state for a PCI port

From: kernel test robot <hidden>
Date: 2021-02-07 13:11:36

Hi Parav,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Parav-Pandit/netdevsim-Add-support-for-add-and-delete-of-a-PCI-PF-port/20210207-174501
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 6626a0266566c5aea16178c5e6cd7fc4db3f2f56
config: arm-randconfig-r004-20210207 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project c9439ca36342fb6013187d0a69aef92736951476)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm cross compiling tool for clang build
        # apt-get install binutils-arm-linux-gnueabi
        # https://github.com/0day-ci/linux/commit/25b30524cf47ad832c961d885836cc7e98c1f2bd
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Parav-Pandit/netdevsim-Add-support-for-add-and-delete-of-a-PCI-PF-port/20210207-174501
        git checkout 25b30524cf47ad832c961d885836cc7e98c1f2bd
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <redacted>

All error/warnings (new ones prefixed by >>):

   In file included from drivers/net/netdevsim/netdev.c:27:
   drivers/net/netdevsim/netdevsim.h:318:23: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
quoted
drivers/net/netdevsim/netdevsim.h:333:16: warning: declaration of 'enum devlink_port_fn_state' will not be visible outside of this function [-Wvisibility]
                                  enum devlink_port_fn_state *state,
                                       ^
quoted
drivers/net/netdevsim/netdevsim.h:334:16: warning: declaration of 'enum devlink_port_fn_opstate' will not be visible outside of this function [-Wvisibility]
                                  enum devlink_port_fn_opstate *opstate,
                                       ^
   3 warnings generated.
--
   In file included from drivers/net/netdevsim/dev.c:36:
   drivers/net/netdevsim/netdevsim.h:318:23: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
quoted
drivers/net/netdevsim/netdevsim.h:333:16: warning: declaration of 'enum devlink_port_fn_state' will not be visible outside of this function [-Wvisibility]
                                  enum devlink_port_fn_state *state,
                                       ^
quoted
drivers/net/netdevsim/netdevsim.h:334:16: warning: declaration of 'enum devlink_port_fn_opstate' will not be visible outside of this function [-Wvisibility]
                                  enum devlink_port_fn_opstate *opstate,
                                       ^
   drivers/net/netdevsim/dev.c:908:3: error: field designator 'port_new' does not refer to any field in type 'const struct devlink_ops'
           .port_new = nsim_dev_devlink_port_new,
            ^
   drivers/net/netdevsim/dev.c:909:3: error: field designator 'port_del' does not refer to any field in type 'const struct devlink_ops'
           .port_del = nsim_dev_devlink_port_del,
            ^
quoted
drivers/net/netdevsim/dev.c:912:3: error: field designator 'port_fn_state_get' does not refer to any field in type 'const struct devlink_ops'
           .port_fn_state_get = nsim_dev_port_fn_state_get,
            ^
   3 warnings and 3 errors generated.
--
   In file included from drivers/net/netdevsim/port_function.c:7:
   drivers/net/netdevsim/netdevsim.h:318:23: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                                 const struct devlink_port_new_attrs *attrs,
                                              ^
quoted
drivers/net/netdevsim/netdevsim.h:333:16: warning: declaration of 'enum devlink_port_fn_state' will not be visible outside of this function [-Wvisibility]
                                  enum devlink_port_fn_state *state,
                                       ^
quoted
drivers/net/netdevsim/netdevsim.h:334:16: warning: declaration of 'enum devlink_port_fn_opstate' will not be visible outside of this function [-Wvisibility]
                                  enum devlink_port_fn_opstate *opstate,
                                       ^
   drivers/net/netdevsim/port_function.c:56:20: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:76:23: error: incomplete definition of type 'struct devlink_port_new_attrs'
           port->flavour = attrs->flavour;
                           ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:78:11: error: incomplete definition of type 'struct devlink_port_new_attrs'
           if (attrs->port_index_valid)
               ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:80:16: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->port_index,
                                         ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:81:16: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->port_index, GFP_KERNEL);
                                         ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:93:16: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->pfnum, attrs->pfnum,
                                         ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:93:30: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                         attrs->pfnum, attrs->pfnum,
                                                       ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:99:7: error: use of undeclared identifier 'DEVLINK_PORT_FLAVOUR_PCI_SF'
           case DEVLINK_PORT_FLAVOUR_PCI_SF:
                ^
   drivers/net/netdevsim/port_function.c:100:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->sfnum_valid)
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:101:63: error: incomplete definition of type 'struct devlink_port_new_attrs'
                           ret = ida_alloc_range(&dev->port_functions.sfnum_ida, attrs->sfnum,
                                                                                 ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:102:17: error: incomplete definition of type 'struct devlink_port_new_attrs'
                                                 attrs->sfnum, GFP_KERNEL);
                                                 ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:108:22: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   port->pfnum = attrs->pfnum;
                                 ~~~~~^
   drivers/net/netdevsim/port_function.c:56:20: note: forward declaration of 'struct devlink_port_new_attrs'
                              const struct devlink_port_new_attrs *attrs)
                                           ^
   drivers/net/netdevsim/port_function.c:133:7: error: use of undeclared identifier 'DEVLINK_PORT_FLAVOUR_PCI_SF'
           case DEVLINK_PORT_FLAVOUR_PCI_SF:
                ^
   drivers/net/netdevsim/port_function.c:153:19: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility]
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:158:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->port_index_valid &&
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:153:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:159:31: error: incomplete definition of type 'struct devlink_port_new_attrs'
                       tmp->port_index == attrs->port_index)
                                          ~~~~~^
   drivers/net/netdevsim/port_function.c:153:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:161:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF &&
                       ~~~~~^
   drivers/net/netdevsim/port_function.c:153:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:163:26: error: incomplete definition of type 'struct devlink_port_new_attrs'
                       tmp->pfnum == attrs->pfnum)
                                     ~~~~~^
   drivers/net/netdevsim/port_function.c:153:19: note: forward declaration of 'struct devlink_port_new_attrs'
                             const struct devlink_port_new_attrs *attrs)
                                          ^
   drivers/net/netdevsim/port_function.c:166:12: error: incomplete definition of type 'struct devlink_port_new_attrs'
                   if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_SF &&


vim +912 drivers/net/netdevsim/dev.c

   894	
   895	static const struct devlink_ops nsim_dev_devlink_ops = {
   896		.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT |
   897						 DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,
   898		.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
   899		.reload_down = nsim_dev_reload_down,
   900		.reload_up = nsim_dev_reload_up,
   901		.info_get = nsim_dev_info_get,
   902		.flash_update = nsim_dev_flash_update,
   903		.trap_init = nsim_dev_devlink_trap_init,
   904		.trap_action_set = nsim_dev_devlink_trap_action_set,
   905		.trap_group_set = nsim_dev_devlink_trap_group_set,
   906		.trap_policer_set = nsim_dev_devlink_trap_policer_set,
   907		.trap_policer_counter_get = nsim_dev_devlink_trap_policer_counter_get,
   908		.port_new = nsim_dev_devlink_port_new,
   909		.port_del = nsim_dev_devlink_port_del,
   910		.port_function_hw_addr_get = nsim_dev_port_fn_hw_addr_get,
   911		.port_function_hw_addr_set = nsim_dev_port_fn_hw_addr_set,
 > 912		.port_fn_state_get = nsim_dev_port_fn_state_get,
   913	};
   914	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

Re: [PATCH net-next v2 7/7] netdevsim: Add netdevsim port add test cases

From: Jakub Kicinski <kuba@kernel.org>
Date: 2021-02-08 21:22:27

On Sun, 7 Feb 2021 10:44:12 +0200 Parav Pandit wrote:
+	RET=0
+	USR_PF_PORT_INDEX=600
+	USR_PFNUM_A=2
+	USR_PFNUM_B=3
+	USR_SF_PORT_INDEX=601
+	USR_SFNUM_A=44
+	USR_SFNUM_B=55
+
+	devlink port add $DL_HANDLE flavour pcipf pfnum $USR_PFNUM_A
+	check_err $? "Failed PF port addition"
+
+	devlink port show
+	check_err $? "Failed PF port show"
+
+	devlink port add $DL_HANDLE flavour pcisf pfnum $USR_PFNUM_A
+	check_err $? "Failed SF port addition"
+
+	devlink port add $DL_HANDLE flavour pcisf pfnum $USR_PFNUM_A \
+			sfnum $USR_SFNUM_A
+	check_err $? "Failed SF port addition"
+
+	devlink port add $DL_HANDLE flavour pcipf pfnum $USR_PFNUM_B
+	check_err $? "Failed second PF port addition"
+
+	devlink port add $DL_HANDLE/$USR_SF_PORT_INDEX flavour pcisf \
+			pfnum $USR_PFNUM_B sfnum $USR_SFNUM_B
+	check_err $? "Failed SF port addition"
+
+	devlink port show
+	check_err $? "Failed PF port show"
+
+	state=$(function_state_get "state")
+	check_err $? "Failed to get function state"
+	[ "$state" == "inactive" ]
+	check_err $? "Unexpected function state $state"
+
+	state=$(function_state_get "opstate")
+	check_err $? "Failed to get operational state"
+	[ "$state" == "detached" ]
+	check_err $? "Unexpected function opstate $opstate"
+
+	devlink port function set $DL_HANDLE/$USR_SF_PORT_INDEX state active
+	check_err $? "Failed to set state"
+
+	state=$(function_state_get "state")
+	check_err $? "Failed to get function state"
+	[ "$state" == "active" ]
+	check_err $? "Unexpected function state $state"
+
+	state=$(function_state_get "opstate")
+	check_err $? "Failed to get operational state"
+	[ "$state" == "attached" ]
+	check_err $? "Unexpected function opstate $opstate"
+
+	devlink port del $DL_HANDLE/$USR_SF_PORT_INDEX
+	check_err $? "Failed SF port deletion"
+
+	log_test "port_add test"
I don't think this very basic test is worth the 600 LoC of netdevsim
code.

If you come up with something better please don't post v3 it in reply 
to previous threads.

RE: [PATCH net-next v2 7/7] netdevsim: Add netdevsim port add test cases

From: Parav Pandit <hidden>
Date: 2021-02-09 04:06:02

From: Jakub Kicinski <kuba@kernel.org>
Sent: Tuesday, February 9, 2021 2:51 AM

On Sun, 7 Feb 2021 10:44:12 +0200 Parav Pandit wrote:
quoted
+	RET=0
+	USR_PF_PORT_INDEX=600
+	USR_PFNUM_A=2
+	USR_PFNUM_B=3
+	USR_SF_PORT_INDEX=601
+	USR_SFNUM_A=44
+	USR_SFNUM_B=55
+
+	devlink port add $DL_HANDLE flavour pcipf pfnum $USR_PFNUM_A
+	check_err $? "Failed PF port addition"
+
+	devlink port show
+	check_err $? "Failed PF port show"
+
+	devlink port add $DL_HANDLE flavour pcisf pfnum $USR_PFNUM_A
+	check_err $? "Failed SF port addition"
+
+	devlink port add $DL_HANDLE flavour pcisf pfnum $USR_PFNUM_A \
+			sfnum $USR_SFNUM_A
+	check_err $? "Failed SF port addition"
+
+	devlink port add $DL_HANDLE flavour pcipf pfnum $USR_PFNUM_B
+	check_err $? "Failed second PF port addition"
+
+	devlink port add $DL_HANDLE/$USR_SF_PORT_INDEX flavour pcisf \
+			pfnum $USR_PFNUM_B sfnum $USR_SFNUM_B
+	check_err $? "Failed SF port addition"
+
+	devlink port show
+	check_err $? "Failed PF port show"
+
+	state=$(function_state_get "state")
+	check_err $? "Failed to get function state"
+	[ "$state" == "inactive" ]
+	check_err $? "Unexpected function state $state"
+
+	state=$(function_state_get "opstate")
+	check_err $? "Failed to get operational state"
+	[ "$state" == "detached" ]
+	check_err $? "Unexpected function opstate $opstate"
+
+	devlink port function set $DL_HANDLE/$USR_SF_PORT_INDEX state
active
quoted
+	check_err $? "Failed to set state"
+
+	state=$(function_state_get "state")
+	check_err $? "Failed to get function state"
+	[ "$state" == "active" ]
+	check_err $? "Unexpected function state $state"
+
+	state=$(function_state_get "opstate")
+	check_err $? "Failed to get operational state"
+	[ "$state" == "attached" ]
+	check_err $? "Unexpected function opstate $opstate"
+
+	devlink port del $DL_HANDLE/$USR_SF_PORT_INDEX
+	check_err $? "Failed SF port deletion"
+
+	log_test "port_add test"
I don't think this very basic test is worth the 600 LoC of netdevsim code.
Do you mean I should improve the test to do more code coverage for 600 LoC?
If you come up with something better please don't post v3 it in reply to
previous threads.
Can you please explain? If only test case improves, wouldn't it be v3 for the last patch?
I must be missing something here.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help