Commit 7b1b843a authored by David S. Miller's avatar David S. Miller

Merge branch '1GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue

Jeff Kirsher says:

====================
1GbE Intel Wired LAN Driver Updates 2020-05-21

This series contains updates to igc and e1000.

Andre cleans up code that was left over from the igb driver that handled
MAC address filters based on the source address, which is not currently
supported.  Simplifies the MAC address filtering code and prepare the
igc driver for future source address support.  Updated the MAC address
filter internal APIs to support filters based on source address.  Added
support for Network Flow Classification (NFC) rules based on source MAC
address.  Cleaned up the 'cookie' field which is not used anywhere in
the code and cleaned up a wrapper function that was not needed.
Simplified the filtering code for readability and aligned the ethtool
functions, so that function names were consistent.

Alex provides a fix for e1000 to resolve a deadlock issue when NAPI is
being disabled.

Sasha does additional cleanup of the igc driver of dead code that is not
used or needed.

v2: Fix the function header comment in patch 3 of the series, based on
    the feedback from Jakub Kicinski.
====================
Reviewed-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2a330b53 c983e327
...@@ -542,8 +542,13 @@ void e1000_reinit_locked(struct e1000_adapter *adapter) ...@@ -542,8 +542,13 @@ void e1000_reinit_locked(struct e1000_adapter *adapter)
WARN_ON(in_interrupt()); WARN_ON(in_interrupt());
while (test_and_set_bit(__E1000_RESETTING, &adapter->flags)) while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
msleep(1); msleep(1);
e1000_down(adapter);
e1000_up(adapter); /* only run the task if not already down */
if (!test_bit(__E1000_DOWN, &adapter->flags)) {
e1000_down(adapter);
e1000_up(adapter);
}
clear_bit(__E1000_RESETTING, &adapter->flags); clear_bit(__E1000_RESETTING, &adapter->flags);
} }
...@@ -1433,10 +1438,15 @@ int e1000_close(struct net_device *netdev) ...@@ -1433,10 +1438,15 @@ int e1000_close(struct net_device *netdev)
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
int count = E1000_CHECK_RESET_COUNT; int count = E1000_CHECK_RESET_COUNT;
while (test_bit(__E1000_RESETTING, &adapter->flags) && count--) while (test_and_set_bit(__E1000_RESETTING, &adapter->flags) && count--)
usleep_range(10000, 20000); usleep_range(10000, 20000);
WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags)); WARN_ON(count < 0);
/* signal that we're down so that the reset task will no longer run */
set_bit(__E1000_DOWN, &adapter->flags);
clear_bit(__E1000_RESETTING, &adapter->flags);
e1000_down(adapter); e1000_down(adapter);
e1000_power_down_phy(adapter); e1000_power_down_phy(adapter);
e1000_free_irq(adapter); e1000_free_irq(adapter);
......
...@@ -16,8 +16,7 @@ ...@@ -16,8 +16,7 @@
#include "igc_hw.h" #include "igc_hw.h"
/* forward declaration */ void igc_ethtool_set_ops(struct net_device *);
void igc_set_ethtool_ops(struct net_device *);
/* Transmit and receive queues */ /* Transmit and receive queues */
#define IGC_MAX_RX_QUEUES 4 #define IGC_MAX_RX_QUEUES 4
...@@ -29,6 +28,11 @@ void igc_set_ethtool_ops(struct net_device *); ...@@ -29,6 +28,11 @@ void igc_set_ethtool_ops(struct net_device *);
#define MAX_ETYPE_FILTER 8 #define MAX_ETYPE_FILTER 8
#define IGC_RETA_SIZE 128 #define IGC_RETA_SIZE 128
enum igc_mac_filter_type {
IGC_MAC_FILTER_TYPE_DST = 0,
IGC_MAC_FILTER_TYPE_SRC
};
struct igc_tx_queue_stats { struct igc_tx_queue_stats {
u64 packets; u64 packets;
u64 bytes; u64 bytes;
...@@ -183,14 +187,12 @@ struct igc_adapter { ...@@ -183,14 +187,12 @@ struct igc_adapter {
u32 rss_queues; u32 rss_queues;
u32 rss_indir_tbl_init; u32 rss_indir_tbl_init;
/* RX network flow classification support */ /* Any access to elements in nfc_rule_list is protected by the
struct hlist_head nfc_filter_list; * nfc_rule_lock.
unsigned int nfc_filter_count; */
spinlock_t nfc_rule_lock;
/* lock for RX network flow classification filter */ struct hlist_head nfc_rule_list;
spinlock_t nfc_lock; unsigned int nfc_rule_count;
struct igc_mac_addr *mac_table;
u8 rss_indir_tbl[IGC_RETA_SIZE]; u8 rss_indir_tbl[IGC_RETA_SIZE];
...@@ -230,10 +232,11 @@ void igc_write_rss_indir_tbl(struct igc_adapter *adapter); ...@@ -230,10 +232,11 @@ void igc_write_rss_indir_tbl(struct igc_adapter *adapter);
bool igc_has_link(struct igc_adapter *adapter); bool igc_has_link(struct igc_adapter *adapter);
void igc_reset(struct igc_adapter *adapter); void igc_reset(struct igc_adapter *adapter);
int igc_set_spd_dplx(struct igc_adapter *adapter, u32 spd, u8 dplx); int igc_set_spd_dplx(struct igc_adapter *adapter, u32 spd, u8 dplx);
int igc_add_mac_filter(struct igc_adapter *adapter, const u8 *addr, int igc_add_mac_filter(struct igc_adapter *adapter,
const s8 queue, const u8 flags); enum igc_mac_filter_type type, const u8 *addr,
int igc_del_mac_filter(struct igc_adapter *adapter, const u8 *addr, int queue);
const u8 flags); int igc_del_mac_filter(struct igc_adapter *adapter,
enum igc_mac_filter_type type, const u8 *addr);
int igc_add_vlan_prio_filter(struct igc_adapter *adapter, int prio, int igc_add_vlan_prio_filter(struct igc_adapter *adapter, int prio,
int queue); int queue);
void igc_del_vlan_prio_filter(struct igc_adapter *adapter, int prio); void igc_del_vlan_prio_filter(struct igc_adapter *adapter, int prio);
...@@ -449,39 +452,22 @@ enum igc_filter_match_flags { ...@@ -449,39 +452,22 @@ enum igc_filter_match_flags {
IGC_FILTER_FLAG_DST_MAC_ADDR = 0x8, IGC_FILTER_FLAG_DST_MAC_ADDR = 0x8,
}; };
/* RX network flow classification data structure */ struct igc_nfc_filter {
struct igc_nfc_input {
/* Byte layout in order, all values with MSB first:
* match_flags - 1 byte
* etype - 2 bytes
* vlan_tci - 2 bytes
*/
u8 match_flags; u8 match_flags;
__be16 etype; u16 etype;
__be16 vlan_tci; u16 vlan_tci;
u8 src_addr[ETH_ALEN]; u8 src_addr[ETH_ALEN];
u8 dst_addr[ETH_ALEN]; u8 dst_addr[ETH_ALEN];
}; };
struct igc_nfc_filter { struct igc_nfc_rule {
struct hlist_node nfc_node; struct hlist_node nfc_node;
struct igc_nfc_input filter; struct igc_nfc_filter filter;
unsigned long cookie;
u16 sw_idx; u16 sw_idx;
u16 action; u16 action;
}; };
struct igc_mac_addr { #define IGC_MAX_RXNFC_RULES 16
u8 addr[ETH_ALEN];
s8 queue;
u8 state; /* bitmask */
};
#define IGC_MAC_STATE_DEFAULT 0x1
#define IGC_MAC_STATE_IN_USE 0x2
#define IGC_MAC_STATE_SRC_ADDR 0x4
#define IGC_MAX_RXNFC_FILTERS 16
/* igc_desc_unused - calculate if we have unused descriptors */ /* igc_desc_unused - calculate if we have unused descriptors */
static inline u16 igc_desc_unused(const struct igc_ring *ring) static inline u16 igc_desc_unused(const struct igc_ring *ring)
...@@ -557,12 +543,11 @@ static inline s32 igc_read_phy_reg(struct igc_hw *hw, u32 offset, u16 *data) ...@@ -557,12 +543,11 @@ static inline s32 igc_read_phy_reg(struct igc_hw *hw, u32 offset, u16 *data)
return 0; return 0;
} }
/* forward declaration */
void igc_reinit_locked(struct igc_adapter *); void igc_reinit_locked(struct igc_adapter *);
int igc_add_filter(struct igc_adapter *adapter, int igc_enable_nfc_rule(struct igc_adapter *adapter,
struct igc_nfc_filter *input); const struct igc_nfc_rule *rule);
int igc_erase_filter(struct igc_adapter *adapter, int igc_disable_nfc_rule(struct igc_adapter *adapter,
struct igc_nfc_filter *input); const struct igc_nfc_rule *rule);
void igc_ptp_init(struct igc_adapter *adapter); void igc_ptp_init(struct igc_adapter *adapter);
void igc_ptp_reset(struct igc_adapter *adapter); void igc_ptp_reset(struct igc_adapter *adapter);
......
...@@ -62,6 +62,9 @@ ...@@ -62,6 +62,9 @@
* (RAR[15]) for our directed address used by controllers with * (RAR[15]) for our directed address used by controllers with
* manageability enabled, allowing us room for 15 multicast addresses. * manageability enabled, allowing us room for 15 multicast addresses.
*/ */
#define IGC_RAH_RAH_MASK 0x0000FFFF
#define IGC_RAH_ASEL_MASK 0x00030000
#define IGC_RAH_ASEL_SRC_ADDR BIT(16)
#define IGC_RAH_QSEL_MASK 0x000C0000 #define IGC_RAH_QSEL_MASK 0x000C0000
#define IGC_RAH_QSEL_SHIFT 18 #define IGC_RAH_QSEL_SHIFT 18
#define IGC_RAH_QSEL_ENABLE BIT(28) #define IGC_RAH_QSEL_ENABLE BIT(28)
......
...@@ -124,8 +124,8 @@ static const char igc_priv_flags_strings[][ETH_GSTRING_LEN] = { ...@@ -124,8 +124,8 @@ static const char igc_priv_flags_strings[][ETH_GSTRING_LEN] = {
#define IGC_PRIV_FLAGS_STR_LEN ARRAY_SIZE(igc_priv_flags_strings) #define IGC_PRIV_FLAGS_STR_LEN ARRAY_SIZE(igc_priv_flags_strings)
static void igc_get_drvinfo(struct net_device *netdev, static void igc_ethtool_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo) struct ethtool_drvinfo *drvinfo)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
...@@ -139,13 +139,13 @@ static void igc_get_drvinfo(struct net_device *netdev, ...@@ -139,13 +139,13 @@ static void igc_get_drvinfo(struct net_device *netdev,
drvinfo->n_priv_flags = IGC_PRIV_FLAGS_STR_LEN; drvinfo->n_priv_flags = IGC_PRIV_FLAGS_STR_LEN;
} }
static int igc_get_regs_len(struct net_device *netdev) static int igc_ethtool_get_regs_len(struct net_device *netdev)
{ {
return IGC_REGS_LEN * sizeof(u32); return IGC_REGS_LEN * sizeof(u32);
} }
static void igc_get_regs(struct net_device *netdev, static void igc_ethtool_get_regs(struct net_device *netdev,
struct ethtool_regs *regs, void *p) struct ethtool_regs *regs, void *p)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
struct igc_hw *hw = &adapter->hw; struct igc_hw *hw = &adapter->hw;
...@@ -323,7 +323,8 @@ static void igc_get_regs(struct net_device *netdev, ...@@ -323,7 +323,8 @@ static void igc_get_regs(struct net_device *netdev,
regs_buff[205 + i] = rd32(IGC_ETQF(i)); regs_buff[205 + i] = rd32(IGC_ETQF(i));
} }
static void igc_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) static void igc_ethtool_get_wol(struct net_device *netdev,
struct ethtool_wolinfo *wol)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
...@@ -354,7 +355,8 @@ static void igc_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) ...@@ -354,7 +355,8 @@ static void igc_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
wol->wolopts |= WAKE_PHY; wol->wolopts |= WAKE_PHY;
} }
static int igc_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) static int igc_ethtool_set_wol(struct net_device *netdev,
struct ethtool_wolinfo *wol)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
...@@ -382,21 +384,21 @@ static int igc_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) ...@@ -382,21 +384,21 @@ static int igc_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
return 0; return 0;
} }
static u32 igc_get_msglevel(struct net_device *netdev) static u32 igc_ethtool_get_msglevel(struct net_device *netdev)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
return adapter->msg_enable; return adapter->msg_enable;
} }
static void igc_set_msglevel(struct net_device *netdev, u32 data) static void igc_ethtool_set_msglevel(struct net_device *netdev, u32 data)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
adapter->msg_enable = data; adapter->msg_enable = data;
} }
static int igc_nway_reset(struct net_device *netdev) static int igc_ethtool_nway_reset(struct net_device *netdev)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
...@@ -405,7 +407,7 @@ static int igc_nway_reset(struct net_device *netdev) ...@@ -405,7 +407,7 @@ static int igc_nway_reset(struct net_device *netdev)
return 0; return 0;
} }
static u32 igc_get_link(struct net_device *netdev) static u32 igc_ethtool_get_link(struct net_device *netdev)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
struct igc_mac_info *mac = &adapter->hw.mac; struct igc_mac_info *mac = &adapter->hw.mac;
...@@ -422,15 +424,15 @@ static u32 igc_get_link(struct net_device *netdev) ...@@ -422,15 +424,15 @@ static u32 igc_get_link(struct net_device *netdev)
return igc_has_link(adapter); return igc_has_link(adapter);
} }
static int igc_get_eeprom_len(struct net_device *netdev) static int igc_ethtool_get_eeprom_len(struct net_device *netdev)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
return adapter->hw.nvm.word_size * 2; return adapter->hw.nvm.word_size * 2;
} }
static int igc_get_eeprom(struct net_device *netdev, static int igc_ethtool_get_eeprom(struct net_device *netdev,
struct ethtool_eeprom *eeprom, u8 *bytes) struct ethtool_eeprom *eeprom, u8 *bytes)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
struct igc_hw *hw = &adapter->hw; struct igc_hw *hw = &adapter->hw;
...@@ -476,8 +478,8 @@ static int igc_get_eeprom(struct net_device *netdev, ...@@ -476,8 +478,8 @@ static int igc_get_eeprom(struct net_device *netdev,
return ret_val; return ret_val;
} }
static int igc_set_eeprom(struct net_device *netdev, static int igc_ethtool_set_eeprom(struct net_device *netdev,
struct ethtool_eeprom *eeprom, u8 *bytes) struct ethtool_eeprom *eeprom, u8 *bytes)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
struct igc_hw *hw = &adapter->hw; struct igc_hw *hw = &adapter->hw;
...@@ -544,8 +546,8 @@ static int igc_set_eeprom(struct net_device *netdev, ...@@ -544,8 +546,8 @@ static int igc_set_eeprom(struct net_device *netdev,
return ret_val; return ret_val;
} }
static void igc_get_ringparam(struct net_device *netdev, static void igc_ethtool_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring) struct ethtool_ringparam *ring)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
...@@ -555,8 +557,8 @@ static void igc_get_ringparam(struct net_device *netdev, ...@@ -555,8 +557,8 @@ static void igc_get_ringparam(struct net_device *netdev,
ring->tx_pending = adapter->tx_ring_count; ring->tx_pending = adapter->tx_ring_count;
} }
static int igc_set_ringparam(struct net_device *netdev, static int igc_ethtool_set_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring) struct ethtool_ringparam *ring)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
struct igc_ring *temp_ring; struct igc_ring *temp_ring;
...@@ -670,8 +672,8 @@ static int igc_set_ringparam(struct net_device *netdev, ...@@ -670,8 +672,8 @@ static int igc_set_ringparam(struct net_device *netdev,
return err; return err;
} }
static void igc_get_pauseparam(struct net_device *netdev, static void igc_ethtool_get_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause) struct ethtool_pauseparam *pause)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
struct igc_hw *hw = &adapter->hw; struct igc_hw *hw = &adapter->hw;
...@@ -689,8 +691,8 @@ static void igc_get_pauseparam(struct net_device *netdev, ...@@ -689,8 +691,8 @@ static void igc_get_pauseparam(struct net_device *netdev,
} }
} }
static int igc_set_pauseparam(struct net_device *netdev, static int igc_ethtool_set_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause) struct ethtool_pauseparam *pause)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
struct igc_hw *hw = &adapter->hw; struct igc_hw *hw = &adapter->hw;
...@@ -729,7 +731,8 @@ static int igc_set_pauseparam(struct net_device *netdev, ...@@ -729,7 +731,8 @@ static int igc_set_pauseparam(struct net_device *netdev,
return retval; return retval;
} }
static void igc_get_strings(struct net_device *netdev, u32 stringset, u8 *data) static void igc_ethtool_get_strings(struct net_device *netdev, u32 stringset,
u8 *data)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
u8 *p = data; u8 *p = data;
...@@ -780,7 +783,7 @@ static void igc_get_strings(struct net_device *netdev, u32 stringset, u8 *data) ...@@ -780,7 +783,7 @@ static void igc_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
} }
} }
static int igc_get_sset_count(struct net_device *netdev, int sset) static int igc_ethtool_get_sset_count(struct net_device *netdev, int sset)
{ {
switch (sset) { switch (sset) {
case ETH_SS_STATS: case ETH_SS_STATS:
...@@ -794,7 +797,7 @@ static int igc_get_sset_count(struct net_device *netdev, int sset) ...@@ -794,7 +797,7 @@ static int igc_get_sset_count(struct net_device *netdev, int sset)
} }
} }
static void igc_get_ethtool_stats(struct net_device *netdev, static void igc_ethtool_get_stats(struct net_device *netdev,
struct ethtool_stats *stats, u64 *data) struct ethtool_stats *stats, u64 *data)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
...@@ -850,8 +853,8 @@ static void igc_get_ethtool_stats(struct net_device *netdev, ...@@ -850,8 +853,8 @@ static void igc_get_ethtool_stats(struct net_device *netdev,
spin_unlock(&adapter->stats64_lock); spin_unlock(&adapter->stats64_lock);
} }
static int igc_get_coalesce(struct net_device *netdev, static int igc_ethtool_get_coalesce(struct net_device *netdev,
struct ethtool_coalesce *ec) struct ethtool_coalesce *ec)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
...@@ -870,8 +873,8 @@ static int igc_get_coalesce(struct net_device *netdev, ...@@ -870,8 +873,8 @@ static int igc_get_coalesce(struct net_device *netdev,
return 0; return 0;
} }
static int igc_set_coalesce(struct net_device *netdev, static int igc_ethtool_set_coalesce(struct net_device *netdev,
struct ethtool_coalesce *ec) struct ethtool_coalesce *ec)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
int i; int i;
...@@ -928,16 +931,15 @@ static int igc_set_coalesce(struct net_device *netdev, ...@@ -928,16 +931,15 @@ static int igc_set_coalesce(struct net_device *netdev,
} }
#define ETHER_TYPE_FULL_MASK ((__force __be16)~0) #define ETHER_TYPE_FULL_MASK ((__force __be16)~0)
static int igc_get_ethtool_nfc_entry(struct igc_adapter *adapter, static int igc_ethtool_get_nfc_rule(struct igc_adapter *adapter,
struct ethtool_rxnfc *cmd) struct ethtool_rxnfc *cmd)
{ {
struct ethtool_rx_flow_spec *fsp = &cmd->fs; struct ethtool_rx_flow_spec *fsp = &cmd->fs;
struct igc_nfc_filter *rule = NULL; struct igc_nfc_rule *rule = NULL;
/* report total rule count */ cmd->data = IGC_MAX_RXNFC_RULES;
cmd->data = IGC_MAX_RXNFC_FILTERS;
hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) { hlist_for_each_entry(rule, &adapter->nfc_rule_list, nfc_node) {
if (fsp->location <= rule->sw_idx) if (fsp->location <= rule->sw_idx)
break; break;
} }
...@@ -945,51 +947,48 @@ static int igc_get_ethtool_nfc_entry(struct igc_adapter *adapter, ...@@ -945,51 +947,48 @@ static int igc_get_ethtool_nfc_entry(struct igc_adapter *adapter,
if (!rule || fsp->location != rule->sw_idx) if (!rule || fsp->location != rule->sw_idx)
return -EINVAL; return -EINVAL;
if (rule->filter.match_flags) { if (!rule->filter.match_flags)
fsp->flow_type = ETHER_FLOW; return -EINVAL;
fsp->ring_cookie = rule->action;
if (rule->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) {
fsp->h_u.ether_spec.h_proto = rule->filter.etype;
fsp->m_u.ether_spec.h_proto = ETHER_TYPE_FULL_MASK;
}
if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) {
fsp->flow_type |= FLOW_EXT;
fsp->h_ext.vlan_tci = rule->filter.vlan_tci;
fsp->m_ext.vlan_tci = htons(VLAN_PRIO_MASK);
}
if (rule->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) {
ether_addr_copy(fsp->h_u.ether_spec.h_dest,
rule->filter.dst_addr);
/* As we only support matching by the full
* mask, return the mask to userspace
*/
eth_broadcast_addr(fsp->m_u.ether_spec.h_dest);
}
if (rule->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) {
ether_addr_copy(fsp->h_u.ether_spec.h_source,
rule->filter.src_addr);
/* As we only support matching by the full
* mask, return the mask to userspace
*/
eth_broadcast_addr(fsp->m_u.ether_spec.h_source);
}
return 0; fsp->flow_type = ETHER_FLOW;
fsp->ring_cookie = rule->action;
if (rule->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) {
fsp->h_u.ether_spec.h_proto = htons(rule->filter.etype);
fsp->m_u.ether_spec.h_proto = ETHER_TYPE_FULL_MASK;
}
if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) {
fsp->flow_type |= FLOW_EXT;
fsp->h_ext.vlan_tci = htons(rule->filter.vlan_tci);
fsp->m_ext.vlan_tci = htons(VLAN_PRIO_MASK);
}
if (rule->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) {
ether_addr_copy(fsp->h_u.ether_spec.h_dest,
rule->filter.dst_addr);
eth_broadcast_addr(fsp->m_u.ether_spec.h_dest);
} }
return -EINVAL;
if (rule->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) {
ether_addr_copy(fsp->h_u.ether_spec.h_source,
rule->filter.src_addr);
eth_broadcast_addr(fsp->m_u.ether_spec.h_source);
}
return 0;
} }
static int igc_get_ethtool_nfc_all(struct igc_adapter *adapter, static int igc_ethtool_get_nfc_rules(struct igc_adapter *adapter,
struct ethtool_rxnfc *cmd, struct ethtool_rxnfc *cmd,
u32 *rule_locs) u32 *rule_locs)
{ {
struct igc_nfc_filter *rule; struct igc_nfc_rule *rule;
int cnt = 0; int cnt = 0;
/* report total rule count */ cmd->data = IGC_MAX_RXNFC_RULES;
cmd->data = IGC_MAX_RXNFC_FILTERS;
hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) { hlist_for_each_entry(rule, &adapter->nfc_rule_list, nfc_node) {
if (cnt == cmd->rule_cnt) if (cnt == cmd->rule_cnt)
return -EMSGSIZE; return -EMSGSIZE;
rule_locs[cnt] = rule->sw_idx; rule_locs[cnt] = rule->sw_idx;
...@@ -1001,8 +1000,8 @@ static int igc_get_ethtool_nfc_all(struct igc_adapter *adapter, ...@@ -1001,8 +1000,8 @@ static int igc_get_ethtool_nfc_all(struct igc_adapter *adapter,
return 0; return 0;
} }
static int igc_get_rss_hash_opts(struct igc_adapter *adapter, static int igc_ethtool_get_rss_hash_opts(struct igc_adapter *adapter,
struct ethtool_rxnfc *cmd) struct ethtool_rxnfc *cmd)
{ {
cmd->data = 0; cmd->data = 0;
...@@ -1051,41 +1050,33 @@ static int igc_get_rss_hash_opts(struct igc_adapter *adapter, ...@@ -1051,41 +1050,33 @@ static int igc_get_rss_hash_opts(struct igc_adapter *adapter,
return 0; return 0;
} }
static int igc_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, static int igc_ethtool_get_rxnfc(struct net_device *dev,
u32 *rule_locs) struct ethtool_rxnfc *cmd, u32 *rule_locs)
{ {
struct igc_adapter *adapter = netdev_priv(dev); struct igc_adapter *adapter = netdev_priv(dev);
int ret = -EOPNOTSUPP;
switch (cmd->cmd) { switch (cmd->cmd) {
case ETHTOOL_GRXRINGS: case ETHTOOL_GRXRINGS:
cmd->data = adapter->num_rx_queues; cmd->data = adapter->num_rx_queues;
ret = 0; return 0;
break;
case ETHTOOL_GRXCLSRLCNT: case ETHTOOL_GRXCLSRLCNT:
cmd->rule_cnt = adapter->nfc_filter_count; cmd->rule_cnt = adapter->nfc_rule_count;
ret = 0; return 0;
break;
case ETHTOOL_GRXCLSRULE: case ETHTOOL_GRXCLSRULE:
ret = igc_get_ethtool_nfc_entry(adapter, cmd); return igc_ethtool_get_nfc_rule(adapter, cmd);
break;
case ETHTOOL_GRXCLSRLALL: case ETHTOOL_GRXCLSRLALL:
ret = igc_get_ethtool_nfc_all(adapter, cmd, rule_locs); return igc_ethtool_get_nfc_rules(adapter, cmd, rule_locs);
break;
case ETHTOOL_GRXFH: case ETHTOOL_GRXFH:
ret = igc_get_rss_hash_opts(adapter, cmd); return igc_ethtool_get_rss_hash_opts(adapter, cmd);
break;
default: default:
break; return -EOPNOTSUPP;
} }
return ret;
} }
#define UDP_RSS_FLAGS (IGC_FLAG_RSS_FIELD_IPV4_UDP | \ #define UDP_RSS_FLAGS (IGC_FLAG_RSS_FIELD_IPV4_UDP | \
IGC_FLAG_RSS_FIELD_IPV6_UDP) IGC_FLAG_RSS_FIELD_IPV6_UDP)
static int igc_set_rss_hash_opt(struct igc_adapter *adapter, static int igc_ethtool_set_rss_hash_opt(struct igc_adapter *adapter,
struct ethtool_rxnfc *nfc) struct ethtool_rxnfc *nfc)
{ {
u32 flags = adapter->flags; u32 flags = adapter->flags;
...@@ -1186,45 +1177,37 @@ static int igc_set_rss_hash_opt(struct igc_adapter *adapter, ...@@ -1186,45 +1177,37 @@ static int igc_set_rss_hash_opt(struct igc_adapter *adapter,
return 0; return 0;
} }
int igc_add_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input) int igc_enable_nfc_rule(struct igc_adapter *adapter,
const struct igc_nfc_rule *rule)
{ {
struct igc_hw *hw = &adapter->hw;
int err = -EINVAL; int err = -EINVAL;
if (hw->mac.type == igc_i225 && if (rule->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) {
!(input->filter.match_flags & ~IGC_FILTER_FLAG_SRC_MAC_ADDR)) { err = igc_add_etype_filter(adapter, rule->filter.etype,
netdev_err(adapter->netdev, rule->action);
"i225 doesn't support flow classification rules specifying only source addresses\n");
return -EOPNOTSUPP;
}
if (input->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) {
u16 etype = ntohs(input->filter.etype);
err = igc_add_etype_filter(adapter, etype, input->action);
if (err) if (err)
return err; return err;
} }
if (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) { if (rule->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) {
err = igc_add_mac_filter(adapter, input->filter.dst_addr, err = igc_add_mac_filter(adapter, IGC_MAC_FILTER_TYPE_SRC,
input->action, 0); rule->filter.src_addr, rule->action);
if (err) if (err)
return err; return err;
} }
if (input->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) { if (rule->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) {
err = igc_add_mac_filter(adapter, input->filter.src_addr, err = igc_add_mac_filter(adapter, IGC_MAC_FILTER_TYPE_DST,
input->action, rule->filter.dst_addr, rule->action);
IGC_MAC_STATE_SRC_ADDR);
if (err) if (err)
return err; return err;
} }
if (input->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) { if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) {
int prio = (ntohs(input->filter.vlan_tci) & VLAN_PRIO_MASK) >> int prio = (rule->filter.vlan_tci & VLAN_PRIO_MASK) >>
VLAN_PRIO_SHIFT; VLAN_PRIO_SHIFT;
err = igc_add_vlan_prio_filter(adapter, prio, input->action);
err = igc_add_vlan_prio_filter(adapter, prio, rule->action);
if (err) if (err)
return err; return err;
} }
...@@ -1232,41 +1215,40 @@ int igc_add_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input) ...@@ -1232,41 +1215,40 @@ int igc_add_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input)
return 0; return 0;
} }
int igc_erase_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input) int igc_disable_nfc_rule(struct igc_adapter *adapter,
const struct igc_nfc_rule *rule)
{ {
if (input->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) { if (rule->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE)
u16 etype = ntohs(input->filter.etype); igc_del_etype_filter(adapter, rule->filter.etype);
igc_del_etype_filter(adapter, etype); if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) {
} int prio = (rule->filter.vlan_tci & VLAN_PRIO_MASK) >>
if (input->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) {
int prio = (ntohs(input->filter.vlan_tci) & VLAN_PRIO_MASK) >>
VLAN_PRIO_SHIFT; VLAN_PRIO_SHIFT;
igc_del_vlan_prio_filter(adapter, prio); igc_del_vlan_prio_filter(adapter, prio);
} }
if (input->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) if (rule->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR)
igc_del_mac_filter(adapter, input->filter.src_addr, igc_del_mac_filter(adapter, IGC_MAC_FILTER_TYPE_SRC,
IGC_MAC_STATE_SRC_ADDR); rule->filter.src_addr);
if (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) if (rule->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR)
igc_del_mac_filter(adapter, input->filter.dst_addr, 0); igc_del_mac_filter(adapter, IGC_MAC_FILTER_TYPE_DST,
rule->filter.dst_addr);
return 0; return 0;
} }
static int igc_update_ethtool_nfc_entry(struct igc_adapter *adapter, static int igc_ethtool_update_nfc_rule(struct igc_adapter *adapter,
struct igc_nfc_filter *input, struct igc_nfc_rule *input,
u16 sw_idx) u16 sw_idx)
{ {
struct igc_nfc_filter *rule, *parent; struct igc_nfc_rule *rule, *parent;
int err = -EINVAL; int err = -EINVAL;
parent = NULL; parent = NULL;
rule = NULL; rule = NULL;
hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) { hlist_for_each_entry(rule, &adapter->nfc_rule_list, nfc_node) {
/* hash found, or no matching entry */ /* hash found, or no matching entry */
if (rule->sw_idx >= sw_idx) if (rule->sw_idx >= sw_idx)
break; break;
...@@ -1276,11 +1258,11 @@ static int igc_update_ethtool_nfc_entry(struct igc_adapter *adapter, ...@@ -1276,11 +1258,11 @@ static int igc_update_ethtool_nfc_entry(struct igc_adapter *adapter,
/* if there is an old rule occupying our place remove it */ /* if there is an old rule occupying our place remove it */
if (rule && rule->sw_idx == sw_idx) { if (rule && rule->sw_idx == sw_idx) {
if (!input) if (!input)
err = igc_erase_filter(adapter, rule); err = igc_disable_nfc_rule(adapter, rule);
hlist_del(&rule->nfc_node); hlist_del(&rule->nfc_node);
kfree(rule); kfree(rule);
adapter->nfc_filter_count--; adapter->nfc_rule_count--;
} }
/* If no input this was a delete, err should be 0 if a rule was /* If no input this was a delete, err should be 0 if a rule was
...@@ -1296,21 +1278,21 @@ static int igc_update_ethtool_nfc_entry(struct igc_adapter *adapter, ...@@ -1296,21 +1278,21 @@ static int igc_update_ethtool_nfc_entry(struct igc_adapter *adapter,
if (parent) if (parent)
hlist_add_behind(&input->nfc_node, &parent->nfc_node); hlist_add_behind(&input->nfc_node, &parent->nfc_node);
else else
hlist_add_head(&input->nfc_node, &adapter->nfc_filter_list); hlist_add_head(&input->nfc_node, &adapter->nfc_rule_list);
/* update counts */ /* update counts */
adapter->nfc_filter_count++; adapter->nfc_rule_count++;
return 0; return 0;
} }
static int igc_add_ethtool_nfc_entry(struct igc_adapter *adapter, static int igc_ethtool_add_nfc_rule(struct igc_adapter *adapter,
struct ethtool_rxnfc *cmd) struct ethtool_rxnfc *cmd)
{ {
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct ethtool_rx_flow_spec *fsp = struct ethtool_rx_flow_spec *fsp =
(struct ethtool_rx_flow_spec *)&cmd->fs; (struct ethtool_rx_flow_spec *)&cmd->fs;
struct igc_nfc_filter *input, *rule; struct igc_nfc_rule *rule, *tmp;
int err = 0; int err = 0;
if (!(netdev->hw_features & NETIF_F_NTUPLE)) if (!(netdev->hw_features & NETIF_F_NTUPLE))
...@@ -1327,7 +1309,7 @@ static int igc_add_ethtool_nfc_entry(struct igc_adapter *adapter, ...@@ -1327,7 +1309,7 @@ static int igc_add_ethtool_nfc_entry(struct igc_adapter *adapter,
} }
/* Don't allow indexes to exist outside of available space */ /* Don't allow indexes to exist outside of available space */
if (fsp->location >= IGC_MAX_RXNFC_FILTERS) { if (fsp->location >= IGC_MAX_RXNFC_RULES) {
netdev_err(netdev, "Location out of range\n"); netdev_err(netdev, "Location out of range\n");
return -EINVAL; return -EINVAL;
} }
...@@ -1335,47 +1317,55 @@ static int igc_add_ethtool_nfc_entry(struct igc_adapter *adapter, ...@@ -1335,47 +1317,55 @@ static int igc_add_ethtool_nfc_entry(struct igc_adapter *adapter,
if ((fsp->flow_type & ~FLOW_EXT) != ETHER_FLOW) if ((fsp->flow_type & ~FLOW_EXT) != ETHER_FLOW)
return -EINVAL; return -EINVAL;
input = kzalloc(sizeof(*input), GFP_KERNEL); rule = kzalloc(sizeof(*rule), GFP_KERNEL);
if (!input) if (!rule)
return -ENOMEM; return -ENOMEM;
if (fsp->m_u.ether_spec.h_proto == ETHER_TYPE_FULL_MASK) { if (fsp->m_u.ether_spec.h_proto == ETHER_TYPE_FULL_MASK) {
input->filter.etype = fsp->h_u.ether_spec.h_proto; rule->filter.etype = ntohs(fsp->h_u.ether_spec.h_proto);
input->filter.match_flags = IGC_FILTER_FLAG_ETHER_TYPE; rule->filter.match_flags = IGC_FILTER_FLAG_ETHER_TYPE;
} }
/* Only support matching addresses by the full mask */ /* Both source and destination address filters only support the full
* mask.
*/
if (is_broadcast_ether_addr(fsp->m_u.ether_spec.h_source)) { if (is_broadcast_ether_addr(fsp->m_u.ether_spec.h_source)) {
input->filter.match_flags |= IGC_FILTER_FLAG_SRC_MAC_ADDR; rule->filter.match_flags |= IGC_FILTER_FLAG_SRC_MAC_ADDR;
ether_addr_copy(input->filter.src_addr, ether_addr_copy(rule->filter.src_addr,
fsp->h_u.ether_spec.h_source); fsp->h_u.ether_spec.h_source);
} }
/* Only support matching addresses by the full mask */
if (is_broadcast_ether_addr(fsp->m_u.ether_spec.h_dest)) { if (is_broadcast_ether_addr(fsp->m_u.ether_spec.h_dest)) {
input->filter.match_flags |= IGC_FILTER_FLAG_DST_MAC_ADDR; rule->filter.match_flags |= IGC_FILTER_FLAG_DST_MAC_ADDR;
ether_addr_copy(input->filter.dst_addr, ether_addr_copy(rule->filter.dst_addr,
fsp->h_u.ether_spec.h_dest); fsp->h_u.ether_spec.h_dest);
} }
if (rule->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR &&
rule->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) {
netdev_dbg(netdev, "Filters with both dst and src are not supported\n");
err = -EOPNOTSUPP;
goto err_out;
}
if ((fsp->flow_type & FLOW_EXT) && fsp->m_ext.vlan_tci) { if ((fsp->flow_type & FLOW_EXT) && fsp->m_ext.vlan_tci) {
if (fsp->m_ext.vlan_tci != htons(VLAN_PRIO_MASK)) { if (fsp->m_ext.vlan_tci != htons(VLAN_PRIO_MASK)) {
netdev_dbg(netdev, "VLAN mask not supported\n"); netdev_dbg(netdev, "VLAN mask not supported\n");
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto err_out; goto err_out;
} }
input->filter.vlan_tci = fsp->h_ext.vlan_tci; rule->filter.vlan_tci = ntohs(fsp->h_ext.vlan_tci);
input->filter.match_flags |= IGC_FILTER_FLAG_VLAN_TCI; rule->filter.match_flags |= IGC_FILTER_FLAG_VLAN_TCI;
} }
input->action = fsp->ring_cookie; rule->action = fsp->ring_cookie;
input->sw_idx = fsp->location; rule->sw_idx = fsp->location;
spin_lock(&adapter->nfc_lock); spin_lock(&adapter->nfc_rule_lock);
hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) { hlist_for_each_entry(tmp, &adapter->nfc_rule_list, nfc_node) {
if (!memcmp(&input->filter, &rule->filter, if (!memcmp(&rule->filter, &tmp->filter,
sizeof(input->filter))) { sizeof(rule->filter))) {
err = -EEXIST; err = -EEXIST;
netdev_err(netdev, netdev_err(netdev,
"ethtool: this filter is already set\n"); "ethtool: this filter is already set\n");
...@@ -1383,55 +1373,51 @@ static int igc_add_ethtool_nfc_entry(struct igc_adapter *adapter, ...@@ -1383,55 +1373,51 @@ static int igc_add_ethtool_nfc_entry(struct igc_adapter *adapter,
} }
} }
err = igc_add_filter(adapter, input); err = igc_enable_nfc_rule(adapter, rule);
if (err) if (err)
goto err_out_w_lock; goto err_out_w_lock;
igc_update_ethtool_nfc_entry(adapter, input, input->sw_idx); igc_ethtool_update_nfc_rule(adapter, rule, rule->sw_idx);
spin_unlock(&adapter->nfc_lock); spin_unlock(&adapter->nfc_rule_lock);
return 0; return 0;
err_out_w_lock: err_out_w_lock:
spin_unlock(&adapter->nfc_lock); spin_unlock(&adapter->nfc_rule_lock);
err_out: err_out:
kfree(input); kfree(rule);
return err; return err;
} }
static int igc_del_ethtool_nfc_entry(struct igc_adapter *adapter, static int igc_ethtool_del_nfc_rule(struct igc_adapter *adapter,
struct ethtool_rxnfc *cmd) struct ethtool_rxnfc *cmd)
{ {
struct ethtool_rx_flow_spec *fsp = struct ethtool_rx_flow_spec *fsp =
(struct ethtool_rx_flow_spec *)&cmd->fs; (struct ethtool_rx_flow_spec *)&cmd->fs;
int err; int err;
spin_lock(&adapter->nfc_lock); spin_lock(&adapter->nfc_rule_lock);
err = igc_update_ethtool_nfc_entry(adapter, NULL, fsp->location); err = igc_ethtool_update_nfc_rule(adapter, NULL, fsp->location);
spin_unlock(&adapter->nfc_lock); spin_unlock(&adapter->nfc_rule_lock);
return err; return err;
} }
static int igc_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) static int igc_ethtool_set_rxnfc(struct net_device *dev,
struct ethtool_rxnfc *cmd)
{ {
struct igc_adapter *adapter = netdev_priv(dev); struct igc_adapter *adapter = netdev_priv(dev);
int ret = -EOPNOTSUPP;
switch (cmd->cmd) { switch (cmd->cmd) {
case ETHTOOL_SRXFH: case ETHTOOL_SRXFH:
ret = igc_set_rss_hash_opt(adapter, cmd); return igc_ethtool_set_rss_hash_opt(adapter, cmd);
break;
case ETHTOOL_SRXCLSRLINS: case ETHTOOL_SRXCLSRLINS:
ret = igc_add_ethtool_nfc_entry(adapter, cmd); return igc_ethtool_add_nfc_rule(adapter, cmd);
break;
case ETHTOOL_SRXCLSRLDEL: case ETHTOOL_SRXCLSRLDEL:
ret = igc_del_ethtool_nfc_entry(adapter, cmd); return igc_ethtool_del_nfc_rule(adapter, cmd);
default: default:
break; return -EOPNOTSUPP;
} }
return ret;
} }
void igc_write_rss_indir_tbl(struct igc_adapter *adapter) void igc_write_rss_indir_tbl(struct igc_adapter *adapter)
...@@ -1456,13 +1442,13 @@ void igc_write_rss_indir_tbl(struct igc_adapter *adapter) ...@@ -1456,13 +1442,13 @@ void igc_write_rss_indir_tbl(struct igc_adapter *adapter)
} }
} }
static u32 igc_get_rxfh_indir_size(struct net_device *netdev) static u32 igc_ethtool_get_rxfh_indir_size(struct net_device *netdev)
{ {
return IGC_RETA_SIZE; return IGC_RETA_SIZE;
} }
static int igc_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, static int igc_ethtool_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
u8 *hfunc) u8 *hfunc)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
int i; int i;
...@@ -1477,8 +1463,8 @@ static int igc_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, ...@@ -1477,8 +1463,8 @@ static int igc_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
return 0; return 0;
} }
static int igc_set_rxfh(struct net_device *netdev, const u32 *indir, static int igc_ethtool_set_rxfh(struct net_device *netdev, const u32 *indir,
const u8 *key, const u8 hfunc) const u8 *key, const u8 hfunc)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
u32 num_queues; u32 num_queues;
...@@ -1506,18 +1492,13 @@ static int igc_set_rxfh(struct net_device *netdev, const u32 *indir, ...@@ -1506,18 +1492,13 @@ static int igc_set_rxfh(struct net_device *netdev, const u32 *indir,
return 0; return 0;
} }
static unsigned int igc_max_channels(struct igc_adapter *adapter) static void igc_ethtool_get_channels(struct net_device *netdev,
{ struct ethtool_channels *ch)
return igc_get_max_rss_queues(adapter);
}
static void igc_get_channels(struct net_device *netdev,
struct ethtool_channels *ch)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
/* Report maximum channels */ /* Report maximum channels */
ch->max_combined = igc_max_channels(adapter); ch->max_combined = igc_get_max_rss_queues(adapter);
/* Report info for other vector */ /* Report info for other vector */
if (adapter->flags & IGC_FLAG_HAS_MSIX) { if (adapter->flags & IGC_FLAG_HAS_MSIX) {
...@@ -1528,8 +1509,8 @@ static void igc_get_channels(struct net_device *netdev, ...@@ -1528,8 +1509,8 @@ static void igc_get_channels(struct net_device *netdev,
ch->combined_count = adapter->rss_queues; ch->combined_count = adapter->rss_queues;
} }
static int igc_set_channels(struct net_device *netdev, static int igc_ethtool_set_channels(struct net_device *netdev,
struct ethtool_channels *ch) struct ethtool_channels *ch)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
unsigned int count = ch->combined_count; unsigned int count = ch->combined_count;
...@@ -1544,7 +1525,7 @@ static int igc_set_channels(struct net_device *netdev, ...@@ -1544,7 +1525,7 @@ static int igc_set_channels(struct net_device *netdev,
return -EINVAL; return -EINVAL;
/* Verify the number of channels doesn't exceed hw limits */ /* Verify the number of channels doesn't exceed hw limits */
max_combined = igc_max_channels(adapter); max_combined = igc_get_max_rss_queues(adapter);
if (count > max_combined) if (count > max_combined)
return -EINVAL; return -EINVAL;
...@@ -1561,8 +1542,8 @@ static int igc_set_channels(struct net_device *netdev, ...@@ -1561,8 +1542,8 @@ static int igc_set_channels(struct net_device *netdev,
return 0; return 0;
} }
static int igc_get_ts_info(struct net_device *dev, static int igc_ethtool_get_ts_info(struct net_device *dev,
struct ethtool_ts_info *info) struct ethtool_ts_info *info)
{ {
struct igc_adapter *adapter = netdev_priv(dev); struct igc_adapter *adapter = netdev_priv(dev);
...@@ -1594,7 +1575,7 @@ static int igc_get_ts_info(struct net_device *dev, ...@@ -1594,7 +1575,7 @@ static int igc_get_ts_info(struct net_device *dev,
} }
} }
static u32 igc_get_priv_flags(struct net_device *netdev) static u32 igc_ethtool_get_priv_flags(struct net_device *netdev)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
u32 priv_flags = 0; u32 priv_flags = 0;
...@@ -1605,7 +1586,7 @@ static u32 igc_get_priv_flags(struct net_device *netdev) ...@@ -1605,7 +1586,7 @@ static u32 igc_get_priv_flags(struct net_device *netdev)
return priv_flags; return priv_flags;
} }
static int igc_set_priv_flags(struct net_device *netdev, u32 priv_flags) static int igc_ethtool_set_priv_flags(struct net_device *netdev, u32 priv_flags)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
unsigned int flags = adapter->flags; unsigned int flags = adapter->flags;
...@@ -1640,8 +1621,8 @@ static void igc_ethtool_complete(struct net_device *netdev) ...@@ -1640,8 +1621,8 @@ static void igc_ethtool_complete(struct net_device *netdev)
pm_runtime_put(&adapter->pdev->dev); pm_runtime_put(&adapter->pdev->dev);
} }
static int igc_get_link_ksettings(struct net_device *netdev, static int igc_ethtool_get_link_ksettings(struct net_device *netdev,
struct ethtool_link_ksettings *cmd) struct ethtool_link_ksettings *cmd)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
struct igc_hw *hw = &adapter->hw; struct igc_hw *hw = &adapter->hw;
...@@ -1747,8 +1728,9 @@ static int igc_get_link_ksettings(struct net_device *netdev, ...@@ -1747,8 +1728,9 @@ static int igc_get_link_ksettings(struct net_device *netdev,
return 0; return 0;
} }
static int igc_set_link_ksettings(struct net_device *netdev, static int
const struct ethtool_link_ksettings *cmd) igc_ethtool_set_link_ksettings(struct net_device *netdev,
const struct ethtool_link_ksettings *cmd)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
struct net_device *dev = adapter->netdev; struct net_device *dev = adapter->netdev;
...@@ -1814,8 +1796,8 @@ static int igc_set_link_ksettings(struct net_device *netdev, ...@@ -1814,8 +1796,8 @@ static int igc_set_link_ksettings(struct net_device *netdev,
return 0; return 0;
} }
static void igc_diag_test(struct net_device *netdev, static void igc_ethtool_diag_test(struct net_device *netdev,
struct ethtool_test *eth_test, u64 *data) struct ethtool_test *eth_test, u64 *data)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
bool if_running = netif_running(netdev); bool if_running = netif_running(netdev);
...@@ -1874,45 +1856,45 @@ static void igc_diag_test(struct net_device *netdev, ...@@ -1874,45 +1856,45 @@ static void igc_diag_test(struct net_device *netdev,
static const struct ethtool_ops igc_ethtool_ops = { static const struct ethtool_ops igc_ethtool_ops = {
.supported_coalesce_params = ETHTOOL_COALESCE_USECS, .supported_coalesce_params = ETHTOOL_COALESCE_USECS,
.get_drvinfo = igc_get_drvinfo, .get_drvinfo = igc_ethtool_get_drvinfo,
.get_regs_len = igc_get_regs_len, .get_regs_len = igc_ethtool_get_regs_len,
.get_regs = igc_get_regs, .get_regs = igc_ethtool_get_regs,
.get_wol = igc_get_wol, .get_wol = igc_ethtool_get_wol,
.set_wol = igc_set_wol, .set_wol = igc_ethtool_set_wol,
.get_msglevel = igc_get_msglevel, .get_msglevel = igc_ethtool_get_msglevel,
.set_msglevel = igc_set_msglevel, .set_msglevel = igc_ethtool_set_msglevel,
.nway_reset = igc_nway_reset, .nway_reset = igc_ethtool_nway_reset,
.get_link = igc_get_link, .get_link = igc_ethtool_get_link,
.get_eeprom_len = igc_get_eeprom_len, .get_eeprom_len = igc_ethtool_get_eeprom_len,
.get_eeprom = igc_get_eeprom, .get_eeprom = igc_ethtool_get_eeprom,
.set_eeprom = igc_set_eeprom, .set_eeprom = igc_ethtool_set_eeprom,
.get_ringparam = igc_get_ringparam, .get_ringparam = igc_ethtool_get_ringparam,
.set_ringparam = igc_set_ringparam, .set_ringparam = igc_ethtool_set_ringparam,
.get_pauseparam = igc_get_pauseparam, .get_pauseparam = igc_ethtool_get_pauseparam,
.set_pauseparam = igc_set_pauseparam, .set_pauseparam = igc_ethtool_set_pauseparam,
.get_strings = igc_get_strings, .get_strings = igc_ethtool_get_strings,
.get_sset_count = igc_get_sset_count, .get_sset_count = igc_ethtool_get_sset_count,
.get_ethtool_stats = igc_get_ethtool_stats, .get_ethtool_stats = igc_ethtool_get_stats,
.get_coalesce = igc_get_coalesce, .get_coalesce = igc_ethtool_get_coalesce,
.set_coalesce = igc_set_coalesce, .set_coalesce = igc_ethtool_set_coalesce,
.get_rxnfc = igc_get_rxnfc, .get_rxnfc = igc_ethtool_get_rxnfc,
.set_rxnfc = igc_set_rxnfc, .set_rxnfc = igc_ethtool_set_rxnfc,
.get_rxfh_indir_size = igc_get_rxfh_indir_size, .get_rxfh_indir_size = igc_ethtool_get_rxfh_indir_size,
.get_rxfh = igc_get_rxfh, .get_rxfh = igc_ethtool_get_rxfh,
.set_rxfh = igc_set_rxfh, .set_rxfh = igc_ethtool_set_rxfh,
.get_ts_info = igc_get_ts_info, .get_ts_info = igc_ethtool_get_ts_info,
.get_channels = igc_get_channels, .get_channels = igc_ethtool_get_channels,
.set_channels = igc_set_channels, .set_channels = igc_ethtool_set_channels,
.get_priv_flags = igc_get_priv_flags, .get_priv_flags = igc_ethtool_get_priv_flags,
.set_priv_flags = igc_set_priv_flags, .set_priv_flags = igc_ethtool_set_priv_flags,
.begin = igc_ethtool_begin, .begin = igc_ethtool_begin,
.complete = igc_ethtool_complete, .complete = igc_ethtool_complete,
.get_link_ksettings = igc_get_link_ksettings, .get_link_ksettings = igc_ethtool_get_link_ksettings,
.set_link_ksettings = igc_set_link_ksettings, .set_link_ksettings = igc_ethtool_set_link_ksettings,
.self_test = igc_diag_test, .self_test = igc_ethtool_diag_test,
}; };
void igc_set_ethtool_ops(struct net_device *netdev) void igc_ethtool_set_ops(struct net_device *netdev)
{ {
netdev->ethtool_ops = &igc_ethtool_ops; netdev->ethtool_ops = &igc_ethtool_ops;
} }
...@@ -307,12 +307,8 @@ void igc_clear_hw_cntrs_base(struct igc_hw *hw) ...@@ -307,12 +307,8 @@ void igc_clear_hw_cntrs_base(struct igc_hw *hw)
rd32(IGC_ICTXQMTC); rd32(IGC_ICTXQMTC);
rd32(IGC_ICRXDMTC); rd32(IGC_ICRXDMTC);
rd32(IGC_CBTMPC);
rd32(IGC_HTDPMC);
rd32(IGC_CBRMPC);
rd32(IGC_RPTHC); rd32(IGC_RPTHC);
rd32(IGC_HGPTC); rd32(IGC_HGPTC);
rd32(IGC_HTCBDPC);
rd32(IGC_HGORCL); rd32(IGC_HGORCL);
rd32(IGC_HGORCH); rd32(IGC_HGORCH);
rd32(IGC_HGOTCL); rd32(IGC_HGOTCL);
......
...@@ -766,12 +766,14 @@ static void igc_setup_tctl(struct igc_adapter *adapter) ...@@ -766,12 +766,14 @@ static void igc_setup_tctl(struct igc_adapter *adapter)
* igc_set_mac_filter_hw() - Set MAC address filter in hardware * igc_set_mac_filter_hw() - Set MAC address filter in hardware
* @adapter: Pointer to adapter where the filter should be set * @adapter: Pointer to adapter where the filter should be set
* @index: Filter index * @index: Filter index
* @addr: Destination MAC address * @type: MAC address filter type (source or destination)
* @addr: MAC address
* @queue: If non-negative, queue assignment feature is enabled and frames * @queue: If non-negative, queue assignment feature is enabled and frames
* matching the filter are enqueued onto 'queue'. Otherwise, queue * matching the filter are enqueued onto 'queue'. Otherwise, queue
* assignment is disabled. * assignment is disabled.
*/ */
static void igc_set_mac_filter_hw(struct igc_adapter *adapter, int index, static void igc_set_mac_filter_hw(struct igc_adapter *adapter, int index,
enum igc_mac_filter_type type,
const u8 *addr, int queue) const u8 *addr, int queue)
{ {
struct net_device *dev = adapter->netdev; struct net_device *dev = adapter->netdev;
...@@ -784,6 +786,11 @@ static void igc_set_mac_filter_hw(struct igc_adapter *adapter, int index, ...@@ -784,6 +786,11 @@ static void igc_set_mac_filter_hw(struct igc_adapter *adapter, int index,
ral = le32_to_cpup((__le32 *)(addr)); ral = le32_to_cpup((__le32 *)(addr));
rah = le16_to_cpup((__le16 *)(addr + 4)); rah = le16_to_cpup((__le16 *)(addr + 4));
if (type == IGC_MAC_FILTER_TYPE_SRC) {
rah &= ~IGC_RAH_ASEL_MASK;
rah |= IGC_RAH_ASEL_SRC_ADDR;
}
if (queue >= 0) { if (queue >= 0) {
rah &= ~IGC_RAH_QSEL_MASK; rah &= ~IGC_RAH_QSEL_MASK;
rah |= (queue << IGC_RAH_QSEL_SHIFT); rah |= (queue << IGC_RAH_QSEL_SHIFT);
...@@ -820,17 +827,12 @@ static void igc_clear_mac_filter_hw(struct igc_adapter *adapter, int index) ...@@ -820,17 +827,12 @@ static void igc_clear_mac_filter_hw(struct igc_adapter *adapter, int index)
/* Set default MAC address for the PF in the first RAR entry */ /* Set default MAC address for the PF in the first RAR entry */
static void igc_set_default_mac_filter(struct igc_adapter *adapter) static void igc_set_default_mac_filter(struct igc_adapter *adapter)
{ {
struct igc_mac_addr *mac_table = &adapter->mac_table[0];
struct net_device *dev = adapter->netdev; struct net_device *dev = adapter->netdev;
u8 *addr = adapter->hw.mac.addr; u8 *addr = adapter->hw.mac.addr;
netdev_dbg(dev, "Set default MAC address filter: address %pM", addr); netdev_dbg(dev, "Set default MAC address filter: address %pM", addr);
ether_addr_copy(mac_table->addr, addr); igc_set_mac_filter_hw(adapter, 0, IGC_MAC_FILTER_TYPE_DST, addr, -1);
mac_table->state = IGC_MAC_STATE_DEFAULT | IGC_MAC_STATE_IN_USE;
mac_table->queue = -1;
igc_set_mac_filter_hw(adapter, 0, addr, mac_table->queue);
} }
/** /**
...@@ -2172,34 +2174,38 @@ static bool igc_clean_tx_irq(struct igc_q_vector *q_vector, int napi_budget) ...@@ -2172,34 +2174,38 @@ static bool igc_clean_tx_irq(struct igc_q_vector *q_vector, int napi_budget)
return !!budget; return !!budget;
} }
static void igc_nfc_filter_restore(struct igc_adapter *adapter) static void igc_restore_nfc_rules(struct igc_adapter *adapter)
{ {
struct igc_nfc_filter *rule; struct igc_nfc_rule *rule;
spin_lock(&adapter->nfc_lock); spin_lock(&adapter->nfc_rule_lock);
hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) hlist_for_each_entry(rule, &adapter->nfc_rule_list, nfc_node)
igc_add_filter(adapter, rule); igc_enable_nfc_rule(adapter, rule);
spin_unlock(&adapter->nfc_lock); spin_unlock(&adapter->nfc_rule_lock);
} }
static int igc_find_mac_filter(struct igc_adapter *adapter, const u8 *addr, static int igc_find_mac_filter(struct igc_adapter *adapter,
u8 flags) enum igc_mac_filter_type type, const u8 *addr)
{ {
int max_entries = adapter->hw.mac.rar_entry_count; struct igc_hw *hw = &adapter->hw;
struct igc_mac_addr *entry; int max_entries = hw->mac.rar_entry_count;
u32 ral, rah;
int i; int i;
for (i = 0; i < max_entries; i++) { for (i = 0; i < max_entries; i++) {
entry = &adapter->mac_table[i]; ral = rd32(IGC_RAL(i));
rah = rd32(IGC_RAH(i));
if (!(entry->state & IGC_MAC_STATE_IN_USE)) if (!(rah & IGC_RAH_AV))
continue; continue;
if (!ether_addr_equal(addr, entry->addr)) if (!!(rah & IGC_RAH_ASEL_SRC_ADDR) != type)
continue; continue;
if ((entry->state & IGC_MAC_STATE_SRC_ADDR) != if ((rah & IGC_RAH_RAH_MASK) !=
(flags & IGC_MAC_STATE_SRC_ADDR)) le16_to_cpup((__le16 *)(addr + 4)))
continue;
if (ral != le32_to_cpup((__le32 *)(addr)))
continue; continue;
return i; return i;
...@@ -2210,14 +2216,15 @@ static int igc_find_mac_filter(struct igc_adapter *adapter, const u8 *addr, ...@@ -2210,14 +2216,15 @@ static int igc_find_mac_filter(struct igc_adapter *adapter, const u8 *addr,
static int igc_get_avail_mac_filter_slot(struct igc_adapter *adapter) static int igc_get_avail_mac_filter_slot(struct igc_adapter *adapter)
{ {
int max_entries = adapter->hw.mac.rar_entry_count; struct igc_hw *hw = &adapter->hw;
struct igc_mac_addr *entry; int max_entries = hw->mac.rar_entry_count;
u32 rah;
int i; int i;
for (i = 0; i < max_entries; i++) { for (i = 0; i < max_entries; i++) {
entry = &adapter->mac_table[i]; rah = rd32(IGC_RAH(i));
if (!(entry->state & IGC_MAC_STATE_IN_USE)) if (!(rah & IGC_RAH_AV))
return i; return i;
} }
...@@ -2227,87 +2234,76 @@ static int igc_get_avail_mac_filter_slot(struct igc_adapter *adapter) ...@@ -2227,87 +2234,76 @@ static int igc_get_avail_mac_filter_slot(struct igc_adapter *adapter)
/** /**
* igc_add_mac_filter() - Add MAC address filter * igc_add_mac_filter() - Add MAC address filter
* @adapter: Pointer to adapter where the filter should be added * @adapter: Pointer to adapter where the filter should be added
* @type: MAC address filter type (source or destination)
* @addr: MAC address * @addr: MAC address
* @queue: If non-negative, queue assignment feature is enabled and frames * @queue: If non-negative, queue assignment feature is enabled and frames
* matching the filter are enqueued onto 'queue'. Otherwise, queue * matching the filter are enqueued onto 'queue'. Otherwise, queue
* assignment is disabled. * assignment is disabled.
* @flags: Set IGC_MAC_STATE_SRC_ADDR bit to indicate @address is a source
* address
* *
* Return: 0 in case of success, negative errno code otherwise. * Return: 0 in case of success, negative errno code otherwise.
*/ */
int igc_add_mac_filter(struct igc_adapter *adapter, const u8 *addr, int igc_add_mac_filter(struct igc_adapter *adapter,
const s8 queue, const u8 flags) enum igc_mac_filter_type type, const u8 *addr,
int queue)
{ {
struct net_device *dev = adapter->netdev; struct net_device *dev = adapter->netdev;
int index; int index;
if (!is_valid_ether_addr(addr)) if (!is_valid_ether_addr(addr))
return -EINVAL; return -EINVAL;
if (flags & IGC_MAC_STATE_SRC_ADDR)
return -ENOTSUPP;
index = igc_find_mac_filter(adapter, addr, flags); index = igc_find_mac_filter(adapter, type, addr);
if (index >= 0) if (index >= 0)
goto update_queue_assignment; goto update_filter;
index = igc_get_avail_mac_filter_slot(adapter); index = igc_get_avail_mac_filter_slot(adapter);
if (index < 0) if (index < 0)
return -ENOSPC; return -ENOSPC;
netdev_dbg(dev, "Add MAC address filter: index %d address %pM queue %d", netdev_dbg(dev, "Add MAC address filter: index %d type %s address %pM queue %d\n",
index, addr, queue); index, type == IGC_MAC_FILTER_TYPE_DST ? "dst" : "src",
addr, queue);
ether_addr_copy(adapter->mac_table[index].addr, addr); update_filter:
adapter->mac_table[index].state |= IGC_MAC_STATE_IN_USE | flags; igc_set_mac_filter_hw(adapter, index, type, addr, queue);
update_queue_assignment:
adapter->mac_table[index].queue = queue;
igc_set_mac_filter_hw(adapter, index, addr, queue);
return 0; return 0;
} }
/** /**
* igc_del_mac_filter() - Delete MAC address filter * igc_del_mac_filter() - Delete MAC address filter
* @adapter: Pointer to adapter where the filter should be deleted from * @adapter: Pointer to adapter where the filter should be deleted from
* @type: MAC address filter type (source or destination)
* @addr: MAC address * @addr: MAC address
* @flags: Set IGC_MAC_STATE_SRC_ADDR bit to indicate @address is a source
* address
* *
* Return: 0 in case of success, negative errno code otherwise. * Return: 0 in case of success, negative errno code otherwise.
*/ */
int igc_del_mac_filter(struct igc_adapter *adapter, const u8 *addr, int igc_del_mac_filter(struct igc_adapter *adapter,
const u8 flags) enum igc_mac_filter_type type, const u8 *addr)
{ {
struct net_device *dev = adapter->netdev; struct net_device *dev = adapter->netdev;
struct igc_mac_addr *entry;
int index; int index;
if (!is_valid_ether_addr(addr)) if (!is_valid_ether_addr(addr))
return -EINVAL; return -EINVAL;
index = igc_find_mac_filter(adapter, addr, flags); index = igc_find_mac_filter(adapter, type, addr);
if (index < 0) if (index < 0)
return -ENOENT; return -ENOENT;
entry = &adapter->mac_table[index]; if (index == 0) {
if (entry->state & IGC_MAC_STATE_DEFAULT) {
/* If this is the default filter, we don't actually delete it. /* If this is the default filter, we don't actually delete it.
* We just reset to its default value i.e. disable queue * We just reset to its default value i.e. disable queue
* assignment. * assignment.
*/ */
netdev_dbg(dev, "Disable default MAC filter queue assignment"); netdev_dbg(dev, "Disable default MAC filter queue assignment");
entry->queue = -1; igc_set_mac_filter_hw(adapter, 0, type, addr, -1);
igc_set_mac_filter_hw(adapter, 0, addr, entry->queue);
} else { } else {
netdev_dbg(dev, "Delete MAC address filter: index %d address %pM", netdev_dbg(dev, "Delete MAC address filter: index %d type %s address %pM\n",
index, addr); index,
type == IGC_MAC_FILTER_TYPE_DST ? "dst" : "src",
addr);
entry->state = 0;
entry->queue = -1;
memset(entry->addr, 0, ETH_ALEN);
igc_clear_mac_filter_hw(adapter, index); igc_clear_mac_filter_hw(adapter, index);
} }
...@@ -2463,14 +2459,14 @@ static int igc_uc_sync(struct net_device *netdev, const unsigned char *addr) ...@@ -2463,14 +2459,14 @@ static int igc_uc_sync(struct net_device *netdev, const unsigned char *addr)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
return igc_add_mac_filter(adapter, addr, -1, 0); return igc_add_mac_filter(adapter, IGC_MAC_FILTER_TYPE_DST, addr, -1);
} }
static int igc_uc_unsync(struct net_device *netdev, const unsigned char *addr) static int igc_uc_unsync(struct net_device *netdev, const unsigned char *addr)
{ {
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
return igc_del_mac_filter(adapter, addr, 0); return igc_del_mac_filter(adapter, IGC_MAC_FILTER_TYPE_DST, addr);
} }
/** /**
...@@ -2541,7 +2537,7 @@ static void igc_configure(struct igc_adapter *adapter) ...@@ -2541,7 +2537,7 @@ static void igc_configure(struct igc_adapter *adapter)
igc_setup_rctl(adapter); igc_setup_rctl(adapter);
igc_set_default_mac_filter(adapter); igc_set_default_mac_filter(adapter);
igc_nfc_filter_restore(adapter); igc_restore_nfc_rules(adapter);
igc_configure_tx(adapter); igc_configure_tx(adapter);
igc_configure_rx(adapter); igc_configure_rx(adapter);
...@@ -2735,12 +2731,7 @@ void igc_set_flag_queue_pairs(struct igc_adapter *adapter, ...@@ -2735,12 +2731,7 @@ void igc_set_flag_queue_pairs(struct igc_adapter *adapter,
unsigned int igc_get_max_rss_queues(struct igc_adapter *adapter) unsigned int igc_get_max_rss_queues(struct igc_adapter *adapter)
{ {
unsigned int max_rss_queues; return IGC_MAX_RX_QUEUES;
/* Determine the maximum number of RSS queues supported. */
max_rss_queues = IGC_MAX_RX_QUEUES;
return max_rss_queues;
} }
static void igc_init_queue_configuration(struct igc_adapter *adapter) static void igc_init_queue_configuration(struct igc_adapter *adapter)
...@@ -3415,8 +3406,6 @@ static int igc_sw_init(struct igc_adapter *adapter) ...@@ -3415,8 +3406,6 @@ static int igc_sw_init(struct igc_adapter *adapter)
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
struct igc_hw *hw = &adapter->hw; struct igc_hw *hw = &adapter->hw;
int size = sizeof(struct igc_mac_addr) * hw->mac.rar_entry_count;
pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word); pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word);
/* set default ring sizes */ /* set default ring sizes */
...@@ -3435,15 +3424,11 @@ static int igc_sw_init(struct igc_adapter *adapter) ...@@ -3435,15 +3424,11 @@ static int igc_sw_init(struct igc_adapter *adapter)
VLAN_HLEN; VLAN_HLEN;
adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
spin_lock_init(&adapter->nfc_lock); spin_lock_init(&adapter->nfc_rule_lock);
spin_lock_init(&adapter->stats64_lock); spin_lock_init(&adapter->stats64_lock);
/* Assume MSI-X interrupts, will be checked during IRQ allocation */ /* Assume MSI-X interrupts, will be checked during IRQ allocation */
adapter->flags |= IGC_FLAG_HAS_MSIX; adapter->flags |= IGC_FLAG_HAS_MSIX;
adapter->mac_table = kzalloc(size, GFP_ATOMIC);
if (!adapter->mac_table)
return -ENOMEM;
igc_init_queue_configuration(adapter); igc_init_queue_configuration(adapter);
/* This call may decrease the number of queues */ /* This call may decrease the number of queues */
...@@ -3666,16 +3651,16 @@ void igc_update_stats(struct igc_adapter *adapter) ...@@ -3666,16 +3651,16 @@ void igc_update_stats(struct igc_adapter *adapter)
adapter->stats.mgpdc += rd32(IGC_MGTPDC); adapter->stats.mgpdc += rd32(IGC_MGTPDC);
} }
static void igc_nfc_filter_exit(struct igc_adapter *adapter) static void igc_nfc_rule_exit(struct igc_adapter *adapter)
{ {
struct igc_nfc_filter *rule; struct igc_nfc_rule *rule;
spin_lock(&adapter->nfc_lock); spin_lock(&adapter->nfc_rule_lock);
hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node) hlist_for_each_entry(rule, &adapter->nfc_rule_list, nfc_node)
igc_erase_filter(adapter, rule); igc_disable_nfc_rule(adapter, rule);
spin_unlock(&adapter->nfc_lock); spin_unlock(&adapter->nfc_rule_lock);
} }
/** /**
...@@ -3696,7 +3681,7 @@ void igc_down(struct igc_adapter *adapter) ...@@ -3696,7 +3681,7 @@ void igc_down(struct igc_adapter *adapter)
wr32(IGC_RCTL, rctl & ~IGC_RCTL_EN); wr32(IGC_RCTL, rctl & ~IGC_RCTL_EN);
/* flush and sleep below */ /* flush and sleep below */
igc_nfc_filter_exit(adapter); igc_nfc_rule_exit(adapter);
/* set trans_start so we don't get spurious watchdogs during reset */ /* set trans_start so we don't get spurious watchdogs during reset */
netif_trans_update(netdev); netif_trans_update(netdev);
...@@ -3848,17 +3833,17 @@ static int igc_set_features(struct net_device *netdev, ...@@ -3848,17 +3833,17 @@ static int igc_set_features(struct net_device *netdev,
if (!(features & NETIF_F_NTUPLE)) { if (!(features & NETIF_F_NTUPLE)) {
struct hlist_node *node2; struct hlist_node *node2;
struct igc_nfc_filter *rule; struct igc_nfc_rule *rule;
spin_lock(&adapter->nfc_lock); spin_lock(&adapter->nfc_rule_lock);
hlist_for_each_entry_safe(rule, node2, hlist_for_each_entry_safe(rule, node2,
&adapter->nfc_filter_list, nfc_node) { &adapter->nfc_rule_list, nfc_node) {
igc_erase_filter(adapter, rule); igc_disable_nfc_rule(adapter, rule);
hlist_del(&rule->nfc_node); hlist_del(&rule->nfc_node);
kfree(rule); kfree(rule);
} }
spin_unlock(&adapter->nfc_lock); spin_unlock(&adapter->nfc_rule_lock);
adapter->nfc_filter_count = 0; adapter->nfc_rule_count = 0;
} }
netdev->features = features; netdev->features = features;
...@@ -4947,7 +4932,7 @@ static int igc_probe(struct pci_dev *pdev, ...@@ -4947,7 +4932,7 @@ static int igc_probe(struct pci_dev *pdev,
hw->hw_addr = adapter->io_addr; hw->hw_addr = adapter->io_addr;
netdev->netdev_ops = &igc_netdev_ops; netdev->netdev_ops = &igc_netdev_ops;
igc_set_ethtool_ops(netdev); igc_ethtool_set_ops(netdev);
netdev->watchdog_timeo = 5 * HZ; netdev->watchdog_timeo = 5 * HZ;
netdev->mem_start = pci_resource_start(pdev, 0); netdev->mem_start = pci_resource_start(pdev, 0);
...@@ -5146,7 +5131,6 @@ static void igc_remove(struct pci_dev *pdev) ...@@ -5146,7 +5131,6 @@ static void igc_remove(struct pci_dev *pdev)
pci_iounmap(pdev, adapter->io_addr); pci_iounmap(pdev, adapter->io_addr);
pci_release_mem_regions(pdev); pci_release_mem_regions(pdev);
kfree(adapter->mac_table);
free_netdev(netdev); free_netdev(netdev);
pci_disable_pcie_error_reporting(pdev); pci_disable_pcie_error_reporting(pdev);
......
...@@ -68,13 +68,6 @@ ...@@ -68,13 +68,6 @@
#define IGC_ICRXDMTC 0x04120 /* Rx Descriptor Min Threshold Count */ #define IGC_ICRXDMTC 0x04120 /* Rx Descriptor Min Threshold Count */
#define IGC_ICRXOC 0x04124 /* Receiver Overrun Count */ #define IGC_ICRXOC 0x04124 /* Receiver Overrun Count */
#define IGC_CBTMPC 0x0402C /* Circuit Breaker TX Packet Count */
#define IGC_HTDPMC 0x0403C /* Host Transmit Discarded Packets */
#define IGC_CBRMPC 0x040FC /* Circuit Breaker RX Packet Count */
#define IGC_RPTHC 0x04104 /* Rx Packets To Host */
#define IGC_HGPTC 0x04118 /* Host Good Packets TX Count */
#define IGC_HTCBDPC 0x04124 /* Host TX Circ.Breaker Drop Count */
/* MSI-X Table Register Descriptions */ /* MSI-X Table Register Descriptions */
#define IGC_PBACL 0x05B68 /* MSIx PBA Clear - R/W 1 to clear */ #define IGC_PBACL 0x05B68 /* MSIx PBA Clear - R/W 1 to clear */
...@@ -131,9 +124,6 @@ ...@@ -131,9 +124,6 @@
#define IGC_MMDAC 13 /* MMD Access Control */ #define IGC_MMDAC 13 /* MMD Access Control */
#define IGC_MMDAAD 14 /* MMD Access Address/Data */ #define IGC_MMDAAD 14 /* MMD Access Address/Data */
/* Good transmitted packets counter registers */
#define IGC_PQGPTC(_n) (0x010014 + (0x100 * (_n)))
/* Statistics Register Descriptions */ /* Statistics Register Descriptions */
#define IGC_CRCERRS 0x04000 /* CRC Error Count - R/clr */ #define IGC_CRCERRS 0x04000 /* CRC Error Count - R/clr */
#define IGC_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */ #define IGC_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
...@@ -206,7 +196,6 @@ ...@@ -206,7 +196,6 @@
#define IGC_HGOTCL 0x04130 /* Host Good Octets Transmit Count Low */ #define IGC_HGOTCL 0x04130 /* Host Good Octets Transmit Count Low */
#define IGC_HGOTCH 0x04134 /* Host Good Octets Transmit Count High */ #define IGC_HGOTCH 0x04134 /* Host Good Octets Transmit Count High */
#define IGC_LENERRS 0x04138 /* Length Errors Count */ #define IGC_LENERRS 0x04138 /* Length Errors Count */
#define IGC_HRMPC 0x0A018 /* Header Redirection Missed Packet Count */
/* Time sync registers */ /* Time sync registers */
#define IGC_TSICR 0x0B66C /* Time Sync Interrupt Cause */ #define IGC_TSICR 0x0B66C /* Time Sync Interrupt Cause */
......
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