summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/intel/igc/igc_ethtool.c
diff options
context:
space:
mode:
authorAndre Guedes <andre.guedes@intel.com>2020-04-24 23:16:18 +0300
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2020-05-23 04:21:51 +0300
commit36fa21520f33317fe51bf80bc154873e922c2a26 (patch)
treea915ab8a3e54ffaa43fc04f5996da03670b68b1f /drivers/net/ethernet/intel/igc/igc_ethtool.c
parentd957c6010a907d86d41d1bee024a9827e385c4fa (diff)
downloadlinux-36fa21520f33317fe51bf80bc154873e922c2a26.tar.xz
igc: Refactor igc_ethtool_update_nfc_rule()
Current implementation of igc_ethtool_update_nfc_rule() is a bit convoluted since it handles too many things: rule lookup, deletion and addition. This patch breaks it into three functions so we simplify the code and improve code reuse. Code related to rule lookup is refactored out to a new function called igc_get_nfc_rule(). Code related to rule addition is refactored out to a new function called igc_add_nfc_rule(). This function enables the rule in hardware and adds it to the adapter's list. Code related to rule deletion is refactored out to a new function called igc_del_nfc_rule(). This function disables the rule in hardware, removes it from adapter's list, and deletes it. As a byproduct of this refactoring, igc_enable_nfc_rule() and igc_disable_nfc_rule() are moved to igc_main.c since they are not used in igc_ethtool.c anymore, and igc_restore_nfc_rules() and igc_nfc_rule_ exit() are moved around to avoid forward declaration. Also, since this patch already touches igc_ethtool_get_nfc_rule(), it takes the opportunity to remove the 'match_flags' check. Empty flags are not allowed to be added so no need to check that. 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/net/ethernet/intel/igc/igc_ethtool.c')
-rw-r--r--drivers/net/ethernet/intel/igc/igc_ethtool.c138
1 files changed, 19 insertions, 119 deletions
diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c
index a90493fee0d2..43dff09a8f86 100644
--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c
+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c
@@ -941,15 +941,8 @@ static int igc_ethtool_get_nfc_rule(struct igc_adapter *adapter,
spin_lock(&adapter->nfc_rule_lock);
- list_for_each_entry(rule, &adapter->nfc_rule_list, list) {
- if (fsp->location <= rule->location)
- break;
- }
-
- if (!rule || fsp->location != rule->location)
- goto out;
-
- if (!rule->filter.match_flags)
+ rule = igc_get_nfc_rule(adapter, fsp->location);
+ if (!rule)
goto out;
fsp->flow_type = ETHER_FLOW;
@@ -1190,108 +1183,6 @@ static int igc_ethtool_set_rss_hash_opt(struct igc_adapter *adapter,
return 0;
}
-int igc_enable_nfc_rule(struct igc_adapter *adapter,
- const struct igc_nfc_rule *rule)
-{
- int err = -EINVAL;
-
- if (rule->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) {
- err = igc_add_etype_filter(adapter, rule->filter.etype,
- rule->action);
- if (err)
- return err;
- }
-
- if (rule->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) {
- err = igc_add_mac_filter(adapter, IGC_MAC_FILTER_TYPE_SRC,
- rule->filter.src_addr, rule->action);
- if (err)
- return err;
- }
-
- if (rule->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) {
- err = igc_add_mac_filter(adapter, IGC_MAC_FILTER_TYPE_DST,
- rule->filter.dst_addr, rule->action);
- if (err)
- return err;
- }
-
- if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) {
- int prio = (rule->filter.vlan_tci & VLAN_PRIO_MASK) >>
- VLAN_PRIO_SHIFT;
-
- err = igc_add_vlan_prio_filter(adapter, prio, rule->action);
- if (err)
- return err;
- }
-
- return 0;
-}
-
-int igc_disable_nfc_rule(struct igc_adapter *adapter,
- const struct igc_nfc_rule *rule)
-{
- if (rule->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE)
- igc_del_etype_filter(adapter, rule->filter.etype);
-
- if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) {
- int prio = (rule->filter.vlan_tci & VLAN_PRIO_MASK) >>
- VLAN_PRIO_SHIFT;
- igc_del_vlan_prio_filter(adapter, prio);
- }
-
- if (rule->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR)
- igc_del_mac_filter(adapter, IGC_MAC_FILTER_TYPE_SRC,
- rule->filter.src_addr);
-
- if (rule->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR)
- igc_del_mac_filter(adapter, IGC_MAC_FILTER_TYPE_DST,
- rule->filter.dst_addr);
-
- return 0;
-}
-
-static int igc_ethtool_update_nfc_rule(struct igc_adapter *adapter,
- struct igc_nfc_rule *input,
- u32 location)
-{
- struct igc_nfc_rule *rule, *parent;
- int err = -EINVAL;
-
- parent = NULL;
- rule = NULL;
-
- list_for_each_entry(rule, &adapter->nfc_rule_list, list) {
- /* hash found, or no matching entry */
- if (rule->location >= location)
- break;
- parent = rule;
- }
-
- /* if there is an old rule occupying our place remove it */
- if (rule && rule->location == location) {
- err = igc_disable_nfc_rule(adapter, rule);
-
- list_del(&rule->list);
- kfree(rule);
- adapter->nfc_rule_count--;
- }
-
- /* If no input this was a delete, err should be 0 if a rule was
- * successfully found and removed from the list else -EINVAL
- */
- if (!input)
- return err;
-
- list_add(&input->list, parent ? &parent->list :
- &adapter->nfc_rule_list);
-
- /* update counts */
- adapter->nfc_rule_count++;
-
- return 0;
-}
-
static void igc_ethtool_init_nfc_rule(struct igc_nfc_rule *rule,
const struct ethtool_rx_flow_spec *fsp)
{
@@ -1376,7 +1267,7 @@ static int igc_ethtool_add_nfc_rule(struct igc_adapter *adapter,
struct net_device *netdev = adapter->netdev;
struct ethtool_rx_flow_spec *fsp =
(struct ethtool_rx_flow_spec *)&cmd->fs;
- struct igc_nfc_rule *rule;
+ struct igc_nfc_rule *rule, *old_rule;
int err;
if (!(netdev->hw_features & NETIF_F_NTUPLE)) {
@@ -1417,12 +1308,14 @@ static int igc_ethtool_add_nfc_rule(struct igc_adapter *adapter,
if (err)
goto err;
- err = igc_enable_nfc_rule(adapter, rule);
+ old_rule = igc_get_nfc_rule(adapter, fsp->location);
+ if (old_rule)
+ igc_del_nfc_rule(adapter, old_rule);
+
+ err = igc_add_nfc_rule(adapter, rule);
if (err)
goto err;
- igc_ethtool_update_nfc_rule(adapter, rule, rule->location);
-
spin_unlock(&adapter->nfc_rule_lock);
return 0;
@@ -1437,13 +1330,20 @@ static int igc_ethtool_del_nfc_rule(struct igc_adapter *adapter,
{
struct ethtool_rx_flow_spec *fsp =
(struct ethtool_rx_flow_spec *)&cmd->fs;
- int err;
+ struct igc_nfc_rule *rule;
spin_lock(&adapter->nfc_rule_lock);
- err = igc_ethtool_update_nfc_rule(adapter, NULL, fsp->location);
- spin_unlock(&adapter->nfc_rule_lock);
- return err;
+ rule = igc_get_nfc_rule(adapter, fsp->location);
+ if (!rule) {
+ spin_unlock(&adapter->nfc_rule_lock);
+ return -EINVAL;
+ }
+
+ igc_del_nfc_rule(adapter, rule);
+
+ spin_unlock(&adapter->nfc_rule_lock);
+ return 0;
}
static int igc_ethtool_set_rxnfc(struct net_device *dev,