summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/intel/igc/igc_main.c
diff options
context:
space:
mode:
authorAndre Guedes <andre.guedes@intel.com>2020-04-24 13:16:18 -0700
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2020-05-22 18:21:51 -0700
commit36fa21520f33317fe51bf80bc154873e922c2a26 (patch)
treea915ab8a3e54ffaa43fc04f5996da03670b68b1f /drivers/net/ethernet/intel/igc/igc_main.c
parentd957c6010a907d86d41d1bee024a9827e385c4fa (diff)
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_main.c')
-rw-r--r--drivers/net/ethernet/intel/igc/igc_main.c205
1 files changed, 172 insertions, 33 deletions
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index cf76e2c1f9b1..ad9217335a64 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -2174,18 +2174,6 @@ static bool igc_clean_tx_irq(struct igc_q_vector *q_vector, int napi_budget)
return !!budget;
}
-static void igc_restore_nfc_rules(struct igc_adapter *adapter)
-{
- struct igc_nfc_rule *rule;
-
- spin_lock(&adapter->nfc_rule_lock);
-
- list_for_each_entry_reverse(rule, &adapter->nfc_rule_list, list)
- igc_enable_nfc_rule(adapter, rule);
-
- spin_unlock(&adapter->nfc_rule_lock);
-}
-
static int igc_find_mac_filter(struct igc_adapter *adapter,
enum igc_mac_filter_type type, const u8 *addr)
{
@@ -2242,9 +2230,9 @@ static int igc_get_avail_mac_filter_slot(struct igc_adapter *adapter)
*
* Return: 0 in case of success, negative errno code otherwise.
*/
-int igc_add_mac_filter(struct igc_adapter *adapter,
- enum igc_mac_filter_type type, const u8 *addr,
- int queue)
+static int igc_add_mac_filter(struct igc_adapter *adapter,
+ enum igc_mac_filter_type type, const u8 *addr,
+ int queue)
{
struct net_device *dev = adapter->netdev;
int index;
@@ -2274,8 +2262,8 @@ update_filter:
*
* Return: 0 in case of success, negative errno code otherwise.
*/
-int igc_del_mac_filter(struct igc_adapter *adapter,
- enum igc_mac_filter_type type, const u8 *addr)
+static int igc_del_mac_filter(struct igc_adapter *adapter,
+ enum igc_mac_filter_type type, const u8 *addr)
{
struct net_device *dev = adapter->netdev;
int index;
@@ -2312,7 +2300,8 @@ int igc_del_mac_filter(struct igc_adapter *adapter,
*
* Return: 0 in case of success, negative errno code otherwise.
*/
-int igc_add_vlan_prio_filter(struct igc_adapter *adapter, int prio, int queue)
+static int igc_add_vlan_prio_filter(struct igc_adapter *adapter, int prio,
+ int queue)
{
struct net_device *dev = adapter->netdev;
struct igc_hw *hw = &adapter->hw;
@@ -2340,7 +2329,7 @@ int igc_add_vlan_prio_filter(struct igc_adapter *adapter, int prio, int queue)
* @adapter: Pointer to adapter where the filter should be deleted from
* @prio: VLAN priority value
*/
-void igc_del_vlan_prio_filter(struct igc_adapter *adapter, int prio)
+static void igc_del_vlan_prio_filter(struct igc_adapter *adapter, int prio)
{
struct igc_hw *hw = &adapter->hw;
u32 vlanpqf;
@@ -2381,7 +2370,8 @@ static int igc_get_avail_etype_filter_slot(struct igc_adapter *adapter)
*
* Return: 0 in case of success, negative errno code otherwise.
*/
-int igc_add_etype_filter(struct igc_adapter *adapter, u16 etype, int queue)
+static int igc_add_etype_filter(struct igc_adapter *adapter, u16 etype,
+ int queue)
{
struct igc_hw *hw = &adapter->hw;
int index;
@@ -2433,7 +2423,7 @@ static int igc_find_etype_filter(struct igc_adapter *adapter, u16 etype)
*
* Return: 0 in case of success, negative errno code otherwise.
*/
-int igc_del_etype_filter(struct igc_adapter *adapter, u16 etype)
+static int igc_del_etype_filter(struct igc_adapter *adapter, u16 etype)
{
struct igc_hw *hw = &adapter->hw;
int index;
@@ -2449,6 +2439,167 @@ int igc_del_etype_filter(struct igc_adapter *adapter, u16 etype)
return 0;
}
+static int igc_enable_nfc_rule(struct igc_adapter *adapter,
+ const struct igc_nfc_rule *rule)
+{
+ int err;
+
+ 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;
+}
+
+static 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;
+}
+
+/**
+ * igc_get_nfc_rule() - Get NFC rule
+ * @adapter: Pointer to adapter
+ * @location: Rule location
+ *
+ * Context: Expects adapter->nfc_rule_lock to be held by caller.
+ *
+ * Return: Pointer to NFC rule at @location. If not found, NULL.
+ */
+struct igc_nfc_rule *igc_get_nfc_rule(struct igc_adapter *adapter,
+ u32 location)
+{
+ struct igc_nfc_rule *rule;
+
+ list_for_each_entry(rule, &adapter->nfc_rule_list, list) {
+ if (rule->location == location)
+ return rule;
+ if (rule->location > location)
+ break;
+ }
+
+ return NULL;
+}
+
+/**
+ * igc_del_nfc_rule() - Delete NFC rule
+ * @adapter: Pointer to adapter
+ * @rule: Pointer to rule to be deleted
+ *
+ * Disable NFC rule in hardware and delete it from adapter.
+ *
+ * Context: Expects adapter->nfc_rule_lock to be held by caller.
+ */
+void igc_del_nfc_rule(struct igc_adapter *adapter, struct igc_nfc_rule *rule)
+{
+ igc_disable_nfc_rule(adapter, rule);
+
+ list_del(&rule->list);
+ adapter->nfc_rule_count--;
+
+ kfree(rule);
+}
+
+/**
+ * igc_add_nfc_rule() - Add NFC rule
+ * @adapter: Pointer to adapter
+ * @rule: Pointer to rule to be added
+ *
+ * Enable NFC rule in hardware and add it to adapter.
+ *
+ * Context: Expects adapter->nfc_rule_lock to be held by caller.
+ *
+ * Return: 0 on success, negative errno on failure.
+ */
+int igc_add_nfc_rule(struct igc_adapter *adapter, struct igc_nfc_rule *rule)
+{
+ struct igc_nfc_rule *pred, *cur;
+ int err;
+
+ err = igc_enable_nfc_rule(adapter, rule);
+ if (err)
+ return err;
+
+ pred = NULL;
+ list_for_each_entry(cur, &adapter->nfc_rule_list, list) {
+ if (cur->location >= rule->location)
+ break;
+ pred = cur;
+ }
+
+ list_add(&rule->list, pred ? &pred->list : &adapter->nfc_rule_list);
+ adapter->nfc_rule_count++;
+ return 0;
+}
+
+static void igc_restore_nfc_rules(struct igc_adapter *adapter)
+{
+ struct igc_nfc_rule *rule;
+
+ spin_lock(&adapter->nfc_rule_lock);
+
+ list_for_each_entry_reverse(rule, &adapter->nfc_rule_list, list)
+ igc_enable_nfc_rule(adapter, rule);
+
+ spin_unlock(&adapter->nfc_rule_lock);
+}
+
+static void igc_nfc_rule_exit(struct igc_adapter *adapter)
+{
+ struct igc_nfc_rule *rule;
+
+ spin_lock(&adapter->nfc_rule_lock);
+
+ list_for_each_entry(rule, &adapter->nfc_rule_list, list)
+ igc_disable_nfc_rule(adapter, rule);
+
+ spin_unlock(&adapter->nfc_rule_lock);
+}
+
static int igc_uc_sync(struct net_device *netdev, const unsigned char *addr)
{
struct igc_adapter *adapter = netdev_priv(netdev);
@@ -3648,18 +3799,6 @@ void igc_update_stats(struct igc_adapter *adapter)
adapter->stats.mgpdc += rd32(IGC_MGTPDC);
}
-static void igc_nfc_rule_exit(struct igc_adapter *adapter)
-{
- struct igc_nfc_rule *rule;
-
- spin_lock(&adapter->nfc_rule_lock);
-
- list_for_each_entry(rule, &adapter->nfc_rule_list, list)
- igc_disable_nfc_rule(adapter, rule);
-
- spin_unlock(&adapter->nfc_rule_lock);
-}
-
/**
* igc_down - Close the interface
* @adapter: board private structure