aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/igc/igc_main.c
diff options
context:
space:
mode:
authorSasha Neftin <sasha.neftin@intel.com>2019-02-14 06:31:37 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2019-03-19 17:45:23 -0400
commit6245c8483ae0110d2eb7e7cd2922dba1a5fce720 (patch)
tree0780b1b6fdfe6a01d5722bee77e039b83bf93c9a /drivers/net/ethernet/intel/igc/igc_main.c
parent2121c2712f8249e4d2555a4c989e4666aba34031 (diff)
igc: Extend the ethtool supporting
Add show and configure network flow classification (NFC) methods to the ethtool. Show the specifies Rx ntuple filters. Configures receive network flow classification option or rules. Signed-off-by: Sasha Neftin <sasha.neftin@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/net/ethernet/intel/igc/igc_main.c')
-rw-r--r--drivers/net/ethernet/intel/igc/igc_main.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index a6fe614820b6..8460894829cb 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -1793,6 +1793,29 @@ static void igc_update_stats(struct igc_adapter *adapter)
1793 1793
1794static void igc_nfc_filter_exit(struct igc_adapter *adapter) 1794static void igc_nfc_filter_exit(struct igc_adapter *adapter)
1795{ 1795{
1796 struct igc_nfc_filter *rule;
1797
1798 spin_lock(&adapter->nfc_lock);
1799
1800 hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node)
1801 igc_erase_filter(adapter, rule);
1802
1803 hlist_for_each_entry(rule, &adapter->cls_flower_list, nfc_node)
1804 igc_erase_filter(adapter, rule);
1805
1806 spin_unlock(&adapter->nfc_lock);
1807}
1808
1809static void igc_nfc_filter_restore(struct igc_adapter *adapter)
1810{
1811 struct igc_nfc_filter *rule;
1812
1813 spin_lock(&adapter->nfc_lock);
1814
1815 hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node)
1816 igc_add_filter(adapter, rule);
1817
1818 spin_unlock(&adapter->nfc_lock);
1796} 1819}
1797 1820
1798/** 1821/**
@@ -1955,6 +1978,7 @@ static void igc_configure(struct igc_adapter *adapter)
1955 igc_setup_mrqc(adapter); 1978 igc_setup_mrqc(adapter);
1956 igc_setup_rctl(adapter); 1979 igc_setup_rctl(adapter);
1957 1980
1981 igc_nfc_filter_restore(adapter);
1958 igc_configure_tx(adapter); 1982 igc_configure_tx(adapter);
1959 igc_configure_rx(adapter); 1983 igc_configure_rx(adapter);
1960 1984
@@ -2016,6 +2040,127 @@ static void igc_set_default_mac_filter(struct igc_adapter *adapter)
2016 igc_rar_set_index(adapter, 0); 2040 igc_rar_set_index(adapter, 0);
2017} 2041}
2018 2042
2043/* If the filter to be added and an already existing filter express
2044 * the same address and address type, it should be possible to only
2045 * override the other configurations, for example the queue to steer
2046 * traffic.
2047 */
2048static bool igc_mac_entry_can_be_used(const struct igc_mac_addr *entry,
2049 const u8 *addr, const u8 flags)
2050{
2051 if (!(entry->state & IGC_MAC_STATE_IN_USE))
2052 return true;
2053
2054 if ((entry->state & IGC_MAC_STATE_SRC_ADDR) !=
2055 (flags & IGC_MAC_STATE_SRC_ADDR))
2056 return false;
2057
2058 if (!ether_addr_equal(addr, entry->addr))
2059 return false;
2060
2061 return true;
2062}
2063
2064/* Add a MAC filter for 'addr' directing matching traffic to 'queue',
2065 * 'flags' is used to indicate what kind of match is made, match is by
2066 * default for the destination address, if matching by source address
2067 * is desired the flag IGC_MAC_STATE_SRC_ADDR can be used.
2068 */
2069static int igc_add_mac_filter_flags(struct igc_adapter *adapter,
2070 const u8 *addr, const u8 queue,
2071 const u8 flags)
2072{
2073 struct igc_hw *hw = &adapter->hw;
2074 int rar_entries = hw->mac.rar_entry_count;
2075 int i;
2076
2077 if (is_zero_ether_addr(addr))
2078 return -EINVAL;
2079
2080 /* Search for the first empty entry in the MAC table.
2081 * Do not touch entries at the end of the table reserved for the VF MAC
2082 * addresses.
2083 */
2084 for (i = 0; i < rar_entries; i++) {
2085 if (!igc_mac_entry_can_be_used(&adapter->mac_table[i],
2086 addr, flags))
2087 continue;
2088
2089 ether_addr_copy(adapter->mac_table[i].addr, addr);
2090 adapter->mac_table[i].queue = queue;
2091 adapter->mac_table[i].state |= IGC_MAC_STATE_IN_USE | flags;
2092
2093 igc_rar_set_index(adapter, i);
2094 return i;
2095 }
2096
2097 return -ENOSPC;
2098}
2099
2100int igc_add_mac_steering_filter(struct igc_adapter *adapter,
2101 const u8 *addr, u8 queue, u8 flags)
2102{
2103 return igc_add_mac_filter_flags(adapter, addr, queue,
2104 IGC_MAC_STATE_QUEUE_STEERING | flags);
2105}
2106
2107/* Remove a MAC filter for 'addr' directing matching traffic to
2108 * 'queue', 'flags' is used to indicate what kind of match need to be
2109 * removed, match is by default for the destination address, if
2110 * matching by source address is to be removed the flag
2111 * IGC_MAC_STATE_SRC_ADDR can be used.
2112 */
2113static int igc_del_mac_filter_flags(struct igc_adapter *adapter,
2114 const u8 *addr, const u8 queue,
2115 const u8 flags)
2116{
2117 struct igc_hw *hw = &adapter->hw;
2118 int rar_entries = hw->mac.rar_entry_count;
2119 int i;
2120
2121 if (is_zero_ether_addr(addr))
2122 return -EINVAL;
2123
2124 /* Search for matching entry in the MAC table based on given address
2125 * and queue. Do not touch entries at the end of the table reserved
2126 * for the VF MAC addresses.
2127 */
2128 for (i = 0; i < rar_entries; i++) {
2129 if (!(adapter->mac_table[i].state & IGC_MAC_STATE_IN_USE))
2130 continue;
2131 if ((adapter->mac_table[i].state & flags) != flags)
2132 continue;
2133 if (adapter->mac_table[i].queue != queue)
2134 continue;
2135 if (!ether_addr_equal(adapter->mac_table[i].addr, addr))
2136 continue;
2137
2138 /* When a filter for the default address is "deleted",
2139 * we return it to its initial configuration
2140 */
2141 if (adapter->mac_table[i].state & IGC_MAC_STATE_DEFAULT) {
2142 adapter->mac_table[i].state =
2143 IGC_MAC_STATE_DEFAULT | IGC_MAC_STATE_IN_USE;
2144 } else {
2145 adapter->mac_table[i].state = 0;
2146 adapter->mac_table[i].queue = 0;
2147 memset(adapter->mac_table[i].addr, 0, ETH_ALEN);
2148 }
2149
2150 igc_rar_set_index(adapter, i);
2151 return 0;
2152 }
2153
2154 return -ENOENT;
2155}
2156
2157int igc_del_mac_steering_filter(struct igc_adapter *adapter,
2158 const u8 *addr, u8 queue, u8 flags)
2159{
2160 return igc_del_mac_filter_flags(adapter, addr, queue,
2161 IGC_MAC_STATE_QUEUE_STEERING | flags);
2162}
2163
2019/** 2164/**
2020 * igc_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set 2165 * igc_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
2021 * @netdev: network interface device structure 2166 * @netdev: network interface device structure