diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/intel/igc/igc_main.c | 112 |
1 files changed, 13 insertions, 99 deletions
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index 6a7c1b081792..ade460f08ed1 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -2191,8 +2191,8 @@ static bool igc_mac_entry_can_be_used(const struct igc_mac_addr *entry, * default for the destination address, if matching by source address * is desired the flag IGC_MAC_STATE_SRC_ADDR can be used. */ -static int igc_add_mac_filter(struct igc_adapter *adapter, - const u8 *addr, const u8 queue) +static int igc_add_mac_filter(struct igc_adapter *adapter, const u8 *addr, + const u8 queue, const u8 flags) { struct igc_hw *hw = &adapter->hw; int rar_entries = hw->mac.rar_entry_count; @@ -2207,12 +2207,12 @@ static int igc_add_mac_filter(struct igc_adapter *adapter, */ for (i = 0; i < rar_entries; i++) { if (!igc_mac_entry_can_be_used(&adapter->mac_table[i], - addr, 0)) + addr, flags)) continue; 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; + adapter->mac_table[i].state |= IGC_MAC_STATE_IN_USE | flags; igc_rar_set_index(adapter, i); return i; @@ -2227,8 +2227,8 @@ static int igc_add_mac_filter(struct igc_adapter *adapter, * matching by source address is to be removed the flag * IGC_MAC_STATE_SRC_ADDR can be used. */ -static int igc_del_mac_filter(struct igc_adapter *adapter, - const u8 *addr, const u8 queue) +static int igc_del_mac_filter(struct igc_adapter *adapter, const u8 *addr, + const u8 queue, const u8 flags) { struct igc_hw *hw = &adapter->hw; int rar_entries = hw->mac.rar_entry_count; @@ -2244,7 +2244,7 @@ static int igc_del_mac_filter(struct igc_adapter *adapter, for (i = 0; i < rar_entries; i++) { if (!(adapter->mac_table[i].state & IGC_MAC_STATE_IN_USE)) continue; - if (adapter->mac_table[i].state != 0) + if (flags && (adapter->mac_table[i].state & flags) != flags) continue; if (adapter->mac_table[i].queue != queue) continue; @@ -2276,7 +2276,7 @@ static int igc_uc_sync(struct net_device *netdev, const unsigned char *addr) struct igc_adapter *adapter = netdev_priv(netdev); int ret; - ret = igc_add_mac_filter(adapter, addr, adapter->num_rx_queues); + ret = igc_add_mac_filter(adapter, addr, adapter->num_rx_queues, 0); return min_t(int, ret, 0); } @@ -2285,7 +2285,7 @@ static int igc_uc_unsync(struct net_device *netdev, const unsigned char *addr) { struct igc_adapter *adapter = netdev_priv(netdev); - igc_del_mac_filter(adapter, addr, adapter->num_rx_queues); + igc_del_mac_filter(adapter, addr, adapter->num_rx_queues, 0); return 0; } @@ -3720,104 +3720,18 @@ igc_features_check(struct sk_buff *skb, struct net_device *dev, return features; } -/* Add a MAC filter for 'addr' directing matching traffic to 'queue', - * 'flags' is used to indicate what kind of match is made, match is by - * default for the destination address, if matching by source address - * is desired the flag IGC_MAC_STATE_SRC_ADDR can be used. - */ -static int igc_add_mac_filter_flags(struct igc_adapter *adapter, - const u8 *addr, const u8 queue, - const u8 flags) -{ - struct igc_hw *hw = &adapter->hw; - int rar_entries = hw->mac.rar_entry_count; - int i; - - if (is_zero_ether_addr(addr)) - return -EINVAL; - - /* 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; - - 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; - - igc_rar_set_index(adapter, i); - return i; - } - - return -ENOSPC; -} - int igc_add_mac_steering_filter(struct igc_adapter *adapter, const u8 *addr, u8 queue, u8 flags) { - return igc_add_mac_filter_flags(adapter, addr, queue, - IGC_MAC_STATE_QUEUE_STEERING | flags); -} - -/* Remove a MAC filter for 'addr' directing matching traffic to - * 'queue', 'flags' is used to indicate what kind of match need to be - * removed, match is by default for the destination address, if - * matching by source address is to be removed the flag - * IGC_MAC_STATE_SRC_ADDR can be used. - */ -static int igc_del_mac_filter_flags(struct igc_adapter *adapter, - const u8 *addr, const u8 queue, - const u8 flags) -{ - struct igc_hw *hw = &adapter->hw; - int rar_entries = hw->mac.rar_entry_count; - int i; - - if (is_zero_ether_addr(addr)) - return -EINVAL; - - /* Search for matching entry in the MAC table based on given address - * and queue. Do not touch entries at the end of the table reserved - * for the VF MAC addresses. - */ - for (i = 0; i < rar_entries; i++) { - if (!(adapter->mac_table[i].state & IGC_MAC_STATE_IN_USE)) - continue; - if ((adapter->mac_table[i].state & flags) != flags) - continue; - if (adapter->mac_table[i].queue != queue) - continue; - if (!ether_addr_equal(adapter->mac_table[i].addr, addr)) - continue; - - /* When a filter for the default address is "deleted", - * we return it to its initial configuration - */ - if (adapter->mac_table[i].state & IGC_MAC_STATE_DEFAULT) { - adapter->mac_table[i].state = - IGC_MAC_STATE_DEFAULT | IGC_MAC_STATE_IN_USE; - } else { - adapter->mac_table[i].state = 0; - adapter->mac_table[i].queue = 0; - memset(adapter->mac_table[i].addr, 0, ETH_ALEN); - } - - igc_rar_set_index(adapter, i); - return 0; - } - - return -ENOENT; + return igc_add_mac_filter(adapter, addr, queue, + IGC_MAC_STATE_QUEUE_STEERING | flags); } int igc_del_mac_steering_filter(struct igc_adapter *adapter, const u8 *addr, u8 queue, u8 flags) { - return igc_del_mac_filter_flags(adapter, addr, queue, - IGC_MAC_STATE_QUEUE_STEERING | flags); + return igc_del_mac_filter(adapter, addr, queue, + IGC_MAC_STATE_QUEUE_STEERING | flags); } static void igc_tsync_interrupt(struct igc_adapter *adapter) |