netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next-2.6 0/8] sfc and ethtool changes for 2.6.37
@ 2010-09-20 18:40 Ben Hutchings
  2010-09-20 18:41 ` [PATCH net-next-2.6 1/8] ethtool: Define RX n-tuple action to clear a rule Ben Hutchings
                   ` (8 more replies)
  0 siblings, 9 replies; 19+ messages in thread
From: Ben Hutchings @ 2010-09-20 18:40 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers

This series adds Ethernet-level filtering and explicit filter clearing
to the ethtool RX n-tuple interface, and implements it in the sfc
driver.

There is a cleanup patch on the end which is preparation for the
following RFC patch series but is worthwhile anyway.

Ben.

Ben Hutchings (8):
  ethtool: Define RX n-tuple action to clear a rule
  ethtool: Add Ethernet MAC-level filtering/steering
  ethtool: Allocate register dump buffer with vmalloc()
  sfc: Add filter table management
  sfc: Implement the ethtool RX n-tuple control functions
  sfc: Include RX IP filter table in register dump
  sfc: Set net_device::num_rx_queues once we know the correct value
  sfc: Clean up and correct comments on efx_monitor()

 drivers/net/sfc/Makefile     |    2 +-
 drivers/net/sfc/efx.c        |   35 ++--
 drivers/net/sfc/efx.h        |   14 ++
 drivers/net/sfc/ethtool.c    |  118 +++++++++++-
 drivers/net/sfc/falcon.c     |    2 +-
 drivers/net/sfc/filter.c     |  445 ++++++++++++++++++++++++++++++++++++++++++
 drivers/net/sfc/filter.h     |  189 ++++++++++++++++++
 drivers/net/sfc/net_driver.h |    4 +
 drivers/net/sfc/nic.c        |    5 +-
 drivers/net/sfc/regs.h       |   14 ++
 drivers/net/sfc/siena.c      |    2 +-
 include/linux/ethtool.h      |   11 +-
 net/core/ethtool.c           |    4 +-
 13 files changed, 819 insertions(+), 26 deletions(-)
 create mode 100644 drivers/net/sfc/filter.c
 create mode 100644 drivers/net/sfc/filter.h

-- 
1.7.2.1


-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


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

* [PATCH net-next-2.6 1/8] ethtool: Define RX n-tuple action to clear a rule
  2010-09-20 18:40 [PATCH net-next-2.6 0/8] sfc and ethtool changes for 2.6.37 Ben Hutchings
@ 2010-09-20 18:41 ` Ben Hutchings
  2010-09-20 18:42 ` [PATCH net-next-2.6 2/8] ethtool: Add Ethernet MAC-level filtering/steering Ben Hutchings
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 19+ messages in thread
From: Ben Hutchings @ 2010-09-20 18:41 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 include/linux/ethtool.h |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index b67af60..3350870 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -492,11 +492,12 @@ struct ethtool_rx_ntuple_flow_spec {
 	__u64		data_mask;
 
 	__s32		action;
-#define ETHTOOL_RXNTUPLE_ACTION_DROP -1		/* drop packet */
+#define ETHTOOL_RXNTUPLE_ACTION_DROP	(-1)	/* drop packet */
+#define ETHTOOL_RXNTUPLE_ACTION_CLEAR	(-2)	/* clear filter */
 };
 
 /**
- * struct ethtool_rx_ntuple - command to set RX flow filter
+ * struct ethtool_rx_ntuple - command to set or clear RX flow filter
  * @cmd: Command number - %ETHTOOL_SRXNTUPLE
  * @fs: Flow filter specification
  */
-- 
1.7.2.1



-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


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

