aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2012-01-03 07:05:15 -0500
committerDavid S. Miller <davem@davemloft.net>2012-01-04 14:09:11 -0500
commitb1f9284b4e6e5f7a44d6af3e111b33e61b261f26 (patch)
tree8157511c668b135babc99ed155fdf649d570d7fe /drivers/net/ethernet
parent55664f324c2a1a6386dc88492c5c94aa3d336b93 (diff)
sfc: Change filter ID generation to satisfy priority semantics of RX NFC
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> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/sfc/filter.c43
-rw-r--r--drivers/net/ethernet/sfc/filter.h5
2 files changed, 43 insertions, 5 deletions
diff --git a/drivers/net/ethernet/sfc/filter.c b/drivers/net/ethernet/sfc/filter.c
index 2b9636f96e05..1e079bd31bb9 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,
366 } 366 }
367} 367}
368 368
369/* Construct/deconstruct external filter IDs */ 369/*
370 * Construct/deconstruct external filter IDs. These must be ordered
371 * by matching priority, for RX NFC semantics.
372 *
373 * Each RX MAC filter entry has a flag for whether it can override an
374 * RX IP filter that also matches. So we assign locations for MAC
375 * filters with overriding behaviour, then for IP filters, then for
376 * MAC filters without overriding behaviour.
377 */
378
379#define EFX_FILTER_INDEX_WIDTH 13
380#define EFX_FILTER_INDEX_MASK ((1 << EFX_FILTER_INDEX_WIDTH) - 1)
381
382static inline u32 efx_filter_make_id(enum efx_filter_table_id table_id,
383 unsigned int index, u8 flags)
384{
385 return (table_id == EFX_FILTER_TABLE_RX_MAC &&
386 flags & EFX_FILTER_FLAG_RX_OVERRIDE_IP) ?
387 index :
388 (table_id + 1) << EFX_FILTER_INDEX_WIDTH | index;
389}
390
391static inline enum efx_filter_table_id efx_filter_id_table_id(u32 id)
392{
393 return (id <= EFX_FILTER_INDEX_MASK) ?
394 EFX_FILTER_TABLE_RX_MAC :
395 (id >> EFX_FILTER_INDEX_WIDTH) - 1;
396}
397
398static inline unsigned int efx_filter_id_index(u32 id)
399{
400 return id & EFX_FILTER_INDEX_MASK;
401}
370 402
371static inline int 403static inline u8 efx_filter_id_flags(u32 id)
372efx_filter_make_id(enum efx_filter_table_id table_id, unsigned index)
373{ 404{
374 return table_id << 16 | index; 405 return (id <= EFX_FILTER_INDEX_MASK) ?
406 EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_RX_OVERRIDE_IP :
407 EFX_FILTER_FLAG_RX;
375} 408}
376 409
377/** 410/**
@@ -439,7 +472,7 @@ int efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec,
439 netif_vdbg(efx, hw, efx->net_dev, 472 netif_vdbg(efx, hw, efx->net_dev,
440 "%s: filter type %d index %d rxq %u set", 473 "%s: filter type %d index %d rxq %u set",
441 __func__, spec->type, filter_idx, spec->dmaq_id); 474 __func__, spec->type, filter_idx, spec->dmaq_id);
442 rc = efx_filter_make_id(table->id, filter_idx); 475 rc = efx_filter_make_id(table->id, filter_idx, spec->flags);
443 476
444out: 477out:
445 spin_unlock_bh(&state->lock); 478 spin_unlock_bh(&state->lock);
diff --git a/drivers/net/ethernet/sfc/filter.h b/drivers/net/ethernet/sfc/filter.h
index 872f2132a496..dc9a256831d1 100644
--- a/drivers/net/ethernet/sfc/filter.h
+++ b/drivers/net/ethernet/sfc/filter.h
@@ -78,6 +78,11 @@ enum efx_filter_flags {
78 * 78 *
79 * Use the efx_filter_set_*() functions to initialise the @type and 79 * Use the efx_filter_set_*() functions to initialise the @type and
80 * @data fields. 80 * @data fields.
81 *
82 * The @priority field is used by software to determine whether a new
83 * filter may replace an old one. The hardware priority of a filter
84 * depends on the filter type and %EFX_FILTER_FLAG_RX_OVERRIDE_IP
85 * flag.
81 */ 86 */
82struct efx_filter_spec { 87struct efx_filter_spec {
83 u8 type:4; 88 u8 type:4;