All of lore.kernel.org
 help / color / mirror / Atom feed
* [Intel-wired-lan] [PATCH 0/4] igc: Enable NFC rules based on source MAC address
@ 2020-04-11  0:28 Andre Guedes
  2020-04-11  0:28 ` [Intel-wired-lan] [PATCH 1/4] igc: Remove IGC_MAC_STATE_SRC_ADDR flag Andre Guedes
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Andre Guedes @ 2020-04-11  0:28 UTC (permalink / raw)
  To: intel-wired-lan

Hi all,

This patch series adds extends the IGC driver to support for Network
Flow Classification (NFC) rules based on source MAC address.

Quick summary of this series: Patches 1 and 2 clean up and prepare
the code for the new feature, patch 3 adds the support for source
address filters in the core layer, and patch 4 enables NFC rules
based on source address on the ethtool layer.

Regards,

Andre

Andre Guedes (4):
  igc: Remove IGC_MAC_STATE_SRC_ADDR flag
  igc: Remove mac_table from igc_adapter
  igc: Add support for source address filters in core
  igc: Enable NFC rules based source MAC address

 drivers/net/ethernet/intel/igc/igc.h         |  26 ++---
 drivers/net/ethernet/intel/igc/igc_defines.h |   3 +
 drivers/net/ethernet/intel/igc/igc_ethtool.c |  41 +++----
 drivers/net/ethernet/intel/igc/igc_main.c    | 111 +++++++++----------
 4 files changed, 84 insertions(+), 97 deletions(-)

-- 
2.26.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Intel-wired-lan] [PATCH 1/4] igc: Remove IGC_MAC_STATE_SRC_ADDR flag
  2020-04-11  0:28 [Intel-wired-lan] [PATCH 0/4] igc: Enable NFC rules based on source MAC address Andre Guedes
@ 2020-04-11  0:28 ` Andre Guedes
  2020-04-23 21:12   ` Brown, Aaron F
  2020-04-11  0:28 ` [Intel-wired-lan] [PATCH 2/4] igc: Remove mac_table from igc_adapter Andre Guedes
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Andre Guedes @ 2020-04-11  0:28 UTC (permalink / raw)
  To: intel-wired-lan

MAC address filters based on source address are not currently supported
by the IGC driver. Despite of that, the driver have some dangling code
to handle it, inherited from IGB driver. This patch removes that code to
prepare for a follow up patch that adds proper source MAC address filter
support.

Signed-off-by: Andre Guedes <andre.guedes@intel.com>
---
 drivers/net/ethernet/intel/igc/igc.h         |  6 ++---
 drivers/net/ethernet/intel/igc/igc_ethtool.c | 16 ++----------
 drivers/net/ethernet/intel/igc/igc_main.c    | 27 ++++++--------------
 3 files changed, 12 insertions(+), 37 deletions(-)

diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
index 22dde0590a23..c4c4498ab48f 100644
--- a/drivers/net/ethernet/intel/igc/igc.h
+++ b/drivers/net/ethernet/intel/igc/igc.h
@@ -231,9 +231,8 @@ bool igc_has_link(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_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);
+		       const s8 queue);
+int igc_del_mac_filter(struct igc_adapter *adapter, const u8 *addr);
 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);
@@ -479,7 +478,6 @@ struct igc_mac_addr {
 
 #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
 
diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c
index 285310a99ddc..36e94142b248 100644
--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c
+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c
@@ -1208,15 +1208,7 @@ int igc_add_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input)
 
 	if (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) {
 		err = igc_add_mac_filter(adapter, input->filter.dst_addr,
-					 input->action, 0);
-		if (err)
-			return err;
-	}
-
-	if (input->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) {
-		err = igc_add_mac_filter(adapter, input->filter.src_addr,
-					 input->action,
-					 IGC_MAC_STATE_SRC_ADDR);
+					 input->action);
 		if (err)
 			return err;
 	}
@@ -1246,12 +1238,8 @@ int igc_erase_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input)
 		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,
-				   IGC_MAC_STATE_SRC_ADDR);
-
 	if (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR)
-		igc_del_mac_filter(adapter, input->filter.dst_addr, 0);
+		igc_del_mac_filter(adapter, input->filter.dst_addr);
 
 	return 0;
 }
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 9c2d487803b2..411af7eafe19 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -2185,8 +2185,7 @@ static void igc_nfc_filter_restore(struct igc_adapter *adapter)
 	spin_unlock(&adapter->nfc_lock);
 }
 
-static int igc_find_mac_filter(struct igc_adapter *adapter, const u8 *addr,
-			       u8 flags)
+static int igc_find_mac_filter(struct igc_adapter *adapter, const u8 *addr)
 {
 	int max_entries = adapter->hw.mac.rar_entry_count;
 	struct igc_mac_addr *entry;
@@ -2199,9 +2198,6 @@ static int igc_find_mac_filter(struct igc_adapter *adapter, const u8 *addr,
 			continue;
 		if (!ether_addr_equal(addr, entry->addr))
 			continue;
-		if ((entry->state & IGC_MAC_STATE_SRC_ADDR) !=
-		    (flags & IGC_MAC_STATE_SRC_ADDR))
-			continue;
 
 		return i;
 	}
@@ -2232,23 +2228,19 @@ static int igc_get_avail_mac_filter_slot(struct igc_adapter *adapter)
  * @queue: If non-negative, queue assignment feature is enabled and frames
  *         matching the filter are enqueued onto 'queue'. Otherwise, queue
  *         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.
  */
 int igc_add_mac_filter(struct igc_adapter *adapter, const u8 *addr,
-		       const s8 queue, const u8 flags)
+		       const s8 queue)
 {
 	struct net_device *dev = adapter->netdev;
 	int index;
 
 	if (!is_valid_ether_addr(addr))
 		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, addr);
 	if (index >= 0)
 		goto update_queue_assignment;
 
@@ -2260,7 +2252,7 @@ int igc_add_mac_filter(struct igc_adapter *adapter, const u8 *addr,
 		   index, addr, queue);
 
 	ether_addr_copy(adapter->mac_table[index].addr, addr);
-	adapter->mac_table[index].state |= IGC_MAC_STATE_IN_USE | flags;
+	adapter->mac_table[index].state |= IGC_MAC_STATE_IN_USE;
 update_queue_assignment:
 	adapter->mac_table[index].queue = queue;
 