* [PATCH net-next-2.6 2/8] ethtool: Add Ethernet MAC-level filtering/steering
  2010-09-20 18:40 [PATCH net-next-2.6 0/8] sfc and ethtool changes for 2.6.37 Ben Hutchings
  2010-09-20 18:41 ` [PATCH net-next-2.6 1/8] ethtool: Define RX n-tuple action to clear a rule Ben Hutchings
@ 2010-09-20 18:42 ` Ben Hutchings
  2010-09-20 18:42 ` [PATCH net-next-2.6 3/8] ethtool: Allocate register dump buffer with vmalloc() Ben Hutchings
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 19+ messages in thread
From: Ben Hutchings @ 2010-09-20 18:42 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 include/linux/ethtool.h |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 3350870..8a3338c 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -14,6 +14,7 @@
 #define _LINUX_ETHTOOL_H
 
 #include <linux/types.h>
+#include <linux/if_ether.h>
 
 /* This should work for both 32 and 64 bit userland. */
 struct ethtool_cmd {
@@ -391,6 +392,7 @@ struct ethtool_rx_flow_spec {
 		struct ethtool_ah_espip4_spec		ah_ip4_spec;
 		struct ethtool_ah_espip4_spec		esp_ip4_spec;
 		struct ethtool_usrip4_spec		usr_ip4_spec;
+		struct ethhdr				ether_spec;
 		__u8					hdata[72];
 	} h_u, m_u;
 	__u64		ring_cookie;
@@ -483,6 +485,7 @@ struct ethtool_rx_ntuple_flow_spec {
 		struct ethtool_ah_espip4_spec		ah_ip4_spec;
 		struct ethtool_ah_espip4_spec		esp_ip4_spec;
 		struct ethtool_usrip4_spec		usr_ip4_spec;
+		struct ethhdr				ether_spec;
 		__u8					hdata[72];
 	} h_u, m_u;
 
@@ -841,7 +844,7 @@ struct ethtool_ops {
 #define WAKE_MAGIC		(1 << 5)
 #define WAKE_MAGICSECURE	(1 << 6) /* only meaningful if WAKE_MAGIC */
 
-/* L3-L4 network traffic flow types */
+/* L2-L4 network traffic flow types */
 #define	TCP_V4_FLOW	0x01	/* hash or spec (tcp_ip4_spec) */
 #define	UDP_V4_FLOW	0x02	/* hash or spec (udp_ip4_spec) */
 #define	SCTP_V4_FLOW	0x03	/* hash or spec (sctp_ip4_spec) */
@@ -857,6 +860,7 @@ struct ethtool_ops {
 #define	IP_USER_FLOW	0x0d	/* spec only (usr_ip4_spec) */
 #define	IPV4_FLOW	0x10	/* hash only */
 #define	IPV6_FLOW	0x11	/* hash only */
+#define	ETHER_FLOW	0x12	/* spec only (ether_spec) */
 
 /* L3-L4 network traffic flow hash options */
 #define	RXH_L2DA	(1 << 1)
-- 
1.7.2.1



-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


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

* [PATCH net-next-2.6 3/8] ethtool: Allocate register dump buffer with vmalloc()
  2010-09-20 18:40 [PATCH net-next-2.6 0/8] sfc and ethtool changes for 2.6.37 Ben Hutchings
  2010-09-20 18:41 ` [PATCH net-next-2.6 1/8] ethtool: Define RX n-tuple action to clear a rule Ben Hutchings
  2010-09-20 18:42 ` [PATCH net-next-2.6 2/8] ethtool: Add Ethernet MAC-level filtering/steering Ben Hutchings
@ 2010-09-20 18:42 ` Ben Hutchings
  2010-09-20 18:43 ` [PATCH net-next-2.6 4/8] sfc: Add filter table management Ben Hutchings
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 19+ messages in thread
From: Ben Hutchings @ 2010-09-20 18:42 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers

Some NICs have huge register files which exceed the maximum heap
allocation size.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 net/core/ethtool.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 91ffce2..dae2fd0 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -815,7 +815,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
 	if (regs.len > reglen)
 		regs.len = reglen;
 
-	regbuf = kmalloc(reglen, GFP_USER);
+	regbuf = vmalloc(reglen);
 	if (!regbuf)
 		return -ENOMEM;
 
@@ -830,7 +830,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
 	ret = 0;
 
  out:
-	kfree(regbuf);
+	vfree(regbuf);
 	return ret;
 }
 
-- 
1.7.2.1



-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


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

* [PATCH net-next-2.6 4/8] sfc: Add filter table management
  2010-09-20 18:40 [PATCH net-next-2.6 0/8] sfc and ethtool changes for 2.6.37 Ben Hutchings
                   ` (2 preceding siblings ...)
  2010-09-20 18:42 ` [PATCH net-next-2.6 3/8] ethtool: Allocate register dump buffer with vmalloc() Ben Hutchings
@ 2010-09-20 18:43 ` Ben Hutchings
  2010-09-20 18:43 ` [PATCH net-next-2.6 5/8] sfc: Implement the ethtool RX n-tuple control functions Ben Hutchings
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 19+ messages in thread
From: Ben Hutchings @ 2010-09-20 18:43 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/Makefile     |    2 +-
 drivers/net/sfc/efx.c        |   11 +
 drivers/net/sfc/efx.h        |   14 ++
 drivers/net/sfc/filter.c     |  445 ++++++++++++++++++++++++++++++++++++++++++
 drivers/net/sfc/filter.h     |  189 ++++++++++++++++++
 drivers/net/sfc/net_driver.h |    4 +
 drivers/net/sfc/regs.h       |   14 ++
 7 files changed, 678 insertions(+), 1 deletions(-)
 create mode 100644 drivers/net/sfc/filter.c
 create mode 100644 drivers/net/sfc/filter.h

diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile
index 1047b19..fd9272b 100644
--- a/drivers/net/sfc/Makefile
+++ b/drivers/net/sfc/Makefile
@@ -1,4 +1,4 @@
-sfc-y			+= efx.o nic.o falcon.o siena.o tx.o rx.o \
+sfc-y			+= efx.o nic.o falcon.o siena.o tx.o rx.o filter.o \
 			   falcon_gmac.o falcon_xmac.o mcdi_mac.o \
 			   selftest.o ethtool.o qt202x_phy.o mdio_10g.o \
 			   tenxpress.o falcon_boards.o mcdi.o mcdi_phy.o
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index f702f1f..4a1c93f 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -1357,8 +1357,17 @@ static int efx_probe_all(struct efx_nic *efx)
 	if (rc)
 		goto fail3;
 
+	rc = efx_probe_filters(efx);
+	if (rc) {
+		netif_err(efx, probe, efx->net_dev,
+			  "failed to create filter tables\n");
+		goto fail4;
+	}
+
 	return 0;
 
+ fail4:
+	efx_remove_channels(efx);
  fail3:
 	efx_remove_port(efx);
  fail2:
@@ -1489,6 +1498,7 @@ static void efx_stop_all(struct efx_nic *efx)
 
 static void efx_remove_all(struct efx_nic *efx)
 {
+	efx_remove_filters(efx);
 	efx_remove_channels(efx);
 	efx_remove_port(efx);
 	efx_remove_nic(efx);
@@ -2002,6 +2012,7 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
 	efx->mac_op->reconfigure(efx);
 
 	efx_init_channels(efx);
+	efx_restore_filters(efx);
 
 	mutex_unlock(&efx->spi_lock);
 	mutex_unlock(&efx->mac_lock);
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index e783c0f..f502b14 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -12,6 +12,7 @@
 #define EFX_EFX_H
 
 #include "net_driver.h"
+#include "filter.h"
 
 /* PCI IDs */
 #define EFX_VENDID_SFC	        0x1924
@@ -64,6 +65,19 @@ extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue);
  * skb. Falcon/A1 may require up to three descriptors per skb_frag. */
 #define EFX_MIN_RING_SIZE (roundup_pow_of_two(2 * 3 * MAX_SKB_FRAGS))
 
+/* Filters */
+extern int efx_probe_filters(struct efx_nic *efx);
+extern void efx_restore_filters(struct efx_nic *efx);
+extern void efx_remove_filters(struct efx_nic *efx);
+extern int efx_filter_insert_filter(struct efx_nic *efx,
+				    struct efx_filter_spec *spec,
+				    bool replace);
+extern int efx_filter_remove_filter(struct efx_nic *efx,
+				    struct efx_filter_spec *spec);
+extern void efx_filter_table_clear(struct efx_nic *efx,
+				   enum efx_filter_table_id table_id,
+				   enum efx_filter_priority priority);
+
 /* Channels */
 extern void efx_process_channel_now(struct efx_channel *channel);
 extern int
diff --git a/drivers/net/sfc/filter.c b/drivers/net/sfc/filter.c
new file mode 100644
index 0000000..abc884d
--- /dev/null
+++ b/drivers/net/sfc/filter.c
@@ -0,0 +1,445 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2005-2010 Solarflare Communications Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#include "efx.h"
+#include "filter.h"
+#include "io.h"
+#include "nic.h"
+#include "regs.h"
+
+/* "Fudge factors" - difference between programmed value and actual depth.
+ * Due to pipelined implementation we need to program H/W with a value that
+ * is larger than the hop limit we want.
+ */
+#define FILTER_CTL_SRCH_FUDGE_WILD 3
+#define FILTER_CTL_SRCH_FUDGE_FULL 1
+
+struct efx_filter_table {
+	u32		offset;		/* address of table relative to BAR */
+	unsigned	size;		/* number of entries */
+	unsigned	step;		/* step between entries */
+	unsigned	used;		/* number currently used */
+	unsigned long	*used_bitmap;
+	struct efx_filter_spec *spec;
+};
+
+struct efx_filter_state {
+	spinlock_t	lock;
+	struct efx_filter_table table[EFX_FILTER_TABLE_COUNT];
+	unsigned	search_depth[EFX_FILTER_TYPE_COUNT];
+};
+
+/* The filter hash function is LFSR polynomial x^16 + x^3 + 1 of a 32-bit
+ * key derived from the n-tuple.  The initial LFSR state is 0xffff. */
+static u16 efx_filter_hash(u32 key)
+{
+	u16 tmp;
+
+	/* First 16 rounds */
+	tmp = 0x1fff ^ key >> 16;
+	tmp = tmp ^ tmp >> 3 ^ tmp >> 6;
+	tmp = tmp ^ tmp >> 9;
+	/* Last 16 rounds */
+	tmp = tmp ^ tmp << 13 ^ key;
+	tmp = tmp ^ tmp >> 3 ^ tmp >> 6;
+	return tmp ^ tmp >> 9;
+}
+
+/* To allow for hash collisions, filter search continues at these
+ * increments from the first possible entry selected by the hash. */
+static u16 efx_filter_increment(u32 key)
+{
+	return key * 2 - 1;
+}
+
+static enum efx_filter_table_id
+efx_filter_type_table_id(enum efx_filter_type type)
+{
+	BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_TCP_FULL >> 2));
+	BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_TCP_WILD >> 2));
+	BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_UDP_FULL >> 2));
+	BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_UDP_WILD >> 2));
+	BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_RX_MAC_FULL >> 2));
+	BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_RX_MAC_WILD >> 2));
+	return type >> 2;
+}
+
+static void
+efx_filter_table_reset_search_depth(struct efx_filter_state *state,
+				    enum efx_filter_table_id table_id)
+{
+	memset(state->search_depth + (table_id << 2), 0,
+	       sizeof(state->search_depth[0]) << 2);
+}
+
+static void efx_filter_push_rx_limits(struct efx_nic *efx)
+{
+	struct efx_filter_state *state = efx->filter_state;
+	efx_oword_t filter_ctl;
+
+	efx_reado(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL);
+
+	EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_FULL_SRCH_LIMIT,
+			    state->search_depth[EFX_FILTER_RX_TCP_FULL] +
+			    FILTER_CTL_SRCH_FUDGE_FULL);
+	EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_WILD_SRCH_LIMIT,
+			    state->search_depth[EFX_FILTER_RX_TCP_WILD] +
+			    FILTER_CTL_SRCH_FUDGE_WILD);
+	EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_FULL_SRCH_LIMIT,
+			    state->search_depth[EFX_FILTER_RX_UDP_FULL] +
+			    FILTER_CTL_SRCH_FUDGE_FULL);
+	EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_WILD_SRCH_LIMIT,
+			    state->search_depth[EFX_FILTER_RX_UDP_WILD] +
+			    FILTER_CTL_SRCH_FUDGE_WILD);
+
+	if (state->table[EFX_FILTER_TABLE_RX_MAC].size) {
+		EFX_SET_OWORD_FIELD(
+			filter_ctl, FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT,
+			state->search_depth[EFX_FILTER_RX_MAC_FULL] +
+			FILTER_CTL_SRCH_FUDGE_FULL);
+		EFX_SET_OWORD_FIELD(
+			filter_ctl, FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT,
+			state->search_depth[EFX_FILTER_RX_MAC_WILD] +
+			FILTER_CTL_SRCH_FUDGE_WILD);
+	}
+
+	efx_writeo(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL);
+}
+
+/* Build a filter entry and return its n-tuple key. */
+static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec)
+{
+	u32 data3;
+
+	switch (efx_filter_type_table_id(spec->type)) {
+	case EFX_FILTER_TABLE_RX_IP: {
+		bool is_udp = (spec->type == EFX_FILTER_RX_UDP_FULL ||
+			       spec->type == EFX_FILTER_RX_UDP_WILD);
+		EFX_POPULATE_OWORD_7(
+			*filter,
+			FRF_BZ_RSS_EN,
+			!!(spec->flags & EFX_FILTER_FLAG_RX_RSS),
+			FRF_BZ_SCATTER_EN,
+			!!(spec->flags & EFX_FILTER_FLAG_RX_SCATTER),
+			FRF_BZ_TCP_UDP, is_udp,
+			FRF_BZ_RXQ_ID, spec->dmaq_id,
+			EFX_DWORD_2, spec->data[2],
+			EFX_DWORD_1, spec->data[1],
+			EFX_DWORD_0, spec->data[0]);
+		data3 = is_udp;
+		break;
+	}
+
+	case EFX_FILTER_TABLE_RX_MAC: {
+		bool is_wild = spec->type == EFX_FILTER_RX_MAC_WILD;
+		EFX_POPULATE_OWORD_8(
+			*filter,
+			FRF_CZ_RMFT_RSS_EN,
+			!!(spec->flags & EFX_FILTER_FLAG_RX_RSS),
+			FRF_CZ_RMFT_SCATTER_EN,
+			!!(spec->flags & EFX_FILTER_FLAG_RX_SCATTER),
+			FRF_CZ_RMFT_IP_OVERRIDE,
+			!!(spec->flags & EFX_FILTER_FLAG_RX_OVERRIDE_IP),
+			FRF_CZ_RMFT_RXQ_ID, spec->dmaq_id,
+			FRF_CZ_RMFT_WILDCARD_MATCH, is_wild,
+			FRF_CZ_RMFT_DEST_MAC_HI, spec->data[2],
+			FRF_CZ_RMFT_DEST_MAC_LO, spec->data[1],
+			FRF_CZ_RMFT_VLAN_ID, spec->data[0]);
+		data3 = is_wild;
+		break;
+	}
+
+	default:
+		BUG();
+	}
+
+	return spec->data[0] ^ spec->data[1] ^ spec->data[2] ^ data3;
+}
+
+static bool efx_filter_equal(const struct efx_filter_spec *left,
+			     const struct efx_filter_spec *right)
+{
+	if (left->type != right->type ||
+	    memcmp(left->data, right->data, sizeof(left->data)))
+		return false;
+
+	return true;
+}
+
+static int efx_filter_search(struct efx_filter_table *table,
+			     struct efx_filter_spec *spec, u32 key,
+			     bool for_insert, int *depth_required)
+{
+	unsigned hash, incr, filter_idx, depth;
+	struct efx_filter_spec *cmp;
+
+	hash = efx_filter_hash(key);
+	incr = efx_filter_increment(key);
+
+	for (depth = 1, filter_idx = hash & (table->size - 1);
+	     test_bit(filter_idx, table->used_bitmap);
+	     ++depth) {
+		cmp = &table->spec[filter_idx];
+		if (efx_filter_equal(spec, cmp))
+			goto found;
+		filter_idx = (filter_idx + incr) & (table->size - 1);
+	}
+	if (!for_insert)
+		return -ENOENT;
+found:
+	*depth_required = depth;
+	return filter_idx;
+}
+
+/**
+ * efx_filter_insert_filter - add or replace a filter
+ * @efx: NIC in which to insert the filter
+ * @spec: Specification for the filter
+ * @replace: Flag for whether the specified filter may replace a filter
+ *	with an identical match expression and equal or lower priority
+ *
+ * On success, return the filter index within its table.
+ * On failure, return a negative error code.
+ */
+int efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec,
+			     bool replace)
+{
+	struct efx_filter_state *state = efx->filter_state;
+	enum efx_filter_table_id table_id =
+		efx_filter_type_table_id(spec->type);
+	struct efx_filter_table *table = &state->table[table_id];
+	struct efx_filter_spec *saved_spec;
+	efx_oword_t filter;
+	int filter_idx, depth;
+	u32 key;
+	int rc;
+
+	if (table->size == 0)
+		return -EINVAL;
+
+	key = efx_filter_build(&filter, spec);
+
+	netif_vdbg(efx, hw, efx->net_dev,
+		   "%s: type %d search_depth=%d", __func__, spec->type,
+		   state->search_depth[spec->type]);
+
+	spin_lock_bh(&state->lock);
+
+	rc = efx_filter_search(table, spec, key, true, &depth);
+	if (rc < 0)
+		goto out;
+	filter_idx = rc;
+	BUG_ON(filter_idx >= table->size);
+	saved_spec = &table->spec[filter_idx];
+
+	if (test_bit(filter_idx, table->used_bitmap)) {
+		/* Should we replace the existing filter? */
+		if (!replace) {
+			rc = -EEXIST;
+			goto out;
+		}
+		if (spec->priority < saved_spec->priority) {
+			rc = -EPERM;
+			goto out;
+		}
+	} else {
+		__set_bit(filter_idx, table->used_bitmap);
+		++table->used;
+	}
+	*saved_spec = *spec;
+
+	if (state->search_depth[spec->type] < depth) {
+		state->search_depth[spec->type] = depth;
+		efx_filter_push_rx_limits(efx);
+	}
+
+	efx_writeo(efx, &filter, table->offset + table->step * filter_idx);
+
+	netif_vdbg(efx, hw, efx->net_dev,
+		   "%s: filter type %d index %d rxq %u set",
+		   __func__, spec->type, filter_idx, spec->dmaq_id);
+
+out:
+	spin_unlock_bh(&state->lock);
+	return rc;
+}
+
+static void efx_filter_table_clear_entry(struct efx_nic *efx,
+					 struct efx_filter_table *table,
+					 int filter_idx)
+{
+	static efx_oword_t filter;
+
+	if (test_bit(filter_idx, table->used_bitmap)) {
+		__clear_bit(filter_idx, table->used_bitmap);
+		--table->used;
+		memset(&table->spec[filter_idx], 0, sizeof(table->spec[0]));
+
+		efx_writeo(efx, &filter,
+			   table->offset + table->step * filter_idx);
+	}
+}
+
+/**
+ * efx_filter_remove_filter - remove a filter by specification
+ * @efx: NIC from which to remove the filter
+ * @spec: Specification for the filter
+ *
+ * On success, return zero.
+ * On failure, return a negative error code.
+ */
+int efx_filter_remove_filter(struct efx_nic *efx, struct efx_filter_spec *spec)
+{
+	struct efx_filter_state *state = efx->filter_state;
+	enum efx_filter_table_id table_id =
+		efx_filter_type_table_id(spec->type);
+	struct efx_filter_table *table = &state->table[table_id];
+	struct efx_filter_spec *saved_spec;
+	efx_oword_t filter;
+	int filter_idx, depth;
+	u32 key;
+	int rc;
+
+	key = efx_filter_build(&filter, spec);
+
+	spin_lock_bh(&state->lock);
+
+	rc = efx_filter_search(table, spec, key, false, &depth);
+	if (rc < 0)
+		goto out;
+	filter_idx = rc;
+	saved_spec = &table->spec[filter_idx];
+
+	if (spec->priority < saved_spec->priority) {
+		rc = -EPERM;
+		goto out;
+	}
+
+	efx_filter_table_clear_entry(efx, table, filter_idx);
+	if (table->used == 0)
+		efx_filter_table_reset_search_depth(state, table_id);
+	rc = 0;
+
+out:
+	spin_unlock_bh(&state->lock);
+	return rc;
+}
+
+/**
+ * efx_filter_table_clear - remove filters from a table by priority
+ * @efx: NIC from which to remove the filters
+ * @table_id: Table from which to remove the filters
+ * @priority: Maximum priority to remove
+ */
+void efx_filter_table_clear(struct efx_nic *efx,
+			    enum efx_filter_table_id table_id,
+			    enum efx_filter_priority priority)
+{
+	struct efx_filter_state *state = efx->filter_state;
+	struct efx_filter_table *table = &state->table[table_id];
+	int filter_idx;
+
+	spin_lock_bh(&state->lock);
+
+	for (filter_idx = 0; filter_idx < table->size; ++filter_idx)
+		if (table->spec[filter_idx].priority <= priority)
+			efx_filter_table_clear_entry(efx, table, filter_idx);
+	if (table->used == 0)
+		efx_filter_table_reset_search_depth(state, table_id);
+
+	spin_unlock_bh(&state->lock);
+}
+
+/* Restore filter stater after reset */
+void efx_restore_filters(struct efx_nic *efx)
+{
+	struct efx_filter_state *state = efx->filter_state;
+	enum efx_filter_table_id table_id;
+	struct efx_filter_table *table;
+	efx_oword_t filter;
+	int filter_idx;
+
+	spin_lock_bh(&state->lock);
+
+	for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) {
+		table = &state->table[table_id];
+		for (filter_idx = 0; filter_idx < table->size; filter_idx++) {
+			if (!test_bit(filter_idx, table->used_bitmap))
+				continue;
+			efx_filter_build(&filter, &table->spec[filter_idx]);
+			efx_writeo(efx, &filter,
+				   table->offset + table->step * filter_idx);
+		}
+	}
+
+	efx_filter_push_rx_limits(efx);
+
+	spin_unlock_bh(&state->lock);
+}
+
+int efx_probe_filters(struct efx_nic *efx)
+{
+	struct efx_filter_state *state;
+	struct efx_filter_table *table;
+	unsigned table_id;
+
+	state = kzalloc(sizeof(*efx->filter_state), GFP_KERNEL);
+	if (!state)
+		return -ENOMEM;
+	efx->filter_state = state;
+
+	spin_lock_init(&state->lock);
+
+	if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) {
+		table = &state->table[EFX_FILTER_TABLE_RX_IP];
+		table->offset = FR_BZ_RX_FILTER_TBL0;
+		table->size = FR_BZ_RX_FILTER_TBL0_ROWS;
+		table->step = FR_BZ_RX_FILTER_TBL0_STEP;
+	}
+
+	if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0) {
+		table = &state->table[EFX_FILTER_TABLE_RX_MAC];
+		table->offset = FR_CZ_RX_MAC_FILTER_TBL0;
+		table->size = FR_CZ_RX_MAC_FILTER_TBL0_ROWS;
+		table->step = FR_CZ_RX_MAC_FILTER_TBL0_STEP;
+	}
+
+	for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) {
+		table = &state->table[table_id];
+		if (table->size == 0)
+			continue;
+		table->used_bitmap = kcalloc(BITS_TO_LONGS(table->size),
+					     sizeof(unsigned long),
+					     GFP_KERNEL);
+		if (!table->used_bitmap)
+			goto fail;
+		table->spec = vmalloc(table->size * sizeof(*table->spec));
+		if (!table->spec)
+			goto fail;
+		memset(table->spec, 0, table->size * sizeof(*table->spec));
+	}
+
+	return 0;
+
+fail:
+	efx_remove_filters(efx);
+	return -ENOMEM;
+}
+
+void efx_remove_filters(struct efx_nic *efx)
+{
+	struct efx_filter_state *state = efx->filter_state;
+	enum efx_filter_table_id table_id;
+
+	for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) {
+		kfree(state->table[table_id].used_bitmap);
+		vfree(state->table[table_id].spec);
+	}
+	kfree(state);
+}
diff --git a/drivers/net/sfc/filter.h b/drivers/net/sfc/filter.h
new file mode 100644
index 0000000..a53319d
--- /dev/null
+++ b/drivers/net/sfc/filter.h
@@ -0,0 +1,189 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2005-2010 Solarflare Communications Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#ifndef EFX_FILTER_H
+#define EFX_FILTER_H
+
+#include <linux/types.h>
+
+enum efx_filter_table_id {
+	EFX_FILTER_TABLE_RX_IP = 0,
+	EFX_FILTER_TABLE_RX_MAC,
+	EFX_FILTER_TABLE_COUNT,
+};
+
+/**
+ * enum efx_filter_type - type of hardware filter
+ * @EFX_FILTER_RX_TCP_FULL: RX, matching TCP/IPv4 4-tuple
+ * @EFX_FILTER_RX_TCP_WILD: RX, matching TCP/IPv4 destination (host, port)
+ * @EFX_FILTER_RX_UDP_FULL: RX, matching UDP/IPv4 4-tuple
+ * @EFX_FILTER_RX_UDP_WILD: RX, matching UDP/IPv4 destination (host, port)
+ * @EFX_FILTER_RX_MAC_FULL: RX, matching Ethernet destination MAC address, VID
+ * @EFX_FILTER_RX_MAC_WILD: RX, matching Ethernet destination MAC address
+ *
+ * Falcon NICs only support the RX TCP/IPv4 and UDP/IPv4 filter types.
+ */
+enum efx_filter_type {
+	EFX_FILTER_RX_TCP_FULL = 0,
+	EFX_FILTER_RX_TCP_WILD,
+	EFX_FILTER_RX_UDP_FULL,
+	EFX_FILTER_RX_UDP_WILD,
+	EFX_FILTER_RX_MAC_FULL = 4,
+	EFX_FILTER_RX_MAC_WILD,
+	EFX_FILTER_TYPE_COUNT,
+};
+
+/**
+ * enum efx_filter_priority - priority of a hardware filter specification
+ * @EFX_FILTER_PRI_HINT: Performance hint
+ * @EFX_FILTER_PRI_MANUAL: Manually configured filter
+ * @EFX_FILTER_PRI_REQUIRED: Required for correct behaviour
+ */
+enum efx_filter_priority {
+	EFX_FILTER_PRI_HINT = 0,
+	EFX_FILTER_PRI_MANUAL,
+	EFX_FILTER_PRI_REQUIRED,
+};
+
+/**
+ * enum efx_filter_flags - flags for hardware filter specifications
+ * @EFX_FILTER_FLAG_RX_RSS: Use RSS to spread across multiple queues.
+ *	By default, matching packets will be delivered only to the
+ *	specified queue. If this flag is set, they will be delivered
+ *	to a range of queues offset from the specified queue number
+ *	according to the indirection table.
+ * @EFX_FILTER_FLAG_RX_SCATTER: Enable DMA scatter on the receiving
+ *	queue.
+ * @EFX_FILTER_FLAG_RX_OVERRIDE_IP: Enables a MAC filter to override
+ *	any IP filter that matches the same packet.  By default, IP
+ *	filters take precedence.
+ *
+ * Currently, no flags are defined for TX filters.
+ */
+enum efx_filter_flags {
+	EFX_FILTER_FLAG_RX_RSS = 0x01,
+	EFX_FILTER_FLAG_RX_SCATTER = 0x02,
+	EFX_FILTER_FLAG_RX_OVERRIDE_IP = 0x04,
+};
+
+/**
+ * struct efx_filter_spec - specification for a hardware filter
+ * @type: Type of match to be performed, from &enum efx_filter_type
+ * @priority: Priority of the filter, from &enum efx_filter_priority
+ * @flags: Miscellaneous flags, from &enum efx_filter_flags
+ * @dmaq_id: Source/target queue index
+ * @data: Match data (type-dependent)
+ *
+ * Use the efx_filter_set_*() functions to initialise the @type and
+ * @data fields.
+ */
+struct efx_filter_spec {
+	u8	type:4;
+	u8	priority:4;
+	u8	flags;
+	u16	dmaq_id;
+	u32	data[3];
+};
+
+/**
+ * efx_filter_set_rx_tcp_full - specify RX filter with TCP/IPv4 full match
+ * @spec: Specification to initialise
+ * @shost: Source host address (host byte order)
+ * @sport: Source port (host byte order)
+ * @dhost: Destination host address (host byte order)
+ * @dport: Destination port (host byte order)
+ */
+static inline void
+efx_filter_set_rx_tcp_full(struct efx_filter_spec *spec,
+			   u32 shost, u16 sport, u32 dhost, u16 dport)
+{
+	spec->type = EFX_FILTER_RX_TCP_FULL;
+	spec->data[0] = sport | shost << 16;
+	spec->data[1] = dport << 16 | shost >> 16;
+	spec->data[2] = dhost;
+}
+
+/**
+ * efx_filter_set_rx_tcp_wild - specify RX filter with TCP/IPv4 wildcard match
+ * @spec: Specification to initialise
+ * @dhost: Destination host address (host byte order)
+ * @dport: Destination port (host byte order)
+ */
+static inline void
+efx_filter_set_rx_tcp_wild(struct efx_filter_spec *spec, u32 dhost, u16 dport)
+{
+	spec->type = EFX_FILTER_RX_TCP_WILD;
+	spec->data[0] = 0;
+	spec->data[1] = dport << 16;
+	spec->data[2] = dhost;
+}
+
+/**
+ * efx_filter_set_rx_udp_full - specify RX filter with UDP/IPv4 full match
+ * @spec: Specification to initialise
+ * @shost: Source host address (host byte order)
+ * @sport: Source port (host byte order)
+ * @dhost: Destination host address (host byte order)
+ * @dport: Destination port (host byte order)
+ */
+static inline void
+efx_filter_set_rx_udp_full(struct efx_filter_spec *spec,
+			   u32 shost, u16 sport, u32 dhost, u16 dport)
+{
+	spec->type = EFX_FILTER_RX_UDP_FULL;
+	spec->data[0] = sport | shost << 16;
+	spec->data[1] = dport << 16 | shost >> 16;
+	spec->data[2] = dhost;
+}
+
+/**
+ * efx_filter_set_rx_udp_wild - specify RX filter with UDP/IPv4 wildcard match
+ * @spec: Specification to initialise
+ * @dhost: Destination host address (host byte order)
+ * @dport: Destination port (host byte order)
+ */
+static inline void
+efx_filter_set_rx_udp_wild(struct efx_filter_spec *spec, u32 dhost, u16 dport)
+{
+	spec->type = EFX_FILTER_RX_UDP_WILD;
+	spec->data[0] = dport;
+	spec->data[1] = 0;
+	spec->data[2] = dhost;
+}
+
+/**
+ * efx_filter_set_rx_mac_full - specify RX filter with MAC full match
+ * @spec: Specification to initialise
+ * @vid: VLAN ID
+ * @addr: Destination MAC address
+ */
+static inline void efx_filter_set_rx_mac_full(struct efx_filter_spec *spec,
+					      u16 vid, const u8 *addr)
+{
+	spec->type = EFX_FILTER_RX_MAC_FULL;
+	spec->data[0] = vid;
+	spec->data[1] = addr[2] << 24 | addr[3] << 16 | addr[4] << 8 | addr[5];
+	spec->data[2] = addr[0] << 8 | addr[1];
+}
+
+/**
+ * efx_filter_set_rx_mac_full - specify RX filter with MAC wildcard match
+ * @spec: Specification to initialise
+ * @addr: Destination MAC address
+ */
+static inline void efx_filter_set_rx_mac_wild(struct efx_filter_spec *spec,
+					      const u8 *addr)
+{
+	spec->type = EFX_FILTER_RX_MAC_WILD;
+	spec->data[0] = 0;
+	spec->data[1] = addr[2] << 24 | addr[3] << 16 | addr[4] << 8 | addr[5];
+	spec->data[2] = addr[0] << 8 | addr[1];
+}
+
+#endif /* EFX_FILTER_H */
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 152342d..ea6691c 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -619,6 +619,8 @@ union efx_multicast_hash {
 	efx_oword_t oword[EFX_MCAST_HASH_ENTRIES / sizeof(efx_oword_t) / 8];
 };
 
+struct efx_filter_state;
+
 /**
  * struct efx_nic - an Efx NIC
  * @name: Device name (net device name or bus id before net device registered)
@@ -799,6 +801,8 @@ struct efx_nic {
 	u64 loopback_modes;
 
 	void *loopback_selftest;
+
+	struct efx_filter_state *filter_state;
 };
 
 static inline int efx_dev_registered(struct efx_nic *efx)
diff --git a/drivers/net/sfc/regs.h b/drivers/net/sfc/regs.h
index 18a3be4..96430ed 100644
--- a/drivers/net/sfc/regs.h
+++ b/drivers/net/sfc/regs.h
@@ -2893,6 +2893,20 @@
 #define	FRF_AB_XX_FORCE_SIG_WIDTH 8
 #define	FFE_AB_XX_FORCE_SIG_ALL_LANES 0xff
 
+/* RX_MAC_FILTER_TBL0 */
+/* RMFT_DEST_MAC is wider than 32 bits */
+#define FRF_CZ_RMFT_DEST_MAC_LO_LBN 12
+#define FRF_CZ_RMFT_DEST_MAC_LO_WIDTH 32
+#define FRF_CZ_RMFT_DEST_MAC_HI_LBN 44
+#define FRF_CZ_RMFT_DEST_MAC_HI_WIDTH 16
+
+/* TX_MAC_FILTER_TBL0 */
+/* TMFT_SRC_MAC is wider than 32 bits */
+#define FRF_CZ_TMFT_SRC_MAC_LO_LBN 12
+#define FRF_CZ_TMFT_SRC_MAC_LO_WIDTH 32
+#define FRF_CZ_TMFT_SRC_MAC_HI_LBN 44
+#define FRF_CZ_TMFT_SRC_MAC_HI_WIDTH 16
+
 /* DRIVER_EV */
 /* Sub-fields of an RX flush completion event */
 #define FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL_LBN 12
-- 
1.7.2.1



-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


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

* [PATCH net-next-2.6 5/8] sfc: Implement the ethtool RX n-tuple control functions
  2010-09-20 18:40 [PATCH net-next-2.6 0/8] sfc and ethtool changes for 2.6.37 Ben Hutchings
                   ` (3 preceding siblings ...)
  2010-09-20 18:43 ` [PATCH net-next-2.6 4/8] sfc: Add filter table management Ben Hutchings
@ 2010-09-20 18:43 ` Ben Hutchings
  2010-09-20 18:43 ` [PATCH net-next-2.6 6/8] sfc: Include RX IP filter table in register dump Ben Hutchings
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 19+ messages in thread
From: Ben Hutchings @ 2010-09-20 18:43 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/ethtool.c |  118 ++++++++++++++++++++++++++++++++++++++++++++-
 drivers/net/sfc/falcon.c  |    2 +-
 drivers/net/sfc/siena.c   |    2 +-
 3 files changed, 118 insertions(+), 4 deletions(-)

diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 7f735d8..1b2570c 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -15,6 +15,7 @@
 #include "workarounds.h"
 #include "selftest.h"
 #include "efx.h"
+#include "filter.h"
 #include "nic.h"
 #include "spi.h"
 #include "mdio_10g.h"
@@ -551,9 +552,22 @@ static u32 efx_ethtool_get_rx_csum(struct net_device *net_dev)
 static int efx_ethtool_set_flags(struct net_device *net_dev, u32 data)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
-	u32 supported = efx->type->offload_features & ETH_FLAG_RXHASH;
+	u32 supported = (efx->type->offload_features &
+			 (ETH_FLAG_RXHASH | ETH_FLAG_NTUPLE));
+	int rc;
+
+	rc = ethtool_op_set_flags(net_dev, data, supported);
+	if (rc)
+		return rc;
+
+	if (!(data & ETH_FLAG_NTUPLE)) {
+		efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_IP,
+				       EFX_FILTER_PRI_MANUAL);
+		efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_MAC,
+				       EFX_FILTER_PRI_MANUAL);
+	}
 
-	return ethtool_op_set_flags(net_dev, data, supported);
+	return 0;
 }
 
 static void efx_ethtool_self_test(struct net_device *net_dev,
@@ -955,6 +969,105 @@ efx_ethtool_get_rxnfc(struct net_device *net_dev,
 	}
 }
 
+static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev,
+				     struct ethtool_rx_ntuple *ntuple)
+{
+	struct efx_nic *efx = netdev_priv(net_dev);
+	struct ethtool_tcpip4_spec *ip_entry = &ntuple->fs.h_u.tcp_ip4_spec;
+	struct ethtool_tcpip4_spec *ip_mask = &ntuple->fs.m_u.tcp_ip4_spec;
+	struct ethhdr *mac_entry = &ntuple->fs.h_u.ether_spec;
+	struct ethhdr *mac_mask = &ntuple->fs.m_u.ether_spec;
+	struct efx_filter_spec filter;
+
+	/* Range-check action */
+	if (ntuple->fs.action < ETHTOOL_RXNTUPLE_ACTION_CLEAR ||
+	    ntuple->fs.action >= (s32)efx->n_rx_channels)
+		return -EINVAL;
+
+	if (~ntuple->fs.data_mask)
+		return -EINVAL;
+
+	switch (ntuple->fs.flow_type) {
+	case TCP_V4_FLOW:
+	case UDP_V4_FLOW:
+		/* Must match all of destination, */
+		if (ip_mask->ip4dst | ip_mask->pdst)
+			return -EINVAL;
+		/* all or none of source, */
+		if ((ip_mask->ip4src | ip_mask->psrc) &&
+		    ((__force u32)~ip_mask->ip4src |
+		     (__force u16)~ip_mask->psrc))
+			return -EINVAL;
+		/* and nothing else */
+		if ((u8)~ip_mask->tos | (u16)~ntuple->fs.vlan_tag_mask)
+			return -EINVAL;
+		break;
+	case ETHER_FLOW:
+		/* Must match all of destination, */
+		if (!is_zero_ether_addr(mac_mask->h_dest))
+			return -EINVAL;
+		/* all or none of VID, */
+		if (ntuple->fs.vlan_tag_mask != 0xf000 &&
+		    ntuple->fs.vlan_tag_mask != 0xffff)
+			return -EINVAL;
+		/* and nothing else */
+		if (!is_broadcast_ether_addr(mac_mask->h_source) ||
+		    mac_mask->h_proto != htons(0xffff))
+			return -EINVAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	filter.priority = EFX_FILTER_PRI_MANUAL;
+	filter.flags = 0;
+
+	switch (ntuple->fs.flow_type) {
+	case TCP_V4_FLOW:
+		if (!ip_mask->ip4src)
+			efx_filter_set_rx_tcp_full(&filter,
+						   htonl(ip_entry->ip4src),
+						   htons(ip_entry->psrc),
+						   htonl(ip_entry->ip4dst),
+						   htons(ip_entry->pdst));
+		else
+			efx_filter_set_rx_tcp_wild(&filter,
+						   htonl(ip_entry->ip4dst),
+						   htons(ip_entry->pdst));
+		break;
+	case UDP_V4_FLOW:
+		if (!ip_mask->ip4src)
+			efx_filter_set_rx_udp_full(&filter,
+						   htonl(ip_entry->ip4src),
+						   htons(ip_entry->psrc),
+						   htonl(ip_entry->ip4dst),
+						   htons(ip_entry->pdst));
+		else
+			efx_filter_set_rx_udp_wild(&filter,
+						   htonl(ip_entry->ip4dst),
+						   htons(ip_entry->pdst));
+		break;
+	case ETHER_FLOW:
+		if (ntuple->fs.vlan_tag_mask == 0xf000)
+			efx_filter_set_rx_mac_full(&filter,
+						   ntuple->fs.vlan_tag & 0xfff,
+						   mac_entry->h_dest);
+		else
+			efx_filter_set_rx_mac_wild(&filter, mac_entry->h_dest);
+		break;
+	}
+
+	if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_CLEAR) {
+		return efx_filter_remove_filter(efx, &filter);
+	} else {
+		if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP)
+			filter.dmaq_id = 0xfff;
+		else
+			filter.dmaq_id = ntuple->fs.action;
+		return efx_filter_insert_filter(efx, &filter, true);
+	}
+}
+
 static int efx_ethtool_get_rxfh_indir(struct net_device *net_dev,
 				      struct ethtool_rxfh_indir *indir)
 {
@@ -1033,6 +1146,7 @@ const struct ethtool_ops efx_ethtool_ops = {
 	.set_wol                = efx_ethtool_set_wol,
 	.reset			= efx_ethtool_reset,
 	.get_rxnfc		= efx_ethtool_get_rxnfc,
+	.set_rx_ntuple		= efx_ethtool_set_rx_ntuple,
 	.get_rxfh_indir		= efx_ethtool_get_rxfh_indir,
 	.set_rxfh_indir		= efx_ethtool_set_rxfh_indir,
 };
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index b4d8efe..b398a41 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -1874,7 +1874,7 @@ struct efx_nic_type falcon_b0_nic_type = {
 				   * channels */
 	.tx_dc_base = 0x130000,
 	.rx_dc_base = 0x100000,
-	.offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH,
+	.offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE,
 	.reset_world_flags = ETH_RESET_IRQ,
 };
 
diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c
index 9f53680..2115f95 100644
--- a/drivers/net/sfc/siena.c
+++ b/drivers/net/sfc/siena.c
@@ -651,6 +651,6 @@ struct efx_nic_type siena_a0_nic_type = {
 	.tx_dc_base = 0x88000,
 	.rx_dc_base = 0x68000,
 	.offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-			     NETIF_F_RXHASH),
+			     NETIF_F_RXHASH | NETIF_F_NTUPLE),
 	.reset_world_flags = ETH_RESET_MGMT << ETH_RESET_SHARED_SHIFT,
 };
-- 
1.7.2.1



-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


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

* [PATCH net-next-2.6 6/8] sfc: Include RX IP filter table in register dump
  2010-09-20 18:40 [PATCH net-next-2.6 0/8] sfc and ethtool changes for 2.6.37 Ben Hutchings
                   ` (4 preceding siblings ...)
  2010-09-20 18:43 ` [PATCH net-next-2.6 5/8] sfc: Implement the ethtool RX n-tuple control functions Ben Hutchings
@ 2010-09-20 18:43 ` Ben Hutchings
  2010-09-20 18:43 ` [PATCH net-next-2.6 7/8] sfc: Set net_device::num_rx_queues once we know the correct value Ben Hutchings
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 19+ messages in thread
From: Ben Hutchings @ 2010-09-20 18:43 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers

For backward compatibility, add it at the end.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/nic.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c
index 6c5c0ce..c4de001 100644
--- a/drivers/net/sfc/nic.c
+++ b/drivers/net/sfc/nic.c
@@ -1849,8 +1849,7 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = {
 	REGISTER_TABLE_BB_CZ(TX_DESC_PTR_TBL),
 	REGISTER_TABLE_AA(EVQ_PTR_TBL_KER),
 	REGISTER_TABLE_BB_CZ(EVQ_PTR_TBL),
-	/* The register buffer is allocated with slab, so we can't
-	 * reasonably read all of the buffer table (up to 8MB!).
+	/* We can't reasonably read all of the buffer table (up to 8MB!).
 	 * However this driver will only use a few entries.  Reading
 	 * 1K entries allows for some expansion of queue count and
 	 * size before we need to change the version. */
@@ -1858,7 +1857,6 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = {
 				  A, A, 8, 1024),
 	REGISTER_TABLE_DIMENSIONS(BUF_FULL_TBL, FR_BZ_BUF_FULL_TBL,
 				  B, Z, 8, 1024),
-	/* RX_FILTER_TBL{0,1} is huge and not used by this driver */
 	REGISTER_TABLE_CZ(RX_MAC_FILTER_TBL0),
 	REGISTER_TABLE_BB_CZ(TIMER_TBL),
 	REGISTER_TABLE_BB_CZ(TX_PACE_TBL),
@@ -1868,6 +1866,7 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = {
 	REGISTER_TABLE_CZ(MC_TREG_SMEM),
 	/* MSIX_PBA_TABLE is not mapped */
 	/* SRM_DBG is not mapped (and is redundant with BUF_FLL_TBL) */
+	REGISTER_TABLE_BZ(RX_FILTER_TBL0),
 };
 
 size_t efx_nic_get_regs_len(struct efx_nic *efx)
-- 
1.7.2.1



-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


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

* [PATCH net-next-2.6 7/8] sfc: Set net_device::num_rx_queues once we know the correct value
  2010-09-20 18:40 [PATCH net-next-2.6 0/8] sfc and ethtool changes for 2.6.37 Ben Hutchings
                   ` (5 preceding siblings ...)
  2010-09-20 18:43 ` [PATCH net-next-2.6 6/8] sfc: Include RX IP filter table in register dump Ben Hutchings
@ 2010-09-20 18:43 ` Ben Hutchings
  2010-09-20 18:54   ` Eric Dumazet
  2010-09-20 18:44 ` [PATCH net-next-2.6 8/8] sfc: Clean up and correct comments on efx_monitor() Ben Hutchings
  2010-09-21 21:58 ` [PATCH net-next-2.6 0/8] sfc and ethtool changes for 2.6.37 David Miller
  8 siblings, 1 reply; 19+ messages in thread
From: Ben Hutchings @ 2010-09-20 18:43 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/efx.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 4a1c93f..48e2bf4 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -1315,6 +1315,7 @@ static int efx_probe_nic(struct efx_nic *efx)
 
 	efx_set_channels(efx);
 	efx->net_dev->real_num_tx_queues = efx->n_tx_channels;
+	efx->net_dev->num_rx_queues = efx->n_rx_channels;
 
 	/* Initialise the interrupt moderation settings */
 	efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec, true);
-- 
1.7.2.1



-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


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

* [PATCH net-next-2.6 8/8] sfc: Clean up and correct comments on efx_monitor()
  2010-09-20 18:40 [PATCH net-next-2.6 0/8] sfc and ethtool changes for 2.6.37 Ben Hutchings
                   ` (6 preceding siblings ...)
  2010-09-20 18:43 ` [PATCH net-next-2.6 7/8] sfc: Set net_device::num_rx_queues once we know the correct value Ben Hutchings
@ 2010-09-20 18:44 ` Ben Hutchings
  2010-09-21 21:58 ` [PATCH net-next-2.6 0/8] sfc and ethtool changes for 2.6.37 David Miller
  8 siblings, 0 replies; 19+ messages in thread
From: Ben Hutchings @ 2010-09-20 18:44 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/efx.c |   23 ++++++++++-------------
 1 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 48e2bf4..8a51c41 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -124,8 +124,9 @@ MODULE_PARM_DESC(separate_tx_channels,
 static int napi_weight = 64;
 
 /* This is the time (in jiffies) between invocations of the hardware
- * monitor, which checks for known hardware bugs and resets the
- * hardware and driver as necessary.
+ * monitor.  On Falcon-based NICs, this will:
+ * - Check the on-board hardware monitor;
+ * - Poll the link state and reconfigure the hardware as necessary.
  */
 unsigned int efx_monitor_interval = 1 * HZ;
 
@@ -1546,8 +1547,7 @@ void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs,
  *
  **************************************************************************/
 
-/* Run periodically off the general workqueue. Serialised against
- * efx_reconfigure_port via the mac_lock */
+/* Run periodically off the general workqueue */
 static void efx_monitor(struct work_struct *data)
 {
 	struct efx_nic *efx = container_of(data, struct efx_nic,
@@ -1560,16 +1560,13 @@ static void efx_monitor(struct work_struct *data)
 
 	/* If the mac_lock is already held then it is likely a port
 	 * reconfiguration is already in place, which will likely do
-	 * most of the work of check_hw() anyway. */
-	if (!mutex_trylock(&efx->mac_lock))
-		goto out_requeue;
-	if (!efx->port_enabled)
-		goto out_unlock;
-	efx->type->monitor(efx);
+	 * most of the work of monitor() anyway. */
+	if (mutex_trylock(&efx->mac_lock)) {
+		if (efx->port_enabled)
+			efx->type->monitor(efx);
+		mutex_unlock(&efx->mac_lock);
+	}
 
-out_unlock:
-	mutex_unlock(&efx->mac_lock);
-out_requeue:
 	queue_delayed_work(efx->workqueue, &efx->monitor_work,
 			   efx_monitor_interval);
 }
-- 
1.7.2.1


-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


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

* Re: [PATCH net-next-2.6 7/8] sfc: Set net_device::num_rx_queues once we know the correct value
  2010-09-20 18:43 ` [PATCH net-next-2.6 7/8] sfc: Set net_device::num_rx_queues once we know the correct value Ben Hutchings
@ 2010-09-20 18:54   ` Eric Dumazet
  2010-09-20 19:05     ` Ben Hutchings
  0 siblings, 1 reply; 19+ messages in thread
From: Eric Dumazet @ 2010-09-20 18:54 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: David Miller, netdev, linux-net-drivers

Le lundi 20 septembre 2010 à 19:43 +0100, Ben Hutchings a écrit :
> Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
> ---
>  drivers/net/sfc/efx.c |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
> index 4a1c93f..48e2bf4 100644
> --- a/drivers/net/sfc/efx.c
> +++ b/drivers/net/sfc/efx.c
> @@ -1315,6 +1315,7 @@ static int efx_probe_nic(struct efx_nic *efx)
>  
>  	efx_set_channels(efx);
>  	efx->net_dev->real_num_tx_queues = efx->n_tx_channels;
> +	efx->net_dev->num_rx_queues = efx->n_rx_channels;
>  
>  	/* Initialise the interrupt moderation settings */
>  	efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec, true);
> -- 
> 1.7.2.1
> 
> 
> 

Interesting, but why ?

No other driver does this AFAIK...




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

* Re: [PATCH net-next-2.6 7/8] sfc: Set net_device::num_rx_queues once we know the correct value
  2010-09-20 18:54   ` Eric Dumazet
@ 2010-09-20 19:05     ` Ben Hutchings
  2010-09-21 21:57       ` David Miller
  0 siblings, 1 reply; 19+ messages in thread
From: Ben Hutchings @ 2010-09-20 19:05 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev, linux-net-drivers

On Mon, 2010-09-20 at 20:54 +0200, Eric Dumazet wrote:
> Le lundi 20 septembre 2010 à 19:43 +0100, Ben Hutchings a écrit :
> > Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
> > ---
> >  drivers/net/sfc/efx.c |    1 +
> >  1 files changed, 1 insertions(+), 0 deletions(-)
> > 
> > diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
> > index 4a1c93f..48e2bf4 100644
> > --- a/drivers/net/sfc/efx.c
> > +++ b/drivers/net/sfc/efx.c
> > @@ -1315,6 +1315,7 @@ static int efx_probe_nic(struct efx_nic *efx)
> >  
> >  	efx_set_channels(efx);
> >  	efx->net_dev->real_num_tx_queues = efx->n_tx_channels;
> > +	efx->net_dev->num_rx_queues = efx->n_rx_channels;
> >  
> >  	/* Initialise the interrupt moderation settings */
> >  	efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec, true);
> > -- 
> > 1.7.2.1
> > 
> > 
> > 
> 
> Interesting, but why ?
> 
> No other driver does this AFAIK...

If RPS is enabled there's a separate kobject for each RX queue.  Those
other drivers probably should be setting it.

Oh, but this only exists if CONFIG_RPS is enabled.  I think we need an
inline function for setting this.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


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

* Re: [PATCH net-next-2.6 7/8] sfc: Set net_device::num_rx_queues once we know the correct value
  2010-09-20 19:05     ` Ben Hutchings
@ 2010-09-21 21:57       ` David Miller
  2010-09-22  1:31         ` Ben Hutchings
  0 siblings, 1 reply; 19+ messages in thread
From: David Miller @ 2010-09-21 21:57 UTC (permalink / raw)
  To: bhutchings; +Cc: eric.dumazet, netdev, linux-net-drivers

From: Ben Hutchings <bhutchings@solarflare.com>
Date: Mon, 20 Sep 2010 20:05:46 +0100

> If RPS is enabled there's a separate kobject for each RX queue.  Those
> other drivers probably should be setting it.
> 
> Oh, but this only exists if CONFIG_RPS is enabled.  I think we need an
> inline function for setting this.

It's set in the core by alloc_netdev_mq(), you should never have to
set this in your driver.

And that also takes care of the CONFIG_RPS dependency in one spot,
another good argument for drivers never touching this value.

I'm not applying this patch.

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

* Re: [PATCH net-next-2.6 0/8] sfc and ethtool changes for 2.6.37
  2010-09-20 18:40 [PATCH net-next-2.6 0/8] sfc and ethtool changes for 2.6.37 Ben Hutchings
                   ` (7 preceding siblings ...)
  2010-09-20 18:44 ` [PATCH net-next-2.6 8/8] sfc: Clean up and correct comments on efx_monitor() Ben Hutchings
