diff options
author | Andre Guedes <andre.guedes@intel.com> | 2020-03-18 16:01:00 -0700 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2020-04-19 12:17:14 -0700 |
commit | 794e5bc817bcc16ca955691e957e23908edbef9c (patch) | |
tree | 9160a97b71de79548bb7f026c26baf582aa627ff /drivers | |
parent | 83ba21b9ef7706413bdaf9fa8357b93c4986d8a0 (diff) | |
download | linux-794e5bc817bcc16ca955691e957e23908edbef9c.tar.bz2 |
igc: Refactor igc_mac_entry_can_be_used()
The helper igc_mac_entry_can_be_used() implementation is a bit
convoluted since it does two different things: find a not-in-use slot
in mac_table or find an in-use slot where the address and address type
match. This patch does a code refactoring and break it up into two
helper functions.
With this patch we might traverse mac_table twice in some situations,
but this is not harmful performance-wise (mac_table has only 16 entries
and adding mac filters is not hot-path), and it improves igc_add_mac_
filter() readability considerably.
Signed-off-by: Andre Guedes <andre.guedes@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/intel/igc/igc_main.c | 80 |
1 files changed, 47 insertions, 33 deletions
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index 3af6ce1712d5..79a9875e0767 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -2176,25 +2176,44 @@ static void igc_nfc_filter_restore(struct igc_adapter *adapter) spin_unlock(&adapter->nfc_lock); } -/* If the filter to be added and an already existing filter express - * the same address and address type, it should be possible to only - * override the other configurations, for example the queue to steer - * traffic. - */ -static bool igc_mac_entry_can_be_used(const struct igc_mac_addr *entry, - const u8 *addr, const u8 flags) +static int igc_find_mac_filter(struct igc_adapter *adapter, const u8 *addr, + u8 flags) { - if (!(entry->state & IGC_MAC_STATE_IN_USE)) - return true; + int max_entries = adapter->hw.mac.rar_entry_count; + struct igc_mac_addr *entry; + int i; - if ((entry->state & IGC_MAC_STATE_SRC_ADDR) != - (flags & IGC_MAC_STATE_SRC_ADDR)) - return false; + for (i = 0; i < max_entries; i++) { + entry = &adapter->mac_table[i]; - if (!ether_addr_equal(addr, entry->addr)) - return false; + if (!(entry->state & IGC_MAC_STATE_IN_USE)) + continue; + if (!ether_addr_equal(addr, entry->addr)) + continue; + if ((entry->state & IGC_MAC_STATE_SRC_ADDR) != + (flags & IGC_MAC_STATE_SRC_ADDR)) + continue; - return true; + return i; + } + + return -1; +} + +static int igc_get_avail_mac_filter_slot(struct igc_adapter *adapter) +{ + int max_entries = adapter->hw.mac.rar_entry_count; + struct igc_mac_addr *entry; + int i; + + for (i = 0; i < max_entries; i++) { + entry = &adapter->mac_table[i]; + + if (!(entry->state & IGC_MAC_STATE_IN_USE)) + return i; + } + + return -1; } /** @@ -2212,33 +2231,28 @@ static bool igc_mac_entry_can_be_used(const struct igc_mac_addr *entry, int igc_add_mac_filter(struct igc_adapter *adapter, const u8 *addr, const s8 queue, const u8 flags) { - struct igc_hw *hw = &adapter->hw; - int rar_entries = hw->mac.rar_entry_count; - int i; + int index; if (!is_valid_ether_addr(addr)) return -EINVAL; if (flags & IGC_MAC_STATE_SRC_ADDR) return -ENOTSUPP; - /* Search for the first empty entry in the MAC table. - * Do not touch entries at the end of the table reserved for the VF MAC - * addresses. - */ - for (i = 0; i < rar_entries; i++) { - if (!igc_mac_entry_can_be_used(&adapter->mac_table[i], - addr, flags)) - continue; + index = igc_find_mac_filter(adapter, addr, flags); + if (index >= 0) + goto update_queue_assignment; - ether_addr_copy(adapter->mac_table[i].addr, addr); - adapter->mac_table[i].queue = queue; - adapter->mac_table[i].state |= IGC_MAC_STATE_IN_USE | flags; + index = igc_get_avail_mac_filter_slot(adapter); + if (index < 0) + return -ENOSPC; - igc_set_mac_filter_hw(adapter, i, addr, queue); - return 0; - } + ether_addr_copy(adapter->mac_table[index].addr, addr); + adapter->mac_table[index].state |= IGC_MAC_STATE_IN_USE | flags; +update_queue_assignment: + adapter->mac_table[index].queue = queue; - return -ENOSPC; + igc_set_mac_filter_hw(adapter, index, addr, queue); + return 0; } /** |