All of lore.kernel.org
 help / color / mirror / Atom feed
* [Intel-wired-lan] [PATCH next-queue v1 0/5] igc: Add support for RX Flex Filters
@ 2021-06-11  0:39 Vinicius Costa Gomes
  2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 1/5] igc: Add possibility to add flex filter Vinicius Costa Gomes
                   ` (4 more replies)
  0 siblings, 5 replies; 15+ messages in thread
From: Vinicius Costa Gomes @ 2021-06-11  0:39 UTC (permalink / raw)
  To: intel-wired-lan

Hi,

Add support for steering traffic to specific RX queues using Flex Filters.

As the name implies, Flex Filters are more flexible than using
Layer-2, VLAN or MAC address filters, one of the reasons is that they
allow "AND" operations more easily, e.g. when the user wants to steer
some traffic based on the source MAC address and the packet ethertype.

Future work include adding support for offloading tc-u32 filters to
the hardware.

The series is divided as follows:

Patch 1/5, add the low level primitives for configuring Flex filters.

Patch 2/5 and 3/5, allow ethtool to manage Flex filters.

Patch 4/5, when specifying filters that have multiple predicates, use Flex filters.

Patch 5/5, Adds support for exposing the i225 LEDs using the LED subsystem.


Cheers,

Kurt Kanzenbach (4):
  igc: Add possibility to add flex filter
  igc: Integrate flex filter into ethtool ops
  igc: Make flex filter more flexible
  igc: Export LEDs

Vinicius Costa Gomes (1):
  igc: Allow for Flex Filters to be installed

 drivers/net/ethernet/intel/Kconfig           |   1 +
 drivers/net/ethernet/intel/igc/igc.h         |  48 +-
 drivers/net/ethernet/intel/igc/igc_defines.h |  62 ++-
 drivers/net/ethernet/intel/igc/igc_ethtool.c |  41 +-
 drivers/net/ethernet/intel/igc/igc_main.c    | 450 ++++++++++++++++++-
 drivers/net/ethernet/intel/igc/igc_regs.h    |  19 +
 6 files changed, 597 insertions(+), 24 deletions(-)

-- 
2.32.0


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

* [Intel-wired-lan] [PATCH next-queue v1 1/5] igc: Add possibility to add flex filter
  2021-06-11  0:39 [Intel-wired-lan] [PATCH next-queue v1 0/5] igc: Add support for RX Flex Filters Vinicius Costa Gomes
@ 2021-06-11  0:39 ` Vinicius Costa Gomes
  2021-06-21 12:31   ` Fuxbrumer, Dvora
  2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 2/5] igc: Integrate flex filter into ethtool ops Vinicius Costa Gomes
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 15+ messages in thread
From: Vinicius Costa Gomes @ 2021-06-11  0:39 UTC (permalink / raw)
  To: intel-wired-lan

From: Kurt Kanzenbach <kurt@linutronix.de>

The Intel i225 NIC has the possibility to add flex filters which can
match up to the first 128 byte of a packet. These filters are useful
for all kind of packet matching. One particular use case is Profinet,
as the different traffic classes are distinguished by the frame id
range which cannot be matched by any other means.

Add code to configure and enable flex filters.

Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
---
 drivers/net/ethernet/intel/igc/igc.h         |  13 ++
 drivers/net/ethernet/intel/igc/igc_defines.h |  48 ++++++-
 drivers/net/ethernet/intel/igc/igc_main.c    | 134 +++++++++++++++++++
 drivers/net/ethernet/intel/igc/igc_regs.h    |  17 +++
 4 files changed, 207 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
index 5901ed9fb545..6016c132d981 100644
--- a/drivers/net/ethernet/intel/igc/igc.h
+++ b/drivers/net/ethernet/intel/igc/igc.h
@@ -33,6 +33,8 @@ void igc_ethtool_set_ops(struct net_device *);
 #define IGC_N_PEROUT	2
 #define IGC_N_SDP	4
 
+#define MAX_FLEX_FILTER			32
+
 enum igc_mac_filter_type {
 	IGC_MAC_FILTER_TYPE_DST = 0,
 	IGC_MAC_FILTER_TYPE_SRC
@@ -502,6 +504,17 @@ struct igc_nfc_rule {
  */
 #define IGC_MAX_RXNFC_RULES		32
 
+struct igc_flex_filter {
+	u8 index;
+	u8 data[128];
+	u8 mask[16];
+	u8 length;
+	u8 rx_queue;
+	u8 prio;
+	u8 immediate_irq;
+	u8 drop;
+};
+
 /* igc_desc_unused - calculate if we have unused descriptors */
 static inline u16 igc_desc_unused(const struct igc_ring *ring)
 {
diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h
index 71fe5b5ad2ed..0a29d9eca634 100644
--- a/drivers/net/ethernet/intel/igc/igc_defines.h
+++ b/drivers/net/ethernet/intel/igc/igc_defines.h
@@ -17,11 +17,20 @@
 #define IGC_WUC_PME_EN	0x00000002 /* PME Enable */
 
 /* Wake Up Filter Control */
-#define IGC_WUFC_LNKC	0x00000001 /* Link Status Change Wakeup Enable */
-#define IGC_WUFC_MAG	0x00000002 /* Magic Packet Wakeup Enable */
-#define IGC_WUFC_EX	0x00000004 /* Directed Exact Wakeup Enable */
-#define IGC_WUFC_MC	0x00000008 /* Directed Multicast Wakeup Enable */
-#define IGC_WUFC_BC	0x00000010 /* Broadcast Wakeup Enable */
+#define IGC_WUFC_LNKC		0x00000001 /* Link Status Change Wakeup Enable */
+#define IGC_WUFC_MAG		0x00000002 /* Magic Packet Wakeup Enable */
+#define IGC_WUFC_EX		0x00000004 /* Directed Exact Wakeup Enable */
+#define IGC_WUFC_MC		0x00000008 /* Directed Multicast Wakeup Enable */
+#define IGC_WUFC_BC		0x00000010 /* Broadcast Wakeup Enable */
+#define IGC_WUFC_FLEX_HQ	BIT(14)	   /* Flex Filters Host Queuing */
+#define IGC_WUFC_FLX0		BIT(16)	   /* Flexible Filter 0 Enable */
+#define IGC_WUFC_FLX1		BIT(17)	   /* Flexible Filter 1 Enable */
+#define IGC_WUFC_FLX2		BIT(18)	   /* Flexible Filter 2 Enable */
+#define IGC_WUFC_FLX3		BIT(19)	   /* Flexible Filter 3 Enable */
+#define IGC_WUFC_FLX4		BIT(20)	   /* Flexible Filter 4 Enable */
+#define IGC_WUFC_FLX5		BIT(21)	   /* Flexible Filter 5 Enable */
+#define IGC_WUFC_FLX6		BIT(22)	   /* Flexible Filter 6 Enable */
+#define IGC_WUFC_FLX7		BIT(23)	   /* Flexible Filter 7 Enable */
 
 #define IGC_CTRL_ADVD3WUC	0x00100000  /* D3 WUC */
 
@@ -46,6 +55,35 @@
 /* Wake Up Packet Memory stores the first 128 bytes of the wake up packet */
 #define IGC_WUPM_BYTES	128
 
+/* Wakeup Filter Control Extended */
+#define IGC_WUFC_EXT_FLX8	BIT(8)	/* Flexible Filter 8 Enable */
+#define IGC_WUFC_EXT_FLX9	BIT(9)	/* Flexible Filter 9 Enable */
+#define IGC_WUFC_EXT_FLX10	BIT(10) /* Flexible Filter 10 Enable */
+#define IGC_WUFC_EXT_FLX11	BIT(11)	/* Flexible Filter 11 Enable */
+#define IGC_WUFC_EXT_FLX12	BIT(12)	/* Flexible Filter 12 Enable */
+#define IGC_WUFC_EXT_FLX13	BIT(13)	/* Flexible Filter 13 Enable */
+#define IGC_WUFC_EXT_FLX14	BIT(14)	/* Flexible Filter 14 Enable */
+#define IGC_WUFC_EXT_FLX15	BIT(15)	/* Flexible Filter 15 Enable */
+#define IGC_WUFC_EXT_FLX16	BIT(16)	/* Flexible Filter 16 Enable */
+#define IGC_WUFC_EXT_FLX17	BIT(17)	/* Flexible Filter 17 Enable */
+#define IGC_WUFC_EXT_FLX18	BIT(18)	/* Flexible Filter 18 Enable */
+#define IGC_WUFC_EXT_FLX19	BIT(19)	/* Flexible Filter 19 Enable */
+#define IGC_WUFC_EXT_FLX20	BIT(20)	/* Flexible Filter 20 Enable */
+#define IGC_WUFC_EXT_FLX21	BIT(21)	/* Flexible Filter 21 Enable */
+#define IGC_WUFC_EXT_FLX22	BIT(22)	/* Flexible Filter 22 Enable */
+#define IGC_WUFC_EXT_FLX23	BIT(23)	/* Flexible Filter 23 Enable */
+#define IGC_WUFC_EXT_FLX24	BIT(24)	/* Flexible Filter 24 Enable */
+#define IGC_WUFC_EXT_FLX25	BIT(25)	/* Flexible Filter 25 Enable */
+#define IGC_WUFC_EXT_FLX26	BIT(26)	/* Flexible Filter 26 Enable */
+#define IGC_WUFC_EXT_FLX27	BIT(27)	/* Flexible Filter 27 Enable */
+#define IGC_WUFC_EXT_FLX28	BIT(28)	/* Flexible Filter 28 Enable */
+#define IGC_WUFC_EXT_FLX29	BIT(29)	/* Flexible Filter 29 Enable */
+#define IGC_WUFC_EXT_FLX30	BIT(30)	/* Flexible Filter 30 Enable */
+#define IGC_WUFC_EXT_FLX31	BIT(31)	/* Flexible Filter 31 Enable */
+
+/* Physical Func Reset Done Indication */
+#define IGC_CTRL_EXT_LINK_MODE_MASK	0x00C00000
+
 /* Loop limit on how long we wait for auto-negotiation to complete */
 #define COPPER_LINK_UP_LIMIT		10
 #define PHY_AUTO_NEG_LIMIT		45
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index ff3c7bc1f0ef..f1e128be475c 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -3079,6 +3079,140 @@ static void igc_del_etype_filter(struct igc_adapter *adapter, u16 etype)
 		   etype);
 }
 
+static int igc_flex_filter_select(struct igc_adapter *adapter,
+				  struct igc_flex_filter *input,
+				  u32 *fhft)
+{
+	struct igc_hw *hw = &adapter->hw;
+	u8 fhft_index;
+	u32 fhftsl;
+
+	if (input->index >= MAX_FLEX_FILTER) {
+		dev_err(&adapter->pdev->dev, "Wrong Flex Filter index selected!\n");
+		return -EINVAL;
+	}
+
+	/* Indirect table select register */
+	fhftsl = rd32(IGC_FHFTSL);
+	fhftsl &= ~IGC_FHFTSL_FTSL_MASK;
+	switch (input->index) {
+	case 0 ... 7:
+		fhftsl |= 0x00;
+		break;
+	case 8 ... 15:
+		fhftsl |= 0x01;
+		break;
+	case 16 ... 23:
+		fhftsl |= 0x02;
+		break;
+	case 24 ... 31:
+		fhftsl |= 0x03;
+		break;
+	}
+	wr32(IGC_FHFTSL, fhftsl);
+
+	/* Normalize index down to host table register */
+	fhft_index = input->index % 8;
+
+	*fhft = (fhft_index < 4) ? IGC_FHFT(fhft_index) :
+		IGC_FHFT_EXT(fhft_index - 4);
+
+	return 0;
+}
+
+static int __maybe_unused igc_write_flex_filter_ll(struct igc_adapter *adapter,
+						   struct igc_flex_filter *input)
+{
+	struct device *dev = &adapter->pdev->dev;
+	struct igc_hw *hw = &adapter->hw;
+	u8 *data = input->data;
+	u8 *mask = input->mask;
+	u32 queuing;
+	u32 fhft;
+	u32 wufc;
+	int ret;
+	int i;
+
+	/* Length has to be aligned to 8. Otherwise the filter will fail. Bail
+	 * out early to avoid surprises later.
+	 */
+	if (input->length % 8 != 0) {
+		dev_err(dev, "The length of a flex filter has to be 8 byte aligned!\n");
+		return -EINVAL;
+	}
+
+	/* Select corresponding flex filter register and get base for host table. */
+	ret = igc_flex_filter_select(adapter, input, &fhft);
+	if (ret)
+		return ret;
+
+	/* When adding a filter globally disable flex filter feature. That is
+	 * recommended within the datasheet.
+	 */
+	wufc = rd32(IGC_WUFC);
+	wufc &= ~IGC_WUFC_FLEX_HQ;
+	wr32(IGC_WUFC, wufc);
+
+	/* Configure filter */
+	queuing = input->length & IGC_FHFT_LENGTH_MASK;
+	queuing |= (input->rx_queue << IGC_FHFT_QUEUE_SHIFT) & IGC_FHFT_QUEUE_MASK;
+	queuing |= (input->prio << IGC_FHFT_PRIO_SHIFT) & IGC_FHFT_PRIO_MASK;
+
+	if (input->immediate_irq)
+		queuing |= IGC_FHFT_IMM_INT;
+
+	if (input->drop)
+		queuing |= IGC_FHFT_DROP;
+
+	wr32(fhft + 0xFC, queuing);
+
+	/* Write data (128 byte) and mask (128 bit) */
+	for (i = 0; i < 16; ++i) {
+		const size_t data_idx = i * 8;
+		const size_t row_idx = i * 16;
+		u32 dw0 =
+			(data[data_idx + 0] << 0) |
+			(data[data_idx + 1] << 8) |
+			(data[data_idx + 2] << 16) |
+			(data[data_idx + 3] << 24);
+		u32 dw1 =
+			(data[data_idx + 4] << 0) |
+			(data[data_idx + 5] << 8) |
+			(data[data_idx + 6] << 16) |
+			(data[data_idx + 7] << 24);
+		u32 tmp;
+
+		/* Write row: dw0, dw1 and mask */
+		wr32(fhft + row_idx, dw0);
+		wr32(fhft + row_idx + 4, dw1);
+
+		/* mask is only valid for MASK(7, 0) */
+		tmp = rd32(fhft + row_idx + 8);
+		tmp &= ~GENMASK(7, 0);
+		tmp |= mask[i];
+		wr32(fhft + row_idx + 8, tmp);
+	}
+
+	/* Enable filter. */
+	wufc |= IGC_WUFC_FLEX_HQ;
+	if (input->index > 8) {
+		/* Filter 0-7 are enabled via WUFC. The other 24 filters are not. */
+		u32 wufc_ext = rd32(IGC_WUFC_EXT);
+
+		wufc_ext |= (IGC_WUFC_EXT_FLX8 << (input->index - 8));
+
+		wr32(IGC_WUFC_EXT, wufc_ext);
+	} else {
+		wufc |= (IGC_WUFC_FLX0 << input->index);
+	}
+	wr32(IGC_WUFC, wufc);
+
+	dev_dbg(&adapter->pdev->dev, "Added flex filter %u to HW.\n",
+		input->index);
+
+	return 0;
+}
+
 static int igc_enable_nfc_rule(struct igc_adapter *adapter,
 			       const struct igc_nfc_rule *rule)
 {
diff --git a/drivers/net/ethernet/intel/igc/igc_regs.h b/drivers/net/ethernet/intel/igc/igc_regs.h
index 0f82990567d9..828c3501c448 100644
--- a/drivers/net/ethernet/intel/igc/igc_regs.h
+++ b/drivers/net/ethernet/intel/igc/igc_regs.h
@@ -67,6 +67,9 @@
 
 /* Filtering Registers */
 #define IGC_ETQF(_n)		(0x05CB0 + (4 * (_n))) /* EType Queue Fltr */
+#define IGC_FHFT(_n)		(0x09000 + (256 * (_n))) /* Flexible Host Filter */
+#define IGC_FHFT_EXT(_n)	(0x09A00 + (256 * (_n))) /* Flexible Host Filter Extended */
+#define IGC_FHFTSL		0x05804 /* Flex Filter indirect table select */
 
 /* ETQF register bit definitions */
 #define IGC_ETQF_FILTER_ENABLE	BIT(26)
@@ -75,6 +78,19 @@
 #define IGC_ETQF_QUEUE_MASK	0x00070000
 #define IGC_ETQF_ETYPE_MASK	0x0000FFFF
 
+/* FHFT register bit definitions */
+#define IGC_FHFT_LENGTH_MASK	GENMASK(7, 0)
+#define IGC_FHFT_QUEUE_SHIFT	8
+#define IGC_FHFT_QUEUE_MASK	GENMASK(10, 8)
+#define IGC_FHFT_PRIO_SHIFT	16
+#define IGC_FHFT_PRIO_MASK	GENMASK(18, 16)
+#define IGC_FHFT_IMM_INT	BIT(24)
+#define IGC_FHFT_DROP		BIT(25)
+
+/* FHFTSL register bit definitions */
+#define IGC_FHFTSL_FTSL_SHIFT	0
+#define IGC_FHFTSL_FTSL_MASK	GENMASK(1, 0)
+
 /* Redirection Table - RW Array */
 #define IGC_RETA(_i)		(0x05C00 + ((_i) * 4))
 /* RSS Random Key - RW Array */
@@ -240,6 +256,7 @@
 #define IGC_WUFC	0x05808  /* Wakeup Filter Control - RW */
 #define IGC_WUS		0x05810  /* Wakeup Status - R/W1C */
 #define IGC_WUPL	0x05900  /* Wakeup Packet Length - RW */
+#define IGC_WUFC_EXT	0x0580C  /* Wakeup Filter Control Register Extended - RW */
 
 /* Wake Up packet memory */
 #define IGC_WUPM_REG(_i)	(0x05A00 + ((_i) * 4))
-- 
2.32.0


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

* [Intel-wired-lan] [PATCH next-queue v1 2/5] igc: Integrate flex filter into ethtool ops
  2021-06-11  0:39 [Intel-wired-lan] [PATCH next-queue v1 0/5] igc: Add support for RX Flex Filters Vinicius Costa Gomes
  2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 1/5] igc: Add possibility to add flex filter Vinicius Costa Gomes
@ 2021-06-11  0:39 ` Vinicius Costa Gomes
  2021-06-21 12:31   ` Fuxbrumer, Dvora
  2021-06-22 21:39   ` Nguyen, Anthony L
  2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 3/5] igc: Allow for Flex Filters to be installed Vinicius Costa Gomes
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 15+ messages in thread
From: Vinicius Costa Gomes @ 2021-06-11  0:39 UTC (permalink / raw)
  To: intel-wired-lan