@ 2010-09-21 21:58 ` David Miller
  2010-09-21 23:23   ` David Miller
  8 siblings, 1 reply; 19+ messages in thread
From: David Miller @ 2010-09-21 21:58 UTC (permalink / raw)
  To: bhutchings; +Cc: netdev, linux-net-drivers

From: Ben Hutchings <bhutchings@solarflare.com>
Date: Mon, 20 Sep 2010 19:40:56 +0100

> This series adds Ethernet-level filtering and explicit filter clearing
> to the ethtool RX n-tuple interface, and implements it in the sfc
> driver.
> 
> There is a cleanup patch on the end which is preparation for the
> following RFC patch series but is worthwhile anyway.
> 
> Ben Hutchings (8):
>   ethtool: Define RX n-tuple action to clear a rule
>   ethtool: Add Ethernet MAC-level filtering/steering
>   ethtool: Allocate register dump buffer with vmalloc()
>   sfc: Add filter table management
>   sfc: Implement the ethtool RX n-tuple control functions
>   sfc: Include RX IP filter table in register dump
>   sfc: Set net_device::num_rx_queues once we know the correct value
>   sfc: Clean up and correct comments on efx_monitor()

All applied except patch #7 as noted in the thread for that patch.

Thanks!

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

* Re: [PATCH net-next-2.6 0/8] sfc and ethtool changes for 2.6.37
  2010-09-21 21:58 ` [PATCH net-next-2.6 0/8] sfc and ethtool changes for 2.6.37 David Miller
@ 2010-09-21 23:23   ` David Miller
  2010-09-22 15:27     ` Ben Hutchings
  0 siblings, 1 reply; 19+ messages in thread
From: David Miller @ 2010-09-21 23:23 UTC (permalink / raw)
  To: bhutchings; +Cc: netdev, linux-net-drivers

From: David Miller <davem@davemloft.net>
Date: Tue, 21 Sep 2010 14:58:27 -0700 (PDT)

> From: Ben Hutchings <bhutchings@solarflare.com>
> Date: Mon, 20 Sep 2010 19:40:56 +0100
> 
>> This series adds Ethernet-level filtering and explicit filter clearing
>> to the ethtool RX n-tuple interface, and implements it in the sfc
>> driver.
>> 
>> There is a cleanup patch on the end which is preparation for the
>> following RFC patch series but is worthwhile anyway.
>> 
>> Ben Hutchings (8):
>>   ethtool: Define RX n-tuple action to clear a rule
>>   ethtool: Add Ethernet MAC-level filtering/steering
>>   ethtool: Allocate register dump buffer with vmalloc()
>>   sfc: Add filter table management
>>   sfc: Implement the ethtool RX n-tuple control functions
>>   sfc: Include RX IP filter table in register dump
>>   sfc: Set net_device::num_rx_queues once we know the correct value
>>   sfc: Clean up and correct comments on efx_monitor()
> 
> All applied except patch #7 as noted in the thread for that patch.

Ben, just FYI, I had to add "linux/vmalloc.h" includes to both
net/core/ethtool.c and drivers/net/sfc/net_driver.h otherwise
the build breaks on some architectures.

x86 can be a really bad arch to validates builds on because it
currently gets vmalloc.h implicitly by some of it's core header files.

In particular, asm/io.h :-/

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

* Re: [PATCH net-next-2.6 7/8] sfc: Set net_device::num_rx_queues once we know the correct value
  2010-09-21 21:57       ` David Miller