@@ -2272,13 +2264,10 @@ int igc_add_mac_filter(struct igc_adapter *adapter, const u8 *addr,
  * igc_del_mac_filter() - Delete MAC address filter.
  * @adapter: Pointer to adapter where the filter should be deleted from.
  * @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.
  */
-int igc_del_mac_filter(struct igc_adapter *adapter, const u8 *addr,
-		       const u8 flags)
+int igc_del_mac_filter(struct igc_adapter *adapter, const u8 *addr)
 {
 	struct net_device *dev = adapter->netdev;
 	struct igc_mac_addr *entry;
@@ -2287,7 +2276,7 @@ int igc_del_mac_filter(struct igc_adapter *adapter, const u8 *addr,
 	if (!is_valid_ether_addr(addr))
 		return -EINVAL;
 
-	index = igc_find_mac_filter(adapter, addr, flags);
+	index = igc_find_mac_filter(adapter, addr);
 	if (index < 0)
 		return -ENOENT;
 
@@ -2464,14 +2453,14 @@ static int igc_uc_sync(struct net_device *netdev, const unsigned char *addr)
 {
 	struct igc_adapter *adapter = netdev_priv(netdev);
 
-	return igc_add_mac_filter(adapter, addr, -1, 0);
+	return igc_add_mac_filter(adapter, addr, -1);
 }
 
 static int igc_uc_unsync(struct net_device *netdev, const unsigned char *addr)
 {
 	struct igc_adapter *adapter = netdev_priv(netdev);
 
-	return igc_del_mac_filter(adapter, addr, 0);
+	return igc_del_mac_filter(adapter, addr);
 }
 
 /**
-- 
2.26.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Intel-wired-lan] [PATCH 2/4] igc: Remove mac_table from igc_adapter
  2020-04-11  0:28 [Intel-wired-lan] [PATCH 0/4] igc: Enable NFC rules based on source MAC address Andre Guedes
  2020-04-11  0:28 ` [Intel-wired-lan] [PATCH 1/4] igc: Remove IGC_MAC_STATE_SRC_ADDR flag Andre Guedes
@ 2020-04-11  0:28 ` Andre Guedes
  2020-04-12  7:18   ` Neftin, Sasha
  2020-04-23 21:17   ` Brown, Aaron F
  2020-04-11  0:28 ` [Intel-wired-lan] [PATCH 3/4] igc: Add support for source address filters in core Andre Guedes
  2020-04-11  0:28 ` [Intel-wired-lan] [PATCH 4/4] igc: Enable NFC rules based source MAC address Andre Guedes
  3 siblings, 2 replies; 12+ messages in thread
From: Andre Guedes @ 2020-04-11  0:28 UTC (permalink / raw)
  To: intel-wired-lan

In igc_adapter we keep a sort of shadow copy of RAL and RAH registers.
There is not much benefit in keeping it, at the cost of maintainability,
since adding/removing MAC address filters is not hot path, and we
already keep filters information in adapter->nfc_filter_list for cleanup
and restoration purposes.

So in order to simplify the MAC address filtering code and prepare it
for source address support, this patch removes the mac_table from
igc_adapter.

Signed-off-by: Andre Guedes <andre.guedes@intel.com>
---
 drivers/net/ethernet/intel/igc/igc.h         | 11 ----
 drivers/net/ethernet/intel/igc/igc_defines.h |  1 +
 drivers/net/ethernet/intel/igc/igc_main.c    | 57 +++++++-------------
 3 files changed, 21 insertions(+), 48 deletions(-)

diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
index c4c4498ab48f..654481cea1f2 100644
--- a/drivers/net/ethernet/intel/igc/igc.h
+++ b/drivers/net/ethernet/intel/igc/igc.h
@@ -190,8 +190,6 @@ struct igc_adapter {
 	/* lock for RX network flow classification filter */
 	spinlock_t nfc_lock;
 
-	struct igc_mac_addr *mac_table;
-
 	u8 rss_indir_tbl[IGC_RETA_SIZE];
 
 	unsigned long link_check_timeout;
@@ -470,15 +468,6 @@ struct igc_nfc_filter {
 	u16 action;
 };
 
-struct igc_mac_addr {
-	u8 addr[ETH_ALEN];
-	s8 queue;
-	u8 state; /* bitmask */
-};
-
-#define IGC_MAC_STATE_DEFAULT		0x1
-#define IGC_MAC_STATE_IN_USE		0x2
-
 #define IGC_MAX_RXNFC_FILTERS		16
 
 /* igc_desc_unused - calculate if we have unused descriptors */
diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h
index 1127ef81e374..e190a7f83c3c 100644
--- a/drivers/net/ethernet/intel/igc/igc_defines.h
+++ b/drivers/net/ethernet/intel/igc/igc_defines.h
@@ -62,6 +62,7 @@
  * (RAR[15]) for our directed address used by controllers with
  * manageability enabled, allowing us room for 15 multicast addresses.
  */
+#define IGC_RAH_RAH_MASK	0x0000FFFF
 #define IGC_RAH_QSEL_MASK	0x000C0000
 #define IGC_RAH_QSEL_SHIFT	18
 #define IGC_RAH_QSEL_ENABLE	BIT(28)
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 411af7eafe19..1779d20299d0 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -820,17 +820,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 */
 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;
 	u8 *addr = adapter->hw.mac.addr;
 
 	netdev_dbg(dev, "Set default MAC address filter: address %pM", addr);
 
-	ether_addr_copy(mac_table->addr, addr);
-	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);
+	igc_set_mac_filter_hw(adapter, 0, addr, -1);
 }
 
 /**
@@ -2187,16 +2182,21 @@ static void igc_nfc_filter_restore(struct igc_adapter *adapter)
 
 static int igc_find_mac_filter(struct igc_adapter *adapter, const u8 *addr)
 {
-	int max_entries = adapter->hw.mac.rar_entry_count;
-	struct igc_mac_addr *entry;
+	struct igc_hw *hw = &adapter->hw;
+	int max_entries = hw->mac.rar_entry_count;
+	u32 ral, rah;
 	int 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;
-		if (!ether_addr_equal(addr, entry->addr))
+		if ((rah & IGC_RAH_RAH_MASK) !=
+		    le16_to_cpup((__le16 *)(addr + 4)))
+			continue;
+		if (ral != le32_to_cpup((__le32 *)(addr)))
 			continue;
 
 		return i;
@@ -2207,14 +2207,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)
 {
-	int max_entries = adapter->hw.mac.rar_entry_count;
-	struct igc_mac_addr *entry;
+	struct igc_hw *hw = &adapter->hw;
+	int max_entries = hw->mac.rar_entry_count;
+	u32 rah;
 	int 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;
 	}
 
@@ -2242,7 +2243,7 @@ int igc_add_mac_filter(struct igc_adapter *adapter, const u8 *addr,
 
 	index = igc_find_mac_filter(adapter, addr);
 	if (index >= 0)
-		goto update_queue_assignment;
+		goto update_filter;
 
 	index = igc_get_avail_mac_filter_slot(adapter);
 	if (index < 0)
@@ -2251,11 +2252,7 @@ int igc_add_mac_filter(struct igc_adapter *adapter, const u8 *addr,
 	netdev_dbg(dev, "Add MAC address filter: index %d address %pM queue %d",
 		   index, addr, queue);
 
-	ether_addr_copy(adapter->mac_table[index].addr, addr);
-	adapter->mac_table[index].state |= IGC_MAC_STATE_IN_USE;
-update_queue_assignment:
-	adapter->mac_table[index].queue = queue;
-
+update_filter:
 	igc_set_mac_filter_hw(adapter, index, addr, queue);
 	return 0;
 }
@@ -2270,7 +2267,6 @@ int igc_add_mac_filter(struct igc_adapter *adapter, const u8 *addr,
 int igc_del_mac_filter(struct igc_adapter *adapter, const u8 *addr)
 {
 	struct net_device *dev = adapter->netdev;
-	struct igc_mac_addr *entry;
 	int index;
 
 	if (!is_valid_ether_addr(addr))
@@ -2280,24 +2276,18 @@ int igc_del_mac_filter(struct igc_adapter *adapter, const u8 *addr)
 	if (index < 0)
 		return -ENOENT;
 
-	entry = &adapter->mac_table[index];
-
-	if (entry->state & IGC_MAC_STATE_DEFAULT) {
+	if (index == 0) {
 		/* If this is the default filter, we don't actually delete it.
 		 * We just reset to its default value i.e. disable queue
 		 * assignment.
 		 */
 		netdev_dbg(dev, "Disable default MAC filter queue assignment");
 
-		entry->queue = -1;
-		igc_set_mac_filter_hw(adapter, 0, addr, entry->queue);
+		igc_set_mac_filter_hw(adapter, 0, addr, -1);
 	} else {
 		netdev_dbg(dev, "Delete MAC address filter: index %d address %pM",
 			   index, addr);
 
-		entry->state = 0;
-		entry->queue = -1;
-		memset(entry->addr, 0, ETH_ALEN);
 		igc_clear_mac_filter_hw(adapter, index);
 	}
 
