diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2013-11-21 14:15:03 -0500 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2013-12-12 17:07:25 -0500 |
commit | fbd791202b8c5a06c8c9312bf191d69c0bb5136c (patch) | |
tree | cc82511a095cff22dfafb6c83bdbbc1acfffba62 | |
parent | f72848021d603846be8aed662bd23372c7d6688e (diff) |
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: Ben Hutchings <bhutchings@solarflare.com>
-rw-r--r-- | drivers/net/ethernet/sfc/ef10.c | 30 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/efx.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/efx.h | 14 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/farch.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/net_driver.h | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/nic.h | 4 |
6 files changed, 32 insertions, 28 deletions
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 155602c500d5..b6a0c2133b8a 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c | |||
@@ -2519,7 +2519,7 @@ static void efx_ef10_filter_update_rx_scatter(struct efx_nic *efx) | |||
2519 | * Filter ID may come from userland and must be range-checked. | 2519 | * Filter ID may come from userland and must be range-checked. |
2520 | */ | 2520 | */ |
2521 | static int efx_ef10_filter_remove_internal(struct efx_nic *efx, | 2521 | static int efx_ef10_filter_remove_internal(struct efx_nic *efx, |
2522 | enum efx_filter_priority priority, | 2522 | unsigned int priority_mask, |
2523 | u32 filter_id, bool by_index) | 2523 | u32 filter_id, bool by_index) |
2524 | { | 2524 | { |
2525 | unsigned int filter_idx = filter_id % HUNT_FILTER_TBL_ROWS; | 2525 | 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 | } | 2555 | } |
2556 | 2556 | ||
2557 | if (spec->flags & EFX_FILTER_FLAG_RX_OVER_AUTO && | 2557 | if (spec->flags & EFX_FILTER_FLAG_RX_OVER_AUTO && |
2558 | priority == EFX_FILTER_PRI_AUTO) { | 2558 | priority_mask == (1U << EFX_FILTER_PRI_AUTO)) { |
2559 | /* Just remove flags */ | 2559 | /* Just remove flags */ |
2560 | spec->flags &= ~EFX_FILTER_FLAG_RX_OVER_AUTO; | 2560 | spec->flags &= ~EFX_FILTER_FLAG_RX_OVER_AUTO; |
2561 | table->entry[filter_idx].spec &= ~EFX_EF10_FILTER_FLAG_AUTO_OLD; | 2561 | 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 | goto out_unlock; | 2563 | goto out_unlock; |
2564 | } | 2564 | } |
2565 | 2565 | ||
2566 | if (spec->priority != priority) { | 2566 | if (!(priority_mask & (1U << spec->priority))) { |
2567 | rc = -ENOENT; | 2567 | rc = -ENOENT; |
2568 | goto out_unlock; | 2568 | goto out_unlock; |
2569 | } | 2569 | } |
@@ -2619,7 +2619,8 @@ static int efx_ef10_filter_remove_safe(struct efx_nic *efx, | |||
2619 | enum efx_filter_priority priority, | 2619 | enum efx_filter_priority priority, |
2620 | u32 filter_id) | 2620 | u32 filter_id) |
2621 | { | 2621 | { |
2622 | return efx_ef10_filter_remove_internal(efx, priority, filter_id, false); | 2622 | return efx_ef10_filter_remove_internal(efx, 1U << priority, |
2623 | filter_id, false); | ||
2623 | } | 2624 | } |
2624 | 2625 | ||
2625 | static int efx_ef10_filter_get_safe(struct efx_nic *efx, | 2626 | 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 | return rc; | 2646 | return rc; |
2646 | } | 2647 | } |
2647 | 2648 | ||
2648 | static void efx_ef10_filter_clear_rx(struct efx_nic *efx, | 2649 | static int efx_ef10_filter_clear_rx(struct efx_nic *efx, |
2649 | enum efx_filter_priority priority) | 2650 | enum efx_filter_priority priority) |
2650 | { | 2651 | { |
2651 | /* TODO */ | 2652 | unsigned int priority_mask; |
2653 | unsigned int i; | ||
2654 | int rc; | ||
2655 | |||
2656 | priority_mask = (((1U << (priority + 1)) - 1) & | ||
2657 | ~(1U << EFX_FILTER_PRI_AUTO)); | ||
2658 | |||
2659 | for (i = 0; i < HUNT_FILTER_TBL_ROWS; i++) { | ||
2660 | rc = efx_ef10_filter_remove_internal(efx, priority_mask, | ||
2661 | i, true); | ||
2662 | if (rc && rc != -ENOENT) | ||
2663 | return rc; | ||
2664 | } | ||
2665 | |||
2666 | return 0; | ||
2652 | } | 2667 | } |
2653 | 2668 | ||
2654 | static u32 efx_ef10_filter_count_rx_used(struct efx_nic *efx, | 2669 | 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 | if (ACCESS_ONCE(table->entry[i].spec) & | 3225 | if (ACCESS_ONCE(table->entry[i].spec) & |
3211 | EFX_EF10_FILTER_FLAG_AUTO_OLD) { | 3226 | EFX_EF10_FILTER_FLAG_AUTO_OLD) { |
3212 | if (efx_ef10_filter_remove_internal( | 3227 | if (efx_ef10_filter_remove_internal( |
3213 | efx, EFX_FILTER_PRI_AUTO, i, true) < 0) | 3228 | efx, 1U << EFX_FILTER_PRI_AUTO, |
3229 | i, true) < 0) | ||
3214 | remove_failed = true; | 3230 | remove_failed = true; |
3215 | } | 3231 | } |
3216 | } | 3232 | } |
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index d6a927021523..ff0d9c624560 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c | |||
@@ -2151,7 +2151,7 @@ static int efx_set_features(struct net_device *net_dev, netdev_features_t data) | |||
2151 | 2151 | ||
2152 | /* If disabling RX n-tuple filtering, clear existing filters */ | 2152 | /* If disabling RX n-tuple filtering, clear existing filters */ |
2153 | if (net_dev->features & ~data & NETIF_F_NTUPLE) | 2153 | if (net_dev->features & ~data & NETIF_F_NTUPLE) |
2154 | efx_filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL); | 2154 | return efx->type->filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL); |
2155 | 2155 | ||
2156 | return 0; | 2156 | return 0; |
2157 | } | 2157 | } |
diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index 3a67030c73ea..601224736b9b 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h | |||
@@ -134,20 +134,6 @@ efx_filter_get_filter_safe(struct efx_nic *efx, | |||
134 | return efx->type->filter_get_safe(efx, priority, filter_id, spec); | 134 | return efx->type->filter_get_safe(efx, priority, filter_id, spec); |
135 | } | 135 | } |
136 | 136 | ||
137 | /** | ||
138 | * efx_farch_filter_clear_rx - remove RX filters by priority | ||
139 | * @efx: NIC from which to remove the filters | ||
140 | * @priority: Maximum priority to remove | ||
141 | * | ||
142 | * Remove all RX filters whose priority is less than or equal to the | ||
143 | * given @priority and is not %EFX_FILTER_PRI_AUTO. | ||
144 | */ | ||
145 | static inline void efx_filter_clear_rx(struct efx_nic *efx, | ||
146 | enum efx_filter_priority priority) | ||
147 | { | ||
148 | return efx->type->filter_clear_rx(efx, priority); | ||
149 | } | ||
150 | |||
151 | static inline u32 efx_filter_count_rx_used(struct efx_nic *efx, | 137 | static inline u32 efx_filter_count_rx_used(struct efx_nic *efx, |
152 | enum efx_filter_priority priority) | 138 | enum efx_filter_priority priority) |
153 | { | 139 | { |
diff --git a/drivers/net/ethernet/sfc/farch.c b/drivers/net/ethernet/sfc/farch.c index eed0741c2497..f72489a105ca 100644 --- a/drivers/net/ethernet/sfc/farch.c +++ b/drivers/net/ethernet/sfc/farch.c | |||
@@ -2638,7 +2638,7 @@ efx_farch_filter_table_clear(struct efx_nic *efx, | |||
2638 | spin_unlock_bh(&efx->filter_lock); | 2638 | spin_unlock_bh(&efx->filter_lock); |
2639 | } | 2639 | } |
2640 | 2640 | ||
2641 | void efx_farch_filter_clear_rx(struct efx_nic *efx, | 2641 | int efx_farch_filter_clear_rx(struct efx_nic *efx, |
2642 | enum efx_filter_priority priority) | 2642 | enum efx_filter_priority priority) |
2643 | { | 2643 | { |
2644 | efx_farch_filter_table_clear(efx, EFX_FARCH_FILTER_TABLE_RX_IP, | 2644 | 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 | priority); | 2647 | priority); |
2648 | efx_farch_filter_table_clear(efx, EFX_FARCH_FILTER_TABLE_RX_DEF, | 2648 | efx_farch_filter_table_clear(efx, EFX_FARCH_FILTER_TABLE_RX_DEF, |
2649 | priority); | 2649 | priority); |
2650 | return 0; | ||
2650 | } | 2651 | } |
2651 | 2652 | ||
2652 | u32 efx_farch_filter_count_rx_used(struct efx_nic *efx, | 2653 | u32 efx_farch_filter_count_rx_used(struct efx_nic *efx, |
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 1b3c4e5207c5..a0de5c50a0e7 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h | |||
@@ -1044,7 +1044,8 @@ struct efx_mtd_partition { | |||
1044 | * @filter_insert: add or replace a filter | 1044 | * @filter_insert: add or replace a filter |
1045 | * @filter_remove_safe: remove a filter by ID, carefully | 1045 | * @filter_remove_safe: remove a filter by ID, carefully |
1046 | * @filter_get_safe: retrieve a filter by ID, carefully | 1046 | * @filter_get_safe: retrieve a filter by ID, carefully |
1047 | * @filter_clear_rx: remove RX filters by priority | 1047 | * @filter_clear_rx: Remove all RX filters whose priority is less than or |
1048 | * equal to the given priority and is not %EFX_FILTER_PRI_AUTO | ||
1048 | * @filter_count_rx_used: Get the number of filters in use at a given priority | 1049 | * @filter_count_rx_used: Get the number of filters in use at a given priority |
1049 | * @filter_get_rx_id_limit: Get maximum value of a filter id, plus 1 | 1050 | * @filter_get_rx_id_limit: Get maximum value of a filter id, plus 1 |
1050 | * @filter_get_rx_ids: Get list of RX filters at a given priority | 1051 | * @filter_get_rx_ids: Get list of RX filters at a given priority |
@@ -1166,8 +1167,8 @@ struct efx_nic_type { | |||
1166 | int (*filter_get_safe)(struct efx_nic *efx, | 1167 | int (*filter_get_safe)(struct efx_nic *efx, |
1167 | enum efx_filter_priority priority, | 1168 | enum efx_filter_priority priority, |
1168 | u32 filter_id, struct efx_filter_spec *); | 1169 | u32 filter_id, struct efx_filter_spec *); |
1169 | void (*filter_clear_rx)(struct efx_nic *efx, | 1170 | int (*filter_clear_rx)(struct efx_nic *efx, |
1170 | enum efx_filter_priority priority); | 1171 | enum efx_filter_priority priority); |
1171 | u32 (*filter_count_rx_used)(struct efx_nic *efx, | 1172 | u32 (*filter_count_rx_used)(struct efx_nic *efx, |
1172 | enum efx_filter_priority priority); | 1173 | enum efx_filter_priority priority); |
1173 | u32 (*filter_get_rx_id_limit)(struct efx_nic *efx); | 1174 | u32 (*filter_get_rx_id_limit)(struct efx_nic *efx); |
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h index c665ff6c8012..e25aaf6bda87 100644 --- a/drivers/net/ethernet/sfc/nic.h +++ b/drivers/net/ethernet/sfc/nic.h | |||
@@ -693,8 +693,8 @@ int efx_farch_filter_remove_safe(struct efx_nic *efx, | |||
693 | int efx_farch_filter_get_safe(struct efx_nic *efx, | 693 | int efx_farch_filter_get_safe(struct efx_nic *efx, |
694 | enum efx_filter_priority priority, u32 filter_id, | 694 | enum efx_filter_priority priority, u32 filter_id, |
695 | struct efx_filter_spec *); | 695 | struct efx_filter_spec *); |
696 | void efx_farch_filter_clear_rx(struct efx_nic *efx, | 696 | int efx_farch_filter_clear_rx(struct efx_nic *efx, |
697 | enum efx_filter_priority priority); | 697 | enum efx_filter_priority priority); |
698 | u32 efx_farch_filter_count_rx_used(struct efx_nic *efx, | 698 | u32 efx_farch_filter_count_rx_used(struct efx_nic *efx, |
699 | enum efx_filter_priority priority); | 699 | enum efx_filter_priority priority); |
700 | u32 efx_farch_filter_get_rx_id_limit(struct efx_nic *efx); | 700 | u32 efx_farch_filter_get_rx_id_limit(struct efx_nic *efx); |