@ 2010-09-22  1:31         ` Ben Hutchings
  2010-09-22  1:38           ` David Miller
  0 siblings, 1 reply; 19+ messages in thread
From: Ben Hutchings @ 2010-09-22  1:31 UTC (permalink / raw)
  To: David Miller; +Cc: eric.dumazet, netdev, linux-net-drivers

On Tue, 2010-09-21 at 14:57 -0700, David Miller wrote:
> From: Ben Hutchings <bhutchings@solarflare.com>
> Date: Mon, 20 Sep 2010 20:05:46 +0100
> 
> > If RPS is enabled there's a separate kobject for each RX queue.  Those
> > other drivers probably should be setting it.
> > 
> > Oh, but this only exists if CONFIG_RPS is enabled.  I think we need an
> > inline function for setting this.
> 
> It's set in the core by alloc_netdev_mq(), you should never have to
> set this in your driver.

That specifies the maximum possible number of queues, but we don't
require that the actual number of TX queues (real_num_tx_queues) is the
same as the maximum (num_tx_queues) and nor should we assume that of RX
queues.  I don't think we should require that the maximum numbers of RX
and TX queues are the same either, for that matter.

> And that also takes care of the CONFIG_RPS dependency in one spot,
> another good argument for drivers never touching this value.
> 
> I'm not applying this patch.