From: Kurt Kanzenbach <kurt@linutronix.de>

Use the flex filter mechanism to extend the current ethtool filter
operations by intercoperating the user data. This allows to match
eight more bytes within a Ethernet frame in addition to macs, ether
types and vlan.

The matching pattern looks like this:

 * dest_mac [6]
 * src_mac [6]
 * tpid [2]
 * vlan tci [2]
 * ether type [2]
 * user data [8]

This can be used to match Profinet traffic classes by FrameID range.

Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/net/ethernet/intel/igc/igc.h         |  24 ++-
 drivers/net/ethernet/intel/igc/igc_defines.h |   4 +
 drivers/net/ethernet/intel/igc/igc_ethtool.c |  20 ++
 drivers/net/ethernet/intel/igc/igc_main.c    | 192 ++++++++++++++++++-
 4 files changed, 230 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
index 6016c132d981..54a1779fa53a 100644
--- a/drivers/net/ethernet/intel/igc/igc.h
+++ b/drivers/net/ethernet/intel/igc/igc.h
@@ -478,18 +478,28 @@ struct igc_q_vector {
 };
 
 enum igc_filter_match_flags {
-	IGC_FILTER_FLAG_ETHER_TYPE =	0x1,
-	IGC_FILTER_FLAG_VLAN_TCI   =	0x2,
-	IGC_FILTER_FLAG_SRC_MAC_ADDR =	0x4,
-	IGC_FILTER_FLAG_DST_MAC_ADDR =	0x8,
+	IGC_FILTER_FLAG_ETHER_TYPE =	BIT(0),
+	IGC_FILTER_FLAG_VLAN_TCI   =	BIT(1),
+	IGC_FILTER_FLAG_SRC_MAC_ADDR =	BIT(2),
+	IGC_FILTER_FLAG_DST_MAC_ADDR =	BIT(3),
+	IGC_FILTER_FLAG_USER_DATA =	BIT(4),
+	IGC_FILTER_FLAG_VLAN_ETYPE =	BIT(5),
 };
 
 struct igc_nfc_filter {
 	u8 match_flags;
 	u16 etype;
+	u16 vlan_etype;
 	u16 vlan_tci;
 	u8 src_addr[ETH_ALEN];
 	u8 dst_addr[ETH_ALEN];
+	u8 user_data[8];
+	u8 user_mask[8];
+	u8 flex_index;
+	u8 rx_queue;
+	u8 prio;
+	u8 immediate_irq;
+	u8 drop;
 };
 
 struct igc_nfc_rule {
@@ -499,10 +509,10 @@ struct igc_nfc_rule {
 	u16 action;
 };
 
-/* IGC supports a total of 32 NFC rules: 16 MAC address based,, 8 VLAN priority
- * based, and 8 ethertype based.
+/* IGC supports a total of 32 NFC rules: 16 MAC address based, 8 VLAN priority
+ * based, 8 ethertype based and 32 Flex filter based rules.
  */
-#define IGC_MAX_RXNFC_RULES		32
+#define IGC_MAX_RXNFC_RULES		64
 
 struct igc_flex_filter {
 	u8 index;
diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h
index 0a29d9eca634..7bdd0b1abf20 100644
--- a/drivers/net/ethernet/intel/igc/igc_defines.h
+++ b/drivers/net/ethernet/intel/igc/igc_defines.h
@@ -32,6 +32,8 @@
 #define IGC_WUFC_FLX6		BIT(22)	   /* Flexible Filter 6 Enable */
 #define IGC_WUFC_FLX7		BIT(23)	   /* Flexible Filter 7 Enable */
 
+#define IGC_WUFC_FILTER_MASK GENMASK(23, 14)
+
 #define IGC_CTRL_ADVD3WUC	0x00100000  /* D3 WUC */
 
 /* Wake Up Status */
@@ -81,6 +83,8 @@
 #define IGC_WUFC_EXT_FLX30	BIT(30)	/* Flexible Filter 30 Enable */
 #define IGC_WUFC_EXT_FLX31	BIT(31)	/* Flexible Filter 31 Enable */
 
+#define IGC_WUFC_EXT_FILTER_MASK GENMASK(31, 8)
+
 /* Physical Func Reset Done Indication */
 #define IGC_CTRL_EXT_LINK_MODE_MASK	0x00C00000
 
diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c
index fa4171860623..3d46eff87638 100644
--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c
+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c
@@ -979,6 +979,12 @@ static int igc_ethtool_get_nfc_rule(struct igc_adapter *adapter,
 		eth_broadcast_addr(fsp->m_u.ether_spec.h_source);
 	}
 
+	if (rule->filter.match_flags & IGC_FILTER_FLAG_USER_DATA) {
+		fsp->flow_type |= FLOW_EXT;
+		memcpy(fsp->h_ext.data, rule->filter.user_data, sizeof(fsp->h_ext.data));
+		memcpy(fsp->m_ext.data, rule->filter.user_mask, sizeof(fsp->m_ext.data));
+	}
+
 	mutex_unlock(&adapter->nfc_rule_lock);
 	return 0;
 
@@ -1215,6 +1221,20 @@ static void igc_ethtool_init_nfc_rule(struct igc_nfc_rule *rule,
 		ether_addr_copy(rule->filter.dst_addr,
 				fsp->h_u.ether_spec.h_dest);
 	}
+
+	/* Check for user defined data */
+	if ((fsp->flow_type & FLOW_EXT) &&
+	    (fsp->h_ext.data[0] || fsp->h_ext.data[1])) {
+		rule->filter.match_flags |= IGC_FILTER_FLAG_USER_DATA;
+		memcpy(rule->filter.user_data, fsp->h_ext.data, sizeof(fsp->h_ext.data));
+		memcpy(rule->filter.user_mask, fsp->m_ext.data, sizeof(fsp->m_ext.data));
+
+		/* VLAN etype matching is only valid using flex filter */
+		if ((fsp->flow_type & FLOW_EXT) && fsp->h_ext.vlan_etype) {
+			rule->filter.vlan_etype = fsp->h_ext.vlan_etype;
+			rule->filter.match_flags |= IGC_FILTER_FLAG_VLAN_ETYPE;
+		}
+	}
 }
 
 /**
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index f1e128be475c..9abcecc57534 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -3120,8 +3120,8 @@ static int igc_flex_filter_select(struct igc_adapter *adapter,
 	return 0;
 }
 
-static int __maybe_unused igc_write_flex_filter_ll(struct igc_adapter *adapter,
-						   struct igc_flex_filter *input)
+static int igc_write_flex_filter_ll(struct igc_adapter *adapter,
+				    struct igc_flex_filter *input)
 {
 	struct device *dev = &adapter->pdev->dev;
 	struct igc_hw *hw = &adapter->hw;
@@ -3133,6 +3133,8 @@ static int __maybe_unused igc_write_flex_filter_ll(struct igc_adapter *adapter,
 	int ret;
 	int i;
 
+	netdev_dbg(adapter->netdev, "input->length %d\n", input->length);
+
 	/* Length has to be aligned to 8. Otherwise the filter will fail. Bail
 	 * out early to avoid surprises later.
 	 */
@@ -3213,11 +3215,192 @@ static int __maybe_unused igc_write_flex_filter_ll(struct igc_adapter *adapter,
 	return 0;
 }
 
+static void igc_flex_filter_add_field(struct igc_flex_filter *flex,
+				      const void *src, unsigned int offset,
+				      size_t len, const void *mask)
+{
+	int i;
+
+	/* data */
+	memcpy(&flex->data[offset], src, len);
+
+	/* mask */
+	for (i = 0; i < len; ++i) {
+		const unsigned int idx = i + offset;
+		const u8 *ptr = mask;
+
+		if (mask) {
+			if (ptr[i] & 0xff)
+				flex->mask[idx / 8] |= BIT(idx % 8);
+
+			continue;
+		}
+
+		flex->mask[idx / 8] |= BIT(idx % 8);
+	}
+}
+
+static int igc_find_avail_flex_filter_slot(struct igc_adapter *adapter)
+{
+	struct igc_hw *hw = &adapter->hw;
+	u32 wufc, wufc_ext;
+	int i;
+
+	wufc = rd32(IGC_WUFC);
+	wufc_ext = rd32(IGC_WUFC_EXT);
+
+	for (i = 0; i < MAX_FLEX_FILTER; i++) {
+		if (i < 8) {
+			if (!(wufc & (IGC_WUFC_FLX0 << i)))
+				return i;
+		} else {
+			if (!(wufc_ext & (IGC_WUFC_EXT_FLX8 << (i - 8))))
+				return i;
+		}
+	}
+
+	return -ENOSPC;
+}
+
+static bool igc_flex_filter_in_use(struct igc_adapter *adapter)
+{
+	struct igc_hw *hw = &adapter->hw;
+	u32 wufc, wufc_ext;
+
+	wufc = rd32(IGC_WUFC);
+	wufc_ext = rd32(IGC_WUFC_EXT);
+
+	if (wufc & IGC_WUFC_FILTER_MASK)
+		return true;
+
+	if (wufc_ext & IGC_WUFC_EXT_FILTER_MASK)
+		return true;
+
+	return false;
+}
+
+static int igc_add_flex_filter(struct igc_adapter *adapter,
+			       struct igc_nfc_rule *rule)
+{
+	struct igc_flex_filter flex = { };
+	struct igc_nfc_filter *filter = &rule->filter;
+	unsigned int eth_offset, user_offset;
+	int ret, index;
+	bool vlan;
+
+	index = igc_find_avail_flex_filter_slot(adapter);
+	if (index < 0)
+		return -ENOSPC;
+
+	/* Construct the flex filter:
+	 *  -> dest_mac [6]
+	 *  -> src_mac [6]
+	 *  -> tpid [2]
+	 *  -> vlan tci [2]
+	 *  -> ether type [2]
+	 *  -> user data [8]
+	 *  -> = 26 bytes => 32 length
+	 */
+	flex.index    = index;
+	flex.length   = 32;
+	flex.rx_queue = rule->action;
+
+	vlan = rule->filter.vlan_tci || rule->filter.vlan_etype;
+	eth_offset = vlan ? 16 : 12;
+	user_offset = vlan ? 18 : 14;
+
+	/* Add destination MAC  */
+	if (rule->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR)
+		igc_flex_filter_add_field(&flex, &filter->dst_addr, 0,
+					  ETH_ALEN, NULL);
+
+	/* Add source MAC */
+	if (rule->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR)
+		igc_flex_filter_add_field(&flex, &filter->src_addr, 6,
+					  ETH_ALEN, NULL);
+
+	/* Add VLAN etype */
+	if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_ETYPE)
+		igc_flex_filter_add_field(&flex, &filter->vlan_etype, 12,
+					  sizeof(filter->vlan_etype),
+					  NULL);
+
+	/* Add VLAN TCI */
+	if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI)
+		igc_flex_filter_add_field(&flex, &filter->vlan_tci, 14,
+					  sizeof(filter->vlan_tci), NULL);
+
+	/* Add Ether type */
+	if (rule->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) {
+		u16 etype = cpu_to_be16(filter->etype);
+
+		igc_flex_filter_add_field(&flex, &etype, eth_offset,
+					  sizeof(etype), NULL);
+	}
+
+	/* Add user data */
+	if (rule->filter.match_flags & IGC_FILTER_FLAG_USER_DATA)
+		igc_flex_filter_add_field(&flex, &filter->user_data,
+					  user_offset,
+					  sizeof(filter->user_data),
+					  filter->user_mask);
+
+	/* Add it down to the hardware and enable it. */
+	ret = igc_write_flex_filter_ll(adapter, &flex);
+	if (ret)
+		return ret;
+
+	filter->flex_index = index;
+
+	return 0;
+}
+
+static void igc_del_flex_filter(struct igc_adapter *adapter,
+				u16 reg_index)
+{
+	struct igc_hw *hw = &adapter->hw;
+	u32 wufc;
+
+	/* Just disable the filter. The filter table itself is kept
+	 * intact. Another flex_filter_add() should override the "old" data
+	 * then.
+	 */
+	if (reg_index > 8) {
+		u32 wufc_ext = rd32(IGC_WUFC_EXT);
+
+		wufc_ext &= ~(IGC_WUFC_EXT_FLX8 << (reg_index - 8));
+		wr32(IGC_WUFC_EXT, wufc_ext);
+	} else {
+		wufc = rd32(IGC_WUFC);
+
+		wufc &= ~(IGC_WUFC_FLX0 << reg_index);
+		wr32(IGC_WUFC, wufc);
+	}
+
+	if (igc_flex_filter_in_use(adapter))
+		return;
+
+	/* No filters are in use, we may disable flex filters */
+	wufc = rd32(IGC_WUFC);
+	wufc &= ~IGC_WUFC_FLEX_HQ;
+	wr32(IGC_WUFC, wufc);
+}
+
 static int igc_enable_nfc_rule(struct igc_adapter *adapter,
-			       const struct igc_nfc_rule *rule)
+			       struct igc_nfc_rule *rule)
 {
 	int err;
 
+	/* Check for user data first: When user data is set, the only option is
+	 * to use a flex filter. When more options are set (ethertype, vlan tci,
+	 * ...) construct a flex filter matching all of that.
+	 */
+	if (rule->filter.match_flags & IGC_FILTER_FLAG_USER_DATA) {
+		err = igc_add_flex_filter(adapter, rule);
+		if (err)
+			return err;
+	}
+
 	if (rule->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) {
 		err = igc_add_etype_filter(adapter, rule->filter.etype,
 					   rule->action);
@@ -3254,6 +3437,9 @@ static int igc_enable_nfc_rule(struct igc_adapter *adapter,
 static void igc_disable_nfc_rule(struct igc_adapter *adapter,
 				 const struct igc_nfc_rule *rule)
 {
+	if (rule->filter.match_flags & IGC_FILTER_FLAG_USER_DATA)
+		igc_del_flex_filter(adapter, rule->filter.flex_index);
+
 	if (rule->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE)
 		igc_del_etype_filter(adapter, rule->filter.etype);
 
-- 
2.32.0


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

* [Intel-wired-lan] [PATCH next-queue v1 3/5] igc: Allow for Flex Filters to be installed
  2021-06-11  0:39 [Intel-wired-lan] [PATCH next-queue v1 0/5] igc: Add support for RX Flex Filters Vinicius Costa Gomes
  2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 1/5] igc: Add possibility to add flex filter Vinicius Costa Gomes
  2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 2/5] igc: Integrate flex filter into ethtool ops Vinicius Costa Gomes
@ 2021-06-11  0:39 ` Vinicius Costa Gomes
  2021-06-21 12:32   ` Fuxbrumer, Dvora
  2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 4/5] igc: Make flex filter more flexible Vinicius Costa Gomes
  2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 5/5] igc: Export LEDs Vinicius Costa Gomes
  4 siblings, 1 reply; 15+ messages in thread
