netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv2 net-next 0/8] RX NFC support for hash-based filters
@ 2012-01-03 21:56 Ben Hutchings
  2012-01-03 21:59 ` [PATCHv2 net-next 1/8] gianfar: Reject out-of-range RX NFC locations Ben Hutchings
                   ` (11 more replies)
  0 siblings, 12 replies; 14+ messages in thread
From: Ben Hutchings @ 2012-01-03 21:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers

1. Fix gianfar's validation of filter rule locations.  In the previous
   version of this series, this was a requirement for part 2, but that's
   no longer the case.

2. Extend ethtool RX NFC rules API to support hash-based filter hardware
   in which rule locations should be selected by the driver or firmware.

3. Change the sfc driver to implement this API instead of RX n-tuple.

4. Remove support for RX n-tuple, now that there are no in-tree
   implementations.

Ben.

Ben Hutchings (8):
  gianfar: Reject out-of-range RX NFC locations
  ethtool: Allow drivers to select RX NFC rule locations
  sfc: Change filter ID generation to satisfy priority semantics of RX
    NFC
  sfc: Use consistent types for filter IDs, indices and search depths
  sfc: Add support for retrieving and removing filters by ID
  sfc: Implement ethtool RX NFC rules API instead of n-tuple API
  sfc: Remove now-unused filter function
  ethtool: Remove ethtool_ops::set_rx_ntuple operation

 drivers/net/ethernet/freescale/gianfar_ethtool.c |    5 +-
 drivers/net/ethernet/sfc/efx.h                   |   16 +-
 drivers/net/ethernet/sfc/ethtool.c               |  188 +++++++++++---
 drivers/net/ethernet/sfc/filter.c                |  310 +++++++++++++++++++---
 drivers/net/ethernet/sfc/filter.h                |   12 +
 include/linux/ethtool.h                          |   30 ++-
 net/core/ethtool.c                               |   66 +----
 net/socket.c                                     |    2 +-
 8 files changed, 484 insertions(+), 145 deletions(-)

-- 
1.7.4.4


-- 
Ben Hutchings, Staff Engineer, Solarflare
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] 14+ messages in thread

* [PATCHv2 net-next 1/8] gianfar: Reject out-of-range RX NFC locations
  2012-01-03 21:56 [PATCHv2 net-next 0/8] RX NFC support for hash-based filters Ben Hutchings
@ 2012-01-03 21:59 ` Ben Hutchings
  2012-01-03 22:04 ` [PATCHv2 net-next 2/8] ethtool: Allow drivers to select RX NFC rule locations Ben Hutchings
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Ben Hutchings @ 2012-01-03 21:59 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers, Sebastian Pöhn

Currently the driver only uses location values to maintain an ordered
list of filters.  Make it reject location values >= MAX_FILER_IDX
passed to the ETHTOOL_SRXCLSRLINS command, consistent with the range
it reports for the ETHTOOL_GRXCLSRLALL command.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Acked-by: Sebastian Pöhn <sebastian.poehn@googlemail.com>
---
Sebastian, I took your private reply as an ack; please shout if that's
wrong.

Ben.

 drivers/net/ethernet/freescale/gianfar_ethtool.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c
index 5890f4b..5a3b2e5 100644
--- a/drivers/net/ethernet/freescale/gianfar_ethtool.c
+++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c
@@ -1692,8 +1692,9 @@ static int gfar_set_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
 		ret = gfar_set_hash_opts(priv, cmd);
 		break;
 	case ETHTOOL_SRXCLSRLINS:
-		if (cmd->fs.ring_cookie != RX_CLS_FLOW_DISC &&
-			cmd->fs.ring_cookie >= priv->num_rx_queues) {
+		if ((cmd->fs.ring_cookie != RX_CLS_FLOW_DISC &&
+		     cmd->fs.ring_cookie >= priv->num_rx_queues) ||
+		    cmd->fs.location >= MAX_FILER_IDX) {
 			ret = -EINVAL;
 			break;
 		}
-- 
1.7.4.4



-- 
Ben Hutchings, Staff Engineer, Solarflare
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] 14+ messages in thread

