All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/9] nfp: CRC32 RSS hash, port name reporting and misc fastpath cleanups
@ 2017-03-08 16:56 Jakub Kicinski
  2017-03-08 16:57 ` [PATCH net-next 1/9] ethtool: add CRC32 as an RSS hash function Jakub Kicinski
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Jakub Kicinski @ 2017-03-08 16:56 UTC (permalink / raw)
  To: netdev; +Cc: oss-drivers, Jakub Kicinski

Hi!

This series adds support for CRC32 RSS hash function to kernel API
of which NFP driver immediately makes use.  There is also a
.ndo_get_phys_port_name() implementation conforming to switchdev 
name format.  Small patch takes advantage of napi_complete_done()'s
return code.  Simon provides a fix for potentially trusting values 
returned from FW too much.

A handful of unassuming fast path adjustments is also thrown in to make
the upcoming xdp_adjust_head() series easier to review.

Jakub Kicinski (8):
  ethtool: add CRC32 as an RSS hash function
  nfp: add support for reporting CRC32 hash function
  nfp: implement .ndo_get_phys_port_name()
  nfp: move more ring debug info to debugfs
  nfp: reorder variables in nfp_net_tx()
  nfp: store device pointer for the fastpath
  nfp: avoid rearming the interrupts when in busy poll
  nfp: add metadata format bit

Simon Horman (1):
  nfp: prevent theoretical buffer overrun in nfp_eth_read_ports

 drivers/net/ethernet/netronome/nfp/nfp_net.h       |  15 ++-
 .../net/ethernet/netronome/nfp/nfp_net_common.c    | 141 ++++++++++++++-------
 drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h  |  14 +-
 .../net/ethernet/netronome/nfp/nfp_net_debugfs.c   |  13 +-
 .../net/ethernet/netronome/nfp/nfp_net_ethtool.c   |  23 +++-
 drivers/net/ethernet/netronome/nfp/nfp_net_main.c  |   7 +-
 .../net/ethernet/netronome/nfp/nfp_net_offload.c   |   7 +-
 .../ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c   |  65 +++++++---
 .../ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.h   |  15 ++-
 include/linux/ethtool.h                            |   2 +
 net/core/ethtool.c                                 |   1 +
 11 files changed, 216 insertions(+), 87 deletions(-)

-- 
2.11.0

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH net-next 1/9] ethtool: add CRC32 as an RSS hash function
  2017-03-08 16:56 [PATCH net-next 0/9] nfp: CRC32 RSS hash, port name reporting and misc fastpath cleanups Jakub Kicinski
@ 2017-03-08 16:57 ` Jakub Kicinski
  2017-03-08 16:57 ` [PATCH net-next 2/9] nfp: add support for reporting CRC32 " Jakub Kicinski
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Jakub Kicinski @ 2017-03-08 16:57 UTC (permalink / raw)
  To: netdev; +Cc: oss-drivers, Jakub Kicinski

CRC32 engines are usually easily available in hardware and generate
OK spread for RSS hash.  Add CRC32 RSS hash function to ethtool API.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 include/linux/ethtool.h | 2 ++
 net/core/ethtool.c      | 1 +
 2 files changed, 3 insertions(+)

diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 9ded8c6d8176..83cc9863444b 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -60,6 +60,7 @@ enum ethtool_phys_id_state {
 enum {
 	ETH_RSS_HASH_TOP_BIT, /* Configurable RSS hash function - Toeplitz */
 	ETH_RSS_HASH_XOR_BIT, /* Configurable RSS hash function - Xor */
+	ETH_RSS_HASH_CRC32_BIT, /* Configurable RSS hash function - Crc32 */
 
 	/*
 	 * Add your fresh new hash function bits above and remember to update
@@ -73,6 +74,7 @@ enum {
 
 #define ETH_RSS_HASH_TOP	__ETH_RSS_HASH(TOP)
 #define ETH_RSS_HASH_XOR	__ETH_RSS_HASH(XOR)
+#define ETH_RSS_HASH_CRC32	__ETH_RSS_HASH(CRC32)
 
 #define ETH_RSS_HASH_UNKNOWN	0
 #define ETH_RSS_HASH_NO_CHANGE	0
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index aecb2c7241b6..905a88ad28e0 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -109,6 +109,7 @@ static const char
 rss_hash_func_strings[ETH_RSS_HASH_FUNCS_COUNT][ETH_GSTRING_LEN] = {
 	[ETH_RSS_HASH_TOP_BIT] =	"toeplitz",
 	[ETH_RSS_HASH_XOR_BIT] =	"xor",
+	[ETH_RSS_HASH_CRC32_BIT] =	"crc32",
 };
 
 static const char
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net-next 2/9] nfp: add support for reporting CRC32 hash function
  2017-03-08 16:56 [PATCH net-next 0/9] nfp: CRC32 RSS hash, port name reporting and misc fastpath cleanups Jakub Kicinski
  2017-03-08 16:57 ` [PATCH net-next 1/9] ethtool: add CRC32 as an RSS hash function Jakub Kicinski
@ 2017-03-08 16:57 ` Jakub Kicinski
  2017-03-08 16:57 ` [PATCH net-next 3/9] nfp: implement .ndo_get_phys_port_name() Jakub Kicinski
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Jakub Kicinski @ 2017-03-08 16:57 UTC (permalink / raw)
  To: netdev; +Cc: oss-drivers, Jakub Kicinski

Some firmware images may reuse CRC32 hardware to compute RXHASH.
Make sure we report the correct hash function.  Note that we don't
support changing functions at runtime.  That would also require
a few more additions to the way the key is set because different
functions have different key sizes.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/nfp_net.h       |  3 ++
 .../net/ethernet/netronome/nfp/nfp_net_common.c    | 46 ++++++++++++++++++++--
 drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h  | 14 ++++++-
 .../net/ethernet/netronome/nfp/nfp_net_ethtool.c   | 23 +++++++----
 4 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net.h b/drivers/net/ethernet/netronome/nfp/nfp_net.h
