|
@@ -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;
|