* [PATCHv2 net-next 2/8] ethtool: Allow drivers to select RX NFC rule locations
  2012-01-03 21:56 [PATCHv2 net-next 0/8] RX NFC support for hash-based filters Ben Hutchings
  2012-01-03 21:59 ` [PATCHv2 net-next 1/8] gianfar: Reject out-of-range RX NFC locations Ben Hutchings
@ 2012-01-03 22:04 ` Ben Hutchings
  2012-01-03 22:05 ` [PATCHv2 net-next 3/8] sfc: Change filter ID generation to satisfy priority semantics of RX NFC Ben Hutchings
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Ben Hutchings @ 2012-01-03 22:04 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, linux-net-drivers, Alexander Duyck,
	Dimitrios Michailidis, Vladislav Zolotarov

Define special location values for RX NFC that request the driver to
select the actual rule location.  This allows for implementation on
devices that use hash-based filter lookup, whereas currently the API is
more suited to devices with TCAM lookup or linear search.

In ethtool_set_rxnfc() and the compat wrapper ethtool_ioctl(), copy
the structure back to user-space after insertion so that the actual
location is returned.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
Drivers are now required to report that they recognise special location
values and userland is expected to check this before using them.  This
should allow me to use them in the ethtool utility without breaking
compatibility with the current gianfar driver.

Ben.

 include/linux/ethtool.h |   26 ++++++++++++++++++++++++--
 net/core/ethtool.c      |   11 ++++++++++-
 net/socket.c            |    2 +-
 3 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index b38bf69..d901714 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -489,7 +489,10 @@ struct ethtool_rx_flow_spec {
  * on return.
  *
  * For %ETHTOOL_GRXCLSRLCNT, @rule_cnt is set to the number of defined
- * rules on return.
+ * rules on return.  If @data is non-zero on return then it is the
+ * size of the rule table, plus the flag %RX_CLS_LOC_SPECIAL if the
+ * driver supports any special location values.  If that flag is not
+ * set in @data then special location values should not be used.
  *
  * For %ETHTOOL_GRXCLSRULE, @fs.@location specifies the location of an
  * existing rule on entry and @fs contains the rule on return.
@@ -501,10 +504,23 @@ struct ethtool_rx_flow_spec {
  * must use the second parameter to get_rxnfc() instead of @rule_locs.
  *
  * For %ETHTOOL_SRXCLSRLINS, @fs specifies the rule to add or update.
- * @fs.@location specifies the location to use and must not be ignored.
+ * @fs.@location either specifies the location to use or is a special
+ * location value with %RX_CLS_LOC_SPECIAL flag set.  On return,
+ * @fs.@location is the actual rule location.
  *
  * For %ETHTOOL_SRXCLSRLDEL, @fs.@location specifies the location of an
  * existing rule on entry.
+ *
+ * A driver supporting the special location values for
+ * %ETHTOOL_SRXCLSRLINS may add the rule at any suitable unused
+ * location, and may remove a rule at a later location (lower
+ * priority) that matches exactly the same set of flows.  The special
+ * values are: %RX_CLS_LOC_ANY, selecting any location;
+ * %RX_CLS_LOC_FIRST, selecting the first suitable location (maximum
+ * priority); and %RX_CLS_LOC_LAST, selecting the last suitable
+ * location (minimum priority).  Additional special values may be
+ * defined in future and drivers must return -%EINVAL for any
+ * unrecognised value.
  */
 struct ethtool_rxnfc {
 	__u32				cmd;
@@ -1141,6 +1157,12 @@ struct ethtool_ops {
 
 #define	RX_CLS_FLOW_DISC	0xffffffffffffffffULL
 
+/* Special RX classification rule insert location values */
+#define RX_CLS_LOC_SPECIAL	0x80000000	/* flag */
+#define RX_CLS_LOC_ANY		0xffffffff
+#define RX_CLS_LOC_FIRST	0xfffffffe
+#define RX_CLS_LOC_LAST		0xfffffffd
+
 /* Reset flags */
 /* The reset() operation must clear the flags for the components which
  * were actually reset.  On successful return, the flags indicate the
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 597732c..e88b80d 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -439,6 +439,7 @@ static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev,
 {
 	struct ethtool_rxnfc info;
 	size_t info_size = sizeof(info);
+	int rc;
 
 	if (!dev->ethtool_ops->set_rxnfc)
 		return -EOPNOTSUPP;
@@ -454,7 +455,15 @@ static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev,
 	if (copy_from_user(&info, useraddr, info_size))
 		return -EFAULT;
 
-	return dev->ethtool_ops->set_rxnfc(dev, &info);
+	rc = dev->ethtool_ops->set_rxnfc(dev, &info);
+	if (rc)
+		return rc;
+
+	if (cmd == ETHTOOL_SRXCLSRLINS &&
+	    copy_to_user(useraddr, &info, info_size))
+		return -EFAULT;
+
+	return 0;
 }
 
 static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev,
diff --git a/net/socket.c b/net/socket.c
index e62b4f0..2cad581 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2758,10 +2758,10 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
 	case ETHTOOL_GRXRINGS:
 	case ETHTOOL_GRXCLSRLCNT:
 	case ETHTOOL_GRXCLSRULE:
+	case ETHTOOL_SRXCLSRLINS:
 		convert_out = true;
 		/* fall through */
 	case ETHTOOL_SRXCLSRLDEL:
-	case ETHTOOL_SRXCLSRLINS:
 		buf_size += sizeof(struct ethtool_rxnfc);
 		convert_in = true;
 		break;
-- 
1.7.4.4

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

* [PATCHv2 net-next 3/8] sfc: Change filter ID generation to satisfy priority semantics of RX NFC
  2012-01-03 21:56 [PATCHv2 net-next 0/8] RX NFC support for hash-based filters Ben Hutchings
  2012-01-03 21:59 ` [PATCHv2 net-next 1/8] gianfar: Reject out-of-range RX NFC locations Ben Hutchings
  2012-01-03 22:04 ` [PATCHv2 net-next 2/8] ethtool: Allow drivers to select RX NFC rule locations Ben Hutchings
@ 2012-01-03 22:05 ` Ben Hutchings
  2012-01-03 22:05 ` [PATCHv2 net-next 4/8] sfc: Use consistent types for filter IDs, indices and search depths Ben Hutchings
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Ben Hutchings @ 2012-01-03 22:05 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers

Also add note that the efx_filter_spec::priority field has nothing
to do with priority between multiple matching filters.

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

diff --git a/drivers/net/ethernet/sfc/filter.c b/drivers/net/ethernet/sfc/filter.c
index 2b9636f..1e079bd 100644
--- a/drivers/net/ethernet/sfc/filter.c
+++ b/drivers/net/ethernet/sfc/filter.c
@@ -366,12 +366,45 @@ static int efx_filter_search(struct efx_filter_table *table,
 	}
 }
 
-/* Construct/deconstruct external filter IDs */
+/*
+ * Construct/deconstruct external filter IDs.  These must be ordered
+ * by matching priority, for RX NFC semantics.
+ *
+ * Each RX MAC filter entry has a flag for whether it can override an
+ * RX IP filter that also matches.  So we assign locations for MAC
+ * filters with overriding behaviour, then for IP filters, then for
+ * MAC filters without overriding behaviour.
+ */
+
+#define EFX_FILTER_INDEX_WIDTH	13
+#define EFX_FILTER_INDEX_MASK	((1 << EFX_FILTER_INDEX_WIDTH) - 1)
+
+static inline u32 efx_filter_make_id(enum efx_filter_table_id table_id,
+				     unsigned int index, u8 flags)
+{
+	return (table_id == EFX_FILTER_TABLE_RX_MAC &&
+		flags & EFX_FILTER_FLAG_RX_OVERRIDE_IP) ?
+		index :
+		(table_id + 1) << EFX_FILTER_INDEX_WIDTH | index;
+}
+
+static inline enum efx_filter_table_id efx_filter_id_table_id(u32 id)
+{
+	return (id <= EFX_FILTER_INDEX_MASK) ?
+		EFX_FILTER_TABLE_RX_MAC :
+		(id >> EFX_FILTER_INDEX_WIDTH) - 1;
+}
+
+static inline unsigned int efx_filter_id_index(u32 id)
+{
+	return id & EFX_FILTER_INDEX_MASK;
+}
 
-static inline int
-efx_filter_make_id(enum efx_filter_table_id table_id, unsigned index)
+static inline u8 efx_filter_id_flags(u32 id)
 {
-	return table_id << 16 | index;
+	return (id <= EFX_FILTER_INDEX_MASK) ?
+		EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_RX_OVERRIDE_IP :
+		EFX_FILTER_FLAG_RX;
 }
 
 /**
@@ -439,7 +472,7 @@ int efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec,
 	netif_vdbg(efx, hw, efx->net_dev,
 		   "%s: filter type %d index %d rxq %u set",
 		   __func__, spec->type, filter_idx, spec->dmaq_id);
-	rc = efx_filter_make_id(table->id, filter_idx);
+	rc = efx_filter_make_id(table->id, filter_idx, spec->flags);
 
 out:
 	spin_unlock_bh(&state->lock);
diff --git a/drivers/net/ethernet/sfc/filter.h b/drivers/net/ethernet/sfc/filter.h
index 872f213..dc9a256 100644
--- a/drivers/net/ethernet/sfc/filter.h
+++ b/drivers/net/ethernet/sfc/filter.h
@@ -78,6 +78,11 @@ enum efx_filter_flags {
  *
  * Use the efx_filter_set_*() functions to initialise the @type and
  * @data fields.
+ *
+ * The @priority field is used by software to determine whether a new
+ * filter may replace an old one.  The hardware priority of a filter
+ * depends on the filter type and %EFX_FILTER_FLAG_RX_OVERRIDE_IP
+ * flag.
  */
 struct efx_filter_spec {
 	u8	type:4;
-- 
1.7.4.4



-- 
Ben Hutchings, Staff Engineer, Solarflare
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] 14+ messages in thread

* [PATCHv2 net-next 4/8] sfc: Use consistent types for filter IDs, indices and search depths
  2012-01-03 21:56 [PATCHv2 net-next 0/8] RX NFC support for hash-based filters Ben Hutchings
                   ` (2 preceding siblings ...)
  2012-01-03 22:05 ` [PATCHv2 net-next 3/8] sfc: Change filter ID generation to satisfy priority semantics of RX NFC Ben Hutchings
@ 2012-01-03 22:05 ` Ben Hutchings
  2012-01-03 22:05 ` [PATCHv2 net-next 5/8] sfc: Add support for retrieving and removing filters by ID Ben Hutchings
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Ben Hutchings @ 2012-01-03 22:05 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers

Filter IDs are u32 (but never very large) so an ID/error return
value should have type s32.

Filter indices and search depths are never negative, so should
have type unsigned int.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/ethernet/sfc/efx.h    |    2 +-
 drivers/net/ethernet/sfc/filter.c |   14 +++++++-------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h
index 8a5336d..27f0b01 100644
--- a/drivers/net/ethernet/sfc/efx.h
+++ b/drivers/net/ethernet/sfc/efx.h
@@ -61,7 +61,7 @@ extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue);
 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,
+extern s32 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,
diff --git a/drivers/net/ethernet/sfc/filter.c b/drivers/net/ethernet/sfc/filter.c
index 1e079bd..f41ed5b 100644
--- a/drivers/net/ethernet/sfc/filter.c
+++ b/drivers/net/ethernet/sfc/filter.c
@@ -332,7 +332,7 @@ static bool efx_filter_equal(const struct efx_filter_spec *left,
 
 static int efx_filter_search(struct efx_filter_table *table,
 			     struct efx_filter_spec *spec, u32 key,
-			     bool for_insert, int *depth_required)
+			     bool for_insert, unsigned int *depth_required)
 {
 	unsigned hash, incr, filter_idx, depth, depth_max;
 
@@ -417,14 +417,14 @@ static inline u8 efx_filter_id_flags(u32 id)
  * On success, return the filter ID.
  * On failure, return a negative error code.
  */
-int efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec,
+s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec,
 			     bool replace)
 {
 	struct efx_filter_state *state = efx->filter_state;
 	struct efx_filter_table *table = efx_filter_spec_table(state, spec);
 	struct efx_filter_spec *saved_spec;
 	efx_oword_t filter;
-	int filter_idx, depth;
+	unsigned int filter_idx, depth;
 	u32 key;
 	int rc;
 
@@ -481,7 +481,7 @@ out:
 
 static void efx_filter_table_clear_entry(struct efx_nic *efx,
 					 struct efx_filter_table *table,
-					 int filter_idx)
+					 unsigned int filter_idx)
 {
 	static efx_oword_t filter;
 
@@ -509,7 +509,7 @@ int efx_filter_remove_filter(struct efx_nic *efx, struct efx_filter_spec *spec)
 	struct efx_filter_table *table = efx_filter_spec_table(state, spec);
 	struct efx_filter_spec *saved_spec;
 	efx_oword_t filter;
-	int filter_idx, depth;
+	unsigned int filter_idx, depth;
 	u32 key;
 	int rc;
 
@@ -547,7 +547,7 @@ static void efx_filter_table_clear(struct efx_nic *efx,
 {
 	struct efx_filter_state *state = efx->filter_state;
 	struct efx_filter_table *table = &state->table[table_id];
-	int filter_idx;
+	unsigned int filter_idx;
 
 	spin_lock_bh(&state->lock);
 
@@ -578,7 +578,7 @@ void efx_restore_filters(struct efx_nic *efx)
 	enum efx_filter_table_id table_id;
 	struct efx_filter_table *table;
 	efx_oword_t filter;
-	int filter_idx;
+	unsigned int filter_idx;
 
 	spin_lock_bh(&state->lock);
 
-- 
1.7.4.4



-- 
Ben Hutchings, Staff Engineer, Solarflare
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] 14+ messages in thread

* [PATCHv2 net-next 5/8] sfc: Add support for retrieving and removing filters by ID
  2012-01-03 21:56 [PATCHv2 net-next 0/8] RX NFC support for hash-based filters Ben Hutchings
                   ` (3 preceding siblings ...)
  2012-01-03 22:05 ` [PATCHv2 net-next 4/8] sfc: Use consistent types for filter IDs, indices and search depths Ben Hutchings
@ 2012-01-03 22:05 ` Ben Hutchings
  2012-01-03 22:05 ` [PATCHv2 net-next 6/8] sfc: Implement ethtool RX NFC rules API instead of n-tuple API Ben Hutchings
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Ben Hutchings @ 2012-01-03 22:05 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers

These new functions will support an implementation of the ethtool
RX NFC rules API.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/ethernet/sfc/efx.h    |   12 ++
 drivers/net/ethernet/sfc/filter.c |  247 +++++++++++++++++++++++++++++++++++++
 drivers/net/ethernet/sfc/filter.h |    7 +
 3 files changed, 266 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h
index 27f0b01..f0a5b7c 100644
--- a/drivers/net/ethernet/sfc/efx.h
+++ b/drivers/net/ethernet/sfc/efx.h
@@ -66,8 +66,20 @@ extern s32 efx_filter_insert_filter(struct efx_nic *efx,
 				    bool replace);
 extern int efx_filter_remove_filter(struct efx_nic *efx,
 				    struct efx_filter_spec *spec);
+extern int efx_filter_remove_id_safe(struct efx_nic *efx,
+				     enum efx_filter_priority priority,
+				     u32 filter_id);
+extern int efx_filter_get_filter_safe(struct efx_nic *efx,
+				      enum efx_filter_priority priority,
+				      u32 filter_id, struct efx_filter_spec *);
 extern void efx_filter_clear_rx(struct efx_nic *efx,
 				enum efx_filter_priority priority);
+extern u32 efx_filter_count_rx_used(struct efx_nic *efx,
+				    enum efx_filter_priority priority);
+extern u32 efx_filter_get_rx_id_limit(struct efx_nic *efx);
+extern s32 efx_filter_get_rx_ids(struct efx_nic *efx,
+				 enum efx_filter_priority priority,
+				 u32 *buf, u32 size);
 #ifdef CONFIG_RFS_ACCEL
 extern int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
 			  u16 rxq_index, u32 flow_id);
diff --git a/drivers/net/ethernet/sfc/filter.c b/drivers/net/ethernet/sfc/filter.c
index f41ed5b..8e3d33d 100644
--- a/drivers/net/ethernet/sfc/filter.c
+++ b/drivers/net/ethernet/sfc/filter.c
@@ -155,6 +155,16 @@ static inline void __efx_filter_set_ipv4(struct efx_filter_spec *spec,
 	spec->data[2] = ntohl(host2);
 }
 
+static inline void __efx_filter_get_ipv4(const struct efx_filter_spec *spec,
+					 __be32 *host1, __be16 *port1,
+					 __be32 *host2, __be16 *port2)
+{
+	*host1 = htonl(spec->data[0] >> 16 | spec->data[1] << 16);
+	*port1 = htons(spec->data[0]);
+	*host2 = htonl(spec->data[2]);
+	*port2 = htons(spec->data[1] >> 16);
+}
+
 /**
  * efx_filter_set_ipv4_local - specify IPv4 host, transport protocol and port
  * @spec: Specification to initialise
@@ -205,6 +215,26 @@ int efx_filter_set_ipv4_local(struct efx_filter_spec *spec, u8 proto,
 	return 0;
 }
 
+int efx_filter_get_ipv4_local(const struct efx_filter_spec *spec,
+			      u8 *proto, __be32 *host, __be16 *port)
+{
+	__be32 host1;
+	__be16 port1;
+
+	switch (spec->type) {
+	case EFX_FILTER_TCP_WILD:
+		*proto = IPPROTO_TCP;
+		__efx_filter_get_ipv4(spec, &host1, &port1, host, port);
+		return 0;
+	case EFX_FILTER_UDP_WILD:
+		*proto = IPPROTO_UDP;
+		__efx_filter_get_ipv4(spec, &host1, port, host, &port1);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
 /**
  * efx_filter_set_ipv4_full - specify IPv4 hosts, transport protocol and ports
  * @spec: Specification to initialise
@@ -242,6 +272,25 @@ int efx_filter_set_ipv4_full(struct efx_filter_spec *spec, u8 proto,
 	return 0;
 }
 
+int efx_filter_get_ipv4_full(const struct efx_filter_spec *spec,
+			     u8 *proto, __be32 *host, __be16 *port,
+			     __be32 *rhost, __be16 *rport)
+{
+	switch (spec->type) {
+	case EFX_FILTER_TCP_FULL:
+		*proto = IPPROTO_TCP;
+		break;
+	case EFX_FILTER_UDP_FULL:
+		*proto = IPPROTO_UDP;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	__efx_filter_get_ipv4(spec, rhost, rport, host, port);
+	return 0;
+}
+
 /**
  * efx_filter_set_eth_local - specify local Ethernet address and optional VID
  * @spec: Specification to initialise
@@ -270,6 +319,29 @@ int efx_filter_set_eth_local(struct efx_filter_spec *spec,
 	return 0;
 }
 
+int efx_filter_get_eth_local(const struct efx_filter_spec *spec,
+			     u16 *vid, u8 *addr)
+{
+	switch (spec->type) {
+	case EFX_FILTER_MAC_WILD:
+		*vid = EFX_FILTER_VID_UNSPEC;
+		break;
+	case EFX_FILTER_MAC_FULL:
+		*vid = spec->data[0];
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	addr[0] = spec->data[2] >> 8;
+	addr[1] = spec->data[2];
+	addr[2] = spec->data[1] >> 24;
+	addr[3] = spec->data[1] >> 16;
+	addr[4] = spec->data[1] >> 8;
+	addr[5] = spec->data[1];
+	return 0;
+}
+
 /* Build a filter entry and return its n-tuple key. */
 static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec)
 {
@@ -407,6 +479,20 @@ static inline u8 efx_filter_id_flags(u32 id)
 		EFX_FILTER_FLAG_RX;
 }
 
+u32 efx_filter_get_rx_id_limit(struct efx_nic *efx)
+{
+	struct efx_filter_state *state = efx->filter_state;
+
+	if (state->table[EFX_FILTER_TABLE_RX_MAC].size != 0)
+		return ((EFX_FILTER_TABLE_RX_MAC + 1) << EFX_FILTER_INDEX_WIDTH)
+			+ state->table[EFX_FILTER_TABLE_RX_MAC].size;
+	else if (state->table[EFX_FILTER_TABLE_RX_IP].size != 0)
+		return ((EFX_FILTER_TABLE_RX_IP + 1) << EFX_FILTER_INDEX_WIDTH) 
+			+ state->table[EFX_FILTER_TABLE_RX_IP].size;
+	else
+		return 0;
+}
+
 /**
  * efx_filter_insert_filter - add or replace a filter
  * @efx: NIC in which to insert the filter
@@ -496,6 +582,105 @@ static void efx_filter_table_clear_entry(struct efx_nic *efx,
 }
 
 /**
+ * efx_filter_remove_id_safe - remove a filter by ID, carefully
+ * @efx: NIC from which to remove the filter
+ * @priority: Priority of filter, as passed to @efx_filter_insert_filter
+ * @filter_id: ID of filter, as returned by @efx_filter_insert_filter
+ *
+ * This function will range-check @filter_id, so it is safe to call
+ * with a value passed from userland.
+ */
+int efx_filter_remove_id_safe(struct efx_nic *efx,
+			      enum efx_filter_priority priority,
+			      u32 filter_id)
+{
+	struct efx_filter_state *state = efx->filter_state;
+	enum efx_filter_table_id table_id;
+	struct efx_filter_table *table;
+	unsigned int filter_idx;
+	struct efx_filter_spec *spec;
+	u8 filter_flags;
+	int rc;
+
+	table_id = efx_filter_id_table_id(filter_id);
+	if ((unsigned int)table_id >= EFX_FILTER_TABLE_COUNT)
+		return -ENOENT;
+	table = &state->table[table_id];
+
+	filter_idx = efx_filter_id_index(filter_id);
+	if (filter_idx >= table->size)
+		return -ENOENT;
+	spec = &table->spec[filter_idx];
+
+	filter_flags = efx_filter_id_flags(filter_id);
+
+	spin_lock_bh(&state->lock);
+
+	if (test_bit(filter_idx, table->used_bitmap) &&
+	    spec->priority == priority && spec->flags == filter_flags) {
+		efx_filter_table_clear_entry(efx, table, filter_idx);
+		if (table->used == 0)
+			efx_filter_table_reset_search_depth(table);
+		rc = 0;
+	} else {
+		rc = -ENOENT;
+	}
+
+	spin_unlock_bh(&state->lock);
+
+	return rc;
+}
+
+/**
+ * efx_filter_get_filter_safe - retrieve a filter by ID, carefully
+ * @efx: NIC from which to remove the filter
+ * @priority: Priority of filter, as passed to @efx_filter_insert_filter
+ * @filter_id: ID of filter, as returned by @efx_filter_insert_filter
+ * @spec: Buffer in which to store filter specification
+ *
+ * This function will range-check @filter_id, so it is safe to call
+ * with a value passed from userland.
+ */
+int efx_filter_get_filter_safe(struct efx_nic *efx,
+			       enum efx_filter_priority priority,
+			       u32 filter_id, struct efx_filter_spec *spec_buf)
+{
+	struct efx_filter_state *state = efx->filter_state;
+	enum efx_filter_table_id table_id;
+	struct efx_filter_table *table;
+	struct efx_filter_spec *spec;
+	unsigned int filter_idx;
+	u8 filter_flags;
+	int rc;
+
+	table_id = efx_filter_id_table_id(filter_id);
+	if ((unsigned int)table_id >= EFX_FILTER_TABLE_COUNT)
+		return -ENOENT;
+	table = &state->table[table_id];
+
+	filter_idx = efx_filter_id_index(filter_id);
+	if (filter_idx >= table->size)
+		return -ENOENT;
+	spec = &table->spec[filter_idx];
+
+	filter_flags = efx_filter_id_flags(filter_id);
+
+	spin_lock_bh(&state->lock);
+
+	if (test_bit(filter_idx, table->used_bitmap) &&
+	    spec->priority == priority && spec->flags == filter_flags) {
+		*spec_buf = *spec;
+		rc = 0;
+	} else {
+		rc = -ENOENT;
+	}
+
+	spin_unlock_bh(&state->lock);
+
+	return rc;
+}
+
+/**
  * efx_filter_remove_filter - remove a filter by specification
  * @efx: NIC from which to remove the filter
  * @spec: Specification for the filter
@@ -571,6 +756,68 @@ void efx_filter_clear_rx(struct efx_nic *efx, enum efx_filter_priority priority)
 	efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_MAC, priority);
 }
 
+u32 efx_filter_count_rx_used(struct efx_nic *efx,
+			     enum efx_filter_priority priority)
+{
+	struct efx_filter_state *state = efx->filter_state;
+	enum efx_filter_table_id table_id;
+	struct efx_filter_table *table;
+	unsigned int filter_idx;
+	u32 count = 0;
+
+	spin_lock_bh(&state->lock);
+
+	for (table_id = EFX_FILTER_TABLE_RX_IP;
+	     table_id <= EFX_FILTER_TABLE_RX_MAC;
+	     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) &&
+			    table->spec[filter_idx].priority == priority)
+				++count;
+		}
+	}
+
+	spin_unlock_bh(&state->lock);
+
+	return count;
+}
+
+s32 efx_filter_get_rx_ids(struct efx_nic *efx,
+			  enum efx_filter_priority priority,
+			  u32 *buf, u32 size)
+{
+	struct efx_filter_state *state = efx->filter_state;
+	enum efx_filter_table_id table_id;
+	struct efx_filter_table *table;
+	unsigned int filter_idx;
+	s32 count = 0;
+
+	spin_lock_bh(&state->lock);
+
+	for (table_id = EFX_FILTER_TABLE_RX_IP;
+	     table_id <= EFX_FILTER_TABLE_RX_MAC;
+	     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) &&
+			    table->spec[filter_idx].priority == priority) {
+				if (count == size) {
+					count = -EMSGSIZE;
+					goto out;
+				}
+				buf[count++] = efx_filter_make_id(
+					table_id, filter_idx,
+					table->spec[filter_idx].flags);
+			}
+		}
+	}
+out:
+	spin_unlock_bh(&state->lock);
+
+	return count;
+}
+
 /* Restore filter stater after reset */
 void efx_restore_filters(struct efx_nic *efx)
 {
diff --git a/drivers/net/ethernet/sfc/filter.h b/drivers/net/ethernet/sfc/filter.h
index dc9a256..3d4108c 100644
--- a/drivers/net/ethernet/sfc/filter.h
+++ b/drivers/net/ethernet/sfc/filter.h
@@ -105,11 +105,18 @@ static inline void efx_filter_init_rx(struct efx_filter_spec *spec,
 
 extern int efx_filter_set_ipv4_local(struct efx_filter_spec *spec, u8 proto,
 				     __be32 host, __be16 port);
+extern int efx_filter_get_ipv4_local(const struct efx_filter_spec *spec,
+				     u8 *proto, __be32 *host, __be16 *port);
 extern int efx_filter_set_ipv4_full(struct efx_filter_spec *spec, u8 proto,
 				    __be32 host, __be16 port,
 				    __be32 rhost, __be16 rport);
+extern int efx_filter_get_ipv4_full(const struct efx_filter_spec *spec,
+				    u8 *proto, __be32 *host, __be16 *port,
+				    __be32 *rhost, __be16 *rport);
 extern int efx_filter_set_eth_local(struct efx_filter_spec *spec,
 				    u16 vid, const u8 *addr);
+extern int efx_filter_get_eth_local(const struct efx_filter_spec *spec,
+				    u16 *vid, u8 *addr);
 enum {
 	EFX_FILTER_VID_UNSPEC = 0xffff,
 };
-- 
1.7.4.4



-- 
Ben Hutchings, Staff Engineer, Solarflare
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] 14+ messages in thread

* [PATCHv2 net-next 6/8] sfc: Implement ethtool RX NFC rules API instead of n-tuple API
  2012-01-03 21:56 [PATCHv2 net-next 0/8] RX NFC support for hash-based filters Ben Hutchings
                   ` (4 preceding siblings ...)
  2012-01-03 22:05 ` [PATCHv2 net-next 5/8] sfc: Add support for retrieving and removing filters by ID Ben Hutchings
@ 2012-01-03 22:05 ` Ben Hutchings
  2012-01-03 22:05 ` [PATCHv2 net-next 7/8] sfc: Remove now-unused filter function Ben Hutchings
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Ben Hutchings @ 2012-01-03 22:05 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers

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

diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c
index 1be51b2..289c13b 100644
--- a/drivers/net/ethernet/sfc/ethtool.c
+++ b/drivers/net/ethernet/sfc/ethtool.c
@@ -818,9 +818,58 @@ static int efx_ethtool_reset(struct net_device *net_dev, u32 *flags)
 	return efx_reset(efx, rc);
 }
 
+static int efx_ethtool_get_class_rule(struct efx_nic *efx,
+				      struct ethtool_rx_flow_spec *rule)
+{
+	struct ethtool_tcpip4_spec *ip_entry = &rule->h_u.tcp_ip4_spec;
+	struct ethtool_tcpip4_spec *ip_mask = &rule->m_u.tcp_ip4_spec;
+	struct efx_filter_spec spec;
+	u16 vid;
+	u8 proto;
+	int rc;
+
+	rc = efx_filter_get_filter_safe(efx, EFX_FILTER_PRI_MANUAL,
+					rule->location, &spec);
+	if (rc)
+		return rc;
+
+	if (spec.dmaq_id == 0xfff)
+		rule->ring_cookie = RX_CLS_FLOW_DISC;
+	else
+		rule->ring_cookie = spec.dmaq_id;
+
+	rc = efx_filter_get_eth_local(&spec, &vid,
+				      rule->h_u.ether_spec.h_dest);
+	if (rc == 0) {
+		rule->flow_type = ETHER_FLOW;
+		memset(rule->m_u.ether_spec.h_dest, ~0, ETH_ALEN);
+		if (vid != EFX_FILTER_VID_UNSPEC) {
+			rule->flow_type |= FLOW_EXT;
+			rule->h_ext.vlan_tci = htons(vid);
+			rule->m_ext.vlan_tci = htons(0xfff);
+		}
+		return 0;
+	}
+
+	rc = efx_filter_get_ipv4_local(&spec, &proto,
+				       &ip_entry->ip4dst, &ip_entry->pdst);
+	if (rc != 0) {
+		rc = efx_filter_get_ipv4_full(
+			&spec, &proto, &ip_entry->ip4src, &ip_entry->psrc,
+			&ip_entry->ip4dst, &ip_entry->pdst);
+		EFX_WARN_ON_PARANOID(rc);
+		ip_mask->ip4src = ~0;
+		ip_mask->psrc = ~0;
+	}
+	rule->flow_type = (proto == IPPROTO_TCP) ? TCP_V4_FLOW : UDP_V4_FLOW;
+	ip_mask->ip4dst = ~0;
+	ip_mask->pdst = ~0;
+	return rc;
+}
+
 static int
 efx_ethtool_get_rxnfc(struct net_device *net_dev,
-		      struct ethtool_rxnfc *info, u32 *rules __always_unused)
+		      struct ethtool_rxnfc *info, u32 *rule_locs)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
 
@@ -862,42 +911,80 @@ efx_ethtool_get_rxnfc(struct net_device *net_dev,
 		return 0;
 	}
 
+	case ETHTOOL_GRXCLSRLCNT:
+		info->data = efx_filter_get_rx_id_limit(efx);
+		if (info->data == 0)
+			return -EOPNOTSUPP;
+		info->data |= RX_CLS_LOC_SPECIAL;
+		info->rule_cnt =
+			efx_filter_count_rx_used(efx, EFX_FILTER_PRI_MANUAL);
+		return 0;
+
+	case ETHTOOL_GRXCLSRULE:
+		if (efx_filter_get_rx_id_limit(efx) == 0)
+			return -EOPNOTSUPP;
+		return efx_ethtool_get_class_rule(efx, &info->fs);
+
+	case ETHTOOL_GRXCLSRLALL: {
+		s32 rc;
+		info->data = efx_filter_get_rx_id_limit(efx);
+		if (info->data == 0)
+			return -EOPNOTSUPP;
+		rc = efx_filter_get_rx_ids(efx, EFX_FILTER_PRI_MANUAL,
+					   rule_locs, info->rule_cnt);
+		if (rc < 0)
+			return rc;
+		info->rule_cnt = rc;
+		return 0;
+	}
+
 	default:
 		return -EOPNOTSUPP;
 	}
 }
 
-static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev,
-				     struct ethtool_rx_ntuple *ntuple)
+static int efx_ethtool_set_class_rule(struct efx_nic *efx,
+				      struct ethtool_rx_flow_spec *rule)
 {
-	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;
+	struct ethtool_tcpip4_spec *ip_entry = &rule->h_u.tcp_ip4_spec;
+	struct ethtool_tcpip4_spec *ip_mask = &rule->m_u.tcp_ip4_spec;
+	struct ethhdr *mac_entry = &rule->h_u.ether_spec;
+	struct ethhdr *mac_mask = &rule->m_u.ether_spec;
+	struct efx_filter_spec spec;
 	int rc;
 
-	/* Range-check action */
-	if (ntuple->fs.action < ETHTOOL_RXNTUPLE_ACTION_CLEAR ||
-	    ntuple->fs.action >= (s32)efx->n_rx_channels)
+	/* Check that user wants us to choose the location */
+	if (rule->location != RX_CLS_LOC_ANY &&
+	    rule->location != RX_CLS_LOC_FIRST &&
+	    rule->location != RX_CLS_LOC_LAST)
 		return -EINVAL;
 
-	if (~ntuple->fs.data_mask)
+	/* Range-check ring_cookie */
+	if (rule->ring_cookie >= efx->n_rx_channels &&
+	    rule->ring_cookie != RX_CLS_FLOW_DISC)
 		return -EINVAL;
 
-	efx_filter_init_rx(&filter, EFX_FILTER_PRI_MANUAL, 0,
-			   (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP) ?
-			   0xfff : ntuple->fs.action);
+	/* Check for unsupported extensions */
+	if ((rule->flow_type & FLOW_EXT) &&
+	    (rule->m_ext.vlan_etype | rule->m_ext.data[0] |
+	     rule->m_ext.data[1]))
+		return -EINVAL;
+
+	efx_filter_init_rx(&spec, EFX_FILTER_PRI_MANUAL,
+			   (rule->location == RX_CLS_LOC_FIRST) ?
+			   EFX_FILTER_FLAG_RX_OVERRIDE_IP : 0,
+			   (rule->ring_cookie == RX_CLS_FLOW_DISC) ?
+			   0xfff : rule->ring_cookie);
 
-	switch (ntuple->fs.flow_type) {
+	switch (rule->flow_type) {
 	case TCP_V4_FLOW:
 	case UDP_V4_FLOW: {
-		u8 proto = (ntuple->fs.flow_type == TCP_V4_FLOW ?
+		u8 proto = (rule->flow_type == TCP_V4_FLOW ?
 			    IPPROTO_TCP : IPPROTO_UDP);
 
 		/* Must match all of destination, */
-		if (ip_mask->ip4dst | ip_mask->pdst)
+		if ((__force u32)~ip_mask->ip4dst |
+		    (__force u16)~ip_mask->pdst)
 			return -EINVAL;
 		/* all or none of source, */
 		if ((ip_mask->ip4src | ip_mask->psrc) &&
@@ -905,17 +992,17 @@ static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev,
 		     (__force u16)~ip_mask->psrc))
 			return -EINVAL;
 		/* and nothing else */
-		if ((u8)~ip_mask->tos | (u16)~ntuple->fs.vlan_tag_mask)
+		if (ip_mask->tos | rule->m_ext.vlan_tci)
 			return -EINVAL;
 
-		if (!ip_mask->ip4src)
-			rc = efx_filter_set_ipv4_full(&filter, proto,
+		if (ip_mask->ip4src)
+			rc = efx_filter_set_ipv4_full(&spec, proto,
 						      ip_entry->ip4dst,
 						      ip_entry->pdst,
 						      ip_entry->ip4src,
 						      ip_entry->psrc);
 		else
-			rc = efx_filter_set_ipv4_local(&filter, proto,
+			rc = efx_filter_set_ipv4_local(&spec, proto,
 						       ip_entry->ip4dst,
 						       ip_entry->pdst);
 		if (rc)
@@ -923,23 +1010,24 @@ static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev,
 		break;
 	}
 
-	case ETHER_FLOW:
-		/* Must match all of destination, */
-		if (!is_zero_ether_addr(mac_mask->h_dest))
+	case ETHER_FLOW | FLOW_EXT:	
+		/* Must match all or none of VID */
+		if (rule->m_ext.vlan_tci != htons(0xfff) &&
+		    rule->m_ext.vlan_tci != 0)
 			return -EINVAL;
-		/* all or none of VID, */
-		if (ntuple->fs.vlan_tag_mask != 0xf000 &&
-		    ntuple->fs.vlan_tag_mask != 0xffff)
+	case ETHER_FLOW:
+		/* Must match all of destination */
+		if (!is_broadcast_ether_addr(mac_mask->h_dest))
 			return -EINVAL;
 		/* and nothing else */
-		if (!is_broadcast_ether_addr(mac_mask->h_source) ||
-		    mac_mask->h_proto != htons(0xffff))
+		if (!is_zero_ether_addr(mac_mask->h_source) ||
+		    mac_mask->h_proto)
 			return -EINVAL;
 
 		rc = efx_filter_set_eth_local(
-			&filter,
-			(ntuple->fs.vlan_tag_mask == 0xf000) ?
-			ntuple->fs.vlan_tag : EFX_FILTER_VID_UNSPEC,
+			&spec,
+			(rule->flow_type & FLOW_EXT && rule->m_ext.vlan_tci) ?
+			ntohs(rule->h_ext.vlan_tci) : EFX_FILTER_VID_UNSPEC,
 			mac_entry->h_dest);
 		if (rc)
 			return rc;
@@ -949,11 +1037,33 @@ static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev,
 		return -EINVAL;
 	}
 
-	if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_CLEAR)
-		return efx_filter_remove_filter(efx, &filter);
+	rc = efx_filter_insert_filter(efx, &spec, true);
+	if (rc < 0)
+		return rc;
 
-	rc = efx_filter_insert_filter(efx, &filter, true);
-	return rc < 0 ? rc : 0;
+	rule->location = rc;
+	return 0;
+}
+
+static int efx_ethtool_set_rxnfc(struct net_device *net_dev,
+				 struct ethtool_rxnfc *info)
+{
+	struct efx_nic *efx = netdev_priv(net_dev);
+
+	if (efx_filter_get_rx_id_limit(efx) == 0)
+		return -EOPNOTSUPP;
+
+	switch (info->cmd) {
+	case ETHTOOL_SRXCLSRLINS:
+		return efx_ethtool_set_class_rule(efx, &info->fs);
+
+	case ETHTOOL_SRXCLSRLDEL:
+		return efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_MANUAL,
+						 info->fs.location);
+
+	default:
+		return -EOPNOTSUPP;
+	}
 }
 
 static u32 efx_ethtool_get_rxfh_indir_size(struct net_device *net_dev)
@@ -1007,7 +1117,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,
+	.set_rxnfc		= efx_ethtool_set_rxnfc,
 	.get_rxfh_indir_size	= efx_ethtool_get_rxfh_indir_size,
 	.get_rxfh_indir		= efx_ethtool_get_rxfh_indir,
 	.set_rxfh_indir		= efx_ethtool_set_rxfh_indir,
-- 
1.7.4.4



-- 
Ben Hutchings, Staff Engineer, Solarflare
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] 14+ messages in thread

* [PATCHv2 net-next 7/8] sfc: Remove now-unused filter function
  2012-01-03 21:56 [PATCHv2 net-next 0/8] RX NFC support for hash-based filters Ben Hutchings
                   ` (5 preceding siblings ...)
  2012-01-03 22:05 ` [PATCHv2 net-next 6/8] sfc: Implement ethtool RX NFC rules API instead of n-tuple API Ben Hutchings
@ 2012-01-03 22:05 ` Ben Hutchings
  2012-01-03 22:07 ` [PATCHv2 net-next 8/8] ethtool: Remove ethtool_ops::set_rx_ntuple operation Ben Hutchings
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Ben Hutchings @ 2012-01-03 22:05 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers

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

diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h
index f0a5b7c..a3541ac 100644
--- a/drivers/net/ethernet/sfc/efx.h
+++ b/drivers/net/ethernet/sfc/efx.h
@@ -64,8 +64,6 @@ extern void efx_remove_filters(struct efx_nic *efx);
 extern s32 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 int efx_filter_remove_id_safe(struct efx_nic *efx,
 				     enum efx_filter_priority priority,
 				     u32 filter_id);
diff --git a/drivers/net/ethernet/sfc/filter.c b/drivers/net/ethernet/sfc/filter.c
index 8e3d33d..929b09b 100644
--- a/drivers/net/ethernet/sfc/filter.c
+++ b/drivers/net/ethernet/sfc/filter.c
@@ -680,52 +680,6 @@ int efx_filter_get_filter_safe(struct efx_nic *efx,
 	return rc;
 }
 
-/**
- * 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;
-	struct efx_filter_table *table = efx_filter_spec_table(state, spec);
-	struct efx_filter_spec *saved_spec;
-	efx_oword_t filter;
-	unsigned int filter_idx, depth;
-	u32 key;
-	int rc;
-
-	if (!table)
-		return -EINVAL;
-
-	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(table);
-	rc = 0;
-
-out:
-	spin_unlock_bh(&state->lock);
-	return rc;
-}
-
 static void efx_filter_table_clear(struct efx_nic *efx,
 				   enum efx_filter_table_id table_id,
 				   enum efx_filter_priority priority)
-- 
1.7.4.4



-- 
Ben Hutchings, Staff Engineer, Solarflare
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] 14+ messages in thread

* [PATCHv2 net-next 8/8] ethtool: Remove ethtool_ops::set_rx_ntuple operation
  2012-01-03 21:56 [PATCHv2 net-next 0/8] RX NFC support for hash-based filters Ben Hutchings
                   ` (6 preceding siblings ...)
  2012-01-03 22:05 ` [PATCHv2 net-next 7/8] sfc: Remove now-unused filter function Ben Hutchings
@ 2012-01-03 22:07 ` Ben Hutchings
  2012-01-03 22:24 ` [PATCHv2 ethtool 1/3] ethtool-copy.h: sync with net-next Ben Hutchings
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Ben Hutchings @ 2012-01-03 22:07 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers, Alexander Duyck

All implementations have been converted to implement set_rxnfc
instead.

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

diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index d901714..da5b2de 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -859,8 +859,6 @@ static inline u32 ethtool_rxfh_indir_default(u32 index, u32 n_rx_rings)
  * @reset: Reset (part of) the device, as specified by a bitmask of
  *	flags from &enum ethtool_reset_flags.  Returns a negative
  *	error code or zero.
- * @set_rx_ntuple: Set an RX n-tuple rule.  Returns a negative error code
- *	or zero.
  * @get_rxfh_indir_size: Get the size of the RX flow hash indirection table.
  *	Returns zero if not supported for this specific device.
  * @get_rxfh_indir: Get the contents of the RX flow hash indirection table.
@@ -929,8 +927,6 @@ struct ethtool_ops {
 	int	(*set_rxnfc)(struct net_device *, struct ethtool_rxnfc *);
 	int	(*flash_device)(struct net_device *, struct ethtool_flash *);
 	int	(*reset)(struct net_device *, u32 *);
-	int	(*set_rx_ntuple)(struct net_device *,
-				 struct ethtool_rx_ntuple *);
 	u32	(*get_rxfh_indir_size)(struct net_device *);
 	int	(*get_rxfh_indir)(struct net_device *, u32 *);
 	int	(*set_rxfh_indir)(struct net_device *, const u32 *);
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index e88b80d..921aa2b 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -631,58 +631,6 @@ out:
 	return ret;
 }
 
-/*
- * ethtool does not (or did not) set masks for flow parameters that are
- * not specified, so if both value and mask are 0 then this must be
- * treated as equivalent to a mask with all bits set.  Implement that
- * here rather than in drivers.
- */
-static void rx_ntuple_fix_masks(struct ethtool_rx_ntuple_flow_spec *fs)
-{
-	struct ethtool_tcpip4_spec *entry = &fs->h_u.tcp_ip4_spec;
-	struct ethtool_tcpip4_spec *mask = &fs->m_u.tcp_ip4_spec;
-
-	if (fs->flow_type != TCP_V4_FLOW &&
-	    fs->flow_type != UDP_V4_FLOW &&
-	    fs->flow_type != SCTP_V4_FLOW)
-		return;
-
-	if (!(entry->ip4src | mask->ip4src))
-		mask->ip4src = htonl(0xffffffff);
-	if (!(entry->ip4dst | mask->ip4dst))
-		mask->ip4dst = htonl(0xffffffff);
-	if (!(entry->psrc | mask->psrc))
-		mask->psrc = htons(0xffff);
-	if (!(entry->pdst | mask->pdst))
-		mask->pdst = htons(0xffff);
-	if (!(entry->tos | mask->tos))
-		mask->tos = 0xff;
-	if (!(fs->vlan_tag | fs->vlan_tag_mask))
-		fs->vlan_tag_mask = 0xffff;
-	if (!(fs->data | fs->data_mask))
-		fs->data_mask = 0xffffffffffffffffULL;
-}
-
-static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev,
-						    void __user *useraddr)
-{
-	struct ethtool_rx_ntuple cmd;
-	const struct ethtool_ops *ops = dev->ethtool_ops;
-
-	if (!ops->set_rx_ntuple)
-		return -EOPNOTSUPP;
-
-	if (!(dev->features & NETIF_F_NTUPLE))
-		return -EINVAL;
-
-	if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
-		return -EFAULT;
-
-	rx_ntuple_fix_masks(&cmd.fs);
-
-	return ops->set_rx_ntuple(dev, &cmd);
-}
-
 static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
 {
 	struct ethtool_regs regs;
@@ -1495,9 +1443,6 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
 	case ETHTOOL_RESET:
 		rc = ethtool_reset(dev, useraddr);
 		break;
-	case ETHTOOL_SRXNTUPLE:
-		rc = ethtool_set_rx_ntuple(dev, useraddr);
-		break;
 	case ETHTOOL_GSSET_INFO:
 		rc = ethtool_get_sset_info(dev, useraddr);
 		break;
-- 
1.7.4.4


-- 
Ben Hutchings, Staff Engineer, Solarflare
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] 14+ messages in thread

* [PATCHv2 ethtool 1/3] ethtool-copy.h: sync with net-next
  2012-01-03 21:56 [PATCHv2 net-next 0/8] RX NFC support for hash-based filters Ben Hutchings
                   ` (7 preceding siblings ...)
  2012-01-03 22:07 ` [PATCHv2 net-next 8/8] ethtool: Remove ethtool_ops::set_rx_ntuple operation Ben Hutchings
@ 2012-01-03 22:24 ` Ben Hutchings
  2012-01-03 22:24 ` [PATCHv2 ethtool 2/3] rxclass: Use RX_CLS_LOC_{ANY,SPECIAL} in place of RX_CLS_LOC_UNSPEC Ben Hutchings
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Ben Hutchings @ 2012-01-03 22:24 UTC (permalink / raw)
  To: netdev; +Cc: linux-net-drivers

This covers kernel changes up to:

commit XXX NOT YET PULLED
Author: Ben Hutchings <bhutchings@solarflare.com>
Date:   Tue Sep 6 21:58:27 2011 +0100

    ethtool: Remove ethtool_ops::set_rx_ntuple operation

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 ethtool-copy.h |   38 ++++++++++++++++++++++++++++++++++----
 1 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/ethtool-copy.h b/ethtool-copy.h
index 8342ade..d904c1a 100644
--- a/ethtool-copy.h
+++ b/ethtool-copy.h
@@ -486,7 +486,10 @@ struct ethtool_rx_flow_spec {
  * on return.
  *
  * For %ETHTOOL_GRXCLSRLCNT, @rule_cnt is set to the number of defined
- * rules on return.
+ * rules on return.  If @data is non-zero on return then it is the
+ * size of the rule table, plus the flag %RX_CLS_LOC_SPECIAL if the
+ * driver supports any special location values.  If that flag is not
+ * set in @data then special location values should not be used.
  *
  * For %ETHTOOL_GRXCLSRULE, @fs.@location specifies the location of an
  * existing rule on entry and @fs contains the rule on return.
@@ -498,10 +501,23 @@ struct ethtool_rx_flow_spec {
  * must use the second parameter to get_rxnfc() instead of @rule_locs.
  *
  * For %ETHTOOL_SRXCLSRLINS, @fs specifies the rule to add or update.
- * @fs.@location specifies the location to use and must not be ignored.
+ * @fs.@location either specifies the location to use or is a special
+ * location value with %RX_CLS_LOC_SPECIAL flag set.  On return,
+ * @fs.@location is the actual rule location.
  *
  * For %ETHTOOL_SRXCLSRLDEL, @fs.@location specifies the location of an
  * existing rule on entry.
+ *
+ * A driver supporting the special location values for
+ * %ETHTOOL_SRXCLSRLINS may add the rule at any suitable unused
+ * location, and may remove a rule at a later location (lower
+ * priority) that matches exactly the same set of flows.  The special
+ * values are: %RX_CLS_LOC_ANY, selecting any location;
+ * %RX_CLS_LOC_FIRST, selecting the first suitable location (maximum
+ * priority); and %RX_CLS_LOC_LAST, selecting the last suitable
+ * location (minimum priority).  Additional special values may be
+ * defined in future and drivers must return -%EINVAL for any
+ * unrecognised value.
  */
 struct ethtool_rxnfc {
 	__u32				cmd;
@@ -516,9 +532,15 @@ struct ethtool_rxnfc {
 /**
  * struct ethtool_rxfh_indir - command to get or set RX flow hash indirection
  * @cmd: Specific command number - %ETHTOOL_GRXFHINDIR or %ETHTOOL_SRXFHINDIR
- * @size: On entry, the array size of the user buffer.  On return from
- *	%ETHTOOL_GRXFHINDIR, the array size of the hardware indirection table.
+ * @size: On entry, the array size of the user buffer, which may be zero.
+ *	On return from %ETHTOOL_GRXFHINDIR, the array size of the hardware
+ *	indirection table.
  * @ring_index: RX ring/queue index for each hash value
+ *
+ * For %ETHTOOL_GRXFHINDIR, a @size of zero means that only the size
+ * should be returned.  For %ETHTOOL_SRXFHINDIR, a @size of zero means
+ * the table should be reset to default values.  This last feature
+ * is not supported by the original implementations.
  */
 struct ethtool_rxfh_indir {
 	__u32	cmd;
@@ -831,10 +853,12 @@ enum ethtool_sfeatures_retval_bits {
 #define SPEED_1000		1000
 #define SPEED_2500		2500
 #define SPEED_10000		10000
+#define SPEED_UNKNOWN		-1
 
 /* Duplex, half or full. */
 #define DUPLEX_HALF		0x00
 #define DUPLEX_FULL		0x01
+#define DUPLEX_UNKNOWN		0xff
 
 /* Which connector port. */
 #define PORT_TP			0x00
@@ -905,6 +929,12 @@ enum ethtool_sfeatures_retval_bits {
 
 #define	RX_CLS_FLOW_DISC	0xffffffffffffffffULL
 
+/* Special RX classification rule insert location values */
+#define RX_CLS_LOC_SPECIAL	0x80000000	/* flag */
+#define RX_CLS_LOC_ANY		0xffffffff
+#define RX_CLS_LOC_FIRST	0xfffffffe
+#define RX_CLS_LOC_LAST		0xfffffffd
+
 /* Reset flags */
 /* The reset() operation must clear the flags for the components which
  * were actually reset.  On successful return, the flags indicate the
-- 
1.7.4.4



-- 
Ben Hutchings, Staff Engineer, Solarflare
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] 14+ messages in thread

* [PATCHv2 ethtool 2/3] rxclass: Use RX_CLS_LOC_{ANY,SPECIAL} in place of RX_CLS_LOC_UNSPEC
  2012-01-03 21:56 [PATCHv2 net-next 0/8] RX NFC support for hash-based filters Ben Hutchings
                   ` (8 preceding siblings ...)
  2012-01-03 22:24 ` [PATCHv2 ethtool 1/3] ethtool-copy.h: sync with net-next Ben Hutchings
@ 2012-01-03 22:24 ` Ben Hutchings
  2012-01-03 22:25 ` [PATCHv2 ethtool 3/3] rxclass: Allow driver to select RX NFC rule location Ben Hutchings
  2012-01-04 19:11 ` [PATCHv2 net-next 0/8] RX NFC support for hash-based filters David Miller
  11 siblings, 0 replies; 14+ messages in thread
