Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ee87db3 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'nfp-get_phys_port_name-for-representors-and-SR-IOV-reorder'



Jakub Kicinski says:

====================
nfp: get_phys_port_name for representors and SR-IOV reorder

This series starts by making the error message if FW cannot be located
easier to understand.  Then I move some functions from PCI probe files
into library code (nfpcore) where they belong, and remove one function
which is never used.

Next few patches equip representors with nfp_port structure and make
their NDOs fully shared (not defined in apps), thanks to which we can
easily determine which netdevs are NFP's by comparing the NDO pointers.

10th patch makes use of the shared NDOs and nfp_ports to deliver
netdev-type independent .ndo_get_phys_port_name() implementation.

Patches 11 and 12 reorder the nfp_app SR-IOV callbacks with enabling
SR-IOV VFs.  Unfortunately due to how PCI subsystem works we can't
guarantee being able to disable SR-IOV at exit or that it will be
disabled when we first probe...  We must therefore make sure FW is
able to deal with being loaded while SR-IOV is already on.

Patch 13 fixes potential deadlock when enabling SR-IOV happens at
the same time as port state refresh.  Note that this can't happen
at this point, since Flower doesn't refresh ports... but lockdep
doesn't know about such details and we will have to deal with this
sooner or later anyway.

Last but not least a new Kconfig is added to make sure those who
don't care about flower offloads have a way of not including the
code in their kernels.  Thanks to nfp_app separation this costs us
a single ifdef and excluding flower files from the build.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ed9208be 57ae676e
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -25,6 +25,16 @@ config NFP
	  cards working as a advanced Ethernet NIC.  It works with both
	  SR-IOV physical and virtual functions.

config NFP_APP_FLOWER
	bool "NFP4000/NFP6000 TC Flower offload support"
	depends on NFP
	depends on NET_SWITCHDEV
	---help---
	  Enable driver support for TC Flower offload on NFP4000 and NFP6000.
	  Say Y, if you are planning to make use of TC Flower offload
	  either directly, with Open vSwitch, or any other way.  Note that
	  TC Flower offload requires specific FW to work.

config NFP_DEBUG
	bool "Debug support for Netronome(R) NFP4000/NFP6000 NIC drivers"
	depends on NFP
+6 −2
Original line number Diff line number Diff line
@@ -27,10 +27,14 @@ nfp-objs := \
	    nfp_port.o \
	    bpf/main.o \
	    bpf/offload.o \
	    flower/cmsg.o \
	    flower/main.o \
	    nic/main.o

ifeq ($(CONFIG_NFP_APP_FLOWER),y)
nfp-objs += \
	    flower/cmsg.o \
	    flower/main.o
endif

ifeq ($(CONFIG_BPF_SYSCALL),y)
nfp-objs += \
	    bpf/verifier.o \
+2 −3
Original line number Diff line number Diff line
@@ -79,9 +79,8 @@ nfp_flower_cmsg_alloc(struct nfp_app *app, unsigned int size,
	return skb;
}

int nfp_flower_cmsg_portmod(struct net_device *netdev, bool carrier_ok)
int nfp_flower_cmsg_portmod(struct nfp_repr *repr, bool carrier_ok)
{
	struct nfp_repr *repr = netdev_priv(netdev);
	struct nfp_flower_cmsg_portmod *msg;
	struct sk_buff *skb;

@@ -94,7 +93,7 @@ int nfp_flower_cmsg_portmod(struct net_device *netdev, bool carrier_ok)
	msg->portnum = cpu_to_be32(repr->dst->u.port_info.port_id);
	msg->reserved = 0;
	msg->info = carrier_ok;
	msg->mtu = cpu_to_be16(netdev->mtu);
	msg->mtu = cpu_to_be16(repr->netdev->mtu);

	nfp_ctrl_tx(repr->app->ctrl, skb);

+1 −1
Original line number Diff line number Diff line
@@ -110,7 +110,7 @@ nfp_flower_cmsg_pcie_port(u8 nfp_pcie, enum nfp_flower_cmsg_port_vnic_type type,
			   NFP_FLOWER_CMSG_PORT_TYPE_PCIE_PORT);
}

int nfp_flower_cmsg_portmod(struct net_device *netdev, bool carrier_ok);
int nfp_flower_cmsg_portmod(struct nfp_repr *repr, bool carrier_ok);
void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb);

#endif
+42 −47
Original line number Diff line number Diff line
@@ -104,51 +104,30 @@ nfp_flower_repr_get(struct nfp_app *app, u32 port_id)
	return reprs->reprs[port];
}

static void
nfp_flower_repr_netdev_get_stats64(struct net_device *netdev,
				   struct rtnl_link_stats64 *stats)
{
	struct nfp_repr *repr = netdev_priv(netdev);
	enum nfp_repr_type type;
	u32 port_id;
	u8 port = 0;

	port_id = repr->dst->u.port_info.port_id;
	type = nfp_flower_repr_get_type_and_port(repr->app, port_id, &port);
	nfp_repr_get_stats64(repr->app, type, port, stats);
}

static int nfp_flower_repr_netdev_open(struct net_device *netdev)
static int
nfp_flower_repr_netdev_open(struct nfp_app *app, struct nfp_repr *repr)
{
	int err;

	err = nfp_flower_cmsg_portmod(netdev, true);
	err = nfp_flower_cmsg_portmod(repr, true);
	if (err)
		return err;

	netif_carrier_on(netdev);
	netif_tx_wake_all_queues(netdev);
	netif_carrier_on(repr->netdev);
	netif_tx_wake_all_queues(repr->netdev);

	return 0;
}