From: Vinicius Costa Gomes @ 2021-06-11  0:39 UTC (permalink / raw)
  To: intel-wired-lan

Allows Flex Filters to be installed.

The previous restriction to the types of filters that can be installed
can now be lifted.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
---
 drivers/net/ethernet/intel/igc/igc_ethtool.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c
index 3d46eff87638..5a7b27b2a95c 100644
--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c
+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c
@@ -1300,12 +1300,6 @@ static int igc_ethtool_add_nfc_rule(struct igc_adapter *adapter,
 		return -EOPNOTSUPP;
 	}
 
-	if ((fsp->flow_type & FLOW_EXT) &&
-	    fsp->m_ext.vlan_tci != htons(VLAN_PRIO_MASK)) {
-		netdev_dbg(netdev, "VLAN mask not supported\n");
-		return -EOPNOTSUPP;
-	}
-
 	if (fsp->ring_cookie >= adapter->num_rx_queues) {
 		netdev_dbg(netdev, "Invalid action\n");
 		return -EINVAL;
-- 
2.32.0


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

* [Intel-wired-lan] [PATCH next-queue v1 4/5] igc: Make flex filter more flexible
  2021-06-11  0:39 [Intel-wired-lan] [PATCH next-queue v1 0/5] igc: Add support for RX Flex Filters Vinicius Costa Gomes
                   ` (2 preceding siblings ...)
  2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 3/5] igc: Allow for Flex Filters to be installed Vinicius Costa Gomes
@ 2021-06-11  0:39 ` Vinicius Costa Gomes
  2021-06-21 12:33   ` Fuxbrumer, Dvora
  2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 5/5] igc: Export LEDs Vinicius Costa Gomes
  4 siblings, 1 reply; 15+ messages in thread
From: Vinicius Costa Gomes @ 2021-06-11  0:39 UTC (permalink / raw)
  To: intel-wired-lan

From: Kurt Kanzenbach <kurt@linutronix.de>

Currently flex filters are only used for filters containing user data.
However, it makes sense to utilize them also for filters having
multiple conditions, because that's not supported by the driver at the
moment. Add it.

Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
---
 drivers/net/ethernet/intel/igc/igc.h         |  1 +
 drivers/net/ethernet/intel/igc/igc_ethtool.c | 27 ++++++++++++--------
 drivers/net/ethernet/intel/igc/igc_main.c    | 14 ++++------
 3 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
index 54a1779fa53a..5710e5420b40 100644
--- a/drivers/net/ethernet/intel/igc/igc.h
+++ b/drivers/net/ethernet/intel/igc/igc.h
@@ -507,6 +507,7 @@ struct igc_nfc_rule {
 	struct igc_nfc_filter filter;
 	u32 location;
 	u16 action;
+	bool flex;
 };
 
 /* IGC supports a total of 32 NFC rules: 16 MAC address based, 8 VLAN priority
diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c
index 5a7b27b2a95c..d3e84416248e 100644
--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c
+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c
@@ -1222,19 +1222,29 @@ static void igc_ethtool_init_nfc_rule(struct igc_nfc_rule *rule,
 				fsp->h_u.ether_spec.h_dest);
 	}
 
+	/* VLAN etype matching */
+	if ((fsp->flow_type & FLOW_EXT) && fsp->h_ext.vlan_etype) {
+		rule->filter.vlan_etype = fsp->h_ext.vlan_etype;
+		rule->filter.match_flags |= IGC_FILTER_FLAG_VLAN_ETYPE;
+	}
+
 	/* Check for user defined data */
 	if ((fsp->flow_type & FLOW_EXT) &&
 	    (fsp->h_ext.data[0] || fsp->h_ext.data[1])) {
 		rule->filter.match_flags |= IGC_FILTER_FLAG_USER_DATA;
 		memcpy(rule->filter.user_data, fsp->h_ext.data, sizeof(fsp->h_ext.data));
 		memcpy(rule->filter.user_mask, fsp->m_ext.data, sizeof(fsp->m_ext.data));
-
-		/* VLAN etype matching is only valid using flex filter */
-		if ((fsp->flow_type & FLOW_EXT) && fsp->h_ext.vlan_etype) {
-			rule->filter.vlan_etype = fsp->h_ext.vlan_etype;
-			rule->filter.match_flags |= IGC_FILTER_FLAG_VLAN_ETYPE;
-		}
 	}
+
+	/* When multiple filter options or user data or vlan etype is set, use a
+	 * flex filter.
+	 */
+	if ((rule->filter.match_flags & IGC_FILTER_FLAG_USER_DATA) ||
+	    (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_ETYPE) ||
+	    (rule->filter.match_flags & (rule->filter.match_flags - 1)))
+		rule->flex = true;
+	else
+		rule->flex = false;
 }
 
 /**
@@ -1264,11 +1274,6 @@ static int igc_ethtool_check_nfc_rule(struct igc_adapter *adapter,
 		return -EINVAL;
 	}
 
-	if (flags & (flags - 1)) {
-		netdev_dbg(dev, "Rule with multiple matches not supported\n");
-		return -EOPNOTSUPP;
-	}
-
 	list_for_each_entry(tmp, &adapter->nfc_rule_list, list) {
 		if (!memcmp(&rule->filter, &tmp->filter,
 			    sizeof(rule->filter)) &&
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 9abcecc57534..ac558a6defe7 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -3391,14 +3391,8 @@ static int igc_enable_nfc_rule(struct igc_adapter *adapter,
 {
 	int err;
 
-	/* Check for user data first: When user data is set, the only option is
-	 * to use a flex filter. When more options are set (ethertype, vlan tci,
-	 * ...) construct a flex filter matching all of that.
-	 */
-	if (rule->filter.match_flags & IGC_FILTER_FLAG_USER_DATA) {
-		err = igc_add_flex_filter(adapter, rule);
-		if (err)
-			return err;
+	if (rule->flex) {
+		return igc_add_flex_filter(adapter, rule);
 	}
 
 	if (rule->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) {
@@ -3437,8 +3431,10 @@ static int igc_enable_nfc_rule(struct igc_adapter *adapter,
 static void igc_disable_nfc_rule(struct igc_adapter *adapter,
 				 const struct igc_nfc_rule *rule)
 {
-	if (rule->filter.match_flags & IGC_FILTER_FLAG_USER_DATA)
+	if (rule->flex) {
 		igc_del_flex_filter(adapter, rule->filter.flex_index);
+		return;
+	}
 
 	if (rule->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE)
 		igc_del_etype_filter(adapter, rule->filter.etype);
-- 
2.32.0


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

* [Intel-wired-lan] [PATCH next-queue v1 5/5] igc: Export LEDs
  2021-06-11  0:39 [Intel-wired-lan] [PATCH next-queue v1 0/5] igc: Add support for RX Flex Filters Vinicius Costa Gomes
                   ` (3 preceding siblings ...)
  2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 4/5] igc: Make flex filter more flexible Vinicius Costa Gomes
