aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2013-11-21 14:15:03 -0500
committerBen Hutchings <bhutchings@solarflare.com>2013-12-12 17:07:25 -0500
commitfbd791202b8c5a06c8c9312bf191d69c0bb5136c (patch)
treecc82511a095cff22dfafb6c83bdbbc1acfffba62
parentf72848021d603846be8aed662bd23372c7d6688e (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.c30
-rw-r--r--drivers/net/ethernet/sfc/efx.c2
-rw-r--r--drivers/net/ethernet/sfc/efx.h14
-rw-r--r--drivers/net/ethernet/sfc/farch.c3
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h7
-rw-r--r--drivers/net/ethernet/sfc/nic.h4
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 */
2521static int efx_ef10_filter_remove_internal(struct efx_nic *efx, 2521static 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
2625static int efx_ef10_filter_get_safe(struct efx_nic *efx, 2626static 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
2648static void efx_ef10_filter_clear_rx(struct efx_nic *efx, 2649static 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
2654static u32 efx_ef10_filter_count_rx_used(struct efx_nic *efx, 2669static 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 */
145static 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
151static inline u32 efx_filter_count_rx_used(struct efx_nic *efx, 137static 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
2641void efx_farch_filter_clear_rx(struct efx_nic *efx, 2641int 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
2652u32 efx_farch_filter_count_rx_used(struct efx_nic *efx, 2653u32 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,
693int efx_farch_filter_get_safe(struct efx_nic *efx, 693int 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 *);
696void efx_farch_filter_clear_rx(struct efx_nic *efx, 696int efx_farch_filter_clear_rx(struct efx_nic *efx,
697 enum efx_filter_priority priority); 697 enum efx_filter_priority priority);
698u32 efx_farch_filter_count_rx_used(struct efx_nic *efx, 698u32 efx_farch_filter_count_rx_used(struct efx_nic *efx,
699 enum efx_filter_priority priority); 699 enum efx_filter_priority priority);
700u32 efx_farch_filter_get_rx_id_limit(struct efx_nic *efx); 700u32 efx_farch_filter_get_rx_id_limit(struct efx_nic *efx);