Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+38 −5
Original line number Diff line number Diff line
@@ -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);
+5 −0
Original line number Diff line number Diff line
@@ -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;