@ 2021-06-11  0:39 ` Vinicius Costa Gomes
  2021-06-11  5:55   ` Paul Menzel
  2021-06-21 12:33   ` Fuxbrumer, Dvora
  4 siblings, 2 replies; 15+ messages in thread
From: Vinicius Costa Gomes @ 2021-06-11  0:39 UTC (permalink / raw)
  To: intel-wired-lan

From: Kurt Kanzenbach <kurt@linutronix.de>

Each i225 has three LEDs. Export them via the LED class framework.

Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/net/ethernet/intel/Kconfig           |   1 +
 drivers/net/ethernet/intel/igc/igc.h         |  10 ++
 drivers/net/ethernet/intel/igc/igc_defines.h |  10 ++
 drivers/net/ethernet/intel/igc/igc_main.c    | 132 +++++++++++++++++++
 drivers/net/ethernet/intel/igc/igc_regs.h    |   2 +
 5 files changed, 155 insertions(+)

diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig
index 82744a7501c7..3639cf79cfae 100644
--- a/drivers/net/ethernet/intel/Kconfig
+++ b/drivers/net/ethernet/intel/Kconfig
@@ -335,6 +335,7 @@ config IGC
 	tristate "Intel(R) Ethernet Controller I225-LM/I225-V support"
 	default n
 	depends on PCI
+	depends on LEDS_CLASS
 	help
 	  This driver supports Intel(R) Ethernet Controller I225-LM/I225-V
 	  family of adapters.
diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
index 5710e5420b40..17b31072b291 100644
--- a/drivers/net/ethernet/intel/igc/igc.h
+++ b/drivers/net/ethernet/intel/igc/igc.h
@@ -13,6 +13,7 @@
 #include <linux/ptp_clock_kernel.h>
 #include <linux/timecounter.h>
 #include <linux/net_tstamp.h>
+#include <linux/leds.h>
 
 #include "igc_hw.h"
 
@@ -239,8 +240,17 @@ struct igc_adapter {
 		struct timespec64 start;
 		struct timespec64 period;
 	} perout[IGC_N_PEROUT];
+
+	/* LEDs */
+	struct mutex led_mutex;
+	struct led_classdev led0;
+	struct led_classdev led1;
+	struct led_classdev led2;
 };
 
+#define led_to_igc(ldev, led)                          \
+	container_of(ldev, struct igc_adapter, led)
+
 void igc_up(struct igc_adapter *adapter);
 void igc_down(struct igc_adapter *adapter);
 int igc_open(struct net_device *netdev);
diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h
index 7bdd0b1abf20..deb4819f1e27 100644
--- a/drivers/net/ethernet/intel/igc/igc_defines.h
+++ b/drivers/net/ethernet/intel/igc/igc_defines.h
@@ -144,6 +144,16 @@
 #define IGC_CTRL_SDP0_DIR	0x00400000  /* SDP0 Data direction */
 #define IGC_CTRL_SDP1_DIR	0x00800000  /* SDP1 Data direction */
 
+/* LED Control */
+#define IGC_LEDCTL_LED0_MODE_SHIFT	0
+#define IGC_LEDCTL_LED0_MODE_MASK	GENMASK(3, 0)
+#define IGC_LEDCTL_LED1_MODE_SHIFT	8
+#define IGC_LEDCTL_LED1_MODE_MASK	GENMASK(11, 8)
+#define IGC_LEDCTL_LED2_MODE_SHIFT	16
+#define IGC_LEDCTL_LED2_MODE_MASK	GENMASK(19, 16)
+
+#define IGC_CONNSW_AUTOSENSE_EN		0x1
+
 /* As per the EAS the maximum supported size is 9.5KB (9728 bytes) */
 #define MAX_JUMBO_FRAME_SIZE	0x2600
 
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index ac558a6defe7..e58f07bbf127 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -6138,6 +6138,134 @@ int igc_set_spd_dplx(struct igc_adapter *adapter, u32 spd, u8 dplx)
 	return -EINVAL;
 }
 
+static void igc_select_led(struct igc_adapter *adapter, int led,
+			   u32 *mask, u32 *shift)
+{
+	switch (led) {
+	case 0:
+		*mask  = IGC_LEDCTL_LED0_MODE_MASK;
+		*shift = IGC_LEDCTL_LED0_MODE_SHIFT;
+		break;
+	case 1:
+		*mask  = IGC_LEDCTL_LED1_MODE_MASK;
+		*shift = IGC_LEDCTL_LED1_MODE_SHIFT;
+		break;
+	case 2:
+		*mask  = IGC_LEDCTL_LED2_MODE_MASK;
+		*shift = IGC_LEDCTL_LED2_MODE_SHIFT;
+		break;
+	default:
+		*mask = *shift = 0;
+		dev_err(&adapter->pdev->dev, "Unknown led %d selected!", led);
+	}
+}
+
+static void igc_led_set(struct igc_adapter *adapter, int led, u16 brightness)
+{
+	struct igc_hw *hw = &adapter->hw;
+	u32 shift, mask, ledctl;
+
+	igc_select_led(adapter, led, &mask, &shift);
+
+	mutex_lock(&adapter->led_mutex);
+	ledctl = rd32(IGC_LEDCTL);
+	ledctl &= ~mask;
+	ledctl |= brightness << shift;
+	wr32(IGC_LEDCTL, ledctl);
+	mutex_unlock(&adapter->led_mutex);
+}
+
+static enum led_brightness igc_led_get(struct igc_adapter *adapter, int led)
+{
+	struct igc_hw *hw = &adapter->hw;
+	u32 shift, mask, ledctl;
+
+	igc_select_led(adapter, led, &mask, &shift);
+
+	mutex_lock(&adapter->led_mutex);
+	ledctl = rd32(IGC_LEDCTL);
+	mutex_unlock(&adapter->led_mutex);
+
+	return (ledctl & mask) >> shift;
+}
+
+static void igc_led0_set(struct led_classdev *ldev, enum led_brightness b)
+{
+	struct igc_adapter *adapter = led_to_igc(ldev, led0);
+
+	igc_led_set(adapter, 0, b);
+}
+
+static enum led_brightness igc_led0_get(struct led_classdev *ldev)
+{
+	struct igc_adapter *adapter = led_to_igc(ldev, led0);
+
+	return igc_led_get(adapter, 0);
+}
+
+static void igc_led1_set(struct led_classdev *ldev, enum led_brightness b)
+{
+	struct igc_adapter *adapter = led_to_igc(ldev, led1);
+
+	igc_led_set(adapter, 1, b);
+}
+
+static enum led_brightness igc_led1_get(struct led_classdev *ldev)
+{
+	struct igc_adapter *adapter = led_to_igc(ldev, led1);
+
+	return igc_led_get(adapter, 1);
+}
+
+static void igc_led2_set(struct led_classdev *ldev, enum led_brightness b)
+{
+	struct igc_adapter *adapter = led_to_igc(ldev, led2);
+
+	igc_led_set(adapter, 2, b);
+}
+
+static enum led_brightness igc_led2_get(struct led_classdev *ldev)
+{
+	struct igc_adapter *adapter = led_to_igc(ldev, led2);
+
+	return igc_led_get(adapter, 2);
+}
+
+static int igc_led_setup(struct igc_adapter *adapter)
+{
+	/* Setup */
+	mutex_init(&adapter->led_mutex);
+
+	adapter->led0.name	     = "igc_led0";
+	adapter->led0.max_brightness = 15;
+	adapter->led0.brightness_set = igc_led0_set;
+	adapter->led0.brightness_get = igc_led0_get;
+
+	adapter->led1.name	     = "igc_led1";
+	adapter->led1.max_brightness = 15;
+	adapter->led1.brightness_set = igc_led1_set;
+	adapter->led1.brightness_get = igc_led1_get;
+
+	adapter->led2.name	     = "igc_led2";
+	adapter->led2.max_brightness = 15;
+	adapter->led2.brightness_set = igc_led2_set;
+	adapter->led2.brightness_get = igc_led2_get;
+
+	/* Register leds */
+	led_classdev_register(&adapter->pdev->dev, &adapter->led0);
+	led_classdev_register(&adapter->pdev->dev, &adapter->led1);
+	led_classdev_register(&adapter->pdev->dev, &adapter->led2);
+
+	return 0;
+}
+
+static void igc_led_destroy(struct igc_adapter *adapter)
+{
+	led_classdev_unregister(&adapter->led0);
+	led_classdev_unregister(&adapter->led1);
+	led_classdev_unregister(&adapter->led2);
+}
+
 /**
  * igc_probe - Device Initialization Routine
  * @pdev: PCI device information struct
@@ -6366,6 +6494,8 @@ static int igc_probe(struct pci_dev *pdev,
 
 	pm_runtime_put_noidle(&pdev->dev);
 
+	igc_led_setup(adapter);
+
 	return 0;
 
 err_register:
@@ -6406,6 +6536,8 @@ static void igc_remove(struct pci_dev *pdev)
 
 	igc_ptp_stop(adapter);
 
+	igc_led_destroy(adapter);
+
 	set_bit(__IGC_DOWN, &adapter->state);
 
 	del_timer_sync(&adapter->watchdog_timer);
diff --git a/drivers/net/ethernet/intel/igc/igc_regs.h b/drivers/net/ethernet/intel/igc/igc_regs.h
index 828c3501c448..f6247b00c4e3 100644
--- a/drivers/net/ethernet/intel/igc/igc_regs.h
+++ b/drivers/net/ethernet/intel/igc/igc_regs.h
@@ -10,6 +10,8 @@
 #define IGC_EECD		0x00010  /* EEPROM/Flash Control - RW */
 #define IGC_CTRL_EXT		0x00018  /* Extended Device Control - RW */
 #define IGC_MDIC		0x00020  /* MDI Control - RW */
+#define IGC_LEDCTL		0x00E00	 /* LED Control - RW */
+#define IGC_MDICNFG		0x00E04  /* MDC/MDIO Configuration - RW */
 #define IGC_CONNSW		0x00034  /* Copper/Fiber switch control - RW */
 #define IGC_VET			0x00038  /* VLAN Ether Type - RW */
 #define IGC_I225_PHPM		0x00E14  /* I225 PHY Power Management */
-- 
2.32.0


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

* [Intel-wired-lan] [PATCH next-queue v1 5/5] igc: Export LEDs
  2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 5/5] igc: Export LEDs Vinicius Costa Gomes
@ 2021-06-11  5:55   ` Paul Menzel
  2021-06-11 11:01     ` Kurt Kanzenbach
  2021-06-21 12:33   ` Fuxbrumer, Dvora
  1 sibling, 1 reply; 15+ messages in thread
From: Paul Menzel @ 2021-06-11  5:55 UTC (permalink / raw)
  To: intel-wired-lan

Dear Vinicius, dear Kurt,


Am 11.06.21 um 02:39 schrieb Vinicius Costa Gomes:
> From: Kurt Kanzenbach <kurt@linutronix.de>
> 
> Each i225 has three LEDs. Export them via the LED class framework.

Very nice. For those not familiar with the LED class framework, could 
you add one example how to control one of the LEDs?

Also it?d be nice to document, how this was tested.


Kind regards,

Paul


> Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
>   drivers/net/ethernet/intel/Kconfig           |   1 +
>   drivers/net/ethernet/intel/igc/igc.h         |  10 ++
>   drivers/net/ethernet/intel/igc/igc_defines.h |  10 ++
>   drivers/net/ethernet/intel/igc/igc_main.c    | 132 +++++++++++++++++++
>   drivers/net/ethernet/intel/igc/igc_regs.h    |   2 +
>   5 files changed, 155 insertions(+)
> 
> diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig
> index 82744a7501c7..3639cf79cfae 100644
> --- a/drivers/net/ethernet/intel/Kconfig
> +++ b/drivers/net/ethernet/intel/Kconfig
> @@ -335,6 +335,7 @@ config IGC
>   	tristate "Intel(R) Ethernet Controller I225-LM/I225-V support"
>   	default n
>   	depends on PCI
> +	depends on LEDS_CLASS
>   	help
>   	  This driver supports Intel(R) Ethernet Controller I225-LM/I225-V
>   	  family of adapters.
> diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
> index 5710e5420b40..17b31072b291 100644
> --- a/drivers/net/ethernet/intel/igc/igc.h
> +++ b/drivers/net/ethernet/intel/igc/igc.h
> @@ -13,6 +13,7 @@
>   #include <linux/ptp_clock_kernel.h>
>   #include <linux/timecounter.h>
>   #include <linux/net_tstamp.h>
> +#include <linux/leds.h>
>   
>   #include "igc_hw.h"
>   
> @@ -239,8 +240,17 @@ struct igc_adapter {
>   		struct timespec64 start;
>   		struct timespec64 period;
>   	} perout[IGC_N_PEROUT];
> +
> +	/* LEDs */
> +	struct mutex led_mutex;
> +	struct led_classdev led0;
> +	struct led_classdev led1;
> +	struct led_classdev led2;
>   };
>   
> +#define led_to_igc(ldev, led)                          \
> +	container_of(ldev, struct igc_adapter, led)
> +
>   void igc_up(struct igc_adapter *adapter);
>   void igc_down(struct igc_adapter *adapter);
>   int igc_open(struct net_device *netdev);
> diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h
> index 7bdd0b1abf20..deb4819f1e27 100644
> --- a/drivers/net/ethernet/intel/igc/igc_defines.h
> +++ b/drivers/net/ethernet/intel/igc/igc_defines.h
> @@ -144,6 +144,16 @@
>   #define IGC_CTRL_SDP0_DIR	0x00400000  /* SDP0 Data direction */
>   #define IGC_CTRL_SDP1_DIR	0x00800000  /* SDP1 Data direction */
>   
> +/* LED Control */
> +#define IGC_LEDCTL_LED0_MODE_SHIFT	0
> +#define IGC_LEDCTL_LED0_MODE_MASK	GENMASK(3, 0)
> +#define IGC_LEDCTL_LED1_MODE_SHIFT	8
> +#define IGC_LEDCTL_LED1_MODE_MASK	GENMASK(11, 8)
> +#define IGC_LEDCTL_LED2_MODE_SHIFT	16
> +#define IGC_LEDCTL_LED2_MODE_MASK	GENMASK(19, 16)
> +
> +#define IGC_CONNSW_AUTOSENSE_EN		0x1
> +
>   /* As per the EAS the maximum supported size is 9.5KB (9728 bytes) */
>   #define MAX_JUMBO_FRAME_SIZE	0x2600
>   
> diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
> index ac558a6defe7..e58f07bbf127 100644
> --- a/drivers/net/ethernet/intel/igc/igc_main.c
> +++ b/drivers/net/ethernet/intel/igc/igc_main.c
> @@ -6138,6 +6138,134 @@ int igc_set_spd_dplx(struct igc_adapter *adapter, u32 spd, u8 dplx)
>   	return -EINVAL;
>   }
>   
> +static void igc_select_led(struct igc_adapter *adapter, int led,
> +			   u32 *mask, u32 *shift)
> +{
> +	switch (led) {
> +	case 0:
> +		*mask  = IGC_LEDCTL_LED0_MODE_MASK;
> +		*shift = IGC_LEDCTL_LED0_MODE_SHIFT;
> +		break;
> +	case 1:
> +		*mask  = IGC_LEDCTL_LED1_MODE_MASK;
> +		*shift = IGC_LEDCTL_LED1_MODE_SHIFT;
> +		break;
> +	case 2:
> +		*mask  = IGC_LEDCTL_LED2_MODE_MASK;
> +		*shift = IGC_LEDCTL_LED2_MODE_SHIFT;
> +		break;
> +	default:
> +		*mask = *shift = 0;
> +		dev_err(&adapter->pdev->dev, "Unknown led %d selected!", led);
> +	}
> +}
> +
> +static void igc_led_set(struct igc_adapter *adapter, int led, u16 brightness)
> +{
> +	struct igc_hw *hw = &adapter->hw;
> +	u32 shift, mask, ledctl;
> +
> +	igc_select_led(adapter, led, &mask, &shift);
> +
> +	mutex_lock(&adapter->led_mutex);
> +	ledctl = rd32(IGC_LEDCTL);
> +	ledctl &= ~mask;
> +	ledctl |= brightness << shift;
> +	wr32(IGC_LEDCTL, ledctl);
> +	mutex_unlock(&adapter->led_mutex);
> +}
> +
> +static enum led_brightness igc_led_get(struct igc_adapter *adapter, int led)
> +{
> +	struct igc_hw *hw = &adapter->hw;
> +	u32 shift, mask, ledctl;
> +
> +	igc_select_led(adapter, led, &mask, &shift);
> +
> +	mutex_lock(&adapter->led_mutex);
> +	ledctl = rd32(IGC_LEDCTL);
> +	mutex_unlock(&adapter->led_mutex);
> +
> +	return (ledctl & mask) >> shift;
> +}
> +
> +static void igc_led0_set(struct led_classdev *ldev, enum led_brightness b)
> +{
> +	struct igc_adapter *adapter = led_to_igc(ldev, led0);
> +
> +	igc_led_set(adapter, 0, b);
> +}
> +
> +static enum led_brightness igc_led0_get(struct led_classdev *ldev)
> +{
> +	struct igc_adapter *adapter = led_to_igc(ldev, led0);
> +
> +	return igc_led_get(adapter, 0);
> +}
> +
> +static void igc_led1_set(struct led_classdev *ldev, enum led_brightness b)
> +{
> +	struct igc_adapter *adapter = led_to_igc(ldev, led1);
> +
> +	igc_led_set(adapter, 1, b);
> +}
> +
> +static enum led_brightness igc_led1_get(struct led_classdev *ldev)
> +{
> +	struct igc_adapter *adapter = led_to_igc(ldev, led1);
> +
> +	return igc_led_get(adapter, 1);
> +}
> +
> +static void igc_led2_set(struct led_classdev *ldev, enum led_brightness b)
> +{
> +	struct igc_adapter *adapter = led_to_igc(ldev, led2);
> +
> +	igc_led_set(adapter, 2, b);
> +}
> +
> +static enum led_brightness igc_led2_get(struct led_classdev *ldev)
> +{
> +	struct igc_adapter *adapter = led_to_igc(ldev, led2);
> +
> +	return igc_led_get(adapter, 2);
> +}
> +
> +static int igc_led_setup(struct igc_adapter *adapter)
> +{
> +	/* Setup */
> +	mutex_init(&adapter->led_mutex);
> +
> +	adapter->led0.name	     = "igc_led0";
> +	adapter->led0.max_brightness = 15;
> +	adapter->led0.brightness_set = igc_led0_set;
> +	adapter->led0.brightness_get = igc_led0_get;
> +
> +	adapter->led1.name	     = "igc_led1";
> +	adapter->led1.max_brightness = 15;
> +	adapter->led1.brightness_set = igc_led1_set;
> +	adapter->led1.brightness_get = igc_led1_get;
> +
> +	adapter->led2.name	     = "igc_led2";
> +	adapter->led2.max_brightness = 15;
> +	adapter->led2.brightness_set = igc_led2_set;
> +	adapter->led2.brightness_get = igc_led2_get;
> +
> +	/* Register leds */
> +	led_classdev_register(&adapter->pdev->dev, &adapter->led0);
> +	led_classdev_register(&adapter->pdev->dev, &adapter->led1);
> +	led_classdev_register(&adapter->pdev->dev, &adapter->led2);
> +
> +	return 0;
> +}
> +
> +static void igc_led_destroy(struct igc_adapter *adapter)
> +{
> +	led_classdev_unregister(&adapter->led0);
> +	led_classdev_unregister(&adapter->led1);
> +	led_classdev_unregister(&adapter->led2);
> +}
> +
>   /**
>    * igc_probe - Device Initialization Routine
>    * @pdev: PCI device information struct
> @@ -6366,6 +6494,8 @@ static int igc_probe(struct pci_dev *pdev,
>   
>   	pm_runtime_put_noidle(&pdev->dev);
>   
> +	igc_led_setup(adapter);
> +
>   	return 0;
>   
>   err_register:
> @@ -6406,6 +6536,8 @@ static void igc_remove(struct pci_dev *pdev)
>   
>   	igc_ptp_stop(adapter);
>   
> +	igc_led_destroy(adapter);
> +
>   	set_bit(__IGC_DOWN, &adapter->state);
>   
>   	del_timer_sync(&adapter->watchdog_timer);
> diff --git a/drivers/net/ethernet/intel/igc/igc_regs.h b/drivers/net/ethernet/intel/igc/igc_regs.h
> index 828c3501c448..f6247b00c4e3 100644
> --- a/drivers/net/ethernet/intel/igc/igc_regs.h
> +++ b/drivers/net/ethernet/intel/igc/igc_regs.h
> @@ -10,6 +10,8 @@
>   #define IGC_EECD		0x00010  /* EEPROM/Flash Control - RW */
>   #define IGC_CTRL_EXT		0x00018  /* Extended Device Control - RW */
>   #define IGC_MDIC		0x00020  /* MDI Control - RW */
> +#define IGC_LEDCTL		0x00E00	 /* LED Control - RW */
> +#define IGC_MDICNFG		0x00E04  /* MDC/MDIO Configuration - RW */
>   #define IGC_CONNSW		0x00034  /* Copper/Fiber switch control - RW */
>   #define IGC_VET			0x00038  /* VLAN Ether Type - RW */
>   #define IGC_I225_PHPM		0x00E14  /* I225 PHY Power Management */
> 

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

