diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2013-11-21 23:02:18 +0400 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2013-12-13 02:07:22 +0400 |
commit | 7665d1abea22cb44d4f0bac99e77275eba39bbf1 (patch) | |
tree | b50444ccc9597cff1871e7c0e04f890f8a85b247 /drivers/net/ethernet/sfc/farch.c | |
parent | d43050c0c7d930cdeb10fb9201d9e2d005cef02a (diff) | |
download | linux-7665d1abea22cb44d4f0bac99e77275eba39bbf1.tar.xz |
sfc: Change priority and flags for automatic MAC filters
MAC filters inserted automatically by the driver, based on the device
address list (EF10) or no-match filters (Siena), should be overridable
at MANUAL or REQUIRED priority. Currently they themselves have
REQUIRED priority and this requires some odd special-casing.
We also can't reliably tell whether such a MAC filter has or has
not been overridden. We just remember that it is wanted by the
stack (RX_STACK flag).
Add another priority level, AUTO, between HINT and MANUAL, and
use this for the automatic filters while they have not been
overridden. Remove the RX_STACK flag. Add an RX_OVER_AUTO
flag which is set only when an AUTO filter has been overridden
(or was requested to be inserted while a higher-priority filter
existed).
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 | 28 |
1 files changed, 12 insertions, 16 deletions
diff --git a/drivers/net/ethernet/sfc/farch.c b/drivers/net/ethernet/sfc/farch.c index 4c64ad7c9200..fbd923ddf546 100644 --- a/drivers/net/ethernet/sfc/farch.c +++ b/drivers/net/ethernet/sfc/farch.c @@ -2190,8 +2190,8 @@ efx_farch_filter_init_rx_for_stack(struct efx_nic *efx, /* If there's only one channel then disable RSS for non VF * traffic, thereby allowing VFs to use RSS when the PF can't. */ - spec->priority = EFX_FILTER_PRI_REQUIRED; - spec->flags = (EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_RX_STACK | + spec->priority = EFX_FILTER_PRI_AUTO; + 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; @@ -2456,20 +2456,13 @@ s32 efx_farch_filter_insert(struct efx_nic *efx, rc = -EEXIST; goto out; } - if (spec.priority < saved_spec->priority && - !(saved_spec->priority == EFX_FILTER_PRI_REQUIRED && - saved_spec->flags & EFX_FILTER_FLAG_RX_STACK)) { + if (spec.priority < saved_spec->priority) { rc = -EPERM; goto out; } - if (spec.flags & EFX_FILTER_FLAG_RX_STACK) { - /* Just make sure it won't be removed */ - saved_spec->flags |= EFX_FILTER_FLAG_RX_STACK; - rc = 0; - goto out; - } - /* Retain the RX_STACK flag */ - spec.flags |= saved_spec->flags & EFX_FILTER_FLAG_RX_STACK; + if (saved_spec->priority == EFX_FILTER_PRI_AUTO || + saved_spec->flags & EFX_FILTER_FLAG_RX_OVER_AUTO) + spec.flags |= EFX_FILTER_FLAG_RX_OVER_AUTO; } /* Insert the filter */ @@ -2553,7 +2546,7 @@ static int efx_farch_filter_remove(struct efx_nic *efx, spec->priority > priority) return -ENOENT; - if (spec->flags & EFX_FILTER_FLAG_RX_STACK) { + if (spec->flags & EFX_FILTER_FLAG_RX_OVER_AUTO) { efx_farch_filter_init_rx_for_stack(efx, spec); efx_farch_filter_push_rx_config(efx); } else { @@ -2637,8 +2630,11 @@ efx_farch_filter_table_clear(struct efx_nic *efx, unsigned int filter_idx; spin_lock_bh(&efx->filter_lock); - for (filter_idx = 0; filter_idx < table->size; ++filter_idx) - efx_farch_filter_remove(efx, table, filter_idx, priority); + for (filter_idx = 0; filter_idx < table->size; ++filter_idx) { + if (table->spec[filter_idx].priority != EFX_FILTER_PRI_AUTO) + efx_farch_filter_remove(efx, table, + filter_idx, priority); + } spin_unlock_bh(&efx->filter_lock); } |