index e614a376b595..9843e953bbed 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net.h
@@ -446,6 +446,7 @@ struct nfp_stat_pair {
  * @fw_ver:             Firmware version
  * @cap:                Capabilities advertised by the Firmware
  * @max_mtu:            Maximum support MTU advertised by the Firmware
+ * @rss_hfunc:		RSS selected hash function
  * @rss_cfg:            RSS configuration
  * @rss_key:            RSS secret key
  * @rss_itbl:           RSS indirection table
@@ -518,6 +519,7 @@ struct nfp_net {
 	u32 cap;
 	u32 max_mtu;
 
+	u8 rss_hfunc;
 	u32 rss_cfg;
 	u8 rss_key[NFP_NET_CFG_RSS_KEY_SZ];
 	u8 rss_itbl[NFP_NET_CFG_RSS_ITBL_SZ];
@@ -776,6 +778,7 @@ void nfp_net_netdev_clean(struct net_device *netdev);
 void nfp_net_set_ethtool_ops(struct net_device *netdev);
 void nfp_net_info(struct nfp_net *nn);
 int nfp_net_reconfig(struct nfp_net *nn, u32 update);
+unsigned int nfp_net_rss_key_sz(struct nfp_net *nn);
 void nfp_net_rss_write_itbl(struct nfp_net *nn);
 void nfp_net_rss_write_key(struct nfp_net *nn);
 void nfp_net_coalesce_write_cfg(struct nfp_net *nn);
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 9179a99563af..e72468d65c28 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -41,6 +41,7 @@
  *          Chris Telfer <chris.telfer@netronome.com>
  */
 
+#include <linux/bitfield.h>
 #include <linux/bpf.h>
 #include <linux/bpf_trace.h>
 #include <linux/module.h>
@@ -2045,7 +2046,7 @@ void nfp_net_rss_write_key(struct nfp_net *nn)
 {
 	int i;
 
-	for (i = 0; i < NFP_NET_CFG_RSS_KEY_SZ; i += 4)
+	for (i = 0; i < nfp_net_rss_key_sz(nn); i += 4)
 		nn_writel(nn, NFP_NET_CFG_RSS_KEY + i,
 			  get_unaligned_le32(nn->rss_key + i));
 }
@@ -3112,19 +3113,58 @@ void nfp_net_netdev_free(struct nfp_net *nn)
 }
 
 /**
+ * nfp_net_rss_key_sz() - Get current size of the RSS key
+ * @nn:		NFP Net device instance
+ *
+ * Return: size of the RSS key for currently selected hash function.
+ */
+unsigned int nfp_net_rss_key_sz(struct nfp_net *nn)
+{
+	switch (nn->rss_hfunc) {
+	case ETH_RSS_HASH_TOP:
+		return NFP_NET_CFG_RSS_KEY_SZ;
+	case ETH_RSS_HASH_XOR:
+		return 0;
+	case ETH_RSS_HASH_CRC32:
+		return 4;
+	}
+
+	nn_warn(nn, "Unknown hash function: %u\n", nn->rss_hfunc);
+	return 0;
+}
+
+/**
  * nfp_net_rss_init() - Set the initial RSS parameters
  * @nn:	     NFP Net device to reconfigure
  */
 static void nfp_net_rss_init(struct nfp_net *nn)
 {
-	netdev_rss_key_fill(nn->rss_key, NFP_NET_CFG_RSS_KEY_SZ);
+	unsigned long func_bit, rss_cap_hfunc;
+	u32 reg;
+
+	/* Read the RSS function capability and select first supported func */
+	reg = nn_readl(nn, NFP_NET_CFG_RSS_CAP);
+	rss_cap_hfunc =	FIELD_GET(NFP_NET_CFG_RSS_CAP_HFUNC, reg);
+	if (!rss_cap_hfunc)
+		rss_cap_hfunc =	FIELD_GET(NFP_NET_CFG_RSS_CAP_HFUNC,
+					  NFP_NET_CFG_RSS_TOEPLITZ);
+
+	func_bit = find_first_bit(&rss_cap_hfunc, NFP_NET_CFG_RSS_HFUNCS);
+	if (func_bit == NFP_NET_CFG_RSS_HFUNCS) {
+		dev_warn(&nn->pdev->dev,
+			 "Bad RSS config, defaulting to Toeplitz hash\n");
+		func_bit = ETH_RSS_HASH_TOP_BIT;
+	}
+	nn->rss_hfunc = 1 << func_bit;
+
+	netdev_rss_key_fill(nn->rss_key, nfp_net_rss_key_sz(nn));
 
 	nfp_net_rss_init_itbl(nn);
 
 	/* Enable IPv4/IPv6 TCP by default */
 	nn->rss_cfg = NFP_NET_CFG_RSS_IPV4_TCP |
 		      NFP_NET_CFG_RSS_IPV6_TCP |
-		      NFP_NET_CFG_RSS_TOEPLITZ |
+		      FIELD_PREP(NFP_NET_CFG_RSS_HFUNC, nn->rss_hfunc) |
 		      NFP_NET_CFG_RSS_MASK;
 }
 
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h b/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h
index 385ba355c965..71d86171b4ee 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Netronome Systems, Inc.
+ * Copyright (C) 2015-2017 Netronome Systems, Inc.
  *
  * This software is dual licensed under the GNU General License Version 2,
  * June 1991 as shown in the file COPYING in the top-level directory of this
@@ -192,6 +192,14 @@
 #define NFP_NET_CFG_RX_OFFSET_DYNAMIC		0	/* Prepend mode */
 
 /**
+ * RSS capabilities
+ * @NFP_NET_CFG_RSS_CAP_HFUNC:	supported hash functions (same bits as
+ *				@NFP_NET_CFG_RSS_HFUNC)
+ */
+#define NFP_NET_CFG_RSS_CAP		0x0054
+#define   NFP_NET_CFG_RSS_CAP_HFUNC	  0xff000000
+
+/**
  * VXLAN/UDP encap configuration
  * @NFP_NET_CFG_VXLAN_PORT:	Base address of table of tunnels' UDP dst ports
  * @NFP_NET_CFG_VXLAN_SZ:	Size of the UDP port table in bytes
@@ -249,7 +257,11 @@
 #define   NFP_NET_CFG_RSS_IPV4_UDP        (1 << 11) /* RSS for IPv4/UDP */
 #define   NFP_NET_CFG_RSS_IPV6_TCP        (1 << 12) /* RSS for IPv6/TCP */
 #define   NFP_NET_CFG_RSS_IPV6_UDP        (1 << 13) /* RSS for IPv6/UDP */
+#define   NFP_NET_CFG_RSS_HFUNC		  0xff000000
 #define   NFP_NET_CFG_RSS_TOEPLITZ        (1 << 24) /* Use Toeplitz hash */
+#define   NFP_NET_CFG_RSS_XOR		  (1 << 25) /* Use XOR as hash */
+#define   NFP_NET_CFG_RSS_CRC32		  (1 << 26) /* Use CRC32 as hash */
+#define   NFP_NET_CFG_RSS_HFUNCS	  3
 #define NFP_NET_CFG_RSS_KEY             (NFP_NET_CFG_RSS_BASE + 0x4)
 #define NFP_NET_CFG_RSS_KEY_SZ          0x28
 #define NFP_NET_CFG_RSS_ITBL            (NFP_NET_CFG_RSS_BASE + 0x4 + \
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
index 2649f7523c81..a1bca2dca0a5 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
@@ -40,6 +40,7 @@
  *          Brad Petrus <brad.petrus@netronome.com>
  */
 
+#include <linux/bitfield.h>
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -454,7 +455,7 @@ static int nfp_net_set_rss_hash_opt(struct nfp_net *nn,
 		return -EINVAL;
 	}
 
-	new_rss_cfg |= NFP_NET_CFG_RSS_TOEPLITZ;
+	new_rss_cfg |= FIELD_PREP(NFP_NET_CFG_RSS_HFUNC, nn->rss_hfunc);
 	new_rss_cfg |= NFP_NET_CFG_RSS_MASK;
 
 	if (new_rss_cfg == nn->rss_cfg)
@@ -496,7 +497,12 @@ static u32 nfp_net_get_rxfh_indir_size(struct net_device *netdev)
 
 static u32 nfp_net_get_rxfh_key_size(struct net_device *netdev)
 {
-	return NFP_NET_CFG_RSS_KEY_SZ;
+	struct nfp_net *nn = netdev_priv(netdev);
+
+	if (!(nn->cap & NFP_NET_CFG_CTRL_RSS))
+		return -EOPNOTSUPP;
+
+	return nfp_net_rss_key_sz(nn);
 }
 
 static int nfp_net_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
@@ -512,9 +518,12 @@ static int nfp_net_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
 		for (i = 0; i < ARRAY_SIZE(nn->rss_itbl); i++)
 			indir[i] = nn->rss_itbl[i];
 	if (key)
-		memcpy(key, nn->rss_key, NFP_NET_CFG_RSS_KEY_SZ);
-	if (hfunc)
-		*hfunc = ETH_RSS_HASH_TOP;
+		memcpy(key, nn->rss_key, nfp_net_rss_key_sz(nn));
+	if (hfunc) {
+		*hfunc = nn->rss_hfunc;
+		if (*hfunc >= 1 << ETH_RSS_HASH_FUNCS_COUNT)
+			*hfunc = ETH_RSS_HASH_UNKNOWN;
+	}
 
 	return 0;
 }
