diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2013-01-14 16:23:15 -0500 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2013-03-07 15:22:00 -0500 |
commit | 385904f819e31fcf5a5aa53fa91f3352bffa6d19 (patch) | |
tree | 92edabc7a7ce6e22d5bb61f4b185de1dfea9402b /drivers/net/ethernet/sfc | |
parent | e3a699fab34a724fa8693c1274d3ddb3e213a134 (diff) |
sfc: Don't use efx_filter_{build,hash,increment}() for default MAC filters
These functions happen to work for default MAC filters: they generate
an initial index of 1/0 for unicast/multicast respectively and an
increment of 1 for either, so a search succeeds at depth 2. But this
is a matter of luck rather than design, and it really won't work well
with the bug fix we're about to do.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/ethernet/sfc')
-rw-r--r-- | drivers/net/ethernet/sfc/filter.c | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/drivers/net/ethernet/sfc/filter.c b/drivers/net/ethernet/sfc/filter.c index 3d94ed73c65e..8d83d9832b21 100644 --- a/drivers/net/ethernet/sfc/filter.c +++ b/drivers/net/ethernet/sfc/filter.c | |||
@@ -463,13 +463,6 @@ static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec) | |||
463 | break; | 463 | break; |
464 | } | 464 | } |
465 | 465 | ||
466 | case EFX_FILTER_TABLE_RX_DEF: | ||
467 | /* One filter spec per type */ | ||
468 | BUILD_BUG_ON(EFX_FILTER_INDEX_UC_DEF != 0); | ||
469 | BUILD_BUG_ON(EFX_FILTER_INDEX_MC_DEF != | ||
470 | EFX_FILTER_MC_DEF - EFX_FILTER_UC_DEF); | ||
471 | return spec->type - EFX_FILTER_UC_DEF; | ||
472 | |||
473 | case EFX_FILTER_TABLE_RX_MAC: { | 466 | case EFX_FILTER_TABLE_RX_MAC: { |
474 | bool is_wild = spec->type == EFX_FILTER_MAC_WILD; | 467 | bool is_wild = spec->type == EFX_FILTER_MAC_WILD; |
475 | EFX_POPULATE_OWORD_7( | 468 | EFX_POPULATE_OWORD_7( |
@@ -667,25 +660,35 @@ s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec, | |||
667 | struct efx_filter_spec *saved_spec; | 660 | struct efx_filter_spec *saved_spec; |
668 | efx_oword_t filter; | 661 | efx_oword_t filter; |
669 | unsigned int filter_idx, depth = 0; | 662 | unsigned int filter_idx, depth = 0; |
670 | u32 key; | ||
671 | int rc; | 663 | int rc; |
672 | 664 | ||
673 | if (!table || table->size == 0) | 665 | if (!table || table->size == 0) |
674 | return -EINVAL; | 666 | return -EINVAL; |
675 | 667 | ||
676 | key = efx_filter_build(&filter, spec); | ||
677 | |||
678 | netif_vdbg(efx, hw, efx->net_dev, | 668 | netif_vdbg(efx, hw, efx->net_dev, |
679 | "%s: type %d search_depth=%d", __func__, spec->type, | 669 | "%s: type %d search_depth=%d", __func__, spec->type, |
680 | table->search_depth[spec->type]); | 670 | table->search_depth[spec->type]); |
681 | 671 | ||
682 | spin_lock_bh(&state->lock); | 672 | if (table->id == EFX_FILTER_TABLE_RX_DEF) { |
673 | /* One filter spec per type */ | ||
674 | BUILD_BUG_ON(EFX_FILTER_INDEX_UC_DEF != 0); | ||
675 | BUILD_BUG_ON(EFX_FILTER_INDEX_MC_DEF != | ||
676 | EFX_FILTER_MC_DEF - EFX_FILTER_UC_DEF); | ||
677 | filter_idx = spec->type - EFX_FILTER_INDEX_UC_DEF; | ||
678 | |||
679 | spin_lock_bh(&state->lock); | ||
680 | } else { | ||
681 | u32 key = efx_filter_build(&filter, spec); | ||
682 | |||
683 | spin_lock_bh(&state->lock); | ||
684 | |||
685 | rc = efx_filter_search(table, spec, key, &depth); | ||
686 | if (rc < 0) | ||
687 | goto out; | ||
688 | filter_idx = rc; | ||
689 | BUG_ON(filter_idx >= table->size); | ||
690 | } | ||
683 | 691 | ||
684 | rc = efx_filter_search(table, spec, key, &depth); | ||
685 | if (rc < 0) | ||
686 | goto out; | ||
687 | filter_idx = rc; | ||
688 | BUG_ON(filter_idx >= table->size); | ||
689 | saved_spec = &table->spec[filter_idx]; | 692 | saved_spec = &table->spec[filter_idx]; |
690 | 693 | ||
691 | if (test_bit(filter_idx, table->used_bitmap)) { | 694 | if (test_bit(filter_idx, table->used_bitmap)) { |