static int nfp_flower_repr_netdev_stop(struct net_device *netdev)
static int
nfp_flower_repr_netdev_stop(struct nfp_app *app, struct nfp_repr *repr)
{
	netif_carrier_off(netdev);
	netif_tx_disable(netdev);
	netif_carrier_off(repr->netdev);
	netif_tx_disable(repr->netdev);

	return nfp_flower_cmsg_portmod(netdev, false);
	return nfp_flower_cmsg_portmod(repr, false);
}

static const struct net_device_ops nfp_flower_repr_netdev_ops = {
	.ndo_open		= nfp_flower_repr_netdev_open,
	.ndo_stop		= nfp_flower_repr_netdev_stop,
	.ndo_start_xmit		= nfp_repr_xmit,
	.ndo_get_stats64	= nfp_flower_repr_netdev_get_stats64,
	.ndo_has_offload_stats	= nfp_repr_has_offload_stats,
	.ndo_get_offload_stats	= nfp_repr_get_offload_stats,
};

static void nfp_flower_sriov_disable(struct nfp_app *app)
{
	nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_VF);
@@ -162,14 +141,19 @@ nfp_flower_spawn_vnic_reprs(struct nfp_app *app,
	u8 nfp_pcie = nfp_cppcore_pcie_unit(app->pf->cpp);
	struct nfp_flower_priv *priv = app->priv;
	struct nfp_reprs *reprs, *old_reprs;
	enum nfp_port_type port_type;
	const u8 queue = 0;
	int i, err;

	port_type = repr_type == NFP_REPR_TYPE_PF ? NFP_PORT_PF_PORT :
						    NFP_PORT_VF_PORT;

	reprs = nfp_reprs_alloc(cnt);
	if (!reprs)
		return -ENOMEM;

	for (i = 0; i < cnt; i++) {
		struct nfp_port *port;
		u32 port_id;

		reprs->reprs[i] = nfp_repr_alloc(app);
@@ -178,15 +162,24 @@ nfp_flower_spawn_vnic_reprs(struct nfp_app *app,
			goto err_reprs_clean;
		}

		port = nfp_port_alloc(app, port_type, reprs->reprs[i]);
		if (repr_type == NFP_REPR_TYPE_PF) {
			port->pf_id = i;
		} else {
			port->pf_id = 0; /* For now we only support 1 PF */
			port->vf_id = i;
		}

		eth_hw_addr_random(reprs->reprs[i]);

		port_id = nfp_flower_cmsg_pcie_port(nfp_pcie, vnic_type,
						    i, queue);
		err = nfp_repr_init(app, reprs->reprs[i],
				    &nfp_flower_repr_netdev_ops,
				    port_id, NULL, priv->nn->dp.netdev);
		if (err)
				    port_id, port, priv->nn->dp.netdev);
		if (err) {
			nfp_port_free(port);
			goto err_reprs_clean;
		}

		nfp_info(app->cpp, "%s%d Representor(%s) created\n",
			 repr_type == NFP_REPR_TYPE_PF ? "PF" : "VF", i,
@@ -260,7 +253,6 @@ nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv)

		cmsg_port_id = nfp_flower_cmsg_phys_port(phys_port);
		err = nfp_repr_init(app, reprs->reprs[phys_port],
				    &nfp_flower_repr_netdev_ops,
				    cmsg_port_id, port, priv->nn->dp.netdev);
		if (err) {
			nfp_port_free(port);
@@ -296,26 +288,16 @@ static int nfp_flower_start(struct nfp_app *app)
					   NFP_REPR_TYPE_PF, 1);
}

static void nfp_flower_vnic_clean(struct nfp_app *app, struct nfp_net *nn)
{
	kfree(app->priv);
	app->priv = NULL;
}

static int nfp_flower_vnic_init(struct nfp_app *app, struct nfp_net *nn,
				unsigned int id)
{
	struct nfp_flower_priv *priv;
	struct nfp_flower_priv *priv = app->priv;

	if (id > 0) {
		nfp_warn(app->cpp, "FlowerNIC doesn't support more than one data vNIC\n");
		goto err_invalid_port;
	}

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;
	app->priv = priv;
	priv->nn = nn;

	eth_hw_addr_random(nn->dp.netdev);
@@ -347,9 +329,19 @@ static int nfp_flower_init(struct nfp_app *app)
		return -EINVAL;
	}

	app->priv = kzalloc(sizeof(struct nfp_flower_priv), GFP_KERNEL);
	if (!app->priv)
		return -ENOMEM;

	return 0;
}

static void nfp_flower_clean(struct nfp_app *app)
{
	kfree(app->priv);
	app->priv = NULL;
}

const struct nfp_app_type app_flower = {
	.id		= NFP_APP_FLOWER_NIC,
	.name		= "flower",
@@ -358,9 +350,12 @@ const struct nfp_app_type app_flower = {
	.extra_cap	= nfp_flower_extra_cap,

	.init		= nfp_flower_init,
	.clean		= nfp_flower_clean,

	.vnic_init	= nfp_flower_vnic_init,
	.vnic_clean	= nfp_flower_vnic_clean,

	.repr_open	= nfp_flower_repr_netdev_open,
	.repr_stop	= nfp_flower_repr_netdev_stop,

	.start		= nfp_flower_start,
	.stop		= nfp_flower_stop,
Loading