Right, but we do need to have some way for drivers to specify the actual
number of RX queues.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

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

* Re: [PATCH net-next-2.6 7/8] sfc: Set net_device::num_rx_queues once we know the correct value
  2010-09-22  1:31         ` Ben Hutchings
@ 2010-09-22  1:38           ` David Miller
  2010-09-22 15:28             ` Ben Hutchings
  0 siblings, 1 reply; 19+ messages in thread
From: David Miller @ 2010-09-22  1:38 UTC (permalink / raw)
  To: bhutchings; +Cc: eric.dumazet, netdev, linux-net-drivers

From: Ben Hutchings <bhutchings@solarflare.com>
Date: Wed, 22 Sep 2010 02:31:36 +0100

> Right, but we do need to have some way for drivers to specify the actual
> number of RX queues.

Ok, the problem stems merely from the fact that we only specify one
"queue count" in alloc_netdev_mq().  We should specify two, one for
TX and one for RX.

So why not fix that instead of putting hacks into the drivers? :-)


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

* Re: [PATCH net-next-2.6 0/8] sfc and ethtool changes for 2.6.37
  2010-09-21 23:23   ` David Miller
@ 2010-09-22 15:27     ` Ben Hutchings
  0 siblings, 0 replies; 19+ messages in thread
From: Ben Hutchings @ 2010-09-22 15:27 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers

On Tue, 2010-09-21 at 16:23 -0700, David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Tue, 21 Sep 2010 14:58:27 -0700 (PDT)
> 
> > From: Ben Hutchings <bhutchings@solarflare.com>
> > Date: Mon, 20 Sep 2010 19:40:56 +0100
> > 
> >> This series adds Ethernet-level filtering and explicit filter clearing
> >> to the ethtool RX n-tuple interface, and implements it in the sfc
> >> driver.
> >> 
> >> There is a cleanup patch on the end which is preparation for the
> >> following RFC patch series but is worthwhile anyway.
> >> 
> >> Ben Hutchings (8):
> >>   ethtool: Define RX n-tuple action to clear a rule
> >>   ethtool: Add Ethernet MAC-level filtering/steering
> >>   ethtool: Allocate register dump buffer with vmalloc()
> >>   sfc: Add filter table management
> >>   sfc: Implement the ethtool RX n-tuple control functions
> >>   sfc: Include RX IP filter table in register dump
> >>   sfc: Set net_device::num_rx_queues once we know the correct value
> >>   sfc: Clean up and correct comments on efx_monitor()
> > 
> > All applied except patch #7 as noted in the thread for that patch.
> 
> Ben, just FYI, I had to add "linux/vmalloc.h" includes to both
> net/core/ethtool.c and drivers/net/sfc/net_driver.h otherwise
> the build breaks on some architectures.
> 
> x86 can be a really bad arch to validates builds on because it
> currently gets vmalloc.h implicitly by some of it's core header files.
> 
> In particular, asm/io.h :-/

Thanks, and sorry for missing this.  We have some SPARC systems that I
could potentially test on but I think they're limited to running
Solaris.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


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

* Re: [PATCH net-next-2.6 7/8] sfc: Set net_device::num_rx_queues once we know the correct value
  2010-09-22  1:38           ` David Miller
@ 2010-09-22 15:28             ` Ben Hutchings
  2010-09-22 15:44               ` Eric Dumazet
  0 siblings, 1 reply; 19+ messages in thread
From: Ben Hutchings @ 2010-09-22 15:28 UTC (permalink / raw)
  To: David Miller; +Cc: eric.dumazet, netdev, linux-net-drivers

On Tue, 2010-09-21 at 18:38 -0700, David Miller wrote:
> From: Ben Hutchings <bhutchings@solarflare.com>
> Date: Wed, 22 Sep 2010 02:31:36 +0100
> 
> > Right, but we do need to have some way for drivers to specify the actual
> > number of RX queues.
> 
> Ok, the problem stems merely from the fact that we only specify one
> "queue count" in alloc_netdev_mq().  We should specify two, one for
> TX and one for RX.
> 
> So why not fix that instead of putting hacks into the drivers? :-)

That still doesn't solve the original problem, since drivers generally
won't know how many RX queues they should (or can) create until some
time after calling alloc_netdev_mq().

You know very well why we distinguish real_num_tx_queues and
num_tx_queues; what's so different about RX queues?

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


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

* Re: [PATCH net-next-2.6 7/8] sfc: Set net_device::num_rx_queues once we know the correct value
  2010-09-22 15:28             ` Ben Hutchings
@ 2010-09-22 15:44               ` Eric Dumazet
  0 siblings, 0 replies; 19+ messages in thread
From: Eric Dumazet @ 2010-09-22 15:44 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: David Miller, netdev, linux-net-drivers

Le mercredi 22 septembre 2010 à 16:28 +0100, Ben Hutchings a écrit :

> 
> That still doesn't solve the original problem, since drivers generally
> won't know how many RX queues they should (or can) create until some
> time after calling alloc_netdev_mq().
> 
> You know very well why we distinguish real_num_tx_queues and
> num_tx_queues; what's so different about RX queues?

rx queues were added by Tom for RPS.
No function prototypes were changed to provide it as a new parameter.

What we need is to extend alloc_netdev_mq() to take a new rx_queue_count
parameter.

Then allow these txq/rxq parameters to be "unset for the moment", and
provide a new function to allocate / populate queues when driver knows
what to do, _after_ its alloc_netdev_mq() call.

Your one line patch is a work around, not a clean solution.




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

end of thread, other threads:[~2010-09-22 15:44 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-09-20 18:40 [PATCH net-next-2.6 0/8] sfc and ethtool changes for 2.6.37 Ben Hutchings
2010-09-20 18:41 ` [PATCH net-next-2.6 1/8] ethtool: Define RX n-tuple action to clear a rule Ben Hutchings
2010-09-20 18:42 ` [PATCH net-next-2.6 2/8] ethtool: Add Ethernet MAC-level filtering/steering Ben Hutchings
2010-09-20 18:42 ` [PATCH net-next-2.6 3/8] ethtool: Allocate register dump buffer with vmalloc() Ben Hutchings
2010-09-20 18:43 ` [PATCH net-next-2.6 4/8] sfc: Add filter table management Ben Hutchings
2010-09-20 18:43 ` [PATCH net-next-2.6 5/8] sfc: Implement the ethtool RX n-tuple control functions Ben Hutchings
2010-09-20 18:43 ` [PATCH net-next-2.6 6/8] sfc: Include RX IP filter table in register dump Ben Hutchings
2010-09-20 18:43 ` [PATCH net-next-2.6 7/8] sfc: Set net_device::num_rx_queues once we know the correct value Ben Hutchings
2010-09-20 18:54   ` Eric Dumazet
2010-09-20 19:05     ` Ben Hutchings
2010-09-21 21:57       ` David Miller
2010-09-22  1:31         ` Ben Hutchings
2010-09-22  1:38           ` David Miller
2010-09-22 15:28             ` Ben Hutchings
2010-09-22 15:44               ` Eric Dumazet
2010-09-20 18:44 ` [PATCH net-next-2.6 8/8] sfc: Clean up and correct comments on efx_monitor() Ben Hutchings
2010-09-21 21:58 ` [PATCH net-next-2.6 0/8] sfc and ethtool changes for 2.6.37 David Miller
2010-09-21 23:23   ` David Miller
2010-09-22 15:27     ` Ben Hutchings

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).