]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
igc: Refactor VLAN priority filtering code
authorAndre Guedes <andre.guedes@intel.com>
Fri, 24 Apr 2020 01:11:19 +0000 (18:11 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Tue, 19 May 2020 22:29:17 +0000 (15:29 -0700)
The whole VLAN priority filtering code is implemented in igc_ethtool.c
and mixes logic from ethtool and core parts. This patch refactors it so
core logic is moved to igc_main.c, aligning the VLAN priority filtering
code organization with the MAC address filtering code.

This patch also takes the opportunity to add some log messages to ease
debugging.

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>
drivers/net/ethernet/intel/igc/igc.h
drivers/net/ethernet/intel/igc/igc_ethtool.c
drivers/net/ethernet/intel/igc/igc_main.c

index 661dc8875f3f2575951d2b6fae6453143d2bb261..5f1e1d31e83248a81ee93fafdcc665f40056fc82 100644 (file)
@@ -235,6 +235,9 @@ int igc_add_mac_filter(struct igc_adapter *adapter, const u8 *addr,
                       const s8 queue, const u8 flags);
 int igc_del_mac_filter(struct igc_adapter *adapter, const u8 *addr,
                       const u8 flags);
+int igc_add_vlan_prio_filter(struct igc_adapter *adapter, int prio,
+                            int queue);
+void igc_del_vlan_prio_filter(struct igc_adapter *adapter, int prio);
 void igc_update_stats(struct igc_adapter *adapter);
 
 /* igc_dump declarations */
index f28f7feb39a55bf3a1d1dac2da02100b36f65f4f..c5be8b936963e4dc3488f5b5feeee0c45cba994f 100644 (file)
@@ -1223,35 +1223,6 @@ static int igc_rxnfc_write_etype_filter(struct igc_adapter *adapter,
        return 0;
 }
 
-static int igc_rxnfc_write_vlan_prio_filter(struct igc_adapter *adapter,
-                                           struct igc_nfc_filter *input)
-{
-       struct igc_hw *hw = &adapter->hw;
-       u8 vlan_priority;
-       u16 queue_index;
-       u32 vlapqf;
-
-       vlapqf = rd32(IGC_VLANPQF);
-       vlan_priority = (ntohs(input->filter.vlan_tci) & VLAN_PRIO_MASK)
-                               >> VLAN_PRIO_SHIFT;
-       queue_index = (vlapqf >> (vlan_priority * 4)) & IGC_VLANPQF_QUEUE_MASK;
-
-       /* check whether this VLAN prio is already set */
-       if (vlapqf & IGC_VLANPQF_VALID(vlan_priority) &&
-           queue_index != input->action) {
-               netdev_err(adapter->netdev,
-                          "ethtool rxnfc set VLAN prio filter failed\n");
-               return -EEXIST;
-       }
-
-       vlapqf |= IGC_VLANPQF_VALID(vlan_priority);
-       vlapqf |= IGC_VLANPQF_QSEL(vlan_priority, input->action);
-
-       wr32(IGC_VLANPQF, vlapqf);
-
-       return 0;
-}
-
 int igc_add_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input)
 {
        struct igc_hw *hw = &adapter->hw;
@@ -1285,10 +1256,15 @@ int igc_add_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input)
                        return err;
        }
 
-       if (input->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI)
-               err = igc_rxnfc_write_vlan_prio_filter(adapter, input);
+       if (input->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) {
+               int prio = (ntohs(input->filter.vlan_tci) & VLAN_PRIO_MASK) >>
+                          VLAN_PRIO_SHIFT;
+               err = igc_add_vlan_prio_filter(adapter, prio, input->action);
+               if (err)
+                       return err;
+       }
 
-       return err;
+       return 0;
 }
 
 static void igc_clear_etype_filter_regs(struct igc_adapter *adapter,
@@ -1306,31 +1282,17 @@ static void igc_clear_etype_filter_regs(struct igc_adapter *adapter,
        adapter->etype_bitmap[reg_index] = false;
 }
 
-static void igc_clear_vlan_prio_filter(struct igc_adapter *adapter,
-                                      u16 vlan_tci)
-{
-       struct igc_hw *hw = &adapter->hw;
-       u8 vlan_priority;
-       u32 vlapqf;
-
-       vlan_priority = (vlan_tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
-
-       vlapqf = rd32(IGC_VLANPQF);
-       vlapqf &= ~IGC_VLANPQF_VALID(vlan_priority);
-       vlapqf &= ~IGC_VLANPQF_QSEL(vlan_priority, IGC_VLANPQF_QUEUE_MASK);
-
-       wr32(IGC_VLANPQF, vlapqf);
-}
-
 int igc_erase_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input)
 {
        if (input->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE)
                igc_clear_etype_filter_regs(adapter,
                                            input->etype_reg_index);
 
-       if (input->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI)
-               igc_clear_vlan_prio_filter(adapter,
-                                          ntohs(input->filter.vlan_tci));
+       if (input->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) {
+               int prio = (ntohs(input->filter.vlan_tci) & VLAN_PRIO_MASK) >>
+                          VLAN_PRIO_SHIFT;
+               igc_del_vlan_prio_filter(adapter, prio);
+       }
 
        if (input->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR)
                igc_del_mac_filter(adapter, input->filter.src_addr,
index 125026d053eb32bfe0155c3ae683242f2e4e8a2c..7e59c0393dbcbec1f597c21a46e54b85e0734727 100644 (file)
@@ -2314,6 +2314,58 @@ int igc_del_mac_filter(struct igc_adapter *adapter, const u8 *addr,
        return 0;
 }
 
+/**
+ * igc_add_vlan_prio_filter() - Add VLAN priority filter
+ * @adapter: Pointer to adapter where the filter should be added
+ * @prio: VLAN priority value
+ * @queue: Queue number which matching frames are assigned to
+ *
+ * Return: 0 in case of success, negative errno code otherwise.
+ */
+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;
+       u32 vlanpqf;
+
+       vlanpqf = rd32(IGC_VLANPQF);
+
+       if (vlanpqf & IGC_VLANPQF_VALID(prio)) {
+               netdev_dbg(dev, "VLAN priority filter already in use\n");
+               return -EEXIST;
+       }
+
+       vlanpqf |= IGC_VLANPQF_QSEL(prio, queue);
+       vlanpqf |= IGC_VLANPQF_VALID(prio);
+
+       wr32(IGC_VLANPQF, vlanpqf);
+
+       netdev_dbg(dev, "Add VLAN priority filter: prio %d queue %d\n",
+                  prio, queue);
+       return 0;
+}
+
+/**
+ * igc_del_vlan_prio_filter() - Delete VLAN priority filter
+ * @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)
+{
+       struct igc_hw *hw = &adapter->hw;
+       u32 vlanpqf;
+
+       vlanpqf = rd32(IGC_VLANPQF);
+
+       vlanpqf &= ~IGC_VLANPQF_VALID(prio);
+       vlanpqf &= ~IGC_VLANPQF_QSEL(prio, IGC_VLANPQF_QUEUE_MASK);
+
+       wr32(IGC_VLANPQF, vlanpqf);
+
+       netdev_dbg(adapter->netdev, "Delete VLAN priority filter: prio %d\n",
+                  prio);
+}
+
 static int igc_uc_sync(struct net_device *netdev, const unsigned char *addr)
 {
        struct igc_adapter *adapter = netdev_priv(netdev);