diff options
-rw-r--r-- | drivers/net/ethernet/sfc/farch.c | 74 |
1 files changed, 40 insertions, 34 deletions
diff --git a/drivers/net/ethernet/sfc/farch.c b/drivers/net/ethernet/sfc/farch.c index 19418045f3e0..d91bcedb9971 100644 --- a/drivers/net/ethernet/sfc/farch.c +++ b/drivers/net/ethernet/sfc/farch.c | |||
@@ -2516,33 +2516,49 @@ efx_farch_filter_table_clear_entry(struct efx_nic *efx, | |||
2516 | { | 2516 | { |
2517 | static efx_oword_t filter; | 2517 | static efx_oword_t filter; |
2518 | 2518 | ||
2519 | EFX_WARN_ON_PARANOID(!test_bit(filter_idx, table->used_bitmap)); | ||
2520 | |||
2521 | __clear_bit(filter_idx, table->used_bitmap); | ||
2522 | --table->used; | ||
2523 | memset(&table->spec[filter_idx], 0, sizeof(table->spec[0])); | ||
2524 | |||
2525 | efx_writeo(efx, &filter, table->offset + table->step * filter_idx); | ||
2526 | |||
2527 | /* If this filter required a greater search depth than | ||
2528 | * any other, the search limit for its type can now be | ||
2529 | * decreased. However, it is hard to determine that | ||
2530 | * unless the table has become completely empty - in | ||
2531 | * which case, all its search limits can be set to 0. | ||
2532 | */ | ||
2533 | if (unlikely(table->used == 0)) { | ||
2534 | memset(table->search_limit, 0, sizeof(table->search_limit)); | ||
2535 | if (table->id == EFX_FARCH_FILTER_TABLE_TX_MAC) | ||
2536 | efx_farch_filter_push_tx_limits(efx); | ||
2537 | else | ||
2538 | efx_farch_filter_push_rx_config(efx); | ||
2539 | } | ||
2540 | } | ||
2541 | |||
2542 | static int efx_farch_filter_remove(struct efx_nic *efx, | ||
2543 | struct efx_farch_filter_table *table, | ||
2544 | unsigned int filter_idx, | ||
2545 | enum efx_filter_priority priority) | ||
2546 | { | ||
2547 | struct efx_farch_filter_spec *spec = &table->spec[filter_idx]; | ||
2548 | |||
2549 | if (!test_bit(filter_idx, table->used_bitmap) || | ||
2550 | spec->priority > priority) | ||
2551 | return -ENOENT; | ||
2552 | |||
2519 | if (table->id == EFX_FARCH_FILTER_TABLE_RX_DEF) { | 2553 | if (table->id == EFX_FARCH_FILTER_TABLE_RX_DEF) { |
2520 | /* RX default filters must always exist */ | 2554 | /* RX default filters must always exist */ |
2521 | efx_farch_filter_reset_rx_def(efx, filter_idx); | 2555 | efx_farch_filter_reset_rx_def(efx, filter_idx); |
2522 | efx_farch_filter_push_rx_config(efx); | 2556 | efx_farch_filter_push_rx_config(efx); |
2523 | } else if (test_bit(filter_idx, table->used_bitmap)) { | 2557 | } else { |
2524 | __clear_bit(filter_idx, table->used_bitmap); | 2558 | efx_farch_filter_table_clear_entry(efx, table, filter_idx); |
2525 | --table->used; | ||
2526 | memset(&table->spec[filter_idx], 0, sizeof(table->spec[0])); | ||
2527 | |||
2528 | efx_writeo(efx, &filter, | ||
2529 | table->offset + table->step * filter_idx); | ||
2530 | |||
2531 | /* If this filter required a greater search depth than | ||
2532 | * any other, the search limit for its type can now be | ||
2533 | * decreased. However, it is hard to determine that | ||
2534 | * unless the table has become completely empty - in | ||
2535 | * which case, all its search limits can be set to 0. | ||
2536 | */ | ||
2537 | if (unlikely(table->used == 0)) { | ||
2538 | memset(table->search_limit, 0, | ||
2539 | sizeof(table->search_limit)); | ||
2540 | if (table->id == EFX_FARCH_FILTER_TABLE_TX_MAC) | ||
2541 | efx_farch_filter_push_tx_limits(efx); | ||
2542 | else | ||
2543 | efx_farch_filter_push_rx_config(efx); | ||
2544 | } | ||
2545 | } | 2559 | } |
2560 | |||
2561 | return 0; | ||
2546 | } | 2562 | } |
2547 | 2563 | ||
2548 | int efx_farch_filter_remove_safe(struct efx_nic *efx, | 2564 | int efx_farch_filter_remove_safe(struct efx_nic *efx, |
@@ -2567,15 +2583,7 @@ int efx_farch_filter_remove_safe(struct efx_nic *efx, | |||
2567 | spec = &table->spec[filter_idx]; | 2583 | spec = &table->spec[filter_idx]; |
2568 | 2584 | ||
2569 | spin_lock_bh(&efx->filter_lock); | 2585 | spin_lock_bh(&efx->filter_lock); |
2570 | 2586 | rc = efx_farch_filter_remove(efx, table, filter_idx, priority); | |
2571 | if (test_bit(filter_idx, table->used_bitmap) && | ||
2572 | spec->priority == priority) { | ||
2573 | efx_farch_filter_table_clear_entry(efx, table, filter_idx); | ||
2574 | rc = 0; | ||
2575 | } else { | ||
2576 | rc = -ENOENT; | ||
2577 | } | ||
2578 | |||
2579 | spin_unlock_bh(&efx->filter_lock); | 2587 | spin_unlock_bh(&efx->filter_lock); |
2580 | 2588 | ||
2581 | return rc; | 2589 | return rc; |
@@ -2628,9 +2636,7 @@ efx_farch_filter_table_clear(struct efx_nic *efx, | |||
2628 | 2636 | ||
2629 | spin_lock_bh(&efx->filter_lock); | 2637 | spin_lock_bh(&efx->filter_lock); |
2630 | for (filter_idx = 0; filter_idx < table->size; ++filter_idx) | 2638 | for (filter_idx = 0; filter_idx < table->size; ++filter_idx) |
2631 | if (table->spec[filter_idx].priority <= priority) | 2639 | efx_farch_filter_remove(efx, table, filter_idx, priority); |
2632 | efx_farch_filter_table_clear_entry(efx, table, | ||
2633 | filter_idx); | ||
2634 | spin_unlock_bh(&efx->filter_lock); | 2640 | spin_unlock_bh(&efx->filter_lock); |
2635 | } | 2641 | } |
2636 | 2642 | ||