From: Ben Hutchings @ 2012-01-03 22:24 UTC (permalink / raw)
  To: netdev; +Cc: linux-net-drivers

The macro RX_CLS_LOC_ANY is now defined in ethtool(-copy).h with the
same intended semantics and same value as RX_CLS_LOC_UNSPEC.

Change some equality tests to check for the flag RX_CLS_LOC_SPECIAL,
to allow for future support of other special location value.

Remove the special case for RX_CLS_LOC_UNSPEC in
rxclass_print_nfc_rule(), since it is dead code.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 ethtool.c  |    2 +-
 internal.h |    2 --
 rxclass.c  |   11 ++++-------
 3 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index d21eaea..d0cc7d4 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -2719,7 +2719,7 @@ static int flow_spec_to_ntuple(struct ethtool_rx_flow_spec *fsp,
 	size_t i;
 
 	/* verify location is not specified */
-	if (fsp->location != RX_CLS_LOC_UNSPEC)
+	if (fsp->location != RX_CLS_LOC_ANY)
 		return -1;
 
 	/* verify ring cookie can transfer to action */
diff --git a/internal.h b/internal.h
index cb126b3..867c0ea 100644
--- a/internal.h
+++ b/internal.h
@@ -86,8 +86,6 @@ static inline int test_bit(unsigned int nr, const unsigned long *addr)
 #define SIOCETHTOOL     0x8946
 #endif
 
-#define	RX_CLS_LOC_UNSPEC	0xffffffffUL
-
 /* Context for sub-commands */
 struct cmd_context {
 	const char *devname;	/* net device name */
diff --git a/rxclass.c b/rxclass.c
index 1980d0e..9c7456f 100644
--- a/rxclass.c
+++ b/rxclass.c
@@ -68,10 +68,7 @@ static void rxclass_print_nfc_rule(struct ethtool_rx_flow_spec *fsp)
 	unsigned char	*smac, *smacm, *dmac, *dmacm;
 	__u32		flow_type;
 
-	if (fsp->location != RX_CLS_LOC_UNSPEC)
-		fprintf(stdout,	"Filter: %d\n", fsp->location);
-	else
-		fprintf(stdout,	"Filter: Unspecified\n");
+	fprintf(stdout,	"Filter: %d\n", fsp->location);
 
 	flow_type = fsp->flow_type & ~FLOW_EXT;
 
@@ -465,7 +462,7 @@ int rxclass_rule_ins(struct cmd_context *ctx,
 	 * if location is unspecified pull rules from device
 	 * and allocate a free rule for our use
 	 */
-	if (loc == RX_CLS_LOC_UNSPEC) {
+	if (loc & RX_CLS_LOC_SPECIAL) {
 		err = rmgr_set_location(ctx, fsp);
 		if (err < 0)
 			return err;
@@ -477,7 +474,7 @@ int rxclass_rule_ins(struct cmd_context *ctx,
 	err = send_ioctl(ctx, &nfccmd);
 	if (err < 0)
 		perror("rmgr: Cannot insert RX class rule");
-	else if (loc == RX_CLS_LOC_UNSPEC)
+	else if (loc & RX_CLS_LOC_SPECIAL)
 		printf("Added rule with ID %d\n", fsp->location);
 
 	return 0;
@@ -998,7 +995,7 @@ int rxclass_parse_ruleopts(struct cmd_context *ctx,
 
 	memset(p, 0, sizeof(*fsp));
 	fsp->flow_type = flow_type;
-	fsp->location = RX_CLS_LOC_UNSPEC;
+	fsp->location = RX_CLS_LOC_ANY;
 
 	for (i = 1; i < argc;) {
 		const struct rule_opts *opt;
-- 
1.7.4.4



-- 
Ben Hutchings, Staff Engineer, Solarflare
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] 14+ messages in thread

* [PATCHv2 ethtool 3/3] rxclass: Allow driver to select RX NFC rule location
  2012-01-03 21:56 [PATCHv2 net-next 0/8] RX NFC support for hash-based filters Ben Hutchings
                   ` (9 preceding siblings ...)
  2012-01-03 22:24 ` [PATCHv2 ethtool 2/3] rxclass: Use RX_CLS_LOC_{ANY,SPECIAL} in place of RX_CLS_LOC_UNSPEC Ben Hutchings
@ 2012-01-03 22:25 ` Ben Hutchings
  2012-01-04 19:11 ` [PATCHv2 net-next 0/8] RX NFC support for hash-based filters David Miller
  11 siblings, 0 replies; 14+ messages in thread
From: Ben Hutchings @ 2012-01-03 22:25 UTC (permalink / raw)
  To: netdev; +Cc: linux-net-drivers

If the user does not specify a location for an RX NFC rule to be added
and the result of the ETHTOOL_GRXCLSRLCNT command indicates that the
driver supports special rule locations, let the driver select the
location.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 rxclass.c |   29 ++++++++++++++++++++---------
 1 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/rxclass.c b/rxclass.c
index 9c7456f..4d49aa6 100644
--- a/rxclass.c
+++ b/rxclass.c
@@ -200,16 +200,17 @@ static void rxclass_print_rule(struct ethtool_rx_flow_spec *fsp)
 	}
 }
 
-static int rxclass_get_count(struct cmd_context *ctx, __u32 *count)
+static int rxclass_get_dev_info(struct cmd_context *ctx, __u32 *count,
+				int *driver_select)
 {
 	struct ethtool_rxnfc nfccmd;
 	int err;
 
-	/* request count and store */
 	nfccmd.cmd = ETHTOOL_GRXCLSRLCNT;
-	nfccmd.rule_cnt = 0;
 	err = send_ioctl(ctx, &nfccmd);
 	*count = nfccmd.rule_cnt;
+	if (driver_select)
+		*driver_select = !!(nfccmd.data & RX_CLS_LOC_SPECIAL);
 	if (err < 0)
 		perror("rxclass: Cannot get RX class rule count");
 
@@ -244,7 +245,7 @@ int rxclass_rule_getall(struct cmd_context *ctx)
 	__u32 count;
 
 	/* determine rule count */
-	err = rxclass_get_count(ctx, &count);
+	err = rxclass_get_dev_info(ctx, &count, NULL);
 	if (err < 0)
 		return err;
 
@@ -290,6 +291,8 @@ int rxclass_rule_getall(struct cmd_context *ctx)
  */
 
 struct rmgr_ctrl {
+	/* flag for device/driver that can select locations itself */
+	int			driver_select;
 	/* slot contains a bitmap indicating which filters are valid */
 	unsigned long		*slot;
 	__u32			n_rules;
@@ -316,6 +319,10 @@ static int rmgr_find_empty_slot(struct rmgr_ctrl *rmgr,
 	__u32 loc;
 	__u32 slot_num;
 
+	/* leave this to the driver if possible */
+	if (rmgr->driver_select)
+		return 0;
+
 	/* start at the end of the list since it is lowest priority */
 	loc = rmgr->size - 1;
 
@@ -373,11 +380,15 @@ static int rmgr_init(struct cmd_context *ctx, struct rmgr_ctrl *rmgr)
 	/* clear rule manager settings */
 	memset(rmgr, 0, sizeof(*rmgr));
 
-	/* request count and store in rmgr->n_rules */
-	err = rxclass_get_count(ctx, &rmgr->n_rules);
+	/* request device/driver information */
+	err = rxclass_get_dev_info(ctx, &rmgr->n_rules, &rmgr->driver_select);
 	if (err < 0)
 		return err;
 
+	/* do not get the table if the device/driver can select locations */
+	if (rmgr->driver_select)
+		return 0;
+
 	/* alloc memory for request of location list */
 	nfccmd = calloc(1, sizeof(*nfccmd) + (rmgr->n_rules * sizeof(__u32)));
 	if (!nfccmd) {
@@ -459,8 +470,8 @@ int rxclass_rule_ins(struct cmd_context *ctx,
 	int err;
 
 	/*
-	 * if location is unspecified pull rules from device
-	 * and allocate a free rule for our use
+	 * if location is unspecified and driver cannot select locations, pull
+	 * rules from device and allocate a free rule for our use
 	 */
 	if (loc & RX_CLS_LOC_SPECIAL) {
 		err = rmgr_set_location(ctx, fsp);
@@ -475,7 +486,7 @@ int rxclass_rule_ins(struct cmd_context *ctx,
 	if (err < 0)
 		perror("rmgr: Cannot insert RX class rule");
 	else if (loc & RX_CLS_LOC_SPECIAL)
-		printf("Added rule with ID %d\n", fsp->location);
+		printf("Added rule with ID %d\n", nfccmd.fs.location);
 
 	return 0;
 }
-- 
1.7.4.4


-- 
Ben Hutchings, Staff Engineer, Solarflare
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] 14+ messages in thread

* Re: [PATCHv2 net-next 0/8] RX NFC support for hash-based filters
  2012-01-03 21:56 [PATCHv2 net-next 0/8] RX NFC support for hash-based filters Ben Hutchings
                   ` (10 preceding siblings ...)
  2012-01-03 22:25 ` [PATCHv2 ethtool 3/3] rxclass: Allow driver to select RX NFC rule location Ben Hutchings
@ 2012-01-04 19:11 ` David Miller
  2012-01-04 21:39   ` Ben Hutchings
  11 siblings, 1 reply; 14+ messages in thread
From: David Miller @ 2012-01-04 19:11 UTC (permalink / raw)
  To: bhutchings; +Cc: netdev, linux-net-drivers

From: Ben Hutchings <bhutchings@solarflare.com>
Date: Tue, 3 Jan 2012 21:56:59 +0000

> 1. Fix gianfar's validation of filter rule locations.  In the previous
>    version of this series, this was a requirement for part 2, but that's
>    no longer the case.
> 
> 2. Extend ethtool RX NFC rules API to support hash-based filter hardware
>    in which rule locations should be selected by the driver or firmware.
> 
> 3. Change the sfc driver to implement this API instead of RX n-tuple.
> 
> 4. Remove support for RX n-tuple, now that there are no in-tree
>    implementations.

All applied, I had to fix some trailing whitespace errors in patches
5 and 6.

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

* Re: [PATCHv2 net-next 0/8] RX NFC support for hash-based filters
  2012-01-04 19:11 ` [PATCHv2 net-next 0/8] RX NFC support for hash-based filters David Miller
@ 2012-01-04 21:39   ` Ben Hutchings
  0 siblings, 0 replies; 14+ messages in thread
From: Ben Hutchings @ 2012-01-04 21:39 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers

On Wed, 2012-01-04 at 14:11 -0500, David Miller wrote:
> From: Ben Hutchings <bhutchings@solarflare.com>
> Date: Tue, 3 Jan 2012 21:56:59 +0000
> 
> > 1. Fix gianfar's validation of filter rule locations.  In the previous
> >    version of this series, this was a requirement for part 2, but that's
> >    no longer the case.
> > 
> > 2. Extend ethtool RX NFC rules API to support hash-based filter hardware
> >    in which rule locations should be selected by the driver or firmware.
> > 
> > 3. Change the sfc driver to implement this API instead of RX n-tuple.
> > 
> > 4. Remove support for RX n-tuple, now that there are no in-tree
> >    implementations.
> 
> All applied, I had to fix some trailing whitespace errors in patches
> 5 and 6.

Thanks, and sorry about the formatting.  I should try to work out why
git didn't alert me to that earlier...

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
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] 14+ messages in thread

end of thread, other threads:[~2012-01-04 21:39 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-03 21:56 [PATCHv2 net-next 0/8] RX NFC support for hash-based filters Ben Hutchings
2012-01-03 21:59 ` [PATCHv2 net-next 1/8] gianfar: Reject out-of-range RX NFC locations Ben Hutchings
2012-01-03 22:04 ` [PATCHv2 net-next 2/8] ethtool: Allow drivers to select RX NFC rule locations Ben Hutchings
2012-01-03 22:05 ` [PATCHv2 net-next 3/8] sfc: Change filter ID generation to satisfy priority semantics of RX NFC Ben Hutchings
2012-01-03 22:05 ` [PATCHv2 net-next 4/8] sfc: Use consistent types for filter IDs, indices and search depths Ben Hutchings
2012-01-03 22:05 ` [PATCHv2 net-next 5/8] sfc: Add support for retrieving and removing filters by ID Ben Hutchings
2012-01-03 22:05 ` [PATCHv2 net-next 6/8] sfc: Implement ethtool RX NFC rules API instead of n-tuple API Ben Hutchings
2012-01-03 22:05 ` [PATCHv2 net-next 7/8] sfc: Remove now-unused filter function Ben Hutchings
2012-01-03 22:07 ` [PATCHv2 net-next 8/8] ethtool: Remove ethtool_ops::set_rx_ntuple operation Ben Hutchings
2012-01-03 22:24 ` [PATCHv2 ethtool 1/3] ethtool-copy.h: sync with net-next Ben Hutchings
2012-01-03 22:24 ` [PATCHv2 ethtool 2/3] rxclass: Use RX_CLS_LOC_{ANY,SPECIAL} in place of RX_CLS_LOC_UNSPEC Ben Hutchings
2012-01-03 22:25 ` [PATCHv2 ethtool 3/3] rxclass: Allow driver to select RX NFC rule location Ben Hutchings
2012-01-04 19:11 ` [PATCHv2 net-next 0/8] RX NFC support for hash-based filters David Miller
2012-01-04 21:39   ` 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).