@@ -527,14 +536,14 @@ static int nfp_net_set_rxfh(struct net_device *netdev,
 	int i;
 
 	if (!(nn->cap & NFP_NET_CFG_CTRL_RSS) ||
-	    !(hfunc == ETH_RSS_HASH_NO_CHANGE || hfunc == ETH_RSS_HASH_TOP))
+	    !(hfunc == ETH_RSS_HASH_NO_CHANGE || hfunc == nn->rss_hfunc))
 		return -EOPNOTSUPP;
 
 	if (!key && !indir)
 		return 0;
 
 	if (key) {
-		memcpy(nn->rss_key, key, NFP_NET_CFG_RSS_KEY_SZ);
+		memcpy(nn->rss_key, key, nfp_net_rss_key_sz(nn));
 		nfp_net_rss_write_key(nn);
 	}
 	if (indir) {
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net-next 3/9] nfp: implement .ndo_get_phys_port_name()
  2017-03-08 16:56 [PATCH net-next 0/9] nfp: CRC32 RSS hash, port name reporting and misc fastpath cleanups Jakub Kicinski
  2017-03-08 16:57 ` [PATCH net-next 1/9] ethtool: add CRC32 as an RSS hash function Jakub Kicinski
  2017-03-08 16:57 ` [PATCH net-next 2/9] nfp: add support for reporting CRC32 " Jakub Kicinski
@ 2017-03-08 16:57 ` Jakub Kicinski
  2017-03-08 16:57 ` [PATCH net-next 4/9] nfp: move more ring debug info to debugfs Jakub Kicinski
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Jakub Kicinski @ 2017-03-08 16:57 UTC (permalink / raw)
  To: netdev; +Cc: oss-drivers, Jakub Kicinski

NSP reports to us port labels.  First id is the id of the physical
port, the other one tells us which logical interface is it within a
split port.  Instead of printing them as string keep them in integer
format.  Compute which interfaces are part of port split.

On netdev side use port labels and split information to provide a
.ndo_get_phys_port_name() implementation.  We follow the name format
of mlxsw which is also suggested in "Port Netdev Naming" section
of Documentation/networking/switchdev.txt.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/nfp_net.h       |  4 +++
 .../net/ethernet/netronome/nfp/nfp_net_common.c    | 22 +++++++++++++++
 drivers/net/ethernet/netronome/nfp/nfp_net_main.c  |  2 ++
 .../ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c   | 31 +++++++++++++++++++---
 .../ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.h   | 15 +++++++++--
 5 files changed, 69 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net.h b/drivers/net/ethernet/netronome/nfp/nfp_net.h
index 9843e953bbed..50413eea9540 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net.h
@@ -112,6 +112,7 @@
 
 /* Forward declarations */
 struct nfp_cpp;
+struct nfp_eth_table_port;
 struct nfp_net;
 struct nfp_net_r_vector;
 