@@ -3405,8 +3395,6 @@ static int igc_sw_init(struct igc_adapter *adapter)
 	struct pci_dev *pdev = adapter->pdev;
 	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);
 
 	/* set default ring sizes */
@@ -3430,10 +3418,6 @@ static int igc_sw_init(struct igc_adapter *adapter)
 	/* Assume MSI-X interrupts, will be checked during IRQ allocation */
 	adapter->flags |= IGC_FLAG_HAS_MSIX;
 
-	adapter->mac_table = kzalloc(size, GFP_ATOMIC);
-	if (!adapter->mac_table)
-		return -ENOMEM;
-
 	igc_init_queue_configuration(adapter);
 
 	/* This call may decrease the number of queues */
@@ -5139,7 +5123,6 @@ static void igc_remove(struct pci_dev *pdev)
 	pci_iounmap(pdev, adapter->io_addr);
 	pci_release_mem_regions(pdev);
 
-	kfree(adapter->mac_table);
 	free_netdev(netdev);
 
 	pci_disable_pcie_error_reporting(pdev);
-- 
2.26.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Intel-wired-lan] [PATCH 3/4] igc: Add support for source address filters in core
  2020-04-11  0:28 [Intel-wired-lan] [PATCH 0/4] igc: Enable NFC rules based on source MAC address Andre Guedes
  2020-04-11  0:28 ` [Intel-wired-lan] [PATCH 1/4] igc: Remove IGC_MAC_STATE_SRC_ADDR flag Andre Guedes
  2020-04-11  0:28 ` [Intel-wired-lan] [PATCH 2/4] igc: Remove mac_table from igc_adapter Andre Guedes
