diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2012-01-03 07:05:15 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-01-04 14:09:11 -0500 |
commit | b1f9284b4e6e5f7a44d6af3e111b33e61b261f26 (patch) | |
tree | 8157511c668b135babc99ed155fdf649d570d7fe /drivers/net/ethernet | |
parent | 55664f324c2a1a6386dc88492c5c94aa3d336b93 (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.c | 43 | ||||
-rw-r--r-- | 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 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 | |||
382 | static 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 | |||
391 | static 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 | |||
398 | static inline unsigned int efx_filter_id_index(u32 id) | ||
399 | { | ||
400 | return id & EFX_FILTER_INDEX_MASK; | ||
401 | } | ||
370 | 402 | ||
371 | static inline int | 403 | static inline u8 efx_filter_id_flags(u32 id) |
372 | efx_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 | ||
444 | out: | 477 | out: |
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 | */ |
82 | struct efx_filter_spec { | 87 | struct efx_filter_spec { |
83 | u8 type:4; | 88 | u8 type:4; |