summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/sfc/filter.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/sfc/filter.c')
-rw-r--r--drivers/net/ethernet/sfc/filter.c452
1 files changed, 243 insertions, 209 deletions
diff --git a/drivers/net/ethernet/sfc/filter.c b/drivers/net/ethernet/sfc/filter.c
index a588c95fae27..c547630cfee4 100644
--- a/drivers/net/ethernet/sfc/filter.c
+++ b/drivers/net/ethernet/sfc/filter.c
@@ -19,60 +19,69 @@
* Due to pipelined implementation we need to program H/W with a value that
* is larger than the hop limit we want.
*/
-#define FILTER_CTL_SRCH_FUDGE_WILD 3
-#define FILTER_CTL_SRCH_FUDGE_FULL 1
+#define EFX_FARCH_FILTER_CTL_SRCH_FUDGE_WILD 3
+#define EFX_FARCH_FILTER_CTL_SRCH_FUDGE_FULL 1
/* Hard maximum hop limit. Hardware will time-out beyond 200-something.
- * We also need to avoid infinite loops in efx_filter_search() when the
+ * We also need to avoid infinite loops in efx_farch_filter_search() when the
* table is full.
*/
-#define FILTER_CTL_SRCH_MAX 200
+#define EFX_FARCH_FILTER_CTL_SRCH_MAX 200
/* Don't try very hard to find space for performance hints, as this is
* counter-productive. */
-#define FILTER_CTL_SRCH_HINT_MAX 5
-
-enum efx_filter_table_id {
- EFX_FILTER_TABLE_RX_IP = 0,
- EFX_FILTER_TABLE_RX_MAC,
- EFX_FILTER_TABLE_RX_DEF,
- EFX_FILTER_TABLE_TX_MAC,
- EFX_FILTER_TABLE_COUNT,
+#define EFX_FARCH_FILTER_CTL_SRCH_HINT_MAX 5
+
+enum efx_farch_filter_table_id {
+ EFX_FARCH_FILTER_TABLE_RX_IP = 0,
+ EFX_FARCH_FILTER_TABLE_RX_MAC,
+ EFX_FARCH_FILTER_TABLE_RX_DEF,
+ EFX_FARCH_FILTER_TABLE_TX_MAC,
+ EFX_FARCH_FILTER_TABLE_COUNT,
};
-enum efx_filter_index {
- EFX_FILTER_INDEX_UC_DEF,
- EFX_FILTER_INDEX_MC_DEF,
- EFX_FILTER_SIZE_RX_DEF,
+enum efx_farch_filter_index {
+ EFX_FARCH_FILTER_INDEX_UC_DEF,
+ EFX_FARCH_FILTER_INDEX_MC_DEF,
+ EFX_FARCH_FILTER_SIZE_RX_DEF,
};
-struct efx_filter_table {
- enum efx_filter_table_id id;
+struct efx_farch_filter_spec {
+ u8 type:4;
+ u8 priority:4;
+ u8 flags;
+ u16 dmaq_id;
+ u32 data[3];
+};
+
+struct efx_farch_filter_table {
+ enum efx_farch_filter_table_id id;
u32 offset; /* address of table relative to BAR */
unsigned size; /* number of entries */
unsigned step; /* step between entries */
unsigned used; /* number currently used */
unsigned long *used_bitmap;
- struct efx_filter_spec *spec;
+ struct efx_farch_filter_spec *spec;
unsigned search_depth[EFX_FILTER_TYPE_COUNT];
};
struct efx_filter_state {
spinlock_t lock;
- struct efx_filter_table table[EFX_FILTER_TABLE_COUNT];
+ struct efx_farch_filter_table table[EFX_FARCH_FILTER_TABLE_COUNT];
#ifdef CONFIG_RFS_ACCEL
u32 *rps_flow_id;
unsigned rps_expire_index;
#endif
};
-static void efx_filter_table_clear_entry(struct efx_nic *efx,
- struct efx_filter_table *table,
- unsigned int filter_idx);
+static void
+efx_farch_filter_table_clear_entry(struct efx_nic *efx,
+ struct efx_farch_filter_table *table,
+ unsigned int filter_idx);
/* The filter hash function is LFSR polynomial x^16 + x^3 + 1 of a 32-bit
* key derived from the n-tuple. The initial LFSR state is 0xffff. */
-static u16 efx_filter_hash(u32 key)
+static u16 efx_farch_filter_hash(u32 key)
{
u16 tmp;
@@ -88,89 +97,97 @@ static u16 efx_filter_hash(u32 key)
/* To allow for hash collisions, filter search continues at these
* increments from the first possible entry selected by the hash. */
-static u16 efx_filter_increment(u32 key)
+static u16 efx_farch_filter_increment(u32 key)
{
return key * 2 - 1;
}
-static enum efx_filter_table_id
-efx_filter_spec_table_id(const struct efx_filter_spec *spec)
+static enum efx_farch_filter_table_id
+efx_farch_filter_spec_table_id(const struct efx_farch_filter_spec *spec)
{
- BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_TCP_FULL >> 2));
- BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_TCP_WILD >> 2));
- BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_UDP_FULL >> 2));
- BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_UDP_WILD >> 2));
- BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_MAC_FULL >> 2));
- BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_MAC_WILD >> 2));
- BUILD_BUG_ON(EFX_FILTER_TABLE_TX_MAC != EFX_FILTER_TABLE_RX_MAC + 2);
+ BUILD_BUG_ON(EFX_FARCH_FILTER_TABLE_RX_IP !=
+ (EFX_FILTER_TCP_FULL >> 2));
+ BUILD_BUG_ON(EFX_FARCH_FILTER_TABLE_RX_IP !=
+ (EFX_FILTER_TCP_WILD >> 2));
+ BUILD_BUG_ON(EFX_FARCH_FILTER_TABLE_RX_IP !=
+ (EFX_FILTER_UDP_FULL >> 2));
+ BUILD_BUG_ON(EFX_FARCH_FILTER_TABLE_RX_IP !=
+ (EFX_FILTER_UDP_WILD >> 2));
+ BUILD_BUG_ON(EFX_FARCH_FILTER_TABLE_RX_MAC !=
+ (EFX_FILTER_MAC_FULL >> 2));
+ BUILD_BUG_ON(EFX_FARCH_FILTER_TABLE_RX_MAC !=
+ (EFX_FILTER_MAC_WILD >> 2));
+ BUILD_BUG_ON(EFX_FARCH_FILTER_TABLE_TX_MAC !=
+ EFX_FARCH_FILTER_TABLE_RX_MAC + 2);
EFX_BUG_ON_PARANOID(spec->type == EFX_FILTER_UNSPEC);
return (spec->type >> 2) + ((spec->flags & EFX_FILTER_FLAG_TX) ? 2 : 0);
}
-static struct efx_filter_table *
-efx_filter_spec_table(struct efx_filter_state *state,
- const struct efx_filter_spec *spec)
+static struct efx_farch_filter_table *
+efx_farch_filter_spec_table(struct efx_filter_state *state,
+ const struct efx_farch_filter_spec *spec)
{
if (spec->type == EFX_FILTER_UNSPEC)
return NULL;
else
- return &state->table[efx_filter_spec_table_id(spec)];
+ return &state->table[efx_farch_filter_spec_table_id(spec)];
}
-static void efx_filter_table_reset_search_depth(struct efx_filter_table *table)
+static void
+efx_farch_filter_table_reset_search_depth(struct efx_farch_filter_table *table)
{
memset(table->search_depth, 0, sizeof(table->search_depth));
}
-static void efx_filter_push_rx_config(struct efx_nic *efx)
+static void efx_farch_filter_push_rx_config(struct efx_nic *efx)
{
struct efx_filter_state *state = efx->filter_state;
- struct efx_filter_table *table;
+ struct efx_farch_filter_table *table;
efx_oword_t filter_ctl;
efx_reado(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL);
- table = &state->table[EFX_FILTER_TABLE_RX_IP];
+ table = &state->table[EFX_FARCH_FILTER_TABLE_RX_IP];
EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_FULL_SRCH_LIMIT,
table->search_depth[EFX_FILTER_TCP_FULL] +
- FILTER_CTL_SRCH_FUDGE_FULL);
+ EFX_FARCH_FILTER_CTL_SRCH_FUDGE_FULL);
EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_WILD_SRCH_LIMIT,
table->search_depth[EFX_FILTER_TCP_WILD] +
- FILTER_CTL_SRCH_FUDGE_WILD);
+ EFX_FARCH_FILTER_CTL_SRCH_FUDGE_WILD);
EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_FULL_SRCH_LIMIT,
table->search_depth[EFX_FILTER_UDP_FULL] +
- FILTER_CTL_SRCH_FUDGE_FULL);
+ EFX_FARCH_FILTER_CTL_SRCH_FUDGE_FULL);
EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_WILD_SRCH_LIMIT,
table->search_depth[EFX_FILTER_UDP_WILD] +
- FILTER_CTL_SRCH_FUDGE_WILD);
+ EFX_FARCH_FILTER_CTL_SRCH_FUDGE_WILD);
- table = &state->table[EFX_FILTER_TABLE_RX_MAC];
+ table = &state->table[EFX_FARCH_FILTER_TABLE_RX_MAC];
if (table->size) {
EFX_SET_OWORD_FIELD(
filter_ctl, FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT,
table->search_depth[EFX_FILTER_MAC_FULL] +
- FILTER_CTL_SRCH_FUDGE_FULL);
+ EFX_FARCH_FILTER_CTL_SRCH_FUDGE_FULL);
EFX_SET_OWORD_FIELD(
filter_ctl, FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT,
table->search_depth[EFX_FILTER_MAC_WILD] +
- FILTER_CTL_SRCH_FUDGE_WILD);
+ EFX_FARCH_FILTER_CTL_SRCH_FUDGE_WILD);
}
- table = &state->table[EFX_FILTER_TABLE_RX_DEF];
+ table = &state->table[EFX_FARCH_FILTER_TABLE_RX_DEF];
if (table->size) {
EFX_SET_OWORD_FIELD(
filter_ctl, FRF_CZ_UNICAST_NOMATCH_Q_ID,
- table->spec[EFX_FILTER_INDEX_UC_DEF].dmaq_id);
+ table->spec[EFX_FARCH_FILTER_INDEX_UC_DEF].dmaq_id);
EFX_SET_OWORD_FIELD(
filter_ctl, FRF_CZ_UNICAST_NOMATCH_RSS_ENABLED,
- !!(table->spec[EFX_FILTER_INDEX_UC_DEF].flags &
+ !!(table->spec[EFX_FARCH_FILTER_INDEX_UC_DEF].flags &
EFX_FILTER_FLAG_RX_RSS));
EFX_SET_OWORD_FIELD(
filter_ctl, FRF_CZ_MULTICAST_NOMATCH_Q_ID,
- table->spec[EFX_FILTER_INDEX_MC_DEF].dmaq_id);
+ table->spec[EFX_FARCH_FILTER_INDEX_MC_DEF].dmaq_id);
EFX_SET_OWORD_FIELD(
filter_ctl, FRF_CZ_MULTICAST_NOMATCH_RSS_ENABLED,
- !!(table->spec[EFX_FILTER_INDEX_MC_DEF].flags &
+ !!(table->spec[EFX_FARCH_FILTER_INDEX_MC_DEF].flags &
EFX_FILTER_FLAG_RX_RSS));
/* There is a single bit to enable RX scatter for all
@@ -179,8 +196,8 @@ static void efx_filter_push_rx_config(struct efx_nic *efx)
*/
EFX_SET_OWORD_FIELD(
filter_ctl, FRF_BZ_SCATTER_ENBL_NO_MATCH_Q,
- !!(table->spec[EFX_FILTER_INDEX_UC_DEF].flags &
- table->spec[EFX_FILTER_INDEX_MC_DEF].flags &
+ !!(table->spec[EFX_FARCH_FILTER_INDEX_UC_DEF].flags &
+ table->spec[EFX_FARCH_FILTER_INDEX_MC_DEF].flags &
EFX_FILTER_FLAG_RX_SCATTER));
} else if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) {
/* We don't expose 'default' filters because unmatched
@@ -196,24 +213,24 @@ static void efx_filter_push_rx_config(struct efx_nic *efx)
efx_writeo(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL);
}
-static void efx_filter_push_tx_limits(struct efx_nic *efx)
+static void efx_farch_filter_push_tx_limits(struct efx_nic *efx)
{
struct efx_filter_state *state = efx->filter_state;
- struct efx_filter_table *table;
+ struct efx_farch_filter_table *table;
efx_oword_t tx_cfg;
efx_reado(efx, &tx_cfg, FR_AZ_TX_CFG);
- table = &state->table[EFX_FILTER_TABLE_TX_MAC];
+ table = &state->table[EFX_FARCH_FILTER_TABLE_TX_MAC];
if (table->size) {
EFX_SET_OWORD_FIELD(
tx_cfg, FRF_CZ_TX_ETH_FILTER_FULL_SEARCH_RANGE,
table->search_depth[EFX_FILTER_MAC_FULL] +
- FILTER_CTL_SRCH_FUDGE_FULL);
+ EFX_FARCH_FILTER_CTL_SRCH_FUDGE_FULL);
EFX_SET_OWORD_FIELD(
tx_cfg, FRF_CZ_TX_ETH_FILTER_WILD_SEARCH_RANGE,
table->search_depth[EFX_FILTER_MAC_WILD] +
- FILTER_CTL_SRCH_FUDGE_WILD);
+ EFX_FARCH_FILTER_CTL_SRCH_FUDGE_WILD);
}
efx_writeo(efx, &tx_cfg, FR_AZ_TX_CFG);
@@ -427,24 +444,23 @@ int efx_filter_set_mc_def(struct efx_filter_spec *spec)
return 0;
}
-static void efx_filter_reset_rx_def(struct efx_nic *efx, unsigned filter_idx)
+static void
+efx_farch_filter_reset_rx_def(struct efx_nic *efx, unsigned filter_idx)
{
struct efx_filter_state *state = efx->filter_state;
- struct efx_filter_table *table = &state->table[EFX_FILTER_TABLE_RX_DEF];
- struct efx_filter_spec *spec = &table->spec[filter_idx];
- enum efx_filter_flags flags = 0;
+ struct efx_farch_filter_table *table =
+ &state->table[EFX_FARCH_FILTER_TABLE_RX_DEF];
+ struct efx_farch_filter_spec *spec = &table->spec[filter_idx];
/* If there's only one channel then disable RSS for non VF
* traffic, thereby allowing VFs to use RSS when the PF can't.
*/
- if (efx->n_rx_channels > 1)
- flags |= EFX_FILTER_FLAG_RX_RSS;
-
- if (efx->rx_scatter)
- flags |= EFX_FILTER_FLAG_RX_SCATTER;
-
- efx_filter_init_rx(spec, EFX_FILTER_PRI_MANUAL, flags, 0);
spec->type = EFX_FILTER_UC_DEF + filter_idx;
+ spec->priority = EFX_FILTER_PRI_MANUAL;
+ spec->flags = (EFX_FILTER_FLAG_RX |
+ (efx->n_rx_channels > 1 ? EFX_FILTER_FLAG_RX_RSS : 0) |
+ (efx->rx_scatter ? EFX_FILTER_FLAG_RX_SCATTER : 0));
+ spec->dmaq_id = 0;
table->used_bitmap[0] |= 1 << filter_idx;
}
@@ -472,12 +488,13 @@ int efx_filter_get_eth_local(const struct efx_filter_spec *spec,
}
/* Build a filter entry and return its n-tuple key. */
-static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec)
+static u32 efx_farch_filter_build(efx_oword_t *filter,
+ struct efx_farch_filter_spec *spec)
{
u32 data3;
- switch (efx_filter_spec_table_id(spec)) {
- case EFX_FILTER_TABLE_RX_IP: {
+ switch (efx_farch_filter_spec_table_id(spec)) {
+ case EFX_FARCH_FILTER_TABLE_RX_IP: {
bool is_udp = (spec->type == EFX_FILTER_UDP_FULL ||
spec->type == EFX_FILTER_UDP_WILD);
EFX_POPULATE_OWORD_7(
@@ -495,7 +512,7 @@ static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec)
break;
}
- case EFX_FILTER_TABLE_RX_MAC: {
+ case EFX_FARCH_FILTER_TABLE_RX_MAC: {
bool is_wild = spec->type == EFX_FILTER_MAC_WILD;
EFX_POPULATE_OWORD_7(
*filter,
@@ -512,7 +529,7 @@ static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec)
break;
}
- case EFX_FILTER_TABLE_TX_MAC: {
+ case EFX_FARCH_FILTER_TABLE_TX_MAC: {
bool is_wild = spec->type == EFX_FILTER_MAC_WILD;
EFX_POPULATE_OWORD_5(*filter,
FRF_CZ_TMFT_TXQ_ID, spec->dmaq_id,
@@ -531,8 +548,8 @@ static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec)
return spec->data[0] ^ spec->data[1] ^ spec->data[2] ^ data3;
}
-static bool efx_filter_equal(const struct efx_filter_spec *left,
- const struct efx_filter_spec *right)
+static bool efx_farch_filter_equal(const struct efx_farch_filter_spec *left,
+ const struct efx_farch_filter_spec *right)
{
if (left->type != right->type ||
memcmp(left->data, right->data, sizeof(left->data)))
@@ -554,9 +571,9 @@ static bool efx_filter_equal(const struct efx_filter_spec *left,
* accept user-provided IDs.
*/
-#define EFX_FILTER_MATCH_PRI_COUNT 5
+#define EFX_FARCH_FILTER_MATCH_PRI_COUNT 5
-static const u8 efx_filter_type_match_pri[EFX_FILTER_TYPE_COUNT] = {
+static const u8 efx_farch_filter_type_match_pri[EFX_FILTER_TYPE_COUNT] = {
[EFX_FILTER_TCP_FULL] = 0,
[EFX_FILTER_UDP_FULL] = 0,
[EFX_FILTER_TCP_WILD] = 1,
@@ -567,58 +584,58 @@ static const u8 efx_filter_type_match_pri[EFX_FILTER_TYPE_COUNT] = {
[EFX_FILTER_MC_DEF] = 4,
};
-static const enum efx_filter_table_id efx_filter_range_table[] = {
- EFX_FILTER_TABLE_RX_IP, /* RX match pri 0 */
- EFX_FILTER_TABLE_RX_IP,
- EFX_FILTER_TABLE_RX_MAC,
- EFX_FILTER_TABLE_RX_MAC,
- EFX_FILTER_TABLE_RX_DEF, /* RX match pri 4 */
- EFX_FILTER_TABLE_COUNT, /* TX match pri 0; invalid */
- EFX_FILTER_TABLE_COUNT, /* invalid */
- EFX_FILTER_TABLE_TX_MAC,
- EFX_FILTER_TABLE_TX_MAC, /* TX match pri 3 */
+static const enum efx_farch_filter_table_id efx_farch_filter_range_table[] = {
+ EFX_FARCH_FILTER_TABLE_RX_IP, /* RX match pri 0 */
+ EFX_FARCH_FILTER_TABLE_RX_IP,
+ EFX_FARCH_FILTER_TABLE_RX_MAC,
+ EFX_FARCH_FILTER_TABLE_RX_MAC,
+ EFX_FARCH_FILTER_TABLE_RX_DEF, /* RX match pri 4 */
+ EFX_FARCH_FILTER_TABLE_TX_MAC, /* TX match pri 0 */
+ EFX_FARCH_FILTER_TABLE_TX_MAC, /* TX match pri 1 */
};
-#define EFX_FILTER_INDEX_WIDTH 13
-#define EFX_FILTER_INDEX_MASK ((1 << EFX_FILTER_INDEX_WIDTH) - 1)
+#define EFX_FARCH_FILTER_INDEX_WIDTH 13
+#define EFX_FARCH_FILTER_INDEX_MASK ((1 << EFX_FARCH_FILTER_INDEX_WIDTH) - 1)
static inline u32
-efx_filter_make_id(const struct efx_filter_spec *spec, unsigned int index)
+efx_farch_filter_make_id(const struct efx_farch_filter_spec *spec,
+ unsigned int index)
{
unsigned int range;
- range = efx_filter_type_match_pri[spec->type];
+ range = efx_farch_filter_type_match_pri[spec->type];
if (!(spec->flags & EFX_FILTER_FLAG_RX))
- range += EFX_FILTER_MATCH_PRI_COUNT;
+ range += EFX_FARCH_FILTER_MATCH_PRI_COUNT;
- return range << EFX_FILTER_INDEX_WIDTH | index;
+ return range << EFX_FARCH_FILTER_INDEX_WIDTH | index;
}
-static inline enum efx_filter_table_id efx_filter_id_table_id(u32 id)
+static inline enum efx_farch_filter_table_id
+efx_farch_filter_id_table_id(u32 id)
{
- unsigned int range = id >> EFX_FILTER_INDEX_WIDTH;
+ unsigned int range = id >> EFX_FARCH_FILTER_INDEX_WIDTH;
- if (range < ARRAY_SIZE(efx_filter_range_table))
- return efx_filter_range_table[range];
+ if (range < ARRAY_SIZE(efx_farch_filter_range_table))
+ return efx_farch_filter_range_table[range];
else
- return EFX_FILTER_TABLE_COUNT; /* invalid */
+ return EFX_FARCH_FILTER_TABLE_COUNT; /* invalid */
}
-static inline unsigned int efx_filter_id_index(u32 id)
+static inline unsigned int efx_farch_filter_id_index(u32 id)
{
- return id & EFX_FILTER_INDEX_MASK;
+ return id & EFX_FARCH_FILTER_INDEX_MASK;
}
u32 efx_filter_get_rx_id_limit(struct efx_nic *efx)
{
struct efx_filter_state *state = efx->filter_state;
- unsigned int range = EFX_FILTER_MATCH_PRI_COUNT - 1;
- enum efx_filter_table_id table_id;
+ unsigned int range = EFX_FARCH_FILTER_MATCH_PRI_COUNT - 1;
+ enum efx_farch_filter_table_id table_id;
do {
- table_id = efx_filter_range_table[range];
+ table_id = efx_farch_filter_range_table[range];
if (state->table[table_id].size != 0)
- return range << EFX_FILTER_INDEX_WIDTH |
+ return range << EFX_FARCH_FILTER_INDEX_WIDTH |
state->table[table_id].size;
} while (range--);
@@ -643,29 +660,35 @@ u32 efx_filter_get_rx_id_limit(struct efx_nic *efx)
* the existing filter has higher priority or -%EEXIST if it has
* equal priority.
*/
-s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec,
+s32 efx_filter_insert_filter(struct efx_nic *efx,
+ struct efx_filter_spec *gen_spec,
bool replace_equal)
{
struct efx_filter_state *state = efx->filter_state;
- struct efx_filter_table *table = efx_filter_spec_table(state, spec);
+ struct efx_farch_filter_table *table;
+ struct efx_farch_filter_spec spec;
efx_oword_t filter;
int rep_index, ins_index;
unsigned int depth = 0;
int rc;
+ /* XXX efx_farch_filter_spec and efx_filter_spec will diverge in future */
+ memcpy(&spec, gen_spec, sizeof(*gen_spec));
+
+ table = efx_farch_filter_spec_table(state, &spec);
if (!table || table->size == 0)
return -EINVAL;
netif_vdbg(efx, hw, efx->net_dev,
- "%s: type %d search_depth=%d", __func__, spec->type,
- table->search_depth[spec->type]);
+ "%s: type %d search_depth=%d", __func__, spec.type,
+ table->search_depth[spec.type]);
- if (table->id == EFX_FILTER_TABLE_RX_DEF) {
+ if (table->id == EFX_FARCH_FILTER_TABLE_RX_DEF) {
/* One filter spec per type */
- BUILD_BUG_ON(EFX_FILTER_INDEX_UC_DEF != 0);
- BUILD_BUG_ON(EFX_FILTER_INDEX_MC_DEF !=
+ BUILD_BUG_ON(EFX_FARCH_FILTER_INDEX_UC_DEF != 0);
+ BUILD_BUG_ON(EFX_FARCH_FILTER_INDEX_MC_DEF !=
EFX_FILTER_MC_DEF - EFX_FILTER_UC_DEF);
- rep_index = spec->type - EFX_FILTER_UC_DEF;
+ rep_index = spec.type - EFX_FILTER_UC_DEF;
ins_index = rep_index;
spin_lock_bh(&state->lock);
@@ -685,13 +708,14 @@ s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec,
* (b) we have searched exhaustively for (1), and have
* either found (2) or searched exhaustively for it
*/
- u32 key = efx_filter_build(&filter, spec);
- unsigned int hash = efx_filter_hash(key);
- unsigned int incr = efx_filter_increment(key);
- unsigned int max_rep_depth = table->search_depth[spec->type];
+ u32 key = efx_farch_filter_build(&filter, &spec);
+ unsigned int hash = efx_farch_filter_hash(key);
+ unsigned int incr = efx_farch_filter_increment(key);
+ unsigned int max_rep_depth = table->search_depth[spec.type];
unsigned int max_ins_depth =
- spec->priority <= EFX_FILTER_PRI_HINT ?
- FILTER_CTL_SRCH_HINT_MAX : FILTER_CTL_SRCH_MAX;
+ spec.priority <= EFX_FILTER_PRI_HINT ?
+ EFX_FARCH_FILTER_CTL_SRCH_HINT_MAX :
+ EFX_FARCH_FILTER_CTL_SRCH_MAX;
unsigned int i = hash & (table->size - 1);
ins_index = -1;
@@ -703,7 +727,8 @@ s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec,
if (!test_bit(i, table->used_bitmap)) {
if (ins_index < 0)
ins_index = i;
- } else if (efx_filter_equal(spec, &table->spec[i])) {
+ } else if (efx_farch_filter_equal(&spec,
+ &table->spec[i])) {
/* Case (a) */
if (ins_index < 0)
ins_index = i;
@@ -731,13 +756,14 @@ s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec,
* should do so
*/
if (rep_index >= 0) {
- struct efx_filter_spec *saved_spec = &table->spec[rep_index];
+ struct efx_farch_filter_spec *saved_spec =
+ &table->spec[rep_index];
- if (spec->priority == saved_spec->priority && !replace_equal) {
+ if (spec.priority == saved_spec->priority && !replace_equal) {
rc = -EEXIST;
goto out;
}
- if (spec->priority < saved_spec->priority) {
+ if (spec.priority < saved_spec->priority) {
rc = -EPERM;
goto out;
}
@@ -748,17 +774,17 @@ s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec,
__set_bit(ins_index, table->used_bitmap);
++table->used;
}
- table->spec[ins_index] = *spec;
+ table->spec[ins_index] = spec;
- if (table->id == EFX_FILTER_TABLE_RX_DEF) {
- efx_filter_push_rx_config(efx);
+ if (table->id == EFX_FARCH_FILTER_TABLE_RX_DEF) {
+ efx_farch_filter_push_rx_config(efx);
} else {
- if (table->search_depth[spec->type] < depth) {
- table->search_depth[spec->type] = depth;
- if (spec->flags & EFX_FILTER_FLAG_TX)
- efx_filter_push_tx_limits(efx);
+ if (table->search_depth[spec.type] < depth) {
+ table->search_depth[spec.type] = depth;
+ if (spec.flags & EFX_FILTER_FLAG_TX)
+ efx_farch_filter_push_tx_limits(efx);
else
- efx_filter_push_rx_config(efx);
+ efx_farch_filter_push_rx_config(efx);
}
efx_writeo(efx, &filter,
@@ -768,29 +794,31 @@ s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec,
* at a lower depth, clear the replaced filter
*/
if (ins_index != rep_index && rep_index >= 0)
- efx_filter_table_clear_entry(efx, table, rep_index);
+ efx_farch_filter_table_clear_entry(efx, table,
+ rep_index);
}
netif_vdbg(efx, hw, efx->net_dev,
"%s: filter type %d index %d rxq %u set",
- __func__, spec->type, ins_index, spec->dmaq_id);
- rc = efx_filter_make_id(spec, ins_index);
+ __func__, spec.type, ins_index, spec.dmaq_id);
+ rc = efx_farch_filter_make_id(&spec, ins_index);
out:
spin_unlock_bh(&state->lock);
return rc;
}
-static void efx_filter_table_clear_entry(struct efx_nic *efx,
- struct efx_filter_table *table,
- unsigned int filter_idx)
+static void
+efx_farch_filter_table_clear_entry(struct efx_nic *efx,
+ struct efx_farch_filter_table *table,
+ unsigned int filter_idx)
{
static efx_oword_t filter;
- if (table->id == EFX_FILTER_TABLE_RX_DEF) {
+ if (table->id == EFX_FARCH_FILTER_TABLE_RX_DEF) {
/* RX default filters must always exist */
- efx_filter_reset_rx_def(efx, filter_idx);
- efx_filter_push_rx_config(efx);
+ efx_farch_filter_reset_rx_def(efx, filter_idx);
+ efx_farch_filter_push_rx_config(efx);
} else if (test_bit(filter_idx, table->used_bitmap)) {
__clear_bit(filter_idx, table->used_bitmap);
--table->used;
@@ -815,18 +843,18 @@ int efx_filter_remove_id_safe(struct efx_nic *efx,
u32 filter_id)
{
struct efx_filter_state *state = efx->filter_state;
- enum efx_filter_table_id table_id;
- struct efx_filter_table *table;
+ enum efx_farch_filter_table_id table_id;
+ struct efx_farch_filter_table *table;
unsigned int filter_idx;
- struct efx_filter_spec *spec;
+ struct efx_farch_filter_spec *spec;
int rc;
- table_id = efx_filter_id_table_id(filter_id);
- if ((unsigned int)table_id >= EFX_FILTER_TABLE_COUNT)
+ table_id = efx_farch_filter_id_table_id(filter_id);
+ if ((unsigned int)table_id >= EFX_FARCH_FILTER_TABLE_COUNT)
return -ENOENT;
table = &state->table[table_id];
- filter_idx = efx_filter_id_index(filter_id);
+ filter_idx = efx_farch_filter_id_index(filter_id);
if (filter_idx >= table->size)
return -ENOENT;
spec = &table->spec[filter_idx];
@@ -835,9 +863,9 @@ int efx_filter_remove_id_safe(struct efx_nic *efx,
if (test_bit(filter_idx, table->used_bitmap) &&
spec->priority == priority) {
- efx_filter_table_clear_entry(efx, table, filter_idx);
+ efx_farch_filter_table_clear_entry(efx, table, filter_idx);
if (table->used == 0)
- efx_filter_table_reset_search_depth(table);
+ efx_farch_filter_table_reset_search_depth(table);
rc = 0;
} else {
rc = -ENOENT;
@@ -863,18 +891,18 @@ int efx_filter_get_filter_safe(struct efx_nic *efx,
u32 filter_id, struct efx_filter_spec *spec_buf)
{
struct efx_filter_state *state = efx->filter_state;
- enum efx_filter_table_id table_id;
- struct efx_filter_table *table;
- struct efx_filter_spec *spec;
+ enum efx_farch_filter_table_id table_id;
+ struct efx_farch_filter_table *table;
+ struct efx_farch_filter_spec *spec;
unsigned int filter_idx;
int rc;
- table_id = efx_filter_id_table_id(filter_id);
- if ((unsigned int)table_id >= EFX_FILTER_TABLE_COUNT)
+ table_id = efx_farch_filter_id_table_id(filter_id);
+ if ((unsigned int)table_id >= EFX_FARCH_FILTER_TABLE_COUNT)
return -ENOENT;
table = &state->table[table_id];
- filter_idx = efx_filter_id_index(filter_id);
+ filter_idx = efx_farch_filter_id_index(filter_id);
if (filter_idx >= table->size)
return -ENOENT;
spec = &table->spec[filter_idx];
@@ -883,7 +911,8 @@ int efx_filter_get_filter_safe(struct efx_nic *efx,
if (test_bit(filter_idx, table->used_bitmap) &&
spec->priority == priority) {
- *spec_buf = *spec;
+ /* XXX efx_farch_filter_spec and efx_filter_spec will diverge */
+ memcpy(spec_buf, spec, sizeof(*spec));
rc = 0;
} else {
rc = -ENOENT;
@@ -894,21 +923,23 @@ int efx_filter_get_filter_safe(struct efx_nic *efx,
return rc;
}
-static void efx_filter_table_clear(struct efx_nic *efx,
- enum efx_filter_table_id table_id,
- enum efx_filter_priority priority)
+static void
+efx_farch_filter_table_clear(struct efx_nic *efx,
+ enum efx_farch_filter_table_id table_id,
+ enum efx_filter_priority priority)
{
struct efx_filter_state *state = efx->filter_state;
- struct efx_filter_table *table = &state->table[table_id];
+ struct efx_farch_filter_table *table = &state->table[table_id];
unsigned int filter_idx;
spin_lock_bh(&state->lock);
for (filter_idx = 0; filter_idx < table->size; ++filter_idx)
if (table->spec[filter_idx].priority <= priority)
- efx_filter_table_clear_entry(efx, table, filter_idx);
+ efx_farch_filter_table_clear_entry(efx, table,
+ filter_idx);
if (table->used == 0)
- efx_filter_table_reset_search_depth(table);
+ efx_farch_filter_table_reset_search_depth(table);
spin_unlock_bh(&state->lock);
}
@@ -920,23 +951,25 @@ static void efx_filter_table_clear(struct efx_nic *efx,
*/
void efx_filter_clear_rx(struct efx_nic *efx, enum efx_filter_priority priority)
{
- efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_IP, priority);
- efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_MAC, priority);
+ efx_farch_filter_table_clear(efx, EFX_FARCH_FILTER_TABLE_RX_IP,
+ priority);
+ efx_farch_filter_table_clear(efx, EFX_FARCH_FILTER_TABLE_RX_MAC,
+ priority);
}
u32 efx_filter_count_rx_used(struct efx_nic *efx,
enum efx_filter_priority priority)
{
struct efx_filter_state *state = efx->filter_state;
- enum efx_filter_table_id table_id;
- struct efx_filter_table *table;
+ enum efx_farch_filter_table_id table_id;
+ struct efx_farch_filter_table *table;
unsigned int filter_idx;
u32 count = 0;
spin_lock_bh(&state->lock);
- for (table_id = EFX_FILTER_TABLE_RX_IP;
- table_id <= EFX_FILTER_TABLE_RX_DEF;
+ for (table_id = EFX_FARCH_FILTER_TABLE_RX_IP;
+ table_id <= EFX_FARCH_FILTER_TABLE_RX_DEF;
table_id++) {
table = &state->table[table_id];
for (filter_idx = 0; filter_idx < table->size; filter_idx++) {
@@ -956,15 +989,15 @@ s32 efx_filter_get_rx_ids(struct efx_nic *efx,
u32 *buf, u32 size)
{
struct efx_filter_state *state = efx->filter_state;
- enum efx_filter_table_id table_id;
- struct efx_filter_table *table;
+ enum efx_farch_filter_table_id table_id;
+ struct efx_farch_filter_table *table;
unsigned int filter_idx;
s32 count = 0;
spin_lock_bh(&state->lock);
- for (table_id = EFX_FILTER_TABLE_RX_IP;
- table_id <= EFX_FILTER_TABLE_RX_DEF;
+ for (table_id = EFX_FARCH_FILTER_TABLE_RX_IP;
+ table_id <= EFX_FARCH_FILTER_TABLE_RX_DEF;
table_id++) {
table = &state->table[table_id];
for (filter_idx = 0; filter_idx < table->size; filter_idx++) {
@@ -974,7 +1007,7 @@ s32 efx_filter_get_rx_ids(struct efx_nic *efx,
count = -EMSGSIZE;
goto out;
}
- buf[count++] = efx_filter_make_id(
+ buf[count++] = efx_farch_filter_make_id(
&table->spec[filter_idx], filter_idx);
}
}
@@ -989,14 +1022,14 @@ out:
void efx_restore_filters(struct efx_nic *efx)
{
struct efx_filter_state *state = efx->filter_state;
- enum efx_filter_table_id table_id;
- struct efx_filter_table *table;
+ enum efx_farch_filter_table_id table_id;
+ struct efx_farch_filter_table *table;
efx_oword_t filter;
unsigned int filter_idx;
spin_lock_bh(&state->lock);
- for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) {
+ for (table_id = 0; table_id < EFX_FARCH_FILTER_TABLE_COUNT; table_id++) {
table = &state->table[table_id];
/* Check whether this is a regular register table */
@@ -1006,14 +1039,14 @@ void efx_restore_filters(struct efx_nic *efx)
for (filter_idx = 0; filter_idx < table->size; filter_idx++) {
if (!test_bit(filter_idx, table->used_bitmap))
continue;
- efx_filter_build(&filter, &table->spec[filter_idx]);
+ efx_farch_filter_build(&filter, &table->spec[filter_idx]);
efx_writeo(efx, &filter,
table->offset + table->step * filter_idx);
}
}
- efx_filter_push_rx_config(efx);
- efx_filter_push_tx_limits(efx);
+ efx_farch_filter_push_rx_config(efx);
+ efx_farch_filter_push_tx_limits(efx);
spin_unlock_bh(&state->lock);
}
@@ -1021,7 +1054,7 @@ void efx_restore_filters(struct efx_nic *efx)
int efx_probe_filters(struct efx_nic *efx)
{
struct efx_filter_state *state;
- struct efx_filter_table *table;
+ struct efx_farch_filter_table *table;
unsigned table_id;
state = kzalloc(sizeof(*efx->filter_state), GFP_KERNEL);
@@ -1039,32 +1072,32 @@ int efx_probe_filters(struct efx_nic *efx)
if (!state->rps_flow_id)
goto fail;
#endif
- table = &state->table[EFX_FILTER_TABLE_RX_IP];
- table->id = EFX_FILTER_TABLE_RX_IP;
+ table = &state->table[EFX_FARCH_FILTER_TABLE_RX_IP];
+ table->id = EFX_FARCH_FILTER_TABLE_RX_IP;
table->offset = FR_BZ_RX_FILTER_TBL0;
table->size = FR_BZ_RX_FILTER_TBL0_ROWS;
table->step = FR_BZ_RX_FILTER_TBL0_STEP;
}
if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0) {
- table = &state->table[EFX_FILTER_TABLE_RX_MAC];
- table->id = EFX_FILTER_TABLE_RX_MAC;
+ table = &state->table[EFX_FARCH_FILTER_TABLE_RX_MAC];
+ table->id = EFX_FARCH_FILTER_TABLE_RX_MAC;
table->offset = FR_CZ_RX_MAC_FILTER_TBL0;
table->size = FR_CZ_RX_MAC_FILTER_TBL0_ROWS;
table->step = FR_CZ_RX_MAC_FILTER_TBL0_STEP;
- table = &state->table[EFX_FILTER_TABLE_RX_DEF];
- table->id = EFX_FILTER_TABLE_RX_DEF;
- table->size = EFX_FILTER_SIZE_RX_DEF;
+ table = &state->table[EFX_FARCH_FILTER_TABLE_RX_DEF];
+ table->id = EFX_FARCH_FILTER_TABLE_RX_DEF;
+ table->size = EFX_FARCH_FILTER_SIZE_RX_DEF;
- table = &state->table[EFX_FILTER_TABLE_TX_MAC];
- table->id = EFX_FILTER_TABLE_TX_MAC;
+ table = &state->table[EFX_FARCH_FILTER_TABLE_TX_MAC];
+ table->id = EFX_FARCH_FILTER_TABLE_TX_MAC;
table->offset = FR_CZ_TX_MAC_FILTER_TBL0;
table->size = FR_CZ_TX_MAC_FILTER_TBL0_ROWS;
table->step = FR_CZ_TX_MAC_FILTER_TBL0_STEP;
}
- for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) {
+ for (table_id = 0; table_id < EFX_FARCH_FILTER_TABLE_COUNT; table_id++) {
table = &state->table[table_id];
if (table->size == 0)
continue;
@@ -1078,14 +1111,14 @@ int efx_probe_filters(struct efx_nic *efx)
goto fail;
}
- if (state->table[EFX_FILTER_TABLE_RX_DEF].size) {
+ if (state->table[EFX_FARCH_FILTER_TABLE_RX_DEF].size) {
/* RX default filters must always exist */
unsigned i;
- for (i = 0; i < EFX_FILTER_SIZE_RX_DEF; i++)
- efx_filter_reset_rx_def(efx, i);
+ for (i = 0; i < EFX_FARCH_FILTER_SIZE_RX_DEF; i++)
+ efx_farch_filter_reset_rx_def(efx, i);
}
- efx_filter_push_rx_config(efx);
+ efx_farch_filter_push_rx_config(efx);
return 0;
@@ -1097,9 +1130,9 @@ fail:
void efx_remove_filters(struct efx_nic *efx)
{
struct efx_filter_state *state = efx->filter_state;
- enum efx_filter_table_id table_id;
+ enum efx_farch_filter_table_id table_id;
- for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) {
+ for (table_id = 0; table_id < EFX_FARCH_FILTER_TABLE_COUNT; table_id++) {
kfree(state->table[table_id].used_bitmap);
vfree(state->table[table_id].spec);
}
@@ -1113,15 +1146,15 @@ void efx_remove_filters(struct efx_nic *efx)
void efx_filter_update_rx_scatter(struct efx_nic *efx)
{
struct efx_filter_state *state = efx->filter_state;
- enum efx_filter_table_id table_id;
- struct efx_filter_table *table;
+ enum efx_farch_filter_table_id table_id;
+ struct efx_farch_filter_table *table;
efx_oword_t filter;
unsigned int filter_idx;
spin_lock_bh(&state->lock);
- for (table_id = EFX_FILTER_TABLE_RX_IP;
- table_id <= EFX_FILTER_TABLE_RX_DEF;
+ for (table_id = EFX_FARCH_FILTER_TABLE_RX_IP;
+ table_id <= EFX_FARCH_FILTER_TABLE_RX_DEF;
table_id++) {
table = &state->table[table_id];
@@ -1138,17 +1171,17 @@ void efx_filter_update_rx_scatter(struct efx_nic *efx)
table->spec[filter_idx].flags &=
~EFX_FILTER_FLAG_RX_SCATTER;
- if (table_id == EFX_FILTER_TABLE_RX_DEF)
- /* Pushed by efx_filter_push_rx_config() */
+ if (table_id == EFX_FARCH_FILTER_TABLE_RX_DEF)
+ /* Pushed by efx_farch_filter_push_rx_config() */
continue;
- efx_filter_build(&filter, &table->spec[filter_idx]);
+ efx_farch_filter_build(&filter, &table->spec[filter_idx]);
efx_writeo(efx, &filter,
table->offset + table->step * filter_idx);
}
}
- efx_filter_push_rx_config(efx);
+ efx_farch_filter_push_rx_config(efx);
spin_unlock_bh(&state->lock);
}
@@ -1222,7 +1255,8 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
bool __efx_filter_rfs_expire(struct efx_nic *efx, unsigned quota)
{
struct efx_filter_state *state = efx->filter_state;
- struct efx_filter_table *table = &state->table[EFX_FILTER_TABLE_RX_IP];
+ struct efx_farch_filter_table *table =
+ &state->table[EFX_FARCH_FILTER_TABLE_RX_IP];
unsigned mask = table->size - 1;
unsigned index;
unsigned stop;
@@ -1242,14 +1276,14 @@ bool __efx_filter_rfs_expire(struct efx_nic *efx, unsigned quota)
netif_info(efx, rx_status, efx->net_dev,
"expiring filter %d [flow %u]\n",
index, state->rps_flow_id[index]);
- efx_filter_table_clear_entry(efx, table, index);
+ efx_farch_filter_table_clear_entry(efx, table, index);
}
index = (index + 1) & mask;
}
state->rps_expire_index = stop;
if (table->used == 0)
- efx_filter_table_reset_search_depth(table);
+ efx_farch_filter_table_reset_search_depth(table);
spin_unlock_bh(&state->lock);
return true;