* [Intel-wired-lan] [PATCH next-queue v1 5/5] igc: Export LEDs
  2021-06-11  5:55   ` Paul Menzel
@ 2021-06-11 11:01     ` Kurt Kanzenbach
  0 siblings, 0 replies; 15+ messages in thread
From: Kurt Kanzenbach @ 2021-06-11 11:01 UTC (permalink / raw)
  To: intel-wired-lan

On Fri Jun 11 2021, Paul Menzel wrote:
> Dear Vinicius, dear Kurt,
>
>
> Am 11.06.21 um 02:39 schrieb Vinicius Costa Gomes:
>> From: Kurt Kanzenbach <kurt@linutronix.de>
>> 
>> Each i225 has three LEDs. Export them via the LED class framework.
>
> Very nice. For those not familiar with the LED class framework, could 
> you add one example how to control one of the LEDs?
>
> Also it?d be nice to document, how this was tested.

Each LED is controllable via sysfs. Example:

 $ cd /sys/class/leds/igc_led0
 $ cat brightness      # Current Mode
 $ cat max_brightness  # 15
 $ echo 0 > brightness # Mode 0
 $ echo 1 > brightness # Mode 1

The brightness field here reflects the different LED modes ranging from
0 to 15.

Thanks,
Kurt
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 861 bytes
Desc: not available
URL: <http://lists.osuosl.org/pipermail/intel-wired-lan/attachments/20210611/62502b6e/attachment.asc>

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

