Commit b1f9284b authored by Ben Hutchings's avatar Ben Hutchings Committed by David S. Miller

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: default avatarBen Hutchings <bhutchings@solarflare.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 55664f32
...@@ -366,12 +366,45 @@ static int efx_filter_search(struct efx_filter_table *table, ...@@ -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 static inline u8 efx_filter_id_flags(u32 id)
efx_filter_make_id(enum efx_filter_table_id table_id, unsigned index)
{ {
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, ...@@ -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, netif_vdbg(efx, hw, efx->net_dev,
"%s: filter type %d index %d rxq %u set", "%s: filter type %d index %d rxq %u set",
__func__, spec->type, filter_idx, spec->dmaq_id); __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: out:
spin_unlock_bh(&state->lock); spin_unlock_bh(&state->lock);
......
...@@ -78,6 +78,11 @@ enum efx_filter_flags { ...@@ -78,6 +78,11 @@ enum efx_filter_flags {
* *
* Use the efx_filter_set_*() functions to initialise the @type and * Use the efx_filter_set_*() functions to initialise the @type and
* @data fields. * @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 { struct efx_filter_spec {
u8 type:4; u8 type:4;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment