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 +#define EFX_FARCH_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, +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;