* [Intel-wired-lan] [PATCH next-queue v1 1/5] igc: Add possibility to add flex filter
  2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 1/5] igc: Add possibility to add flex filter Vinicius Costa Gomes
@ 2021-06-21 12:31   ` Fuxbrumer, Dvora
  0 siblings, 0 replies; 15+ messages in thread
From: Fuxbrumer, Dvora @ 2021-06-21 12:31 UTC (permalink / raw)
  To: intel-wired-lan

On 6/11/2021 03:39, Vinicius Costa Gomes wrote:
> From: Kurt Kanzenbach <kurt@linutronix.de>
> 
> The Intel i225 NIC has the possibility to add flex filters which can
> match up to the first 128 byte of a packet. These filters are useful
> for all kind of packet matching. One particular use case is Profinet,
> as the different traffic classes are distinguished by the frame id
> range which cannot be matched by any other means.
> 
> Add code to configure and enable flex filters.
> 
> Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
> ---
>   drivers/net/ethernet/intel/igc/igc.h         |  13 ++
>   drivers/net/ethernet/intel/igc/igc_defines.h |  48 ++++++-
>   drivers/net/ethernet/intel/igc/igc_main.c    | 134 +++++++++++++++++++
>   drivers/net/ethernet/intel/igc/igc_regs.h    |  17 +++
>   4 files changed, 207 insertions(+), 5 deletions(-)
> 
Tested-by: Dvora Fuxbrumer <dvorax.fuxbrumer@linux.intel.com>

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

* [Intel-wired-lan] [PATCH next-queue v1 2/5] igc: Integrate flex filter into ethtool ops
  2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 2/5] igc: Integrate flex filter into ethtool ops Vinicius Costa Gomes
@ 2021-06-21 12:31   ` Fuxbrumer, Dvora
  2021-06-22 21:39   ` Nguyen, Anthony L
  1 sibling, 0 replies; 15+ messages in thread
From: Fuxbrumer, Dvora @ 2021-06-21 12:31 UTC (permalink / raw)
  To: intel-wired-lan

On 6/11/2021 03:39, Vinicius Costa Gomes wrote:
> From: Kurt Kanzenbach <kurt@linutronix.de>
> 
> Use the flex filter mechanism to extend the current ethtool filter
> operations by intercoperating the user data. This allows to match
> eight more bytes within a Ethernet frame in addition to macs, ether
> types and vlan.
> 
> The matching pattern looks like this:
> 
>   * dest_mac [6]
>   * src_mac [6]
>   * tpid [2]
>   * vlan tci [2]
>   * ether type [2]
>   * user data [8]
> 
> This can be used to match Profinet traffic classes by FrameID range.
> 
> Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
>   drivers/net/ethernet/intel/igc/igc.h         |  24 ++-
>   drivers/net/ethernet/intel/igc/igc_defines.h |   4 +
>   drivers/net/ethernet/intel/igc/igc_ethtool.c |  20 ++
>   drivers/net/ethernet/intel/igc/igc_main.c    | 192 ++++++++++++++++++-
>   4 files changed, 230 insertions(+), 10 deletions(-)
> 
Tested-by: Dvora Fuxbrumer <dvorax.fuxbrumer@linux.intel.com>

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

* [Intel-wired-lan] [PATCH next-queue v1 3/5] igc: Allow for Flex Filters to be installed
  2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 3/5] igc: Allow for Flex Filters to be installed Vinicius Costa Gomes
@ 2021-06-21 12:32   ` Fuxbrumer, Dvora
  0 siblings, 0 replies; 15+ messages in thread
From: Fuxbrumer, Dvora @ 2021-06-21 12:32 UTC (permalink / raw)
  To: intel-wired-lan

On 6/11/2021 03:39, Vinicius Costa Gomes wrote:
> Allows Flex Filters to be installed.
> 
> The previous restriction to the types of filters that can be installed
> can now be lifted.
> 
> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
> ---
>   drivers/net/ethernet/intel/igc/igc_ethtool.c | 6 ------
>   1 file changed, 6 deletions(-)
> 
Tested-by: Dvora Fuxbrumer <dvorax.fuxbrumer@linux.intel.com>

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

* [Intel-wired-lan] [PATCH next-queue v1 4/5] igc: Make flex filter more flexible
  2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 4/5] igc: Make flex filter more flexible Vinicius Costa Gomes
@ 2021-06-21 12:33   ` Fuxbrumer, Dvora
  0 siblings, 0 replies; 15+ messages in thread
From: Fuxbrumer, Dvora @ 2021-06-21 12:33 UTC (permalink / raw)
  To: intel-wired-lan

On 6/11/2021 03:39, Vinicius Costa Gomes wrote:
> From: Kurt Kanzenbach <kurt@linutronix.de>
> 
> Currently flex filters are only used for filters containing user data.
> However, it makes sense to utilize them also for filters having
> multiple conditions, because that's not supported by the driver at the
> moment. Add it.
> 
> Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
> ---
>   drivers/net/ethernet/intel/igc/igc.h         |  1 +
>   drivers/net/ethernet/intel/igc/igc_ethtool.c | 27 ++++++++++++--------
>   drivers/net/ethernet/intel/igc/igc_main.c    | 14 ++++------
>   3 files changed, 22 insertions(+), 20 deletions(-)
> 
Tested-by: Dvora Fuxbrumer <dvorax.fuxbrumer@linux.intel.com>

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

* [Intel-wired-lan] [PATCH next-queue v1 5/5] igc: Export LEDs
  2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 5/5] igc: Export LEDs Vinicius Costa Gomes
  2021-06-11  5:55   ` Paul Menzel
@ 2021-06-21 12:33   ` Fuxbrumer, Dvora
  1 sibling, 0 replies; 15+ messages in thread
From: Fuxbrumer, Dvora @ 2021-06-21 12:33 UTC (permalink / raw)
  To: intel-wired-lan

On 6/11/2021 03:39, Vinicius Costa Gomes wrote:
> From: Kurt Kanzenbach <kurt@linutronix.de>
> 
> Each i225 has three LEDs. Export them via the LED class framework.
> 
> Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
>   drivers/net/ethernet/intel/Kconfig           |   1 +
>   drivers/net/ethernet/intel/igc/igc.h         |  10 ++
>   drivers/net/ethernet/intel/igc/igc_defines.h |  10 ++
>   drivers/net/ethernet/intel/igc/igc_main.c    | 132 +++++++++++++++++++
>   drivers/net/ethernet/intel/igc/igc_regs.h    |   2 +
>   5 files changed, 155 insertions(+)
> 
Tested-by: Dvora Fuxbrumer <dvorax.fuxbrumer@linux.intel.com>

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

* [Intel-wired-lan] [PATCH next-queue v1 2/5] igc: Integrate flex filter into ethtool ops
  2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 2/5] igc: Integrate flex filter into ethtool ops Vinicius Costa Gomes
  2021-06-21 12:31   ` Fuxbrumer, Dvora
@ 2021-06-22 21:39   ` Nguyen, Anthony L
  2021-06-22 23:13     ` Vinicius Costa Gomes
  1 sibling, 1 reply; 15+ messages in thread
From: Nguyen, Anthony L @ 2021-06-22 21:39 UTC (permalink / raw)
  To: intel-wired-lan

On Thu, 2021-06-10 at 17:39 -0700, Vinicius Costa Gomes wrote:
> From: Kurt Kanzenbach <kurt@linutronix.de>
> 
> Use the flex filter mechanism to extend the current ethtool filter
> operations by intercoperating the user data. This allows to match
> eight more bytes within a Ethernet frame in addition to macs, ether
> types and vlan.
> 
> The matching pattern looks like this:
> 
>  * dest_mac [6]
>  * src_mac [6]
>  * tpid [2]
>  * vlan tci [2]
>  * ether type [2]
>  * user data [8]
> 
> This can be used to match Profinet traffic classes by FrameID range.
> 
> Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---

I was preparing these patches for a pull request and came across a
couple warnings. Could you address them before I send these on?

<snip>

> @@ -1215,6 +1221,20 @@ static void igc_ethtool_init_nfc_rule(struct
> igc_nfc_rule *rule,
>  		ether_addr_copy(rule->filter.dst_addr,
>  				fsp->h_u.ether_spec.h_dest);
>  	}
> +
> +	/* Check for user defined data */
> +	if ((fsp->flow_type & FLOW_EXT) &&
> +	    (fsp->h_ext.data[0] || fsp->h_ext.data[1])) {
> +		rule->filter.match_flags |= IGC_FILTER_FLAG_USER_DATA;
> +		memcpy(rule->filter.user_data, fsp->h_ext.data,
> sizeof(fsp->h_ext.data));
> +		memcpy(rule->filter.user_mask, fsp->m_ext.data,
> sizeof(fsp->m_ext.data));
> +
> +		/* VLAN etype matching is only valid using flex filter
> */
> +		if ((fsp->flow_type & FLOW_EXT) && fsp-
> >h_ext.vlan_etype) {
> +			rule->filter.vlan_etype = fsp-
> >h_ext.vlan_etype;
> +			rule->filter.match_flags |=
> IGC_FILTER_FLAG_VLAN_ETYPE;

drivers/net/ethernet/intel/igc/igc_ethtool.c:1234:49: warning:
incorrect type in assignment (different base types)
drivers/net/ethernet/intel/igc/igc_ethtool.c:1234:49:    expected
unsigned short [usertype] vlan_etype
drivers/net/ethernet/intel/igc/igc_ethtool.c:1234:49:    got restricted
__be16 const [usertype] vlan_etype

<snip>

> +static int igc_add_flex_filter(struct igc_adapter *adapter,
> +			       struct igc_nfc_rule *rule)
> +{
> +	struct igc_flex_filter flex = { };
> +	struct igc_nfc_filter *filter = &rule->filter;
> +	unsigned int eth_offset, user_offset;
> +	int ret, index;
> +	bool vlan;
> +
> +	index = igc_find_avail_flex_filter_slot(adapter);
> +	if (index < 0)
> +		return -ENOSPC;
> +
> +	/* Construct the flex filter:
> +	 *  -> dest_mac [6]
> +	 *  -> src_mac [6]
> +	 *  -> tpid [2]
> +	 *  -> vlan tci [2]
> +	 *  -> ether type [2]
> +	 *  -> user data [8]
> +	 *  -> = 26 bytes => 32 length
> +	 */
> +	flex.index    = index;
> +	flex.length   = 32;
> +	flex.rx_queue = rule->action;
> +
> +	vlan = rule->filter.vlan_tci || rule->filter.vlan_etype;
> +	eth_offset = vlan ? 16 : 12;
> +	user_offset = vlan ? 18 : 14;
> +
> +	/* Add destination MAC  */
> +	if (rule->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR)
> +		igc_flex_filter_add_field(&flex, &filter->dst_addr, 0,
> +					  ETH_ALEN, NULL);
> +
> +	/* Add source MAC */
> +	if (rule->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR)
> +		igc_flex_filter_add_field(&flex, &filter->src_addr, 6,
> +					  ETH_ALEN, NULL);
> +
> +	/* Add VLAN etype */
> +	if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_ETYPE)
> +		igc_flex_filter_add_field(&flex, &filter->vlan_etype,
> 12,
> +					  sizeof(filter->vlan_etype),
> +					  NULL);
> +
> +	/* Add VLAN TCI */
> +	if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI)
> +		igc_flex_filter_add_field(&flex, &filter->vlan_tci, 14,
> +					  sizeof(filter->vlan_tci),
> NULL);
> +
> +	/* Add Ether type */
> +	if (rule->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) {
> +		u16 etype = cpu_to_be16(filter->etype);

drivers/net/ethernet/intel/igc/igc_main.c:3332:29: warning: incorrect
type in initializer (different base types)
drivers/net/ethernet/intel/igc/igc_main.c:3332:29:    expected unsigned
short [usertype] etype
drivers/net/ethernet/intel/igc/igc_main.c:3332:29:    got restricted
__be16 [usertype]


> +		igc_flex_filter_add_field(&flex, &etype, eth_offset,
> +					  sizeof(etype), NULL);
> +	}
>  

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

* [Intel-wired-lan] [PATCH next-queue v1 2/5] igc: Integrate flex filter into ethtool ops
  2021-06-22 21:39   ` Nguyen, Anthony L
@ 2021-06-22 23:13     ` Vinicius Costa Gomes
  0 siblings, 0 replies; 15+ messages in thread
From: Vinicius Costa Gomes @ 2021-06-22 23:13 UTC (permalink / raw)
  To: intel-wired-lan

Hi Tony,

"Nguyen, Anthony L" <anthony.l.nguyen@intel.com> writes:

> On Thu, 2021-06-10 at 17:39 -0700, Vinicius Costa Gomes wrote:
>> From: Kurt Kanzenbach <kurt@linutronix.de>
>>
>> Use the flex filter mechanism to extend the current ethtool filter
>> operations by intercoperating the user data. This allows to match
>> eight more bytes within a Ethernet frame in addition to macs, ether
>> types and vlan.
>>
>> The matching pattern looks like this:
>>
>>  * dest_mac [6]
>>  * src_mac [6]
>>  * tpid [2]
>>  * vlan tci [2]
>>  * ether type [2]
>>  * user data [8]
>>
>> This can be used to match Profinet traffic classes by FrameID range.
>>
>> Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
>> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
>> ---
>
> I was preparing these patches for a pull request and came across a
> couple warnings. Could you address them before I send these on?

Sure thing. Sorry I missed those.

>
> <snip>
>
>> @@ -1215,6 +1221,20 @@ static void igc_ethtool_init_nfc_rule(struct
>> igc_nfc_rule *rule,
>>               ether_addr_copy(rule->filter.dst_addr,
>>                               fsp->h_u.ether_spec.h_dest);
>>       }
>> +
>> +     /* Check for user defined data */
>> +     if ((fsp->flow_type & FLOW_EXT) &&
>> +         (fsp->h_ext.data[0] || fsp->h_ext.data[1])) {
>> +             rule->filter.match_flags |= IGC_FILTER_FLAG_USER_DATA;
>> +             memcpy(rule->filter.user_data, fsp->h_ext.data,
>> sizeof(fsp->h_ext.data));
>> +             memcpy(rule->filter.user_mask, fsp->m_ext.data,
>> sizeof(fsp->m_ext.data));
>> +
>> +             /* VLAN etype matching is only valid using flex filter
>> */
>> +             if ((fsp->flow_type & FLOW_EXT) && fsp-
>> >h_ext.vlan_etype) {
>> +                     rule->filter.vlan_etype = fsp-
>> >h_ext.vlan_etype;
>> +                     rule->filter.match_flags |=
>> IGC_FILTER_FLAG_VLAN_ETYPE;
>
> drivers/net/ethernet/intel/igc/igc_ethtool.c:1234:49: warning:
> incorrect type in assignment (different base types)
> drivers/net/ethernet/intel/igc/igc_ethtool.c:1234:49:    expected
> unsigned short [usertype] vlan_etype
> drivers/net/ethernet/intel/igc/igc_ethtool.c:1234:49:    got restricted
> __be16 const [usertype] vlan_etype

Will fix.

>
> <snip>
>
>> +static int igc_add_flex_filter(struct igc_adapter *adapter,
>> +                            struct igc_nfc_rule *rule)
>> +{
>> +     struct igc_flex_filter flex = { };
>> +     struct igc_nfc_filter *filter = &rule->filter;
>> +     unsigned int eth_offset, user_offset;
>> +     int ret, index;
>> +     bool vlan;
>> +
>> +     index = igc_find_avail_flex_filter_slot(adapter);
>> +     if (index < 0)
>> +             return -ENOSPC;
>> +
>> +     /* Construct the flex filter:
>> +      *  -> dest_mac [6]
>> +      *  -> src_mac [6]
>> +      *  -> tpid [2]
>> +      *  -> vlan tci [2]
>> +      *  -> ether type [2]
>> +      *  -> user data [8]
>> +      *  -> = 26 bytes => 32 length
>> +      */
>> +     flex.index    = index;
>> +     flex.length   = 32;
>> +     flex.rx_queue = rule->action;
>> +
>> +     vlan = rule->filter.vlan_tci || rule->filter.vlan_etype;
>> +     eth_offset = vlan ? 16 : 12;
>> +     user_offset = vlan ? 18 : 14;
>> +
>> +     /* Add destination MAC  */
>> +     if (rule->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR)
>> +             igc_flex_filter_add_field(&flex, &filter->dst_addr, 0,
>> +                                       ETH_ALEN, NULL);
>> +
>> +     /* Add source MAC */
>> +     if (rule->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR)
>> +             igc_flex_filter_add_field(&flex, &filter->src_addr, 6,
>> +                                       ETH_ALEN, NULL);
>> +
>> +     /* Add VLAN etype */
>> +     if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_ETYPE)
>> +             igc_flex_filter_add_field(&flex, &filter->vlan_etype,
>> 12,
>> +                                       sizeof(filter->vlan_etype),
>> +                                       NULL);
>> +
>> +     /* Add VLAN TCI */
>> +     if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI)
>> +             igc_flex_filter_add_field(&flex, &filter->vlan_tci, 14,
>> +                                       sizeof(filter->vlan_tci),
>> NULL);
>> +
>> +     /* Add Ether type */
>> +     if (rule->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) {
>> +             u16 etype = cpu_to_be16(filter->etype);
>
> drivers/net/ethernet/intel/igc/igc_main.c:3332:29: warning: incorrect
> type in initializer (different base types)
> drivers/net/ethernet/intel/igc/igc_main.c:3332:29:    expected unsigned
> short [usertype] etype
> drivers/net/ethernet/intel/igc/igc_main.c:3332:29:    got restricted
> __be16 [usertype]

Will fix.

>
>
>> +             igc_flex_filter_add_field(&flex, &etype, eth_offset,
>> +                                       sizeof(etype), NULL);
>> +     }
>>


Cheers,
-- 
Vinicius

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

end of thread, other threads:[~2021-06-22 23:13 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-11  0:39 [Intel-wired-lan] [PATCH next-queue v1 0/5] igc: Add support for RX Flex Filters Vinicius Costa Gomes
2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 1/5] igc: Add possibility to add flex filter Vinicius Costa Gomes
2021-06-21 12:31   ` Fuxbrumer, Dvora
2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 2/5] igc: Integrate flex filter into ethtool ops Vinicius Costa Gomes
2021-06-21 12:31   ` Fuxbrumer, Dvora
2021-06-22 21:39   ` Nguyen, Anthony L
2021-06-22 23:13     ` Vinicius Costa Gomes
2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 3/5] igc: Allow for Flex Filters to be installed Vinicius Costa Gomes
2021-06-21 12:32   ` Fuxbrumer, Dvora
2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 4/5] igc: Make flex filter more flexible Vinicius Costa Gomes
2021-06-21 12:33   ` Fuxbrumer, Dvora
2021-06-11  0:39 ` [Intel-wired-lan] [PATCH next-queue v1 5/5] igc: Export LEDs Vinicius Costa Gomes
2021-06-11  5:55   ` Paul Menzel
2021-06-11 11:01     ` Kurt Kanzenbach
2021-06-21 12:33   ` Fuxbrumer, Dvora

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.