diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2012-11-19 23:08:19 (GMT) |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2013-08-22 18:25:58 (GMT) |
commit | 14990a5d66b5b51a422bc46a9e8fedb20d8a770c (patch) | |
tree | 68ee21b20a185e5d6811c283ed68704614ad096b /drivers/net/ethernet/sfc/farch.c | |
parent | add7247718c003c8f7c275954083f7db85405bd9 (diff) | |
download | linux-14990a5d66b5b51a422bc46a9e8fedb20d8a770c.tar.xz |
sfc: Refactor Falcon-arch filter removal
Move the special case for removal of default filters from
efx_farch_filter_table_clear_entry() into a wrapper function,
efx_farch_filter_table_remove(). Move the existence and priority
checks into the latter and use it where appropriate.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/ethernet/sfc/farch.c')
-rw-r--r-- | drivers/net/ethernet/sfc/farch.c | 74 |
1 files changed, 40 insertions, 34 deletions
diff --git a/drivers/net/ethernet/sfc/farch.c b/drivers/net/ethernet/sfc/farch.c index 1941804..d91bced 100644 --- a/drivers/net/ethernet/sfc/farch.c +++ b/drivers/net/ethernet/sfc/farch.c @@ -2516,33 +2516,49 @@ efx_farch_filter_table_clear_entry(struct efx_nic *efx, { static efx_oword_t filter; + EFX_WARN_ON_PARANOID(!test_bit(filter_idx, table->used_bitmap)); + + __clear_bit(filter_idx, table->used_bitmap); + --table->used; + memset(&table->spec[filter_idx], 0, sizeof(table->spec[0])); + + efx_writeo(efx, &filter, table->offset + table->step * filter_idx); + + /* If this filter required a greater search depth than + * any other, the search limit for its type can now be + * decreased. However, it is hard to determine that + * unless the table has become completely empty - in + * which case, all its search limits can be set to 0. + */ + if (unlikely(table->used == 0)) { + memset(table->search_limit, 0, sizeof(table->search_limit)); + if (table->id == EFX_FARCH_FILTER_TABLE_TX_MAC) + efx_farch_filter_push_tx_limits(efx); + else + efx_farch_filter_push_rx_config(efx); + } +} + +static int efx_farch_filter_remove(struct efx_nic *efx, + struct efx_farch_filter_table *table, + unsigned int filter_idx, + enum efx_filter_priority priority) +{ + struct efx_farch_filter_spec *spec = &table->spec[filter_idx]; + + if (!test_bit(filter_idx, table->used_bitmap) || + spec->priority > priority) + return -ENOENT; + if (table->id == EFX_FARCH_FILTER_TABLE_RX_DEF) { /* RX default filters must always exist */ 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; - memset(&table->spec[filter_idx], 0, sizeof(table->spec[0])); - - efx_writeo(efx, &filter, - table->offset + table->step * filter_idx); - - /* If this filter required a greater search depth than - * any other, the search limit for its type can now be - * decreased. However, it is hard to determine that - * unless the table has become completely empty - in - * which case, all its search limits can be set to 0. - */ - if (unlikely(table->used == 0)) { - memset(table->search_limit, 0, - sizeof(table->search_limit)); - if (table->id == EFX_FARCH_FILTER_TABLE_TX_MAC) - efx_farch_filter_push_tx_limits(efx); - else - efx_farch_filter_push_rx_config(efx); - } + } else { + efx_farch_filter_table_clear_entry(efx, table, filter_idx); } + + return 0; } int efx_farch_filter_remove_safe(struct efx_nic *efx, @@ -2567,15 +2583,7 @@ int efx_farch_filter_remove_safe(struct efx_nic *efx, spec = &table->spec[filter_idx]; spin_lock_bh(&efx->filter_lock); - - if (test_bit(filter_idx, table->used_bitmap) && - spec->priority == priority) { - efx_farch_filter_table_clear_entry(efx, table, filter_idx); - rc = 0; - } else { - rc = -ENOENT; - } - + rc = efx_farch_filter_remove(efx, table, filter_idx, priority); spin_unlock_bh(&efx->filter_lock); return rc; @@ -2628,9 +2636,7 @@ efx_farch_filter_table_clear(struct efx_nic *efx, spin_lock_bh(&efx->filter_lock); for (filter_idx = 0; filter_idx < table->size; ++filter_idx) - if (table->spec[filter_idx].priority <= priority) - efx_farch_filter_table_clear_entry(efx, table, - filter_idx); + efx_farch_filter_remove(efx, table, filter_idx, priority); spin_unlock_bh(&efx->filter_lock); } |