@@ -496,6 +497,7 @@ struct nfp_stat_pair {
  * @ethtool_dump_flag:	Ethtool dump flag
  * @port_list:		Entry on device port list
  * @cpp:		CPP device handle if available
+ * @eth_port:		Translated ETH Table port entry
  */
 struct nfp_net {
 	struct pci_dev *pdev;
@@ -587,6 +589,8 @@ struct nfp_net {
 	struct list_head port_list;
 
 	struct nfp_cpp *cpp;
+
+	struct nfp_eth_table_port *eth_port;
 };
 
 struct nfp_net_ring_set {
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index e72468d65c28..5c34f79053f7 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -67,6 +67,7 @@
 #include <net/pkt_cls.h>
 #include <net/vxlan.h>
 
+#include "nfpcore/nfp_nsp_eth.h"
 #include "nfp_net_ctrl.h"
 #include "nfp_net.h"
 
@@ -2831,6 +2832,26 @@ nfp_net_features_check(struct sk_buff *skb, struct net_device *dev,
 	return features;
 }
 
+static int
+nfp_net_get_phys_port_name(struct net_device *netdev, char *name, size_t len)
+{
+	struct nfp_net *nn = netdev_priv(netdev);
+	int err;
+
+	if (!nn->eth_port)
+		return -EOPNOTSUPP;
+
+	if (!nn->eth_port->is_split)
+		err = snprintf(name, len, "p%d", nn->eth_port->label_port);
+	else
+		err = snprintf(name, len, "p%ds%d", nn->eth_port->label_port,
+			       nn->eth_port->label_subport);
+	if (err >= len)
+		return -EINVAL;
+
+	return 0;
+}
+
 /**
  * nfp_net_set_vxlan_port() - set vxlan port in SW and reconfigure HW
  * @nn:   NFP Net device to reconfigure
@@ -3009,6 +3030,7 @@ static const struct net_device_ops nfp_net_netdev_ops = {
 	.ndo_set_mac_address	= eth_mac_addr,
 	.ndo_set_features	= nfp_net_set_features,
 	.ndo_features_check	= nfp_net_features_check,
+	.ndo_get_phys_port_name	= nfp_net_get_phys_port_name,
 	.ndo_udp_tunnel_add	= nfp_net_add_vxlan_port,
 	.ndo_udp_tunnel_del	= nfp_net_del_vxlan_port,
 	.ndo_xdp		= nfp_net_xdp,
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
index 3afcdc11480c..f04d0b8e84ad 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
@@ -178,6 +178,8 @@ nfp_net_get_mac_addr(struct nfp_net *nn, struct nfp_pf *pf, unsigned int id)
 		if (pf->eth_tbl->ports[i].eth_index == id) {
 			const u8 *mac_addr = pf->eth_tbl->ports[i].mac_addr;
 
+			nn->eth_port = &pf->eth_tbl->ports[i];
+
 			ether_addr_copy(nn->netdev->dev_addr, mac_addr);
 			ether_addr_copy(nn->netdev->perm_addr, mac_addr);
 			return;
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c
index 1ece1f8ae4b3..10a0c8392d2b 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c
@@ -134,9 +134,32 @@ nfp_eth_port_translate(const struct eth_table_entry *src, unsigned int index,
 
 	nfp_eth_copy_mac_reverse(dst->mac_addr, src->mac_addr);
 
-	snprintf(dst->label, sizeof(dst->label) - 1, "%llu.%llu",
-		 FIELD_GET(NSP_ETH_PORT_PHYLABEL, port),
-		 FIELD_GET(NSP_ETH_PORT_LABEL, port));
+	dst->label_port = FIELD_GET(NSP_ETH_PORT_PHYLABEL, port);
+	dst->label_subport = FIELD_GET(NSP_ETH_PORT_LABEL, port);
+}
+
+static void
+nfp_eth_mark_split_ports(struct nfp_cpp *cpp, struct nfp_eth_table *table)
+{
+	unsigned int i, j;
+
+	for (i = 0; i < table->count; i++)
+		for (j = 0; j < table->count; j++) {
+			if (i == j)
+				continue;
+			if (table->ports[i].label_port !=
+			    table->ports[j].label_port)
+				continue;
+			if (table->ports[i].label_subport ==
+			    table->ports[j].label_subport)
+				nfp_warn(cpp,
+					 "Port %d subport %d is a duplicate\n",
+					 table->ports[i].label_port,
+					 table->ports[i].label_subport);
+
+			table->ports[i].is_split = true;
+			break;
+		}
 }
 
 /**
@@ -203,6 +226,8 @@ __nfp_eth_read_ports(struct nfp_cpp *cpp, struct nfp_nsp *nsp)
 			nfp_eth_port_translate(&entries[i], i,
 					       &table->ports[j++]);
 
+	nfp_eth_mark_split_ports(cpp, table);
+
 	kfree(entries);
 
 	return table;
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.h b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.h
index edf703d319c8..325e841ca90a 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.h
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.h
@@ -49,10 +49,13 @@
  * @lanes:	number of channels
  * @speed:	interface speed (in Mbps)
  * @mac_addr:	interface MAC address
- * @label:	interface id string
+ * @label_port:	port id
+ * @label_subport:  id of interface within port (for split ports)
  * @enabled:	is enabled?
  * @tx_enabled:	is TX enabled?
  * @rx_enabled:	is RX enabled?
+ *
+ * @is_split:	is interface part of a split port
  */
 struct nfp_eth_table {
 	unsigned int count;
@@ -65,14 +68,22 @@ struct nfp_eth_table {
 		unsigned int speed;
 
 		u8 mac_addr[ETH_ALEN];
-		char label[8];
+
+		u8 label_port;
+		u8 label_subport;
 
 		bool enabled;
 		bool tx_enabled;
 		bool rx_enabled;
+
+		/* Computed fields */
+		bool is_split;
 	} ports[0];
 };
 
+struct nfp_cpp;
+struct nfp_nsp;
+
 struct nfp_eth_table *nfp_eth_read_ports(struct nfp_cpp *cpp);
 struct nfp_eth_table *
 __nfp_eth_read_ports(struct nfp_cpp *cpp, struct nfp_nsp *nsp);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net-next 4/9] nfp: move more ring debug info to debugfs
  2017-03-08 16:56 [PATCH net-next 0/9] nfp: CRC32 RSS hash, port name reporting and misc fastpath cleanups Jakub Kicinski
                   ` (2 preceding siblings ...)
  2017-03-08 16:57 ` [PATCH net-next 3/9] nfp: implement .ndo_get_phys_port_name() Jakub Kicinski
@ 2017-03-08 16:57 ` Jakub Kicinski
  2017-03-08 16:57 ` [PATCH net-next 5/9] nfp: reorder variables in nfp_net_tx() Jakub Kicinski
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Jakub Kicinski @ 2017-03-08 16:57 UTC (permalink / raw)
  To: netdev; +Cc: oss-drivers, Jakub Kicinski

We already print most of ring configuration including descriptors
in debugfs, add the few missing pieces and remove debug prints.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/nfp_net_common.c  |  9 ---------
 drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c | 13 +++++++++----
 2 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 5c34f79053f7..0be47188fd36 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -1776,11 +1776,6 @@ nfp_net_tx_ring_alloc(struct nfp_net_tx_ring *tx_ring, u32 cnt, bool is_xdp)
 		netif_set_xps_queue(nn->netdev, &r_vec->affinity_mask,
 				    tx_ring->idx);
 
-	nn_dbg(nn, "TxQ%02d: QCidx=%02d cnt=%d dma=%#llx host=%p %s\n",
-	       tx_ring->idx, tx_ring->qcidx,
-	       tx_ring->cnt, (unsigned long long)tx_ring->dma, tx_ring->txds,
-	       is_xdp ? "XDP" : "");
-
 	return 0;
 
 err_alloc:
@@ -1900,10 +1895,6 @@ nfp_net_rx_ring_alloc(struct nfp_net_rx_ring *rx_ring, unsigned int fl_bufsz,
 	if (!rx_ring->rxbufs)
 		goto err_alloc;
 
-	nn_dbg(nn, "RxQ%02d: FlQCidx=%02d RxQCidx=%02d cnt=%d dma=%#llx host=%p\n",
-	       rx_ring->idx, rx_ring->fl_qcidx, rx_ring->rx_qcidx,
-	       rx_ring->cnt, (unsigned long long)rx_ring->dma, rx_ring->rxds);
-
 	return 0;
 
 err_alloc:
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c b/drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c
index 6e9372a18375..edfa59e51fdd 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c
@@ -64,8 +64,10 @@ static int nfp_net_debugfs_rx_q_read(struct seq_file *file, void *data)
 	rx_rd_p = nfp_qcp_rd_ptr_read(rx_ring->qcp_rx);
 	rx_wr_p = nfp_qcp_wr_ptr_read(rx_ring->qcp_rx);
 
-	seq_printf(file, "RX[%02d]: H_RD=%d H_WR=%d FL_RD=%d FL_WR=%d RX_RD=%d RX_WR=%d\n",
-		   rx_ring->idx, rx_ring->rd_p, rx_ring->wr_p,
+	seq_printf(file, "RX[%02d,%02d,%02d]: cnt=%d dma=%pad host=%p   H_RD=%d H_WR=%d FL_RD=%d FL_WR=%d RX_RD=%d RX_WR=%d\n",
+		   rx_ring->idx, rx_ring->fl_qcidx, rx_ring->rx_qcidx,
+		   rx_ring->cnt, &rx_ring->dma, rx_ring->rxds,
+		   rx_ring->rd_p, rx_ring->wr_p,
 		   fl_rd_p, fl_wr_p, rx_rd_p, rx_wr_p);
 
 	for (i = 0; i < rxd_cnt; i++) {
@@ -151,8 +153,11 @@ static int nfp_net_debugfs_tx_q_read(struct seq_file *file, void *data)
 	d_rd_p = nfp_qcp_rd_ptr_read(tx_ring->qcp_q);
 	d_wr_p = nfp_qcp_wr_ptr_read(tx_ring->qcp_q);
 
-	seq_printf(file, "TX[%02d]: H_RD=%d H_WR=%d D_RD=%d D_WR=%d\n",
-		   tx_ring->idx, tx_ring->rd_p, tx_ring->wr_p, d_rd_p, d_wr_p);
+	seq_printf(file, "TX[%02d,%02d%s]: cnt=%d dma=%pad host=%p   H_RD=%d H_WR=%d D_RD=%d D_WR=%d\n",
+		   tx_ring->idx, tx_ring->qcidx,
+		   tx_ring == r_vec->tx_ring ? "" : "xdp",
+		   tx_ring->cnt, &tx_ring->dma, tx_ring->txds,
+		   tx_ring->rd_p, tx_ring->wr_p, d_rd_p, d_wr_p);
 
 	for (i = 0; i < txd_cnt; i++) {
 		txd = &tx_ring->txds[i];
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net-next 5/9] nfp: reorder variables in nfp_net_tx()
  2017-03-08 16:56 [PATCH net-next 0/9] nfp: CRC32 RSS hash, port name reporting and misc fastpath cleanups Jakub Kicinski
                   ` (3 preceding siblings ...)
  2017-03-08 16:57 ` [PATCH net-next 4/9] nfp: move more ring debug info to debugfs Jakub Kicinski
@ 2017-03-08 16:57 ` Jakub Kicinski
  2017-03-08 16:57 ` [PATCH net-next 6/9] nfp: store device pointer for the fastpath Jakub Kicinski
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Jakub Kicinski @ 2017-03-08 16:57 UTC (permalink / raw)
  To: netdev; +Cc: oss-drivers, Jakub Kicinski

Reorder variables longest to shortest to comply with netdev coding style.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 0be47188fd36..8b5fa6fe8807 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -739,10 +739,10 @@ static int nfp_net_tx(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct nfp_net *nn = netdev_priv(netdev);
 	const struct skb_frag_struct *frag;
-	struct nfp_net_r_vector *r_vec;
 	struct nfp_net_tx_desc *txd, txdg;
-	struct nfp_net_tx_buf *txbuf;
 	struct nfp_net_tx_ring *tx_ring;
+	struct nfp_net_r_vector *r_vec;
+	struct nfp_net_tx_buf *txbuf;
 	struct netdev_queue *nd_q;
 	dma_addr_t dma_addr;
 	unsigned int fsize;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net-next 6/9] nfp: store device pointer for the fastpath
  2017-03-08 16:56 [PATCH net-next 0/9] nfp: CRC32 RSS hash, port name reporting and misc fastpath cleanups Jakub Kicinski
                   ` (4 preceding siblings ...)
  2017-03-08 16:57 ` [PATCH net-next 5/9] nfp: reorder variables in nfp_net_tx() Jakub Kicinski
@ 2017-03-08 16:57 ` Jakub Kicinski
  2017-03-08 16:57 ` [PATCH net-next 7/9] nfp: avoid rearming the interrupts when in busy poll Jakub Kicinski
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Jakub Kicinski @ 2017-03-08 16:57 UTC (permalink / raw)
  To: netdev; +Cc: oss-drivers, Jakub Kicinski

We really only need the device pointer on the fast path, stash it at
the beginning of the adapter structure and move pci_dev pointer down.
This saves up a few lines of code.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/nfp_net.h       |  6 ++-
 .../net/ethernet/netronome/nfp/nfp_net_common.c    | 51 ++++++++++------------
 drivers/net/ethernet/netronome/nfp/nfp_net_main.c  |  5 +--
 .../net/ethernet/netronome/nfp/nfp_net_offload.c   |  7 ++-
 4 files changed, 31 insertions(+), 38 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net.h b/drivers/net/ethernet/netronome/nfp/nfp_net.h
index 50413eea9540..4ad27570b6c4 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net.h
@@ -435,7 +435,7 @@ struct nfp_stat_pair {
 
 /**
  * struct nfp_net - NFP network device structure
- * @pdev:               Backpointer to PCI device
+ * @dev:		Backpointer to struct device
  * @netdev:             Backpointer to net_device structure
  * @is_vf:              Is the driver attached to a VF?
  * @bpf_offload_skip_sw:  Offloaded BPF program will not be rerun by cls_bpf
@@ -496,11 +496,12 @@ struct nfp_stat_pair {
  * @debugfs_dir:	Device directory in debugfs
  * @ethtool_dump_flag:	Ethtool dump flag
  * @port_list:		Entry on device port list
+ * @pdev:		Backpointer to PCI device
  * @cpp:		CPP device handle if available
  * @eth_port:		Translated ETH Table port entry
  */
 struct nfp_net {
-	struct pci_dev *pdev;
+	struct device *dev;
 	struct net_device *netdev;
 
 	unsigned is_vf:1;
@@ -588,6 +589,7 @@ struct nfp_net {
 
 	struct list_head port_list;
 
+	struct pci_dev *pdev;
 	struct nfp_cpp *cpp;
 
 	struct nfp_eth_table_port *eth_port;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 8b5fa6fe8807..397d9e82ed0e 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -89,7 +89,7 @@ static dma_addr_t
 nfp_net_dma_map_rx(struct nfp_net *nn, void *frag, unsigned int bufsz,
 		   int direction)
 {
-	return dma_map_single(&nn->pdev->dev, frag + NFP_NET_RX_BUF_HEADROOM,
+	return dma_map_single(nn->dev, frag + NFP_NET_RX_BUF_HEADROOM,
 			      bufsz - NFP_NET_RX_BUF_NON_DATA, direction);
 }
 
@@ -97,7 +97,7 @@ static void
 nfp_net_dma_unmap_rx(struct nfp_net *nn, dma_addr_t dma_addr,
 		     unsigned int bufsz, int direction)
 {
-	dma_unmap_single(&nn->pdev->dev, dma_addr,
+	dma_unmap_single(nn->dev, dma_addr,
 			 bufsz - NFP_NET_RX_BUF_NON_DATA, direction);
 }
 
@@ -768,9 +768,9 @@ static int nfp_net_tx(struct sk_buff *skb, struct net_device *netdev)
 	}
 
 	/* Start with the head skbuf */
-	dma_addr = dma_map_single(&nn->pdev->dev, skb->data, skb_headlen(skb),
+	dma_addr = dma_map_single(nn->dev, skb->data, skb_headlen(skb),
 				  DMA_TO_DEVICE);
-	if (dma_mapping_error(&nn->pdev->dev, dma_addr))
+	if (dma_mapping_error(nn->dev, dma_addr))
 		goto err_free;
 
 	wr_idx = tx_ring->wr_p & (tx_ring->cnt - 1);
@@ -812,9 +812,9 @@ static int nfp_net_tx(struct sk_buff *skb, struct net_device *netdev)
 			frag = &skb_shinfo(skb)->frags[f];
 			fsize = skb_frag_size(frag);
 
-			dma_addr = skb_frag_dma_map(&nn->pdev->dev, frag, 0,
+			dma_addr = skb_frag_dma_map(nn->dev, frag, 0,
 						    fsize, DMA_TO_DEVICE);
-			if (dma_mapping_error(&nn->pdev->dev, dma_addr))
+			if (dma_mapping_error(nn->dev, dma_addr))
 				goto err_unmap;
 
 			wr_idx = (wr_idx + 1) & (tx_ring->cnt - 1);
@@ -853,8 +853,7 @@ static int nfp_net_tx(struct sk_buff *skb, struct net_device *netdev)
 	--f;
 	while (f >= 0) {
 		frag = &skb_shinfo(skb)->frags[f];
-		dma_unmap_page(&nn->pdev->dev,
-			       tx_ring->txbufs[wr_idx].dma_addr,
+		dma_unmap_page(nn->dev, tx_ring->txbufs[wr_idx].dma_addr,
 			       skb_frag_size(frag), DMA_TO_DEVICE);
 		tx_ring->txbufs[wr_idx].skb = NULL;
 		tx_ring->txbufs[wr_idx].dma_addr = 0;
@@ -863,7 +862,7 @@ static int nfp_net_tx(struct sk_buff *skb, struct net_device *netdev)
 		if (wr_idx < 0)
 			wr_idx += tx_ring->cnt;
 	}
-	dma_unmap_single(&nn->pdev->dev, tx_ring->txbufs[wr_idx].dma_addr,
+	dma_unmap_single(nn->dev, tx_ring->txbufs[wr_idx].dma_addr,
 			 skb_headlen(skb), DMA_TO_DEVICE);
 	tx_ring->txbufs[wr_idx].skb = NULL;
 	tx_ring->txbufs[wr_idx].dma_addr = 0;
@@ -920,8 +919,7 @@ static void nfp_net_tx_complete(struct nfp_net_tx_ring *tx_ring)
 
 		if (fidx == -1) {
 			/* unmap head */
-			dma_unmap_single(&nn->pdev->dev,
-					 tx_ring->txbufs[idx].dma_addr,
+			dma_unmap_single(nn->dev, tx_ring->txbufs[idx].dma_addr,
 					 skb_headlen(skb), DMA_TO_DEVICE);
 
 			done_pkts += tx_ring->txbufs[idx].pkt_cnt;
@@ -929,8 +927,7 @@ static void nfp_net_tx_complete(struct nfp_net_tx_ring *tx_ring)
 		} else {
 			/* unmap fragment */
 			frag = &skb_shinfo(skb)->frags[fidx];
-			dma_unmap_page(&nn->pdev->dev,
-				       tx_ring->txbufs[idx].dma_addr,
+			dma_unmap_page(nn->dev, tx_ring->txbufs[idx].dma_addr,
 				       skb_frag_size(frag), DMA_TO_DEVICE);
 		}
 
@@ -1027,7 +1024,6 @@ nfp_net_tx_ring_reset(struct nfp_net *nn, struct nfp_net_tx_ring *tx_ring)
 {
 	struct nfp_net_r_vector *r_vec = tx_ring->r_vec;
 	const struct skb_frag_struct *frag;
-	struct pci_dev *pdev = nn->pdev;
 	struct netdev_queue *nd_q;
 
 	while (tx_ring->rd_p != tx_ring->wr_p) {
@@ -1047,13 +1043,13 @@ nfp_net_tx_ring_reset(struct nfp_net *nn, struct nfp_net_tx_ring *tx_ring)
 
 			if (tx_buf->fidx == -1) {
 				/* unmap head */
-				dma_unmap_single(&pdev->dev, tx_buf->dma_addr,
+				dma_unmap_single(nn->dev, tx_buf->dma_addr,
 						 skb_headlen(skb),
 						 DMA_TO_DEVICE);
 			} else {
 				/* unmap fragment */
 				frag = &skb_shinfo(skb)->frags[tx_buf->fidx];
-				dma_unmap_page(&pdev->dev, tx_buf->dma_addr,
+				dma_unmap_page(nn->dev, tx_buf->dma_addr,
 					       skb_frag_size(frag),
 					       DMA_TO_DEVICE);
 			}
@@ -1157,7 +1153,7 @@ nfp_net_rx_alloc_one(struct nfp_net_rx_ring *rx_ring, dma_addr_t *dma_addr,
 	direction = xdp ? DMA_BIDIRECTIONAL : DMA_FROM_DEVICE;
 
 	*dma_addr = nfp_net_dma_map_rx(nn, frag, fl_bufsz, direction);
-	if (dma_mapping_error(&nn->pdev->dev, *dma_addr)) {
+	if (dma_mapping_error(nn->dev, *dma_addr)) {
 		nfp_net_free_frag(frag, xdp);
 		nn_warn_ratelimit(nn, "Failed to map DMA RX buffer\n");
 		return NULL;
@@ -1181,7 +1177,7 @@ nfp_net_napi_alloc_one(struct nfp_net *nn, int direction, dma_addr_t *dma_addr)
 	}
 
 	*dma_addr = nfp_net_dma_map_rx(nn, frag, nn->fl_bufsz, direction);
-	if (dma_mapping_error(&nn->pdev->dev, *dma_addr)) {
+	if (dma_mapping_error(nn->dev, *dma_addr)) {
 		nfp_net_free_frag(frag, nn->xdp_prog);
 		nn_warn_ratelimit(nn, "Failed to map DMA RX buffer\n");
 		return NULL;
@@ -1499,7 +1495,7 @@ nfp_net_tx_xdp_buf(struct nfp_net *nn, struct nfp_net_rx_ring *rx_ring,
 	txbuf->pkt_cnt = 1;
 	txbuf->real_len = pkt_len;
 
-	dma_sync_single_for_device(&nn->pdev->dev, rxbuf->dma_addr + pkt_off,
+	dma_sync_single_for_device(nn->dev, rxbuf->dma_addr + pkt_off,
 				   pkt_len, DMA_BIDIRECTIONAL);
 
 	/* Build TX descriptor */
@@ -1611,7 +1607,7 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget)
 				  nn->bpf_offload_xdp)) {
 			int act;
 
-			dma_sync_single_for_cpu(&nn->pdev->dev,
+			dma_sync_single_for_cpu(nn->dev,
 						rxbuf->dma_addr + pkt_off,
 						pkt_len, DMA_BIDIRECTIONAL);
 			act = nfp_net_run_xdp(xdp_prog, rxbuf->frag + data_off,
@@ -1728,12 +1724,11 @@ static void nfp_net_tx_ring_free(struct nfp_net_tx_ring *tx_ring)
 {
 	struct nfp_net_r_vector *r_vec = tx_ring->r_vec;
 	struct nfp_net *nn = r_vec->nfp_net;
-	struct pci_dev *pdev = nn->pdev;
 
 	kfree(tx_ring->txbufs);
 
 	if (tx_ring->txds)
-		dma_free_coherent(&pdev->dev, tx_ring->size,
+		dma_free_coherent(nn->dev, tx_ring->size,
 				  tx_ring->txds, tx_ring->dma);
 
 	tx_ring->cnt = 0;
@@ -1756,13 +1751,12 @@ nfp_net_tx_ring_alloc(struct nfp_net_tx_ring *tx_ring, u32 cnt, bool is_xdp)
 {
 	struct nfp_net_r_vector *r_vec = tx_ring->r_vec;
 	struct nfp_net *nn = r_vec->nfp_net;
-	struct pci_dev *pdev = nn->pdev;
 	int sz;
 
 	tx_ring->cnt = cnt;
 
 	tx_ring->size = sizeof(*tx_ring->txds) * tx_ring->cnt;
-	tx_ring->txds = dma_zalloc_coherent(&pdev->dev, tx_ring->size,
+	tx_ring->txds = dma_zalloc_coherent(nn->dev, tx_ring->size,
 					    &tx_ring->dma, GFP_KERNEL);
 	if (!tx_ring->txds)
 		goto err_alloc;
@@ -1849,12 +1843,11 @@ static void nfp_net_rx_ring_free(struct nfp_net_rx_ring *rx_ring)
 {
 	struct nfp_net_r_vector *r_vec = rx_ring->r_vec;
 	struct nfp_net *nn = r_vec->nfp_net;
-	struct pci_dev *pdev = nn->pdev;
 
 	kfree(rx_ring->rxbufs);
 
 	if (rx_ring->rxds)
-		dma_free_coherent(&pdev->dev, rx_ring->size,
+		dma_free_coherent(nn->dev, rx_ring->size,
 				  rx_ring->rxds, rx_ring->dma);
 
 	rx_ring->cnt = 0;
@@ -1878,14 +1871,13 @@ nfp_net_rx_ring_alloc(struct nfp_net_rx_ring *rx_ring, unsigned int fl_bufsz,
 {
 	struct nfp_net_r_vector *r_vec = rx_ring->r_vec;
 	struct nfp_net *nn = r_vec->nfp_net;
-	struct pci_dev *pdev = nn->pdev;
 	int sz;
 
 	rx_ring->cnt = cnt;
 	rx_ring->bufsz = fl_bufsz;
 
 	rx_ring->size = sizeof(*rx_ring->rxds) * rx_ring->cnt;
-	rx_ring->rxds = dma_zalloc_coherent(&pdev->dev, rx_ring->size,
+	rx_ring->rxds = dma_zalloc_coherent(nn->dev, rx_ring->size,
 					    &rx_ring->dma, GFP_KERNEL);
 	if (!rx_ring->rxds)
 		goto err_alloc;
@@ -3089,6 +3081,7 @@ struct nfp_net *nfp_net_netdev_alloc(struct pci_dev *pdev,
 	nn = netdev_priv(netdev);
 
 	nn->netdev = netdev;
+	nn->dev = &pdev->dev;
 	nn->pdev = pdev;
 
 	nn->max_tx_rings = max_tx_rings;
@@ -3164,7 +3157,7 @@ static void nfp_net_rss_init(struct nfp_net *nn)
 
 	func_bit = find_first_bit(&rss_cap_hfunc, NFP_NET_CFG_RSS_HFUNCS);
 	if (func_bit == NFP_NET_CFG_RSS_HFUNCS) {
-		dev_warn(&nn->pdev->dev,
+		dev_warn(nn->dev,
 			 "Bad RSS config, defaulting to Toeplitz hash\n");
 		func_bit = ETH_RSS_HASH_TOP_BIT;
 	}
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
index f04d0b8e84ad..8a9b3f3b95a8 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
@@ -141,8 +141,7 @@ nfp_net_get_mac_addr_hwinfo(struct nfp_net *nn, struct nfp_cpp *cpp,
 
 	mac_str = nfp_hwinfo_lookup(cpp, name);
 	if (!mac_str) {
-		dev_warn(&nn->pdev->dev,
-			 "Can't lookup MAC address. Generate\n");
+		dev_warn(nn->dev, "Can't lookup MAC address. Generate\n");
 		eth_hw_addr_random(nn->netdev);
 		return;
 	}
@@ -150,7 +149,7 @@ nfp_net_get_mac_addr_hwinfo(struct nfp_net *nn, struct nfp_cpp *cpp,
 	if (sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
 		   &mac_addr[0], &mac_addr[1], &mac_addr[2],
 		   &mac_addr[3], &mac_addr[4], &mac_addr[5]) != 6) {
-		dev_warn(&nn->pdev->dev,
+		dev_warn(nn->dev,
 			 "Can't parse MAC address (%s). Generate.\n", mac_str);
 		eth_hw_addr_random(nn->netdev);
 		return;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_offload.c b/drivers/net/ethernet/netronome/nfp/nfp_net_offload.c
index 18a851eb3508..f6ed1aa9d94b 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_offload.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_offload.c
@@ -168,8 +168,7 @@ nfp_net_bpf_offload_prepare(struct nfp_net *nn,
 	start_off = nn_readw(nn, NFP_NET_CFG_BPF_START);
 	done_off = nn_readw(nn, NFP_NET_CFG_BPF_DONE);
 
-	*code = dma_zalloc_coherent(&nn->pdev->dev, code_sz, dma_addr,
-				    GFP_KERNEL);
+	*code = dma_zalloc_coherent(nn->dev, code_sz, dma_addr, GFP_KERNEL);
 	if (!*code)
 		return -ENOMEM;
 
@@ -181,7 +180,7 @@ nfp_net_bpf_offload_prepare(struct nfp_net *nn,
 	return 0;
 
 out:
-	dma_free_coherent(&nn->pdev->dev, code_sz, *code, *dma_addr);
+	dma_free_coherent(nn->dev, code_sz, *code, *dma_addr);
 	return ret;
 }
 
@@ -214,7 +213,7 @@ nfp_net_bpf_load_and_start(struct nfp_net *nn, u32 tc_flags,
 	if (err)
 		nn_err(nn, "FW command error while enabling BPF: %d\n", err);
 
-	dma_free_coherent(&nn->pdev->dev, code_sz, code, dma_addr);
+	dma_free_coherent(nn->dev, code_sz, code, dma_addr);
 
 	nfp_net_bpf_stats_reset(nn);
 	mod_timer(&nn->rx_filter_stats_timer, jiffies + NFP_NET_STAT_POLL_IVL);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net-next 7/9] nfp: avoid rearming the interrupts when in busy poll
  2017-03-08 16:56 [PATCH net-next 0/9] nfp: CRC32 RSS hash, port name reporting and misc fastpath cleanups Jakub Kicinski
                   ` (5 preceding siblings ...)
  2017-03-08 16:57 ` [PATCH net-next 6/9] nfp: store device pointer for the fastpath Jakub Kicinski
@ 2017-03-08 16:57 ` Jakub Kicinski
  2017-03-08 16:57 ` [PATCH net-next 8/9] nfp: add metadata format bit Jakub Kicinski
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Jakub Kicinski @ 2017-03-08 16:57 UTC (permalink / raw)
  To: netdev; +Cc: oss-drivers, Jakub Kicinski

Make use of return code from napi_complete_done() to avoid rearming
interrupts when busy polling is on.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 397d9e82ed0e..119775d4097e 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -1705,10 +1705,9 @@ static int nfp_net_poll(struct napi_struct *napi, int budget)
 			nfp_net_xdp_complete(r_vec->xdp_ring);
 	}
 
-	if (pkts_polled < budget) {
-		napi_complete_done(napi, pkts_polled);
-		nfp_net_irq_unmask(r_vec->nfp_net, r_vec->irq_entry);
-	}
+	if (pkts_polled < budget)
+		if (napi_complete_done(napi, pkts_polled))
+			nfp_net_irq_unmask(r_vec->nfp_net, r_vec->irq_entry);
 
 	return pkts_polled;
 }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net-next 8/9] nfp: add metadata format bit
  2017-03-08 16:56 [PATCH net-next 0/9] nfp: CRC32 RSS hash, port name reporting and misc fastpath cleanups Jakub Kicinski
                   ` (6 preceding siblings ...)
  2017-03-08 16:57 ` [PATCH net-next 7/9] nfp: avoid rearming the interrupts when in busy poll Jakub Kicinski
@ 2017-03-08 16:57 ` Jakub Kicinski
  2017-03-08 16:57 ` [PATCH net-next 9/9] nfp: prevent theoretical buffer overrun in nfp_eth_read_ports Jakub Kicinski
  2017-03-10  0:41 ` [PATCH net-next 0/9] nfp: CRC32 RSS hash, port name reporting and misc fastpath cleanups David Miller
  9 siblings, 0 replies; 11+ messages in thread
From: Jakub Kicinski @ 2017-03-08 16:57 UTC (permalink / raw)
  To: netdev; +Cc: oss-drivers, Jakub Kicinski

We only need FW version in the first cache line of adapter struct
because we need to know the metadata format.  To save space add a
metadata format bit.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/nfp_net.h        | 2 ++
 drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 4 +++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net.h b/drivers/net/ethernet/netronome/nfp/nfp_net.h
index 4ad27570b6c4..34f8c439f42f 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net.h
@@ -440,6 +440,7 @@ struct nfp_stat_pair {
  * @is_vf:              Is the driver attached to a VF?
  * @bpf_offload_skip_sw:  Offloaded BPF program will not be rerun by cls_bpf
  * @bpf_offload_xdp:	Offloaded BPF program is XDP
+ * @chained_metadata_format:  Firemware will use new metadata format
  * @ctrl:               Local copy of the control register/word.
  * @fl_bufsz:           Currently configured size of the freelist buffers
  * @rx_offset:		Offset in the RX buffers where packet data starts
@@ -507,6 +508,7 @@ struct nfp_net {
 	unsigned is_vf:1;
 	unsigned bpf_offload_skip_sw:1;
 	unsigned bpf_offload_xdp:1;
+	unsigned chained_metadata_format:1;
 
 	u32 ctrl;
 	u32 fl_bufsz;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 119775d4097e..2d964d030dbe 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -1652,7 +1652,7 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget)
 		skb_reserve(skb, data_off);
 		skb_put(skb, pkt_len);
 
-		if (nn->fw_ver.major <= 3) {
+		if (!nn->chained_metadata_format) {
 			nfp_net_set_hash_desc(nn->netdev, skb, rxd);
 		} else if (meta_len) {
 			void *end;
@@ -3196,6 +3196,8 @@ int nfp_net_netdev_init(struct net_device *netdev)
 	struct nfp_net *nn = netdev_priv(netdev);
 	int err;
 
+	nn->chained_metadata_format = nn->fw_ver.major > 3;
+
 	/* Get some of the read-only fields from the BAR */
 	nn->cap = nn_readl(nn, NFP_NET_CFG_CAP);
 	nn->max_mtu = nn_readl(nn, NFP_NET_CFG_MAX_MTU);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net-next 9/9] nfp: prevent theoretical buffer overrun in nfp_eth_read_ports
  2017-03-08 16:56 [PATCH net-next 0/9] nfp: CRC32 RSS hash, port name reporting and misc fastpath cleanups Jakub Kicinski
                   ` (7 preceding siblings ...)
  2017-03-08 16:57 ` [PATCH net-next 8/9] nfp: add metadata format bit Jakub Kicinski
@ 2017-03-08 16:57 ` Jakub Kicinski
  2017-03-10  0:41 ` [PATCH net-next 0/9] nfp: CRC32 RSS hash, port name reporting and misc fastpath cleanups David Miller
  9 siblings, 0 replies; 11+ messages in thread
From: Jakub Kicinski @ 2017-03-08 16:57 UTC (permalink / raw)
  To: netdev; +Cc: oss-drivers, Simon Horman

From: Simon Horman <simon.horman@netronome.com>

Prevent theoretical buffer overrun by returning an error if
the number of entries returned by the firmware does not match those
present.

Also use a common handling error path.

Found by inspection.

Signed-off-by: Simon Horman <simon.horman@netronome.com>
Tested-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 .../ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c   | 34 +++++++++++++---------
 1 file changed, 20 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c
index 10a0c8392d2b..38bd80077e33 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c
@@ -191,8 +191,7 @@ __nfp_eth_read_ports(struct nfp_cpp *cpp, struct nfp_nsp *nsp)
 {
 	struct eth_table_entry *entries;
 	struct nfp_eth_table *table;
-	unsigned int cnt;
-	int i, j, ret;
+	int i, j, ret, cnt = 0;
 
 	entries = kzalloc(NSP_ETH_TABLE_SIZE, GFP_KERNEL);
 	if (!entries)
@@ -201,24 +200,27 @@ __nfp_eth_read_ports(struct nfp_cpp *cpp, struct nfp_nsp *nsp)
 	ret = nfp_nsp_read_eth_table(nsp, entries, NSP_ETH_TABLE_SIZE);
 	if (ret < 0) {
 		nfp_err(cpp, "reading port table failed %d\n", ret);
-		kfree(entries);
-		return NULL;
+		goto err;
 	}
 
-	/* Some versions of flash will give us 0 instead of port count */
-	cnt = ret;
-	if (!cnt) {
-		for (i = 0; i < NSP_ETH_MAX_COUNT; i++)
-			if (entries[i].port & NSP_ETH_PORT_LANES_MASK)
-				cnt++;
+	for (i = 0; i < NSP_ETH_MAX_COUNT; i++)
+		if (entries[i].port & NSP_ETH_PORT_LANES_MASK)
+			cnt++;
+
+	/* Some versions of flash will give us 0 instead of port count.
+	 * For those that give a port count, verify it against the value
+	 * calculated above.
+	 */
+	if (ret && ret != cnt) {
+		nfp_err(cpp, "table entry count reported (%d) does not match entries present (%d)\n",
+			ret, cnt);
+		goto err;
 	}
 
 	table = kzalloc(sizeof(*table) +
 			sizeof(struct nfp_eth_table_port) * cnt, GFP_KERNEL);
-	if (!table) {
-		kfree(entries);
-		return NULL;
-	}
+	if (!table)
+		goto err;
 
 	table->count = cnt;
 	for (i = 0, j = 0; i < NSP_ETH_MAX_COUNT; i++)
@@ -231,6 +233,10 @@ __nfp_eth_read_ports(struct nfp_cpp *cpp, struct nfp_nsp *nsp)
 	kfree(entries);
 
 	return table;
+
+err:
+	kfree(entries);
+	return NULL;
 }
 
 /**
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH net-next 0/9] nfp: CRC32 RSS hash, port name reporting and misc fastpath cleanups
  2017-03-08 16:56 [PATCH net-next 0/9] nfp: CRC32 RSS hash, port name reporting and misc fastpath cleanups Jakub Kicinski
                   ` (8 preceding siblings ...)
  2017-03-08 16:57 ` [PATCH net-next 9/9] nfp: prevent theoretical buffer overrun in nfp_eth_read_ports Jakub Kicinski
@ 2017-03-10  0:41 ` David Miller
  9 siblings, 0 replies; 11+ messages in thread
From: David Miller @ 2017-03-10  0:41 UTC (permalink / raw)
  To: jakub.kicinski; +Cc: netdev, oss-drivers

From: Jakub Kicinski <jakub.kicinski@netronome.com>
Date: Wed,  8 Mar 2017 08:56:59 -0800

> This series adds support for CRC32 RSS hash function to kernel API
> of which NFP driver immediately makes use.  There is also a
> .ndo_get_phys_port_name() implementation conforming to switchdev 
> name format.  Small patch takes advantage of napi_complete_done()'s
> return code.  Simon provides a fix for potentially trusting values 
> returned from FW too much.
> 
> A handful of unassuming fast path adjustments is also thrown in to make
> the upcoming xdp_adjust_head() series easier to review.

Series applied, thanks.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2017-03-10  0:41 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-08 16:56 [PATCH net-next 0/9] nfp: CRC32 RSS hash, port name reporting and misc fastpath cleanups Jakub Kicinski
2017-03-08 16:57 ` [PATCH net-next 1/9] ethtool: add CRC32 as an RSS hash function Jakub Kicinski
2017-03-08 16:57 ` [PATCH net-next 2/9] nfp: add support for reporting CRC32 " Jakub Kicinski
2017-03-08 16:57 ` [PATCH net-next 3/9] nfp: implement .ndo_get_phys_port_name() Jakub Kicinski
2017-03-08 16:57 ` [PATCH net-next 4/9] nfp: move more ring debug info to debugfs Jakub Kicinski
2017-03-08 16:57 ` [PATCH net-next 5/9] nfp: reorder variables in nfp_net_tx() Jakub Kicinski
2017-03-08 16:57 ` [PATCH net-next 6/9] nfp: store device pointer for the fastpath Jakub Kicinski
2017-03-08 16:57 ` [PATCH net-next 7/9] nfp: avoid rearming the interrupts when in busy poll Jakub Kicinski
2017-03-08 16:57 ` [PATCH net-next 8/9] nfp: add metadata format bit Jakub Kicinski
2017-03-08 16:57 ` [PATCH net-next 9/9] nfp: prevent theoretical buffer overrun in nfp_eth_read_ports Jakub Kicinski
2017-03-10  0:41 ` [PATCH net-next 0/9] nfp: CRC32 RSS hash, port name reporting and misc fastpath cleanups David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.