@ 2020-04-11  0:28 ` Andre Guedes
  2020-04-23 21:21   ` Brown, Aaron F
  2020-04-11  0:28 ` [Intel-wired-lan] [PATCH 4/4] igc: Enable NFC rules based source MAC address Andre Guedes
  3 siblings, 1 reply; 12+ messages in thread
From: Andre Guedes @ 2020-04-11  0:28 UTC (permalink / raw)
  To: intel-wired-lan

This patch extends MAC address filter internal APIs igc_add_mac_filter()
and igc_del_mac_filter(), as well as local helpers, to support filters
based on source address.

A new parameters 'type' is added to the APIs to indicate if the filter
type is source or destination. In case it is source type, the RAH
register is configured accordingly in igc_set_mac_filter_hw().

Signed-off-by: Andre Guedes <andre.guedes@intel.com>
---
 drivers/net/ethernet/intel/igc/igc.h         | 13 ++++--
 drivers/net/ethernet/intel/igc/igc_defines.h |  2 +
 drivers/net/ethernet/intel/igc/igc_ethtool.c |  6 ++-
 drivers/net/ethernet/intel/igc/igc_main.c    | 49 +++++++++++++-------
 4 files changed, 49 insertions(+), 21 deletions(-)

diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
index 654481cea1f2..a887331bc622 100644
--- a/drivers/net/ethernet/intel/igc/igc.h
+++ b/drivers/net/ethernet/intel/igc/igc.h
@@ -29,6 +29,11 @@ void igc_set_ethtool_ops(struct net_device *);
 #define MAX_ETYPE_FILTER		8
 #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 {
 	u64 packets;
 	u64 bytes;
@@ -228,9 +233,11 @@ void igc_write_rss_indir_tbl(struct igc_adapter *adapter);
 bool igc_has_link(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_add_mac_filter(struct igc_adapter *adapter, const u8 *addr,
-		       const s8 queue);
-int igc_del_mac_filter(struct igc_adapter *adapter, const u8 *addr);
+int igc_add_mac_filter(struct igc_adapter *adapter,
+		       enum igc_mac_filter_type type, const u8 *addr,
+		       int queue);
+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 queue);
 void igc_del_vlan_prio_filter(struct igc_adapter *adapter, int prio);
diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h
index e190a7f83c3c..389a2c340261 100644
--- a/drivers/net/ethernet/intel/igc/igc_defines.h
+++ b/drivers/net/ethernet/intel/igc/igc_defines.h
@@ -63,6 +63,8 @@
  * 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_SHIFT	18
 #define IGC_RAH_QSEL_ENABLE	BIT(28)
diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c
index 36e94142b248..20d22df52f09 100644
--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c
+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c
@@ -1207,7 +1207,8 @@ int igc_add_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input)
 	}
 
 	if (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) {
-		err = igc_add_mac_filter(adapter, input->filter.dst_addr,
+		err = igc_add_mac_filter(adapter, IGC_MAC_FILTER_TYPE_DST,
+					 input->filter.dst_addr,
 					 input->action);
 		if (err)
 			return err;
@@ -1239,7 +1240,8 @@ int igc_erase_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input)
 	}
 
 	if (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR)
-		igc_del_mac_filter(adapter, input->filter.dst_addr);
+		igc_del_mac_filter(adapter, IGC_MAC_FILTER_TYPE_DST,
+				   input->filter.dst_addr);
 
 	return 0;
 }
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 1779d20299d0..c5f0f7690ad3 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -766,12 +766,14 @@ static void igc_setup_tctl(struct igc_adapter *adapter)
  * igc_set_mac_filter_hw() - Set MAC address filter in hardware.
  * @adapter: Pointer to adapter where the filter should be set.
  * @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
  *         matching the filter are enqueued onto 'queue'. Otherwise, queue
  *         assignment is disabled.
  */
 static void igc_set_mac_filter_hw(struct igc_adapter *adapter, int index,
+				  enum igc_mac_filter_type type,
 				  const u8 *addr, int queue)
 {
 	struct net_device *dev = adapter->netdev;
@@ -784,6 +786,11 @@ static void igc_set_mac_filter_hw(struct igc_adapter *adapter, int index,
 	ral = le32_to_cpup((__le32 *)(addr));
 	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) {
 		rah &= ~IGC_RAH_QSEL_MASK;
 		rah |= (queue << IGC_RAH_QSEL_SHIFT);
@@ -825,7 +832,7 @@ static void igc_set_default_mac_filter(struct igc_adapter *adapter)
 
 	netdev_dbg(dev, "Set default MAC address filter: address %pM", addr);
 
-	igc_set_mac_filter_hw(adapter, 0, addr, -1);
+	igc_set_mac_filter_hw(adapter, 0, IGC_MAC_FILTER_TYPE_DST, addr, -1);
 }
 
 /**
@@ -2180,7 +2187,8 @@ static void igc_nfc_filter_restore(struct igc_adapter *adapter)
 	spin_unlock(&adapter->nfc_lock);
 }
 
-static int igc_find_mac_filter(struct igc_adapter *adapter, const u8 *addr)
+static int igc_find_mac_filter(struct igc_adapter *adapter,
+			       enum igc_mac_filter_type type, const u8 *addr)
 {
 	struct igc_hw *hw = &adapter->hw;
 	int max_entries = hw->mac.rar_entry_count;
@@ -2193,6 +2201,8 @@ static int igc_find_mac_filter(struct igc_adapter *adapter, const u8 *addr)
 
 		if (!(rah & IGC_RAH_AV))
 			continue;
+		if (!!(rah & IGC_RAH_ASEL_SRC_ADDR) != type)
+			continue;
 		if ((rah & IGC_RAH_RAH_MASK) !=
 		    le16_to_cpup((__le16 *)(addr + 4)))
 			continue;
@@ -2225,6 +2235,7 @@ static int igc_get_avail_mac_filter_slot(struct igc_adapter *adapter)
 /**
  * igc_add_mac_filter() - Add MAC address filter.
  * @adapter: Pointer to adapter where the filter should be added.
+ * @type: MAC address filter type (source or destination).
  * @addr: MAC address.
  * @queue: If non-negative, queue assignment feature is enabled and frames
  *         matching the filter are enqueued onto 'queue'. Otherwise, queue
@@ -2232,8 +2243,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, const u8 *addr,
-		       const s8 queue)
+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;
@@ -2241,7 +2253,7 @@ int igc_add_mac_filter(struct igc_adapter *adapter, const u8 *addr,
 	if (!is_valid_ether_addr(addr))
 		return -EINVAL;
 
-	index = igc_find_mac_filter(adapter, addr);
+	index = igc_find_mac_filter(adapter, type, addr);
 	if (index >= 0)
 		goto update_filter;
 
@@ -2249,22 +2261,25 @@ int igc_add_mac_filter(struct igc_adapter *adapter, const u8 *addr,
 	if (index < 0)
 		return -ENOSPC;
 
-	netdev_dbg(dev, "Add MAC address filter: index %d address %pM queue %d",
-		   index, addr, queue);
+	netdev_dbg(dev, "Add MAC address filter: index %d type %s address %pM queue %d",
+		   index, type == IGC_MAC_FILTER_TYPE_DST ? "dst" : "src",
+		   addr, queue);
 
 update_filter:
-	igc_set_mac_filter_hw(adapter, index, addr, queue);
+	igc_set_mac_filter_hw(adapter, index, type, addr, queue);
 	return 0;
 }
 
 /**
  * igc_del_mac_filter() - Delete MAC address filter.
  * @adapter: Pointer to adapter where the filter should be deleted from.
+ * @type: MAC address filter type (source or destination).
  * @addr: MAC address.
  *
  * 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,
+		       enum igc_mac_filter_type type, const u8 *addr)
 {
 	struct net_device *dev = adapter->netdev;
 	int index;
@@ -2272,7 +2287,7 @@ int igc_del_mac_filter(struct igc_adapter *adapter, const u8 *addr)
 	if (!is_valid_ether_addr(addr))
 		return -EINVAL;
 
-	index = igc_find_mac_filter(adapter, addr);
+	index = igc_find_mac_filter(adapter, type, addr);
 	if (index < 0)
 		return -ENOENT;
 
@@ -2283,10 +2298,12 @@ int igc_del_mac_filter(struct igc_adapter *adapter, const u8 *addr)
 		 */
 		netdev_dbg(dev, "Disable default MAC filter queue assignment");
 
-		igc_set_mac_filter_hw(adapter, 0, addr, -1);
+		igc_set_mac_filter_hw(adapter, 0, type, addr, -1);
 	} else {
-		netdev_dbg(dev, "Delete MAC address filter: index %d address %pM",
-			   index, addr);
+		netdev_dbg(dev, "Delete MAC address filter: index %d type %s address %pM",
+			   index,
+			   type == IGC_MAC_FILTER_TYPE_DST ? "dst" : "src",
+			   addr);
 
 		igc_clear_mac_filter_hw(adapter, index);
 	}
@@ -2443,14 +2460,14 @@ static int igc_uc_sync(struct net_device *netdev, const unsigned char *addr)
 {
 	struct igc_adapter *adapter = netdev_priv(netdev);
 
-	return igc_add_mac_filter(adapter, addr, -1);
+	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)
 {
 	struct igc_adapter *adapter = netdev_priv(netdev);
 
-	return igc_del_mac_filter(adapter, addr);
+	return igc_del_mac_filter(adapter, IGC_MAC_FILTER_TYPE_DST, addr);
 }
 
 /**
-- 
2.26.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Intel-wired-lan] [PATCH 4/4] igc: Enable NFC rules based source MAC address
  2020-04-11  0:28 [Intel-wired-lan] [PATCH 0/4] igc: Enable NFC rules based on source MAC address Andre Guedes
                   ` (2 preceding siblings ...)
  2020-04-11  0:28 ` [Intel-wired-lan] [PATCH 3/4] igc: Add support for source address filters in core Andre Guedes
@ 2020-04-11  0:28 ` Andre Guedes
  2020-04-13 16:00   ` [Intel-wired-lan] [PATCH v2 " Andre Guedes
  3 siblings, 1 reply; 12+ messages in thread
From: Andre Guedes @ 2020-04-11  0:28 UTC (permalink / raw)
  To: intel-wired-lan

This patch adds support for Network Flow Classification (NFC) rules
based on source MAC address. Note that the controller doesn't support
rules with both source and destination addresses set, so this special
case is checked in igc_add_ethtool_nfc_entry().

Signed-off-by: Andre Guedes <andre.guedes@intel.com>
---
 drivers/net/ethernet/intel/igc/igc_ethtool.c | 31 +++++++++++++-------
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c
index 20d22df52f09..9cd629b7d5f4 100644
--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c
+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c
@@ -1188,16 +1188,8 @@ static int igc_set_rss_hash_opt(struct igc_adapter *adapter,
 
 int igc_add_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input)
 {
-	struct igc_hw *hw = &adapter->hw;
 	int err = -EINVAL;
 
-	if (hw->mac.type == igc_i225 &&
-	    !(input->filter.match_flags & ~IGC_FILTER_FLAG_SRC_MAC_ADDR)) {
-		netdev_err(adapter->netdev,
-			   "i225 doesn't support flow classification rules specifying only source addresses");
-		return -EOPNOTSUPP;
-	}
-
 	if (input->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) {
 		u16 etype = ntohs(input->filter.etype);
 
@@ -1206,6 +1198,14 @@ int igc_add_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input)
 			return err;
 	}
 
+	if (input->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) {
+		err = igc_add_mac_filter(adapter, IGC_MAC_FILTER_TYPE_SRC,
+					 input->filter.src_addr,
+					 input->action);
+		if (err)
+			return err;
+	}
+
 	if (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) {
 		err = igc_add_mac_filter(adapter, IGC_MAC_FILTER_TYPE_DST,
 					 input->filter.dst_addr,
@@ -1239,6 +1239,10 @@ int igc_erase_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input)
 		igc_del_vlan_prio_filter(adapter, prio);
 	}
 
+	if (input->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR)
+		igc_del_mac_filter(adapter, IGC_MAC_FILTER_TYPE_SRC,
+				   input->filter.src_addr);
+
 	if (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR)
 		igc_del_mac_filter(adapter, IGC_MAC_FILTER_TYPE_DST,
 				   input->filter.dst_addr);
@@ -1334,20 +1338,27 @@ static int igc_add_ethtool_nfc_entry(struct igc_adapter *adapter,
 		input->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)) {
 		input->filter.match_flags |= IGC_FILTER_FLAG_SRC_MAC_ADDR;
 		ether_addr_copy(input->filter.src_addr,
 				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)) {
 		input->filter.match_flags |= IGC_FILTER_FLAG_DST_MAC_ADDR;
 		ether_addr_copy(input->filter.dst_addr,
 				fsp->h_u.ether_spec.h_dest);
 	}
 
+	if (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR &&
+	    input->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) {
+		netdev_dbg(netdev, "Filters with both dst and src are not supported");
+		return -EOPNOTSUPP;
+	}
+
 	if ((fsp->flow_type & FLOW_EXT) && fsp->m_ext.vlan_tci) {
 		if (fsp->m_ext.vlan_tci != htons(VLAN_PRIO_MASK)) {
 			netdev_dbg(netdev, "VLAN mask not supported");
-- 
2.26.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Intel-wired-lan] [PATCH 2/4] igc: Remove mac_table from igc_adapter
  2020-04-11  0:28 ` [Intel-wired-lan] [PATCH 2/4] igc: Remove mac_table from igc_adapter Andre Guedes
@ 2020-04-12  7:18   ` Neftin, Sasha
  2020-04-13 14:21     ` Andre Guedes
  2020-04-23 21:17   ` Brown, Aaron F
  1 sibling, 1 reply; 12+ messages in thread
From: Neftin, Sasha @ 2020-04-12  7:18 UTC (permalink / raw)
  To: intel-wired-lan

On 4/11/2020 03:28, Andre Guedes wrote:
> In igc_adapter we keep a sort of shadow copy of RAL and RAH registers.
> There is not much benefit in keeping it, at the cost of maintainability,
> since adding/removing MAC address filters is not hot path, and we
> already keep filters information in adapter->nfc_filter_list for cleanup
> and restoration purposes.
> 
> So in order to simplify the MAC address filtering code and prepare it
> for source address support, this patch removes the mac_table from
> igc_adapter.
> 
> Signed-off-by: Andre Guedes <andre.guedes@intel.com>
> ---
>   drivers/net/ethernet/intel/igc/igc.h         | 11 ----
>   drivers/net/ethernet/intel/igc/igc_defines.h |  1 +
>   drivers/net/ethernet/intel/igc/igc_main.c    | 57 +++++++-------------
>   3 files changed, 21 insertions(+), 48 deletions(-)
> 
> diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
> index c4c4498ab48f..654481cea1f2 100644
> --- a/drivers/net/ethernet/intel/igc/igc.h
> +++ b/drivers/net/ethernet/intel/igc/igc.h
> @@ -190,8 +190,6 @@ struct igc_adapter {
>   	/* lock for RX network flow classification filter */
>   	spinlock_t nfc_lock;
>   
> -	struct igc_mac_addr *mac_table;
> -
>   	u8 rss_indir_tbl[IGC_RETA_SIZE];
>   
>   	unsigned long link_check_timeout;
> @@ -470,15 +468,6 @@ struct igc_nfc_filter {
>   	u16 action;
>   };
>   
> -struct igc_mac_addr {
> -	u8 addr[ETH_ALEN];
> -	s8 queue;
> -	u8 state; /* bitmask */
> -};
> -
> -#define IGC_MAC_STATE_DEFAULT		0x1
> -#define IGC_MAC_STATE_IN_USE		0x2
> -
>   #define IGC_MAX_RXNFC_FILTERS		16
>   
>   /* igc_desc_unused - calculate if we have unused descriptors */
> diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h
> index 1127ef81e374..e190a7f83c3c 100644
> --- a/drivers/net/ethernet/intel/igc/igc_defines.h
> +++ b/drivers/net/ethernet/intel/igc/igc_defines.h
> @@ -62,6 +62,7 @@
>    * (RAR[15]) for our directed address used by controllers with
>    * manageability enabled, allowing us room for 15 multicast addresses.
>    */
> +#define IGC_RAH_RAH_MASK	0x0000FFFF
Hello Andre, does it intentioanlly twice _RAH_RAH_?
>   #define IGC_RAH_QSEL_MASK	0x000C0000
>   #define IGC_RAH_QSEL_SHIFT	18
>   #define IGC_RAH_QSEL_ENABLE	BIT(28)
> diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
> index 411af7eafe19..1779d20299d0 100644
> --- a/drivers/net/ethernet/intel/igc/igc_main.c
> +++ b/drivers/net/ethernet/intel/igc/igc_main.c
> @@ -820,17 +820,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 */
>   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;
>   	u8 *addr = adapter->hw.mac.addr;
>   
>   	netdev_dbg(dev, "Set default MAC address filter: address %pM", addr);
>   
> -	ether_addr_copy(mac_table->addr, addr);
> -	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);
> +	igc_set_mac_filter_hw(adapter, 0, addr, -1);
>   }
>   
>   /**
> @@ -2187,16 +2182,21 @@ static void igc_nfc_filter_restore(struct igc_adapter *adapter)
>   
>   static int igc_find_mac_filter(struct igc_adapter *adapter, const u8 *addr)
>   {
> -	int max_entries = adapter->hw.mac.rar_entry_count;
> -	struct igc_mac_addr *entry;
> +	struct igc_hw *hw = &adapter->hw;
> +	int max_entries = hw->mac.rar_entry_count;
> +	u32 ral, rah;
>   	int 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;
> -		if (!ether_addr_equal(addr, entry->addr))
> +		if ((rah & IGC_RAH_RAH_MASK) !=
> +		    le16_to_cpup((__le16 *)(addr + 4)))
> +			continue;
> +		if (ral != le32_to_cpup((__le32 *)(addr)))
>   			continue;
>   
>   		return i;
> @@ -2207,14 +2207,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)
>   {
> -	int max_entries = adapter->hw.mac.rar_entry_count;
> -	struct igc_mac_addr *entry;
> +	struct igc_hw *hw = &adapter->hw;
> +	int max_entries = hw->mac.rar_entry_count;
> +	u32 rah;
>   	int 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;
>   	}
>   
> @@ -2242,7 +2243,7 @@ int igc_add_mac_filter(struct igc_adapter *adapter, const u8 *addr,
>   
>   	index = igc_find_mac_filter(adapter, addr);
>   	if (index >= 0)
> -		goto update_queue_assignment;
> +		goto update_filter;
>   
>   	index = igc_get_avail_mac_filter_slot(adapter);
>   	if (index < 0)
> @@ -2251,11 +2252,7 @@ int igc_add_mac_filter(struct igc_adapter *adapter, const u8 *addr,
>   	netdev_dbg(dev, "Add MAC address filter: index %d address %pM queue %d",
>   		   index, addr, queue);
>   
> -	ether_addr_copy(adapter->mac_table[index].addr, addr);
> -	adapter->mac_table[index].state |= IGC_MAC_STATE_IN_USE;
> -update_queue_assignment:
> -	adapter->mac_table[index].queue = queue;
> -
> +update_filter:
>   	igc_set_mac_filter_hw(adapter, index, addr, queue);
>   	return 0;
>   }
> @@ -2270,7 +2267,6 @@ int igc_add_mac_filter(struct igc_adapter *adapter, const u8 *addr,
>   int igc_del_mac_filter(struct igc_adapter *adapter, const u8 *addr)
>   {
>   	struct net_device *dev = adapter->netdev;
> -	struct igc_mac_addr *entry;
>   	int index;
>   
>   	if (!is_valid_ether_addr(addr))
> @@ -2280,24 +2276,18 @@ int igc_del_mac_filter(struct igc_adapter *adapter, const u8 *addr)
>   	if (index < 0)
>   		return -ENOENT;
>   
> -	entry = &adapter->mac_table[index];
> -
> -	if (entry->state & IGC_MAC_STATE_DEFAULT) {
> +	if (index == 0) {
>   		/* If this is the default filter, we don't actually delete it.
>   		 * We just reset to its default value i.e. disable queue
>   		 * assignment.
>   		 */
>   		netdev_dbg(dev, "Disable default MAC filter queue assignment");
>   
> -		entry->queue = -1;
> -		igc_set_mac_filter_hw(adapter, 0, addr, entry->queue);
> +		igc_set_mac_filter_hw(adapter, 0, addr, -1);
>   	} else {
>   		netdev_dbg(dev, "Delete MAC address filter: index %d address %pM",
>   			   index, addr);
>   
> -		entry->state = 0;
> -		entry->queue = -1;
> -		memset(entry->addr, 0, ETH_ALEN);
>   		igc_clear_mac_filter_hw(adapter, index);
>   	}
>   
> @@ -3405,8 +3395,6 @@ static int igc_sw_init(struct igc_adapter *adapter)
>   	struct pci_dev *pdev = adapter->pdev;
>   	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);
>   
>   	/* set default ring sizes */
> @@ -3430,10 +3418,6 @@ static int igc_sw_init(struct igc_adapter *adapter)
>   	/* Assume MSI-X interrupts, will be checked during IRQ allocation */
>   	adapter->flags |= IGC_FLAG_HAS_MSIX;
>   
> -	adapter->mac_table = kzalloc(size, GFP_ATOMIC);
> -	if (!adapter->mac_table)
> -		return -ENOMEM;
> -
>   	igc_init_queue_configuration(adapter);
>   
>   	/* This call may decrease the number of queues */
> @@ -5139,7 +5123,6 @@ static void igc_remove(struct pci_dev *pdev)
>   	pci_iounmap(pdev, adapter->io_addr);
>   	pci_release_mem_regions(pdev);
>   
> -	kfree(adapter->mac_table);
>   	free_netdev(netdev);
>   
>   	pci_disable_pcie_error_reporting(pdev);
> 


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Intel-wired-lan] [PATCH 2/4] igc: Remove mac_table from igc_adapter
  2020-04-12  7:18   ` Neftin, Sasha
@ 2020-04-13 14:21     ` Andre Guedes
  0 siblings, 0 replies; 12+ messages in thread
From: Andre Guedes @ 2020-04-13 14:21 UTC (permalink / raw)
  To: intel-wired-lan

> > diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h
> > index 1127ef81e374..e190a7f83c3c 100644
> > --- a/drivers/net/ethernet/intel/igc/igc_defines.h
> > +++ b/drivers/net/ethernet/intel/igc/igc_defines.h
> > @@ -62,6 +62,7 @@
> >    * (RAR[15]) for our directed address used by controllers with
> >    * manageability enabled, allowing us room for 15 multicast addresses.
> >    */
> > +#define IGC_RAH_RAH_MASK     0x0000FFFF
> Hello Andre, does it intentioanlly twice _RAH_RAH_?

Yes. The field name in the datasheet is also 'RAH'. So we have one for the
register name and one for the field name.

- Andre

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Intel-wired-lan] [PATCH v2 4/4] igc: Enable NFC rules based source MAC address
  2020-04-11  0:28 ` [Intel-wired-lan] [PATCH 4/4] igc: Enable NFC rules based source MAC address Andre Guedes
@ 2020-04-13 16:00   ` Andre Guedes
  2020-04-23 21:35     ` Brown, Aaron F
  0 siblings, 1 reply; 12+ messages in thread
From: Andre Guedes @ 2020-04-13 16:00 UTC (permalink / raw)
  To: intel-wired-lan

This patch adds support for Network Flow Classification (NFC) rules
based on source MAC address. Note that the controller doesn't support
rules with both source and destination addresses set, so this special
case is checked in igc_add_ethtool_nfc_entry().

Signed-off-by: Andre Guedes <andre.guedes@intel.com>
---
v2: Fix memory leak when both dst and src are set.
---
 drivers/net/ethernet/intel/igc/igc_ethtool.c | 32 ++++++++++++++------
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c
index 20d22df52f09..9023dc2a2446 100644
--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c
+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c
@@ -1188,16 +1188,8 @@ static int igc_set_rss_hash_opt(struct igc_adapter *adapter,
 
 int igc_add_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input)
 {
-	struct igc_hw *hw = &adapter->hw;
 	int err = -EINVAL;
 
-	if (hw->mac.type == igc_i225 &&
-	    !(input->filter.match_flags & ~IGC_FILTER_FLAG_SRC_MAC_ADDR)) {
-		netdev_err(adapter->netdev,
-			   "i225 doesn't support flow classification rules specifying only source addresses");
-		return -EOPNOTSUPP;
-	}
-
 	if (input->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) {
 		u16 etype = ntohs(input->filter.etype);
 
@@ -1206,6 +1198,14 @@ int igc_add_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input)
 			return err;
 	}
 
+	if (input->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) {
+		err = igc_add_mac_filter(adapter, IGC_MAC_FILTER_TYPE_SRC,
+					 input->filter.src_addr,
+					 input->action);
+		if (err)
+			return err;
+	}
+
 	if (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) {
 		err = igc_add_mac_filter(adapter, IGC_MAC_FILTER_TYPE_DST,
 					 input->filter.dst_addr,
@@ -1239,6 +1239,10 @@ int igc_erase_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input)
 		igc_del_vlan_prio_filter(adapter, prio);
 	}
 
+	if (input->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR)
+		igc_del_mac_filter(adapter, IGC_MAC_FILTER_TYPE_SRC,
+				   input->filter.src_addr);
+
 	if (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR)
 		igc_del_mac_filter(adapter, IGC_MAC_FILTER_TYPE_DST,
 				   input->filter.dst_addr);
@@ -1334,20 +1338,28 @@ static int igc_add_ethtool_nfc_entry(struct igc_adapter *adapter,
 		input->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)) {
 		input->filter.match_flags |= IGC_FILTER_FLAG_SRC_MAC_ADDR;
 		ether_addr_copy(input->filter.src_addr,
 				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)) {
 		input->filter.match_flags |= IGC_FILTER_FLAG_DST_MAC_ADDR;
 		ether_addr_copy(input->filter.dst_addr,
 				fsp->h_u.ether_spec.h_dest);
 	}
 
+	if (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR &&
+	    input->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) {
+		netdev_dbg(netdev, "Filters with both dst and src are not supported");
+		err = -EOPNOTSUPP;
+		goto err_out;
+	}
+
 	if ((fsp->flow_type & FLOW_EXT) && fsp->m_ext.vlan_tci) {
 		if (fsp->m_ext.vlan_tci != htons(VLAN_PRIO_MASK)) {
 			netdev_dbg(netdev, "VLAN mask not supported");
-- 
2.26.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Intel-wired-lan] [PATCH 1/4] igc: Remove IGC_MAC_STATE_SRC_ADDR flag
  2020-04-11  0:28 ` [Intel-wired-lan] [PATCH 1/4] igc: Remove IGC_MAC_STATE_SRC_ADDR flag Andre Guedes
@ 2020-04-23 21:12   ` Brown, Aaron F
  0 siblings, 0 replies; 12+ messages in thread
From: Brown, Aaron F @ 2020-04-23 21:12 UTC (permalink / raw)
  To: intel-wired-lan

> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of
> Andre Guedes
> Sent: Friday, April 10, 2020 5:29 PM
> To: intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [PATCH 1/4] igc: Remove
> IGC_MAC_STATE_SRC_ADDR flag
> 
> MAC address filters based on source address are not currently supported
> by the IGC driver. Despite of that, the driver have some dangling code
> to handle it, inherited from IGB driver. This patch removes that code to
> prepare for a follow up patch that adds proper source MAC address filter
> support.
> 
> Signed-off-by: Andre Guedes <andre.guedes@intel.com>
> ---
>  drivers/net/ethernet/intel/igc/igc.h         |  6 ++---
>  drivers/net/ethernet/intel/igc/igc_ethtool.c | 16 ++----------
>  drivers/net/ethernet/intel/igc/igc_main.c    | 27 ++++++--------------
>  3 files changed, 12 insertions(+), 37 deletions(-)
> 
Tested-by: Aaron Brown <aaron.f.brown@intel.com>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Intel-wired-lan] [PATCH 2/4] igc: Remove mac_table from igc_adapter
  2020-04-11  0:28 ` [Intel-wired-lan] [PATCH 2/4] igc: Remove mac_table from igc_adapter Andre Guedes
  2020-04-12  7:18   ` Neftin, Sasha
@ 2020-04-23 21:17   ` Brown, Aaron F
  1 sibling, 0 replies; 12+ messages in thread
From: Brown, Aaron F @ 2020-04-23 21:17 UTC (permalink / raw)
  To: intel-wired-lan

> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of
> Andre Guedes
> Sent: Friday, April 10, 2020 5:29 PM
> To: intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [PATCH 2/4] igc: Remove mac_table from
> igc_adapter
> 
> In igc_adapter we keep a sort of shadow copy of RAL and RAH registers.
> There is not much benefit in keeping it, at the cost of maintainability,
> since adding/removing MAC address filters is not hot path, and we
> already keep filters information in adapter->nfc_filter_list for cleanup
> and restoration purposes.
> 
> So in order to simplify the MAC address filtering code and prepare it
> for source address support, this patch removes the mac_table from
> igc_adapter.
> 
> Signed-off-by: Andre Guedes <andre.guedes@intel.com>
> ---
>  drivers/net/ethernet/intel/igc/igc.h         | 11 ----
>  drivers/net/ethernet/intel/igc/igc_defines.h |  1 +
>  drivers/net/ethernet/intel/igc/igc_main.c    | 57 +++++++-------------
>  3 files changed, 21 insertions(+), 48 deletions(-)
Tested-by: Aaron Brown <aaron .f.brown@intel.com>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Intel-wired-lan] [PATCH 3/4] igc: Add support for source address filters in core
  2020-04-11  0:28 ` [Intel-wired-lan] [PATCH 3/4] igc: Add support for source address filters in core Andre Guedes
@ 2020-04-23 21:21   ` Brown, Aaron F
  0 siblings, 0 replies; 12+ messages in thread
From: Brown, Aaron F @ 2020-04-23 21:21 UTC (permalink / raw)
  To: intel-wired-lan

> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of
> Andre Guedes
> Sent: Friday, April 10, 2020 5:29 PM
> To: intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [PATCH 3/4] igc: Add support for source address
> filters in core
> 
> This patch extends MAC address filter internal APIs igc_add_mac_filter()
> and igc_del_mac_filter(), as well as local helpers, to support filters
> based on source address.
> 
> A new parameters 'type' is added to the APIs to indicate if the filter
> type is source or destination. In case it is source type, the RAH
> register is configured accordingly in igc_set_mac_filter_hw().
> 
> Signed-off-by: Andre Guedes <andre.guedes@intel.com>
> ---
>  drivers/net/ethernet/intel/igc/igc.h         | 13 ++++--
>  drivers/net/ethernet/intel/igc/igc_defines.h |  2 +
>  drivers/net/ethernet/intel/igc/igc_ethtool.c |  6 ++-
>  drivers/net/ethernet/intel/igc/igc_main.c    | 49 +++++++++++++-------
>  4 files changed, 49 insertions(+), 21 deletions(-)
> 
Tested-by: Aaron Brown <aaron.f.brown@intel.com>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Intel-wired-lan] [PATCH v2 4/4] igc: Enable NFC rules based source MAC address
  2020-04-13 16:00   ` [Intel-wired-lan] [PATCH v2 " Andre Guedes
@ 2020-04-23 21:35     ` Brown, Aaron F
  0 siblings, 0 replies; 12+ messages in thread
From: Brown, Aaron F @ 2020-04-23 21:35 UTC (permalink / raw)
  To: intel-wired-lan

> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of
> Andre Guedes
> Sent: Monday, April 13, 2020 9:01 AM
> To: intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [PATCH v2 4/4] igc: Enable NFC rules based source
> MAC address
> 
> This patch adds support for Network Flow Classification (NFC) rules
> based on source MAC address. Note that the controller doesn't support
> rules with both source and destination addresses set, so this special
> case is checked in igc_add_ethtool_nfc_entry().
> 
> Signed-off-by: Andre Guedes <andre.guedes@intel.com>
> ---
> v2: Fix memory leak when both dst and src are set.
> ---
>  drivers/net/ethernet/intel/igc/igc_ethtool.c | 32 ++++++++++++++------
>  1 file changed, 22 insertions(+), 10 deletions(-)
> 
Tested-by: Aaron Brown <aaron.f.brown@intel.com>

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2020-04-23 21:35 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-11  0:28 [Intel-wired-lan] [PATCH 0/4] igc: Enable NFC rules based on source MAC address Andre Guedes
2020-04-11  0:28 ` [Intel-wired-lan] [PATCH 1/4] igc: Remove IGC_MAC_STATE_SRC_ADDR flag Andre Guedes
2020-04-23 21:12   ` Brown, Aaron F
2020-04-11  0:28 ` [Intel-wired-lan] [PATCH 2/4] igc: Remove mac_table from igc_adapter Andre Guedes
2020-04-12  7:18   ` Neftin, Sasha
2020-04-13 14:21     ` Andre Guedes
2020-04-23 21:17   ` Brown, Aaron F
2020-04-11  0:28 ` [Intel-wired-lan] [PATCH 3/4] igc: Add support for source address filters in core Andre Guedes
2020-04-23 21:21   ` Brown, Aaron F
2020-04-11  0:28 ` [Intel-wired-lan] [PATCH 4/4] igc: Enable NFC rules based source MAC address Andre Guedes
2020-04-13 16:00   ` [Intel-wired-lan] [PATCH v2 " Andre Guedes
2020-04-23 21:35     ` Brown, Aaron F

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.