Commit fbd79120 authored by Ben Hutchings's avatar Ben Hutchings

sfc: Implement efx_nic_type::filter_clear_rx operation for EF10

The operation can now fail, so change its return type to int.

Remove the inline wrapper while we're changing the signature.
Signed-off-by: default avatarBen Hutchings <bhutchings@solarflare.com>
parent f7284802
...@@ -2519,7 +2519,7 @@ static void efx_ef10_filter_update_rx_scatter(struct efx_nic *efx) ...@@ -2519,7 +2519,7 @@ static void efx_ef10_filter_update_rx_scatter(struct efx_nic *efx)
* Filter ID may come from userland and must be range-checked. * Filter ID may come from userland and must be range-checked.
*/ */
static int efx_ef10_filter_remove_internal(struct efx_nic *efx, static int efx_ef10_filter_remove_internal(struct efx_nic *efx,
enum efx_filter_priority priority, unsigned int priority_mask,
u32 filter_id, bool by_index) u32 filter_id, bool by_index)
{ {
unsigned int filter_idx = filter_id % HUNT_FILTER_TBL_ROWS; unsigned int filter_idx = filter_id % HUNT_FILTER_TBL_ROWS;
...@@ -2555,7 +2555,7 @@ static int efx_ef10_filter_remove_internal(struct efx_nic *efx, ...@@ -2555,7 +2555,7 @@ static int efx_ef10_filter_remove_internal(struct efx_nic *efx,
} }
if (spec->flags & EFX_FILTER_FLAG_RX_OVER_AUTO && if (spec->flags & EFX_FILTER_FLAG_RX_OVER_AUTO &&
priority == EFX_FILTER_PRI_AUTO) { priority_mask == (1U << EFX_FILTER_PRI_AUTO)) {
/* Just remove flags */ /* Just remove flags */
spec->flags &= ~EFX_FILTER_FLAG_RX_OVER_AUTO; spec->flags &= ~EFX_FILTER_FLAG_RX_OVER_AUTO;
table->entry[filter_idx].spec &= ~EFX_EF10_FILTER_FLAG_AUTO_OLD; table->entry[filter_idx].spec &= ~EFX_EF10_FILTER_FLAG_AUTO_OLD;
...@@ -2563,7 +2563,7 @@ static int efx_ef10_filter_remove_internal(struct efx_nic *efx, ...@@ -2563,7 +2563,7 @@ static int efx_ef10_filter_remove_internal(struct efx_nic *efx,
goto out_unlock; goto out_unlock;
} }
if (spec->priority != priority) { if (!(priority_mask & (1U << spec->priority))) {
rc = -ENOENT; rc = -ENOENT;
goto out_unlock; goto out_unlock;
} }
...@@ -2619,7 +2619,8 @@ static int efx_ef10_filter_remove_safe(struct efx_nic *efx, ...@@ -2619,7 +2619,8 @@ static int efx_ef10_filter_remove_safe(struct efx_nic *efx,
enum efx_filter_priority priority, enum efx_filter_priority priority,
u32 filter_id) u32 filter_id)
{ {
return efx_ef10_filter_remove_internal(efx, priority, filter_id, false); return efx_ef10_filter_remove_internal(efx, 1U << priority,
filter_id, false);
} }
static int efx_ef10_filter_get_safe(struct efx_nic *efx, static int efx_ef10_filter_get_safe(struct efx_nic *efx,
...@@ -2645,10 +2646,24 @@ static int efx_ef10_filter_get_safe(struct efx_nic *efx, ...@@ -2645,10 +2646,24 @@ static int efx_ef10_filter_get_safe(struct efx_nic *efx,
return rc; return rc;
} }
static void efx_ef10_filter_clear_rx(struct efx_nic *efx, static int efx_ef10_filter_clear_rx(struct efx_nic *efx,
enum efx_filter_priority priority) enum efx_filter_priority priority)
{ {
/* TODO */ unsigned int priority_mask;
unsigned int i;
int rc;
priority_mask = (((1U << (priority + 1)) - 1) &
~(1U << EFX_FILTER_PRI_AUTO));
for (i = 0; i < HUNT_FILTER_TBL_ROWS; i++) {
rc = efx_ef10_filter_remove_internal(efx, priority_mask,
i, true);
if (rc && rc != -ENOENT)
return rc;
}
return 0;
} }
static u32 efx_ef10_filter_count_rx_used(struct efx_nic *efx, static u32 efx_ef10_filter_count_rx_used(struct efx_nic *efx,
...@@ -3210,7 +3225,8 @@ static void efx_ef10_filter_sync_rx_mode(struct efx_nic *efx) ...@@ -3210,7 +3225,8 @@ static void efx_ef10_filter_sync_rx_mode(struct efx_nic *efx)
if (ACCESS_ONCE(table->entry[i].spec) & if (ACCESS_ONCE(table->entry[i].spec) &
EFX_EF10_FILTER_FLAG_AUTO_OLD) { EFX_EF10_FILTER_FLAG_AUTO_OLD) {
if (efx_ef10_filter_remove_internal( if (efx_ef10_filter_remove_internal(
efx, EFX_FILTER_PRI_AUTO, i, true) < 0) efx, 1U << EFX_FILTER_PRI_AUTO,
i, true) < 0)
remove_failed = true; remove_failed = true;
} }
} }
......
...@@ -2151,7 +2151,7 @@ static int efx_set_features(struct net_device *net_dev, netdev_features_t data) ...@@ -2151,7 +2151,7 @@ static int efx_set_features(struct net_device *net_dev, netdev_features_t data)
/* If disabling RX n-tuple filtering, clear existing filters */ /* If disabling RX n-tuple filtering, clear existing filters */
if (net_dev->features & ~data & NETIF_F_NTUPLE) if (net_dev->features & ~data & NETIF_F_NTUPLE)
efx_filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL); return efx->type->filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
return 0; return 0;
} }
......
...@@ -134,20 +134,6 @@ efx_filter_get_filter_safe(struct efx_nic *efx, ...@@ -134,20 +134,6 @@ efx_filter_get_filter_safe(struct efx_nic *efx,
return efx->type->filter_get_safe(efx, priority, filter_id, spec); return efx->type->filter_get_safe(efx, priority, filter_id, spec);
} }
/**
* efx_farch_filter_clear_rx - remove RX filters by priority
* @efx: NIC from which to remove the filters
* @priority: Maximum priority to remove
*
* Remove all RX filters whose priority is less than or equal to the
* given @priority and is not %EFX_FILTER_PRI_AUTO.
*/
static inline void efx_filter_clear_rx(struct efx_nic *efx,
enum efx_filter_priority priority)
{
return efx->type->filter_clear_rx(efx, priority);
}
static inline u32 efx_filter_count_rx_used(struct efx_nic *efx, static inline u32 efx_filter_count_rx_used(struct efx_nic *efx,
enum efx_filter_priority priority) enum efx_filter_priority priority)
{ {
......
...@@ -2638,7 +2638,7 @@ efx_farch_filter_table_clear(struct efx_nic *efx, ...@@ -2638,7 +2638,7 @@ efx_farch_filter_table_clear(struct efx_nic *efx,
spin_unlock_bh(&efx->filter_lock); spin_unlock_bh(&efx->filter_lock);
} }
void efx_farch_filter_clear_rx(struct efx_nic *efx, int efx_farch_filter_clear_rx(struct efx_nic *efx,
enum efx_filter_priority priority) enum efx_filter_priority priority)
{ {
efx_farch_filter_table_clear(efx, EFX_FARCH_FILTER_TABLE_RX_IP, efx_farch_filter_table_clear(efx, EFX_FARCH_FILTER_TABLE_RX_IP,
...@@ -2647,6 +2647,7 @@ void efx_farch_filter_clear_rx(struct efx_nic *efx, ...@@ -2647,6 +2647,7 @@ void efx_farch_filter_clear_rx(struct efx_nic *efx,
priority); priority);
efx_farch_filter_table_clear(efx, EFX_FARCH_FILTER_TABLE_RX_DEF, efx_farch_filter_table_clear(efx, EFX_FARCH_FILTER_TABLE_RX_DEF,
priority); priority);
return 0;
} }
u32 efx_farch_filter_count_rx_used(struct efx_nic *efx, u32 efx_farch_filter_count_rx_used(struct efx_nic *efx,
......
...@@ -1044,7 +1044,8 @@ struct efx_mtd_partition { ...@@ -1044,7 +1044,8 @@ struct efx_mtd_partition {
* @filter_insert: add or replace a filter * @filter_insert: add or replace a filter
* @filter_remove_safe: remove a filter by ID, carefully * @filter_remove_safe: remove a filter by ID, carefully
* @filter_get_safe: retrieve a filter by ID, carefully * @filter_get_safe: retrieve a filter by ID, carefully
* @filter_clear_rx: remove RX filters by priority * @filter_clear_rx: Remove all RX filters whose priority is less than or
* equal to the given priority and is not %EFX_FILTER_PRI_AUTO
* @filter_count_rx_used: Get the number of filters in use at a given priority * @filter_count_rx_used: Get the number of filters in use at a given priority
* @filter_get_rx_id_limit: Get maximum value of a filter id, plus 1 * @filter_get_rx_id_limit: Get maximum value of a filter id, plus 1
* @filter_get_rx_ids: Get list of RX filters at a given priority * @filter_get_rx_ids: Get list of RX filters at a given priority
...@@ -1166,7 +1167,7 @@ struct efx_nic_type { ...@@ -1166,7 +1167,7 @@ struct efx_nic_type {
int (*filter_get_safe)(struct efx_nic *efx, int (*filter_get_safe)(struct efx_nic *efx,
enum efx_filter_priority priority, enum efx_filter_priority priority,
u32 filter_id, struct efx_filter_spec *); u32 filter_id, struct efx_filter_spec *);
void (*filter_clear_rx)(struct efx_nic *efx, int (*filter_clear_rx)(struct efx_nic *efx,
enum efx_filter_priority priority); enum efx_filter_priority priority);
u32 (*filter_count_rx_used)(struct efx_nic *efx, u32 (*filter_count_rx_used)(struct efx_nic *efx,
enum efx_filter_priority priority); enum efx_filter_priority priority);
......
...@@ -693,7 +693,7 @@ int efx_farch_filter_remove_safe(struct efx_nic *efx, ...@@ -693,7 +693,7 @@ int efx_farch_filter_remove_safe(struct efx_nic *efx,
int efx_farch_filter_get_safe(struct efx_nic *efx, int efx_farch_filter_get_safe(struct efx_nic *efx,
enum efx_filter_priority priority, u32 filter_id, enum efx_filter_priority priority, u32 filter_id,
struct efx_filter_spec *); struct efx_filter_spec *);
void efx_farch_filter_clear_rx(struct efx_nic *efx, int efx_farch_filter_clear_rx(struct efx_nic *efx,
enum efx_filter_priority priority); enum efx_filter_priority priority);
u32 efx_farch_filter_count_rx_used(struct efx_nic *efx, u32 efx_farch_filter_count_rx_used(struct efx_nic *efx,
enum efx_filter_priority priority); enum efx_filter_priority priority);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment