Commit 1d717cf4 authored by Vinicius Costa Gomes's avatar Vinicius Costa Gomes Committed by Jeff Kirsher

igb: Add support for MAC address filters specifying source addresses

Makes it possible to direct packets to queues based on their source
address. Documents the expected usage of the 'flags' parameter.
Signed-off-by: default avatarVinicius Costa Gomes <vinicius.gomes@intel.com>
Tested-by: default avatarAaron Brown <aaron.f.brown@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 6995ddc4
...@@ -491,6 +491,7 @@ ...@@ -491,6 +491,7 @@
* manageability enabled, allowing us room for 15 multicast addresses. * manageability enabled, allowing us room for 15 multicast addresses.
*/ */
#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */ #define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
#define E1000_RAH_ASEL_SRC_ADDR 0x00010000
#define E1000_RAL_MAC_ADDR_LEN 4 #define E1000_RAL_MAC_ADDR_LEN 4
#define E1000_RAH_MAC_ADDR_LEN 2 #define E1000_RAH_MAC_ADDR_LEN 2
#define E1000_RAH_POOL_MASK 0x03FC0000 #define E1000_RAH_POOL_MASK 0x03FC0000
......
...@@ -474,6 +474,7 @@ struct igb_mac_addr { ...@@ -474,6 +474,7 @@ struct igb_mac_addr {
#define IGB_MAC_STATE_DEFAULT 0x1 #define IGB_MAC_STATE_DEFAULT 0x1
#define IGB_MAC_STATE_IN_USE 0x2 #define IGB_MAC_STATE_IN_USE 0x2
#define IGB_MAC_STATE_SRC_ADDR 0x4
/* board specific private data structure */ /* board specific private data structure */
struct igb_adapter { struct igb_adapter {
......
...@@ -6859,8 +6859,14 @@ static void igb_set_default_mac_filter(struct igb_adapter *adapter) ...@@ -6859,8 +6859,14 @@ static void igb_set_default_mac_filter(struct igb_adapter *adapter)
igb_rar_set_index(adapter, 0); igb_rar_set_index(adapter, 0);
} }
static int igb_add_mac_filter(struct igb_adapter *adapter, const u8 *addr, /* Add a MAC filter for 'addr' directing matching traffic to 'queue',
const u8 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 IGB_MAC_STATE_SRC_ADDR can be used.
*/
static int igb_add_mac_filter_flags(struct igb_adapter *adapter,
const u8 *addr, const u8 queue,
const u8 flags)
{ {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
int rar_entries = hw->mac.rar_entry_count - int rar_entries = hw->mac.rar_entry_count -
...@@ -6880,7 +6886,7 @@ static int igb_add_mac_filter(struct igb_adapter *adapter, const u8 *addr, ...@@ -6880,7 +6886,7 @@ static int igb_add_mac_filter(struct igb_adapter *adapter, const u8 *addr,
ether_addr_copy(adapter->mac_table[i].addr, addr); ether_addr_copy(adapter->mac_table[i].addr, addr);
adapter->mac_table[i].queue = queue; adapter->mac_table[i].queue = queue;
adapter->mac_table[i].state |= IGB_MAC_STATE_IN_USE; adapter->mac_table[i].state |= IGB_MAC_STATE_IN_USE | flags;
igb_rar_set_index(adapter, i); igb_rar_set_index(adapter, i);
return i; return i;
...@@ -6889,8 +6895,21 @@ static int igb_add_mac_filter(struct igb_adapter *adapter, const u8 *addr, ...@@ -6889,8 +6895,21 @@ static int igb_add_mac_filter(struct igb_adapter *adapter, const u8 *addr,
return -ENOSPC; return -ENOSPC;
} }
static int igb_del_mac_filter(struct igb_adapter *adapter, const u8 *addr, static int igb_add_mac_filter(struct igb_adapter *adapter, const u8 *addr,
const u8 queue) const u8 queue)
{
return igb_add_mac_filter_flags(adapter, addr, queue, 0);
}
/* 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
* IGB_MAC_STATE_SRC_ADDR can be used.
*/
static int igb_del_mac_filter_flags(struct igb_adapter *adapter,
const u8 *addr, const u8 queue,
const u8 flags)
{ {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
int rar_entries = hw->mac.rar_entry_count - int rar_entries = hw->mac.rar_entry_count -
...@@ -6907,12 +6926,14 @@ static int igb_del_mac_filter(struct igb_adapter *adapter, const u8 *addr, ...@@ -6907,12 +6926,14 @@ static int igb_del_mac_filter(struct igb_adapter *adapter, const u8 *addr,
for (i = 0; i < rar_entries; i++) { for (i = 0; i < rar_entries; i++) {
if (!(adapter->mac_table[i].state & IGB_MAC_STATE_IN_USE)) if (!(adapter->mac_table[i].state & IGB_MAC_STATE_IN_USE))
continue; continue;
if ((adapter->mac_table[i].state & flags) != flags)
continue;
if (adapter->mac_table[i].queue != queue) if (adapter->mac_table[i].queue != queue)
continue; continue;
if (!ether_addr_equal(adapter->mac_table[i].addr, addr)) if (!ether_addr_equal(adapter->mac_table[i].addr, addr))
continue; continue;
adapter->mac_table[i].state &= ~IGB_MAC_STATE_IN_USE; adapter->mac_table[i].state = 0;
memset(adapter->mac_table[i].addr, 0, ETH_ALEN); memset(adapter->mac_table[i].addr, 0, ETH_ALEN);
adapter->mac_table[i].queue = 0; adapter->mac_table[i].queue = 0;
...@@ -6923,6 +6944,12 @@ static int igb_del_mac_filter(struct igb_adapter *adapter, const u8 *addr, ...@@ -6923,6 +6944,12 @@ static int igb_del_mac_filter(struct igb_adapter *adapter, const u8 *addr,
return -ENOENT; return -ENOENT;
} }
static int igb_del_mac_filter(struct igb_adapter *adapter, const u8 *addr,
const u8 queue)
{
return igb_del_mac_filter_flags(adapter, addr, queue, 0);
}
static int igb_uc_sync(struct net_device *netdev, const unsigned char *addr) static int igb_uc_sync(struct net_device *netdev, const unsigned char *addr)
{ {
struct igb_adapter *adapter = netdev_priv(netdev); struct igb_adapter *adapter = netdev_priv(netdev);
...@@ -8766,6 +8793,9 @@ static void igb_rar_set_index(struct igb_adapter *adapter, u32 index) ...@@ -8766,6 +8793,9 @@ static void igb_rar_set_index(struct igb_adapter *adapter, u32 index)
if (is_valid_ether_addr(addr)) if (is_valid_ether_addr(addr))
rar_high |= E1000_RAH_AV; rar_high |= E1000_RAH_AV;
if (adapter->mac_table[index].state & IGB_MAC_STATE_SRC_ADDR)
rar_high |= E1000_RAH_ASEL_SRC_ADDR;
switch (hw->mac.type) { switch (hw->mac.type) {
case e1000_82575: case e1000_82575:
case e1000_i210: case e1000_i210:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment