mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 09:19:51 +00:00
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>
This commit is contained in:
parent
55664f324c
commit
b1f9284b4e
2 changed files with 43 additions and 5 deletions
|
@ -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.
|
||||
*/
|
||||
|
||||
static inline int
|
||||
efx_filter_make_id(enum efx_filter_table_id table_id, unsigned index)
|
||||
#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 << 16 | index;
|
||||
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 u8 efx_filter_id_flags(u32 id)
|
||||
{
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue