summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/sfc/farch.c
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2013-11-21 23:02:18 +0400
committerBen Hutchings <bhutchings@solarflare.com>2013-12-13 02:07:22 +0400
commit7665d1abea22cb44d4f0bac99e77275eba39bbf1 (patch)
treeb50444ccc9597cff1871e7c0e04f890f8a85b247 /drivers/net/ethernet/sfc/farch.c
parentd43050c0c7d930cdeb10fb9201d9e2d005cef02a (diff)
downloadlinux-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.c28
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);
}