- * [PATCH net-next 01/12] dt-bindings: net: airoha: Add AN7583 support
  2025-10-15  7:15 [PATCH net-next 00/12] net: airoha: Add AN7583 ethernet controller support Lorenzo Bianconi
@ 2025-10-15  7:15 ` Lorenzo Bianconi
  2025-10-15  7:15 ` [PATCH net-next 02/12] net: airoha: ppe: Dynamically allocate foe_check_time array in airoha_ppe struct Lorenzo Bianconi
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Lorenzo Bianconi @ 2025-10-15  7:15 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Lorenzo Bianconi
  Cc: linux-arm-kernel, linux-mediatek, netdev, devicetree
Introduce AN7583 ethernet controller support to Airoha EN7581
device-tree bindings. The main difference between EN7581 and AN7583 is
the number of reset lines required by the controller (AN7583 does not
require hsi-mac).
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 .../devicetree/bindings/net/airoha,en7581-eth.yaml | 60 ++++++++++++++++++----
 1 file changed, 51 insertions(+), 9 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml b/Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
index 6d22131ac2f9e28390b9e785ce33e8d983eafd0f..7b258949a76d5c603a8e66e181895c4a4ae95db8 100644
--- a/Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
+++ b/Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
@@ -17,6 +17,7 @@ properties:
   compatible:
     enum:
       - airoha,en7581-eth
+      - airoha,an7583-eth
 
   reg:
     items:
@@ -44,18 +45,12 @@ properties:
       - description: PDMA irq
 
   resets:
+    minItems: 7
     maxItems: 8
 
   reset-names:
-    items:
-      - const: fe
-      - const: pdma
-      - const: qdma
-      - const: xsi-mac
-      - const: hsi0-mac
-      - const: hsi1-mac
-      - const: hsi-mac
-      - const: xfp-mac
+    minItems: 7
+    maxItems: 8
 
   memory-region:
     items:
@@ -81,6 +76,53 @@ properties:
       interface to implement hardware flow offloading programming Packet
       Processor Engine (PPE) flow table.
 
+allOf:
+  - $ref: ethernet-controller.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - airoha,en7581-eth
+    then:
+      properties:
+        resets:
+          minItems: 8
+          maxItems: 8
+
+        reset-names:
+          items:
+            - const: fe
+            - const: pdma
+            - const: qdma
+            - const: xsi-mac
+            - const: hsi0-mac
+            - const: hsi1-mac
+            - const: hsi-mac
+            - const: xfp-mac
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - airoha,an7583-eth
+    then:
+      properties:
+        resets:
+          minItems: 7
+          maxItems: 7
+
+        reset-names:
+          items:
+            - const: fe
+            - const: pdma
+            - const: qdma
+            - const: xsi-mac
+            - const: hsi0-mac
+            - const: hsi1-mac
+            - const: xfp-mac
+
 patternProperties:
   "^ethernet@[1-4]$":
     type: object
-- 
2.51.0
^ permalink raw reply related	[flat|nested] 27+ messages in thread
- * [PATCH net-next 02/12] net: airoha: ppe: Dynamically allocate foe_check_time array in airoha_ppe struct
  2025-10-15  7:15 [PATCH net-next 00/12] net: airoha: Add AN7583 ethernet controller support Lorenzo Bianconi
  2025-10-15  7:15 ` [PATCH net-next 01/12] dt-bindings: net: airoha: Add AN7583 support Lorenzo Bianconi
@ 2025-10-15  7:15 ` Lorenzo Bianconi
  2025-10-15 16:06   ` Simon Horman
  2025-10-15  7:15 ` [PATCH net-next 03/12] net: airoha: Add airoha_ppe_get_num_stats_entries() and airoha_ppe_get_num_total_stats_entries() Lorenzo Bianconi
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 27+ messages in thread
From: Lorenzo Bianconi @ 2025-10-15  7:15 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Lorenzo Bianconi
  Cc: linux-arm-kernel, linux-mediatek, netdev, devicetree
This is a preliminary patch to properly enable PPE support for AN7583
SoC.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/airoha/airoha_eth.h | 2 +-
 drivers/net/ethernet/airoha/airoha_ppe.c | 5 +++++
 2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index cd13c1c1224f64b63d455b24ce722c33c2fa7125..4330b672d99e1e190efa5ad75d13fb35e77d070e 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -554,7 +554,7 @@ struct airoha_ppe {
 	struct rhashtable l2_flows;
 
 	struct hlist_head *foe_flow;
-	u16 foe_check_time[PPE_NUM_ENTRIES];
+	u16 *foe_check_time;
 
 	struct airoha_foe_stats *foe_stats;
 	dma_addr_t foe_stats_dma;
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index 691361b254075555549ee80a4ed358c52e8e00b2..8d1dceadce0becb2b1ce656d64ab77bd3c2f914a 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -1440,6 +1440,11 @@ int airoha_ppe_init(struct airoha_eth *eth)
 			return -ENOMEM;
 	}
 
+	ppe->foe_check_time = devm_kzalloc(eth->dev, PPE_NUM_ENTRIES,
+					   GFP_KERNEL);
+	if (!ppe->foe_check_time)
+		return -ENOMEM;
+
 	err = rhashtable_init(ð->flow_table, &airoha_flow_table_params);
 	if (err)
 		return err;
-- 
2.51.0
^ permalink raw reply related	[flat|nested] 27+ messages in thread
- * Re: [PATCH net-next 02/12] net: airoha: ppe: Dynamically allocate foe_check_time array in airoha_ppe struct
  2025-10-15  7:15 ` [PATCH net-next 02/12] net: airoha: ppe: Dynamically allocate foe_check_time array in airoha_ppe struct Lorenzo Bianconi
@ 2025-10-15 16:06   ` Simon Horman
  0 siblings, 0 replies; 27+ messages in thread
From: Simon Horman @ 2025-10-15 16:06 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, linux-arm-kernel, linux-mediatek, netdev,
	devicetree
On Wed, Oct 15, 2025 at 09:15:02AM +0200, Lorenzo Bianconi wrote:
> This is a preliminary patch to properly enable PPE support for AN7583
> SoC.
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
^ permalink raw reply	[flat|nested] 27+ messages in thread 
 
- * [PATCH net-next 03/12] net: airoha: Add airoha_ppe_get_num_stats_entries() and airoha_ppe_get_num_total_stats_entries()
  2025-10-15  7:15 [PATCH net-next 00/12] net: airoha: Add AN7583 ethernet controller support Lorenzo Bianconi
  2025-10-15  7:15 ` [PATCH net-next 01/12] dt-bindings: net: airoha: Add AN7583 support Lorenzo Bianconi
  2025-10-15  7:15 ` [PATCH net-next 02/12] net: airoha: ppe: Dynamically allocate foe_check_time array in airoha_ppe struct Lorenzo Bianconi
@ 2025-10-15  7:15 ` Lorenzo Bianconi
  2025-10-15 12:52   ` Simon Horman
  2025-10-15  7:15 ` [PATCH net-next 04/12] net: airoha: Add airoha_eth_soc_data struct Lorenzo Bianconi
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 27+ messages in thread
From: Lorenzo Bianconi @ 2025-10-15  7:15 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Lorenzo Bianconi
  Cc: linux-arm-kernel, linux-mediatek, netdev, devicetree
Introduce airoha_ppe_get_num_stats_entries and
airoha_ppe_get_num_total_stats_entries routines in order to make the
code more readable controlling if CONFIG_NET_AIROHA_FLOW_STATS is
enabled or disabled.
Modify airoha_ppe_foe_get_flow_stats_index routine signature relying on
airoha_ppe_get_num_total_stats_entries().
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/airoha/airoha_eth.h |  10 +--
 drivers/net/ethernet/airoha/airoha_ppe.c | 103 +++++++++++++++++++++++++------
 2 files changed, 86 insertions(+), 27 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index 4330b672d99e1e190efa5ad75d13fb35e77d070e..1f7e34a5f457ca2200e9c81dd05dc03cd7c5eb77 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -50,15 +50,9 @@
 
 #define PPE_NUM				2
 #define PPE1_SRAM_NUM_ENTRIES		(8 * 1024)
-#define PPE_SRAM_NUM_ENTRIES		(2 * PPE1_SRAM_NUM_ENTRIES)
-#ifdef CONFIG_NET_AIROHA_FLOW_STATS
+#define PPE_SRAM_NUM_ENTRIES		(PPE_NUM * PPE1_SRAM_NUM_ENTRIES)
 #define PPE1_STATS_NUM_ENTRIES		(4 * 1024)
-#else
-#define PPE1_STATS_NUM_ENTRIES		0
-#endif /* CONFIG_NET_AIROHA_FLOW_STATS */
-#define PPE_STATS_NUM_ENTRIES		(2 * PPE1_STATS_NUM_ENTRIES)
-#define PPE1_SRAM_NUM_DATA_ENTRIES	(PPE1_SRAM_NUM_ENTRIES - PPE1_STATS_NUM_ENTRIES)
-#define PPE_SRAM_NUM_DATA_ENTRIES	(2 * PPE1_SRAM_NUM_DATA_ENTRIES)
+#define PPE_STATS_NUM_ENTRIES		(PPE_NUM * PPE1_STATS_NUM_ENTRIES)
 #define PPE_DRAM_NUM_ENTRIES		(16 * 1024)
 #define PPE_NUM_ENTRIES			(PPE_SRAM_NUM_ENTRIES + PPE_DRAM_NUM_ENTRIES)
 #define PPE_HASH_MASK			(PPE_NUM_ENTRIES - 1)
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index 8d1dceadce0becb2b1ce656d64ab77bd3c2f914a..303d31e1da4b723023ee0cc1ca5f6038c16966cd 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -32,6 +32,30 @@ static const struct rhashtable_params airoha_l2_flow_table_params = {
 	.automatic_shrinking = true,
 };
 
+static int airoha_ppe_get_num_stats_entries(struct airoha_ppe *ppe,
+					    u32 *num_stats)
+{
+#ifdef CONFIG_NET_AIROHA_FLOW_STATS
+	*num_stats = PPE1_STATS_NUM_ENTRIES;
+	return 0;
+#else
+	return -EOPNOTSUPP;
+#endif /* CONFIG_NET_AIROHA_FLOW_STATS */
+}
+
+static int airoha_ppe_get_total_num_stats_entries(struct airoha_ppe *ppe,
+						  u32 *num_stats)
+{
+	int err;
+
+	err = airoha_ppe_get_num_stats_entries(ppe, num_stats);
+	if (err)
+		return err;
+
+	*num_stats = *num_stats * PPE_NUM;
+	return 0;
+}
+
 static bool airoha_ppe2_is_enabled(struct airoha_eth *eth)
 {
 	return airoha_fe_rr(eth, REG_PPE_GLO_CFG(1)) & PPE_GLO_CFG_EN_MASK;
@@ -48,6 +72,7 @@ static void airoha_ppe_hw_init(struct airoha_ppe *ppe)
 {
 	u32 sram_tb_size, sram_num_entries, dram_num_entries;
 	struct airoha_eth *eth = ppe->eth;
+	u32 sram_num_stats_entries;
 	int i;
 
 	sram_tb_size = PPE_SRAM_NUM_ENTRIES * sizeof(struct airoha_foe_entry);
@@ -103,8 +128,12 @@ static void airoha_ppe_hw_init(struct airoha_ppe *ppe)
 	}
 
 	if (airoha_ppe2_is_enabled(eth)) {
-		sram_num_entries =
-			PPE_RAM_NUM_ENTRIES_SHIFT(PPE1_SRAM_NUM_DATA_ENTRIES);
+		sram_num_entries = PPE1_SRAM_NUM_ENTRIES;
+		if (!airoha_ppe_get_num_stats_entries(ppe,
+						      &sram_num_stats_entries))
+			sram_num_entries -= sram_num_stats_entries;
+		sram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(sram_num_entries);
+
 		airoha_fe_rmw(eth, REG_PPE_TB_CFG(0),
 			      PPE_SRAM_TB_NUM_ENTRY_MASK |
 			      PPE_DRAM_TB_NUM_ENTRY_MASK,
@@ -120,8 +149,12 @@ static void airoha_ppe_hw_init(struct airoha_ppe *ppe)
 			      FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK,
 					 dram_num_entries));
 	} else {
-		sram_num_entries =
-			PPE_RAM_NUM_ENTRIES_SHIFT(PPE_SRAM_NUM_DATA_ENTRIES);
+		sram_num_entries = PPE_SRAM_NUM_ENTRIES;
+		if (!airoha_ppe_get_total_num_stats_entries(ppe,
+							    &sram_num_stats_entries))
+			sram_num_entries -= sram_num_stats_entries;
+		sram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(sram_num_entries);
+
 		airoha_fe_rmw(eth, REG_PPE_TB_CFG(0),
 			      PPE_SRAM_TB_NUM_ENTRY_MASK |
 			      PPE_DRAM_TB_NUM_ENTRY_MASK,
@@ -480,13 +513,23 @@ static u32 airoha_ppe_foe_get_entry_hash(struct airoha_foe_entry *hwe)
 	return hash;
 }
 
-static u32 airoha_ppe_foe_get_flow_stats_index(struct airoha_ppe *ppe, u32 hash)
+static int airoha_ppe_foe_get_flow_stats_index(struct airoha_ppe *ppe,
+					       u32 hash, u32 *index)
 {
-	if (!airoha_ppe2_is_enabled(ppe->eth))
-		return hash;
+	u32 ppe_num_stats_entries;
+	int err;
+
+	err = airoha_ppe_get_total_num_stats_entries(ppe,
+						     &ppe_num_stats_entries);
+	if (err)
+		return err;
 
-	return hash >= PPE_STATS_NUM_ENTRIES ? hash - PPE1_STATS_NUM_ENTRIES
-					     : hash;
+	*index = hash;
+	if (airoha_ppe2_is_enabled(ppe->eth) &&
+	    hash >= ppe_num_stats_entries)
+		*index = *index - PPE_STATS_NUM_ENTRIES;
+
+	return 0;
 }
 
 static void airoha_ppe_foe_flow_stat_entry_reset(struct airoha_ppe *ppe,
@@ -500,9 +543,14 @@ static void airoha_ppe_foe_flow_stat_entry_reset(struct airoha_ppe *ppe,
 static void airoha_ppe_foe_flow_stats_reset(struct airoha_ppe *ppe,
 					    struct airoha_npu *npu)
 {
+	u32 ppe_num_stats_entries;
 	int i;
 
-	for (i = 0; i < PPE_STATS_NUM_ENTRIES; i++)
+	if (airoha_ppe_get_total_num_stats_entries(ppe,
+						   &ppe_num_stats_entries))
+		return;
+
+	for (i = 0; i < ppe_num_stats_entries; i++)
 		airoha_ppe_foe_flow_stat_entry_reset(ppe, npu, i);
 }
 
@@ -511,12 +559,18 @@ static void airoha_ppe_foe_flow_stats_update(struct airoha_ppe *ppe,
 					     struct airoha_foe_entry *hwe,
 					     u32 hash)
 {
+	u32 ppe_num_stats_entries, index, pse_port, val, *data, *ib2, *meter;
 	int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1);
-	u32 index, pse_port, val, *data, *ib2, *meter;
 	u8 nbq;
 
-	index = airoha_ppe_foe_get_flow_stats_index(ppe, hash);
-	if (index >= PPE_STATS_NUM_ENTRIES)
+	if (airoha_ppe_get_total_num_stats_entries(ppe,
+						   &ppe_num_stats_entries))
+		return;
+
+	if (airoha_ppe_foe_get_flow_stats_index(ppe, hash, &index))
+		return;
+
+	if (index >= ppe_num_stats_entries)
 		return;
 
 	if (type == PPE_PKT_TYPE_BRIDGE) {
@@ -1158,11 +1212,18 @@ static int airoha_ppe_flow_offload_destroy(struct airoha_eth *eth,
 void airoha_ppe_foe_entry_get_stats(struct airoha_ppe *ppe, u32 hash,
 				    struct airoha_foe_stats64 *stats)
 {
-	u32 index = airoha_ppe_foe_get_flow_stats_index(ppe, hash);
 	struct airoha_eth *eth = ppe->eth;
+	u32 index, ppe_num_stats_entries;
 	struct airoha_npu *npu;
 
-	if (index >= PPE_STATS_NUM_ENTRIES)
+	if (airoha_ppe_get_total_num_stats_entries(ppe,
+						   &ppe_num_stats_entries))
+		return;
+
+	if (airoha_ppe_foe_get_flow_stats_index(ppe, hash, &index))
+		return;
+
+	if (index >= ppe_num_stats_entries)
 		return;
 
 	rcu_read_lock();
@@ -1257,6 +1318,7 @@ static int airoha_ppe_offload_setup(struct airoha_eth *eth)
 {
 	struct airoha_npu *npu = airoha_ppe_npu_get(eth);
 	struct airoha_ppe *ppe = eth->ppe;
+	u32 ppe_num_stats_entries;
 	int err;
 
 	if (IS_ERR(npu))
@@ -1266,9 +1328,10 @@ static int airoha_ppe_offload_setup(struct airoha_eth *eth)
 	if (err)
 		goto error_npu_put;
 
-	if (PPE_STATS_NUM_ENTRIES) {
+	if (!airoha_ppe_get_total_num_stats_entries(ppe,
+						    &ppe_num_stats_entries)) {
 		err = npu->ops.ppe_init_stats(npu, ppe->foe_stats_dma,
-					      PPE_STATS_NUM_ENTRIES);
+					      ppe_num_stats_entries);
 		if (err)
 			goto error_npu_put;
 	}
@@ -1405,6 +1468,7 @@ EXPORT_SYMBOL_GPL(airoha_ppe_put_dev);
 
 int airoha_ppe_init(struct airoha_eth *eth)
 {
+	u32 ppe_num_stats_entries;
 	struct airoha_ppe *ppe;
 	int foe_size, err;
 
@@ -1431,8 +1495,9 @@ int airoha_ppe_init(struct airoha_eth *eth)
 	if (!ppe->foe_flow)
 		return -ENOMEM;
 
-	foe_size = PPE_STATS_NUM_ENTRIES * sizeof(*ppe->foe_stats);
-	if (foe_size) {
+	if (!airoha_ppe_get_total_num_stats_entries(ppe,
+						    &ppe_num_stats_entries)) {
+		foe_size = ppe_num_stats_entries * sizeof(*ppe->foe_stats);
 		ppe->foe_stats = dmam_alloc_coherent(eth->dev, foe_size,
 						     &ppe->foe_stats_dma,
 						     GFP_KERNEL);
-- 
2.51.0
^ permalink raw reply related	[flat|nested] 27+ messages in thread
- * Re: [PATCH net-next 03/12] net: airoha: Add airoha_ppe_get_num_stats_entries() and airoha_ppe_get_num_total_stats_entries()
  2025-10-15  7:15 ` [PATCH net-next 03/12] net: airoha: Add airoha_ppe_get_num_stats_entries() and airoha_ppe_get_num_total_stats_entries() Lorenzo Bianconi
@ 2025-10-15 12:52   ` Simon Horman
  2025-10-16  8:10     ` Lorenzo Bianconi
  0 siblings, 1 reply; 27+ messages in thread
From: Simon Horman @ 2025-10-15 12:52 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, linux-arm-kernel, linux-mediatek, netdev,
	devicetree
On Wed, Oct 15, 2025 at 09:15:03AM +0200, Lorenzo Bianconi wrote:
> Introduce airoha_ppe_get_num_stats_entries and
> airoha_ppe_get_num_total_stats_entries routines in order to make the
> code more readable controlling if CONFIG_NET_AIROHA_FLOW_STATS is
> enabled or disabled.
> Modify airoha_ppe_foe_get_flow_stats_index routine signature relying on
> airoha_ppe_get_num_total_stats_entries().
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
>  drivers/net/ethernet/airoha/airoha_eth.h |  10 +--
>  drivers/net/ethernet/airoha/airoha_ppe.c | 103 +++++++++++++++++++++++++------
>  2 files changed, 86 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
> index 4330b672d99e1e190efa5ad75d13fb35e77d070e..1f7e34a5f457ca2200e9c81dd05dc03cd7c5eb77 100644
> --- a/drivers/net/ethernet/airoha/airoha_eth.h
> +++ b/drivers/net/ethernet/airoha/airoha_eth.h
> @@ -50,15 +50,9 @@
>  
>  #define PPE_NUM				2
>  #define PPE1_SRAM_NUM_ENTRIES		(8 * 1024)
> -#define PPE_SRAM_NUM_ENTRIES		(2 * PPE1_SRAM_NUM_ENTRIES)
> -#ifdef CONFIG_NET_AIROHA_FLOW_STATS
> +#define PPE_SRAM_NUM_ENTRIES		(PPE_NUM * PPE1_SRAM_NUM_ENTRIES)
>  #define PPE1_STATS_NUM_ENTRIES		(4 * 1024)
> -#else
> -#define PPE1_STATS_NUM_ENTRIES		0
> -#endif /* CONFIG_NET_AIROHA_FLOW_STATS */
> -#define PPE_STATS_NUM_ENTRIES		(2 * PPE1_STATS_NUM_ENTRIES)
> -#define PPE1_SRAM_NUM_DATA_ENTRIES	(PPE1_SRAM_NUM_ENTRIES - PPE1_STATS_NUM_ENTRIES)
> -#define PPE_SRAM_NUM_DATA_ENTRIES	(2 * PPE1_SRAM_NUM_DATA_ENTRIES)
> +#define PPE_STATS_NUM_ENTRIES		(PPE_NUM * PPE1_STATS_NUM_ENTRIES)
>  #define PPE_DRAM_NUM_ENTRIES		(16 * 1024)
>  #define PPE_NUM_ENTRIES			(PPE_SRAM_NUM_ENTRIES + PPE_DRAM_NUM_ENTRIES)
>  #define PPE_HASH_MASK			(PPE_NUM_ENTRIES - 1)
> diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
> index 8d1dceadce0becb2b1ce656d64ab77bd3c2f914a..303d31e1da4b723023ee0cc1ca5f6038c16966cd 100644
> --- a/drivers/net/ethernet/airoha/airoha_ppe.c
> +++ b/drivers/net/ethernet/airoha/airoha_ppe.c
> @@ -32,6 +32,30 @@ static const struct rhashtable_params airoha_l2_flow_table_params = {
>  	.automatic_shrinking = true,
>  };
>  
> +static int airoha_ppe_get_num_stats_entries(struct airoha_ppe *ppe,
> +					    u32 *num_stats)
> +{
> +#ifdef CONFIG_NET_AIROHA_FLOW_STATS
> +	*num_stats = PPE1_STATS_NUM_ENTRIES;
> +	return 0;
> +#else
> +	return -EOPNOTSUPP;
> +#endif /* CONFIG_NET_AIROHA_FLOW_STATS */
> +}
Hi Lorenzo,
I think that in general using IS_ENABLED is preferred over #ifdef
in cases where the former can be used. For one thing it improves compile
coverage.
That does seem applicable here, so I'm wondering if
we can do something like the following.
(Compile tested only!)
static int airoha_ppe_get_num_stats_entries(struct airoha_ppe *ppe,
                                            u32 *num_stats)
{
        if (!IS_ENABLED(CONFIG_NET_AIROHA_FLOW_STATS))
                return -EOPNOTSUPP;
        *num_stats = PPE1_STATS_NUM_ENTRIES;
        return 0;
}
Also, very subjectively, I might have returned num_stats as
a positive return value. I'm assuming it's value will never overflow an int.
Likewise elsewhere.
But that's just my idea. Feel free to stick with the current scheme.
...
^ permalink raw reply	[flat|nested] 27+ messages in thread
- * Re: [PATCH net-next 03/12] net: airoha: Add airoha_ppe_get_num_stats_entries() and airoha_ppe_get_num_total_stats_entries()
  2025-10-15 12:52   ` Simon Horman
@ 2025-10-16  8:10     ` Lorenzo Bianconi
  0 siblings, 0 replies; 27+ messages in thread
From: Lorenzo Bianconi @ 2025-10-16  8:10 UTC (permalink / raw)
  To: Simon Horman
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, linux-arm-kernel, linux-mediatek, netdev,
	devicetree
[-- Attachment #1: Type: text/plain, Size: 3678 bytes --]
> On Wed, Oct 15, 2025 at 09:15:03AM +0200, Lorenzo Bianconi wrote:
> > Introduce airoha_ppe_get_num_stats_entries and
> > airoha_ppe_get_num_total_stats_entries routines in order to make the
> > code more readable controlling if CONFIG_NET_AIROHA_FLOW_STATS is
> > enabled or disabled.
> > Modify airoha_ppe_foe_get_flow_stats_index routine signature relying on
> > airoha_ppe_get_num_total_stats_entries().
> > 
> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > ---
> >  drivers/net/ethernet/airoha/airoha_eth.h |  10 +--
> >  drivers/net/ethernet/airoha/airoha_ppe.c | 103 +++++++++++++++++++++++++------
> >  2 files changed, 86 insertions(+), 27 deletions(-)
> > 
> > diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
> > index 4330b672d99e1e190efa5ad75d13fb35e77d070e..1f7e34a5f457ca2200e9c81dd05dc03cd7c5eb77 100644
> > --- a/drivers/net/ethernet/airoha/airoha_eth.h
> > +++ b/drivers/net/ethernet/airoha/airoha_eth.h
> > @@ -50,15 +50,9 @@
> >  
> >  #define PPE_NUM				2
> >  #define PPE1_SRAM_NUM_ENTRIES		(8 * 1024)
> > -#define PPE_SRAM_NUM_ENTRIES		(2 * PPE1_SRAM_NUM_ENTRIES)
> > -#ifdef CONFIG_NET_AIROHA_FLOW_STATS
> > +#define PPE_SRAM_NUM_ENTRIES		(PPE_NUM * PPE1_SRAM_NUM_ENTRIES)
> >  #define PPE1_STATS_NUM_ENTRIES		(4 * 1024)
> > -#else
> > -#define PPE1_STATS_NUM_ENTRIES		0
> > -#endif /* CONFIG_NET_AIROHA_FLOW_STATS */
> > -#define PPE_STATS_NUM_ENTRIES		(2 * PPE1_STATS_NUM_ENTRIES)
> > -#define PPE1_SRAM_NUM_DATA_ENTRIES	(PPE1_SRAM_NUM_ENTRIES - PPE1_STATS_NUM_ENTRIES)
> > -#define PPE_SRAM_NUM_DATA_ENTRIES	(2 * PPE1_SRAM_NUM_DATA_ENTRIES)
> > +#define PPE_STATS_NUM_ENTRIES		(PPE_NUM * PPE1_STATS_NUM_ENTRIES)
> >  #define PPE_DRAM_NUM_ENTRIES		(16 * 1024)
> >  #define PPE_NUM_ENTRIES			(PPE_SRAM_NUM_ENTRIES + PPE_DRAM_NUM_ENTRIES)
> >  #define PPE_HASH_MASK			(PPE_NUM_ENTRIES - 1)
> > diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
> > index 8d1dceadce0becb2b1ce656d64ab77bd3c2f914a..303d31e1da4b723023ee0cc1ca5f6038c16966cd 100644
> > --- a/drivers/net/ethernet/airoha/airoha_ppe.c
> > +++ b/drivers/net/ethernet/airoha/airoha_ppe.c
> > @@ -32,6 +32,30 @@ static const struct rhashtable_params airoha_l2_flow_table_params = {
> >  	.automatic_shrinking = true,
> >  };
> >  
> > +static int airoha_ppe_get_num_stats_entries(struct airoha_ppe *ppe,
> > +					    u32 *num_stats)
> > +{
> > +#ifdef CONFIG_NET_AIROHA_FLOW_STATS
> > +	*num_stats = PPE1_STATS_NUM_ENTRIES;
> > +	return 0;
> > +#else
> > +	return -EOPNOTSUPP;
> > +#endif /* CONFIG_NET_AIROHA_FLOW_STATS */
> > +}
> 
> Hi Lorenzo,
Hi Simon,
> 
> I think that in general using IS_ENABLED is preferred over #ifdef
> in cases where the former can be used. For one thing it improves compile
> coverage.
> 
> That does seem applicable here, so I'm wondering if
> we can do something like the following.
> (Compile tested only!)
> 
> static int airoha_ppe_get_num_stats_entries(struct airoha_ppe *ppe,
>                                             u32 *num_stats)
> {
>         if (!IS_ENABLED(CONFIG_NET_AIROHA_FLOW_STATS))
>                 return -EOPNOTSUPP;
> 
>         *num_stats = PPE1_STATS_NUM_ENTRIES;
>         return 0;
> }
ack, fine. I will fix it in v2.
> 
> Also, very subjectively, I might have returned num_stats as
> a positive return value. I'm assuming it's value will never overflow an int.
> Likewise elsewhere.
> 
> But that's just my idea. Feel free to stick with the current scheme.
I guess it is fine. I will fix it in v2.
Regards,
Lorenzo
> 
> ...
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply	[flat|nested] 27+ messages in thread
 
 
- * [PATCH net-next 04/12] net: airoha: Add airoha_eth_soc_data struct
  2025-10-15  7:15 [PATCH net-next 00/12] net: airoha: Add AN7583 ethernet controller support Lorenzo Bianconi
                   ` (2 preceding siblings ...)
  2025-10-15  7:15 ` [PATCH net-next 03/12] net: airoha: Add airoha_ppe_get_num_stats_entries() and airoha_ppe_get_num_total_stats_entries() Lorenzo Bianconi
@ 2025-10-15  7:15 ` Lorenzo Bianconi
  2025-10-15 16:06   ` Simon Horman
  2025-10-15  7:15 ` [PATCH net-next 05/12] net: airoha: Generalize airoha_ppe2_is_enabled routine Lorenzo Bianconi
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 27+ messages in thread
From: Lorenzo Bianconi @ 2025-10-15  7:15 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Lorenzo Bianconi
  Cc: linux-arm-kernel, linux-mediatek, netdev, devicetree,
	Christian Marangi
Introduce airoha_eth_soc_data struct to contain differences between
various SoC. Move XSI reset names in airoha_eth_soc_data. This is a
preliminary patch to enable AN7583 ethernet controller support in
airoha-eth driver.
Co-developed-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/airoha/airoha_eth.c | 42 +++++++++++++++++++++++++-------
 drivers/net/ethernet/airoha/airoha_eth.h | 17 +++++++++++--
 2 files changed, 48 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 6effdda64380bf72ce3c5b6b2f551f560f2ee097..32015c41b58df68a0fe87bb026ee0a6d44ea6ec9 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1387,8 +1387,7 @@ static int airoha_hw_init(struct platform_device *pdev,
 	int err, i;
 
 	/* disable xsi */
-	err = reset_control_bulk_assert(ARRAY_SIZE(eth->xsi_rsts),
-					eth->xsi_rsts);
+	err = reset_control_bulk_assert(eth->soc->num_xsi_rsts, eth->xsi_rsts);
 	if (err)
 		return err;
 
@@ -2908,6 +2907,7 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth,
 
 static int airoha_probe(struct platform_device *pdev)
 {
+	struct reset_control_bulk_data *xsi_rsts;
 	struct device_node *np;
 	struct airoha_eth *eth;
 	int i, err;
@@ -2916,6 +2916,10 @@ static int airoha_probe(struct platform_device *pdev)
 	if (!eth)
 		return -ENOMEM;
 
+	eth->soc = of_device_get_match_data(&pdev->dev);
+	if (!eth->soc)
+		return -EINVAL;
+
 	eth->dev = &pdev->dev;
 
 	err = dma_set_mask_and_coherent(eth->dev, DMA_BIT_MASK(32));
@@ -2940,13 +2944,18 @@ static int airoha_probe(struct platform_device *pdev)
 		return err;
 	}
 
-	eth->xsi_rsts[0].id = "xsi-mac";
-	eth->xsi_rsts[1].id = "hsi0-mac";
-	eth->xsi_rsts[2].id = "hsi1-mac";
-	eth->xsi_rsts[3].id = "hsi-mac";
-	eth->xsi_rsts[4].id = "xfp-mac";
+	xsi_rsts = devm_kzalloc(eth->dev,
+				eth->soc->num_xsi_rsts * sizeof(*xsi_rsts),
+				GFP_KERNEL);
+	if (err)
+		return err;
+
+	eth->xsi_rsts = xsi_rsts;
+	for (i = 0; i < eth->soc->num_xsi_rsts; i++)
+		eth->xsi_rsts[i].id = eth->soc->xsi_rsts_names[i];
+
 	err = devm_reset_control_bulk_get_exclusive(eth->dev,
-						    ARRAY_SIZE(eth->xsi_rsts),
+						    eth->soc->num_xsi_rsts,
 						    eth->xsi_rsts);
 	if (err) {
 		dev_err(eth->dev, "failed to get bulk xsi reset lines\n");
@@ -3034,8 +3043,23 @@ static void airoha_remove(struct platform_device *pdev)
 	platform_set_drvdata(pdev, NULL);
 }
 
+static const char * const en7581_xsi_rsts_names[] = {
+	"xsi-mac",
+	"hsi0-mac",
+	"hsi1-mac",
+	"hsi-mac",
+	"xfp-mac",
+};
+
+static const struct airoha_eth_soc_data en7581_soc_data = {
+	.version = 0x7581,
+	.xsi_rsts_names = en7581_xsi_rsts_names,
+	.num_xsi_rsts = ARRAY_SIZE(en7581_xsi_rsts_names),
+	.num_ppe = 2,
+};
+
 static const struct of_device_id of_airoha_match[] = {
-	{ .compatible = "airoha,en7581-eth" },
+	{ .compatible = "airoha,en7581-eth", .data = &en7581_soc_data },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, of_airoha_match);
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index 1f7e34a5f457ca2200e9c81dd05dc03cd7c5eb77..cb7e198e40eeb2f44bd6e035cc7b583f47441d59 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -21,7 +21,6 @@
 #define AIROHA_MAX_NUM_IRQ_BANKS	4
 #define AIROHA_MAX_DSA_PORTS		7
 #define AIROHA_MAX_NUM_RSTS		3
-#define AIROHA_MAX_NUM_XSI_RSTS		5
 #define AIROHA_MAX_MTU			9216
 #define AIROHA_MAX_PACKET_SIZE		2048
 #define AIROHA_NUM_QOS_CHANNELS		4
@@ -556,9 +555,18 @@ struct airoha_ppe {
 	struct dentry *debugfs_dir;
 };
 
+struct airoha_eth_soc_data {
+	u16 version;
+	const char * const *xsi_rsts_names;
+	int num_xsi_rsts;
+	int num_ppe;
+};
+
 struct airoha_eth {
 	struct device *dev;
 
+	const struct airoha_eth_soc_data *soc;
+
 	unsigned long state;
 	void __iomem *fe_regs;
 
@@ -568,7 +576,7 @@ struct airoha_eth {
 	struct rhashtable flow_table;
 
 	struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS];
-	struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS];
+	struct reset_control_bulk_data *xsi_rsts;
 
 	struct net_device *napi_dev;
 
@@ -611,6 +619,11 @@ static inline bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port)
 	return port->id == 1;
 }
 
+static inline bool airoha_is_7581(struct airoha_eth *eth)
+{
+	return eth->soc->version == 0x7581;
+}
+
 bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
 			      struct airoha_gdm_port *port);
 
-- 
2.51.0
^ permalink raw reply related	[flat|nested] 27+ messages in thread
- * Re: [PATCH net-next 04/12] net: airoha: Add airoha_eth_soc_data struct
  2025-10-15  7:15 ` [PATCH net-next 04/12] net: airoha: Add airoha_eth_soc_data struct Lorenzo Bianconi
@ 2025-10-15 16:06   ` Simon Horman
  0 siblings, 0 replies; 27+ messages in thread
From: Simon Horman @ 2025-10-15 16:06 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, linux-arm-kernel, linux-mediatek, netdev,
	devicetree, Christian Marangi
On Wed, Oct 15, 2025 at 09:15:04AM +0200, Lorenzo Bianconi wrote:
> Introduce airoha_eth_soc_data struct to contain differences between
> various SoC. Move XSI reset names in airoha_eth_soc_data. This is a
> preliminary patch to enable AN7583 ethernet controller support in
> airoha-eth driver.
> 
> Co-developed-by: Christian Marangi <ansuelsmth@gmail.com>
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
^ permalink raw reply	[flat|nested] 27+ messages in thread 
 
- * [PATCH net-next 05/12] net: airoha: Generalize airoha_ppe2_is_enabled routine
  2025-10-15  7:15 [PATCH net-next 00/12] net: airoha: Add AN7583 ethernet controller support Lorenzo Bianconi
                   ` (3 preceding siblings ...)
  2025-10-15  7:15 ` [PATCH net-next 04/12] net: airoha: Add airoha_eth_soc_data struct Lorenzo Bianconi
@ 2025-10-15  7:15 ` Lorenzo Bianconi
  2025-10-15 16:07   ` Simon Horman
  2025-10-15  7:15 ` [PATCH net-next 06/12] net: airoha: ppe: Move PPE memory info in airoha_eth_soc_data struct Lorenzo Bianconi
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 27+ messages in thread
From: Lorenzo Bianconi @ 2025-10-15  7:15 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Lorenzo Bianconi
  Cc: linux-arm-kernel, linux-mediatek, netdev, devicetree
Rename airoha_ppe2_is_enabled() in airoha_ppe_is_enabled() and
generalize it in order to check if each PPE module is enabled.
Rely on airoha_ppe_is_enabled routine to properly initialize PPE for
AN7583 SoC since AN7583 does not support PPE2.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/airoha/airoha_eth.c | 32 +++++++++++++++++++++-----------
 drivers/net/ethernet/airoha/airoha_eth.h |  1 +
 drivers/net/ethernet/airoha/airoha_ppe.c | 17 ++++++++++-------
 3 files changed, 32 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 32015c41b58df68a0fe87bb026ee0a6d44ea6ec9..99e7fea52c6db9c4686fcef368f21e25f21ced58 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -297,8 +297,11 @@ static void airoha_fe_pse_ports_init(struct airoha_eth *eth)
 	int q;
 
 	all_rsv = airoha_fe_get_pse_all_rsv(eth);
-	/* hw misses PPE2 oq rsv */
-	all_rsv += PSE_RSV_PAGES * pse_port_num_queues[FE_PSE_PORT_PPE2];
+	if (airoha_ppe_is_enabled(eth, 1)) {
+		/* hw misses PPE2 oq rsv */
+		all_rsv += PSE_RSV_PAGES *
+			   pse_port_num_queues[FE_PSE_PORT_PPE2];
+	}
 	airoha_fe_set(eth, REG_FE_PSE_BUF_SET, all_rsv);
 
 	/* CMD1 */
@@ -335,13 +338,17 @@ static void airoha_fe_pse_ports_init(struct airoha_eth *eth)
 	for (q = 4; q < pse_port_num_queues[FE_PSE_PORT_CDM4]; q++)
 		airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM4, q,
 					 PSE_QUEUE_RSV_PAGES);
-	/* PPE2 */
-	for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE2]; q++) {
-		if (q < pse_port_num_queues[FE_PSE_PORT_PPE2] / 2)
-			airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q,
-						 PSE_QUEUE_RSV_PAGES);
-		else
-			airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q, 0);
+	if (airoha_ppe_is_enabled(eth, 1)) {
+		/* PPE2 */
+		for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE2]; q++) {
+			if (q < pse_port_num_queues[FE_PSE_PORT_PPE2] / 2)
+				airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2,
+							 q,
+							 PSE_QUEUE_RSV_PAGES);
+			else
+				airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2,
+							 q, 0);
+		}
 	}
 	/* GMD4 */
 	for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM4]; q++)
@@ -1762,8 +1769,11 @@ static int airoha_dev_init(struct net_device *dev)
 			airhoha_set_gdm2_loopback(port);
 		fallthrough;
 	case 2:
-		pse_port = FE_PSE_PORT_PPE2;
-		break;
+		if (airoha_ppe_is_enabled(eth, 1)) {
+			pse_port = FE_PSE_PORT_PPE2;
+			break;
+		}
+		fallthrough;
 	default:
 		pse_port = FE_PSE_PORT_PPE1;
 		break;
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index cb7e198e40eeb2f44bd6e035cc7b583f47441d59..81b1e5f273df20fb8aef7a03e94ac14a3cfaf4d5 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -627,6 +627,7 @@ static inline bool airoha_is_7581(struct airoha_eth *eth)
 bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
 			      struct airoha_gdm_port *port);
 
+bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index);
 void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
 			  u16 hash, bool rx_wlan);
 int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data);
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index 303d31e1da4b723023ee0cc1ca5f6038c16966cd..68b0b7ebf0e809bb1905f80ac544fb87027ec62f 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -56,9 +56,12 @@ static int airoha_ppe_get_total_num_stats_entries(struct airoha_ppe *ppe,
 	return 0;
 }
 
-static bool airoha_ppe2_is_enabled(struct airoha_eth *eth)
+bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index)
 {
-	return airoha_fe_rr(eth, REG_PPE_GLO_CFG(1)) & PPE_GLO_CFG_EN_MASK;
+	if (index >= eth->soc->num_ppe)
+		return false;
+
+	return airoha_fe_rr(eth, REG_PPE_GLO_CFG(index)) & PPE_GLO_CFG_EN_MASK;
 }
 
 static u32 airoha_ppe_get_timestamp(struct airoha_ppe *ppe)
@@ -127,7 +130,7 @@ static void airoha_ppe_hw_init(struct airoha_ppe *ppe)
 						 AIROHA_MAX_MTU));
 	}
 
-	if (airoha_ppe2_is_enabled(eth)) {
+	if (airoha_ppe_is_enabled(eth, 1)) {
 		sram_num_entries = PPE1_SRAM_NUM_ENTRIES;
 		if (!airoha_ppe_get_num_stats_entries(ppe,
 						      &sram_num_stats_entries))
@@ -525,7 +528,7 @@ static int airoha_ppe_foe_get_flow_stats_index(struct airoha_ppe *ppe,
 		return err;
 
 	*index = hash;
-	if (airoha_ppe2_is_enabled(ppe->eth) &&
+	if (airoha_ppe_is_enabled(ppe->eth, 1) &&
 	    hash >= ppe_num_stats_entries)
 		*index = *index - PPE_STATS_NUM_ENTRIES;
 
@@ -620,7 +623,7 @@ airoha_ppe_foe_get_entry_locked(struct airoha_ppe *ppe, u32 hash)
 		u32 val;
 		int i;
 
-		ppe2 = airoha_ppe2_is_enabled(ppe->eth) &&
+		ppe2 = airoha_ppe_is_enabled(ppe->eth, 1) &&
 		       hash >= PPE1_SRAM_NUM_ENTRIES;
 		airoha_fe_wr(ppe->eth, REG_PPE_RAM_CTRL(ppe2),
 			     FIELD_PREP(PPE_SRAM_CTRL_ENTRY_MASK, hash) |
@@ -698,7 +701,7 @@ static int airoha_ppe_foe_commit_entry(struct airoha_ppe *ppe,
 
 	if (hash < PPE_SRAM_NUM_ENTRIES) {
 		dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe);
-		bool ppe2 = airoha_ppe2_is_enabled(eth) &&
+		bool ppe2 = airoha_ppe_is_enabled(eth, 1) &&
 			    hash >= PPE1_SRAM_NUM_ENTRIES;
 
 		err = npu->ops.ppe_foe_commit_entry(npu, addr, sizeof(*hwe),
@@ -1292,7 +1295,7 @@ static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe,
 	int i, sram_num_entries = PPE_SRAM_NUM_ENTRIES;
 	struct airoha_foe_entry *hwe = ppe->foe;
 
-	if (airoha_ppe2_is_enabled(ppe->eth))
+	if (airoha_ppe_is_enabled(ppe->eth, 1))
 		sram_num_entries = sram_num_entries / 2;
 
 	for (i = 0; i < sram_num_entries; i++)
-- 
2.51.0
^ permalink raw reply related	[flat|nested] 27+ messages in thread
- * Re: [PATCH net-next 05/12] net: airoha: Generalize airoha_ppe2_is_enabled routine
  2025-10-15  7:15 ` [PATCH net-next 05/12] net: airoha: Generalize airoha_ppe2_is_enabled routine Lorenzo Bianconi
@ 2025-10-15 16:07   ` Simon Horman
  0 siblings, 0 replies; 27+ messages in thread
From: Simon Horman @ 2025-10-15 16:07 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, linux-arm-kernel, linux-mediatek, netdev,
	devicetree
On Wed, Oct 15, 2025 at 09:15:05AM +0200, Lorenzo Bianconi wrote:
> Rename airoha_ppe2_is_enabled() in airoha_ppe_is_enabled() and
> generalize it in order to check if each PPE module is enabled.
> Rely on airoha_ppe_is_enabled routine to properly initialize PPE for
> AN7583 SoC since AN7583 does not support PPE2.
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
^ permalink raw reply	[flat|nested] 27+ messages in thread 
 
- * [PATCH net-next 06/12] net: airoha: ppe: Move PPE memory info in airoha_eth_soc_data struct
  2025-10-15  7:15 [PATCH net-next 00/12] net: airoha: Add AN7583 ethernet controller support Lorenzo Bianconi
                   ` (4 preceding siblings ...)
  2025-10-15  7:15 ` [PATCH net-next 05/12] net: airoha: Generalize airoha_ppe2_is_enabled routine Lorenzo Bianconi
@ 2025-10-15  7:15 ` Lorenzo Bianconi
  2025-10-15 16:07   ` Simon Horman
  2025-10-15  7:15 ` [PATCH net-next 07/12] net: airoha: ppe: Remove airoha_ppe_is_enabled() where not necessary Lorenzo Bianconi
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 27+ messages in thread
From: Lorenzo Bianconi @ 2025-10-15  7:15 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Lorenzo Bianconi
  Cc: linux-arm-kernel, linux-mediatek, netdev, devicetree
AN7583 SoC runs a single PPE device while EN7581 runs two of them.
Moreover PPE SRAM in AN7583 SoC is reduced to 8K (while SRAM is 16K on
EN7581). Take into account PPE memory layout during PPE configuration.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/airoha/airoha_eth.h         |  10 +-
 drivers/net/ethernet/airoha/airoha_ppe.c         | 129 +++++++++++------------
 drivers/net/ethernet/airoha/airoha_ppe_debugfs.c |   3 +-
 3 files changed, 67 insertions(+), 75 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index 81b1e5f273df20fb8aef7a03e94ac14a3cfaf4d5..df168d798699d50c70fa5f87764de24e85994dfd 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -47,14 +47,9 @@
 #define QDMA_METER_IDX(_n)		((_n) & 0xff)
 #define QDMA_METER_GROUP(_n)		(((_n) >> 8) & 0x3)
 
-#define PPE_NUM				2
-#define PPE1_SRAM_NUM_ENTRIES		(8 * 1024)
-#define PPE_SRAM_NUM_ENTRIES		(PPE_NUM * PPE1_SRAM_NUM_ENTRIES)
-#define PPE1_STATS_NUM_ENTRIES		(4 * 1024)
-#define PPE_STATS_NUM_ENTRIES		(PPE_NUM * PPE1_STATS_NUM_ENTRIES)
+#define PPE_SRAM_NUM_ENTRIES		(8 * 1024)
+#define PPE_STATS_NUM_ENTRIES		(4 * 1024)
 #define PPE_DRAM_NUM_ENTRIES		(16 * 1024)
-#define PPE_NUM_ENTRIES			(PPE_SRAM_NUM_ENTRIES + PPE_DRAM_NUM_ENTRIES)
-#define PPE_HASH_MASK			(PPE_NUM_ENTRIES - 1)
 #define PPE_ENTRY_SIZE			80
 #define PPE_RAM_NUM_ENTRIES_SHIFT(_n)	(__ffs((_n) >> 10))
 
@@ -634,6 +629,7 @@ int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data);
 int airoha_ppe_init(struct airoha_eth *eth);
 void airoha_ppe_deinit(struct airoha_eth *eth);
 void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port);
+u32 airoha_ppe_get_total_num_entries(struct airoha_ppe *ppe);
 struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe,
 						  u32 hash);
 void airoha_ppe_foe_entry_get_stats(struct airoha_ppe *ppe, u32 hash,
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index 68b0b7ebf0e809bb1905f80ac544fb87027ec62f..58306cf91daf9faeb4f1cc0092579654dde3cfb0 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -36,7 +36,7 @@ static int airoha_ppe_get_num_stats_entries(struct airoha_ppe *ppe,
 					    u32 *num_stats)
 {
 #ifdef CONFIG_NET_AIROHA_FLOW_STATS
-	*num_stats = PPE1_STATS_NUM_ENTRIES;
+	*num_stats = PPE_STATS_NUM_ENTRIES;
 	return 0;
 #else
 	return -EOPNOTSUPP;
@@ -46,16 +46,31 @@ static int airoha_ppe_get_num_stats_entries(struct airoha_ppe *ppe,
 static int airoha_ppe_get_total_num_stats_entries(struct airoha_ppe *ppe,
 						  u32 *num_stats)
 {
+	struct airoha_eth *eth = ppe->eth;
 	int err;
 
 	err = airoha_ppe_get_num_stats_entries(ppe, num_stats);
 	if (err)
 		return err;
 
-	*num_stats = *num_stats * PPE_NUM;
+	*num_stats = *num_stats * eth->soc->num_ppe;
 	return 0;
 }
 
+static u32 airoha_ppe_get_total_sram_num_entries(struct airoha_ppe *ppe)
+{
+	struct airoha_eth *eth = ppe->eth;
+
+	return PPE_SRAM_NUM_ENTRIES * eth->soc->num_ppe;
+}
+
+u32 airoha_ppe_get_total_num_entries(struct airoha_ppe *ppe)
+{
+	u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe);
+
+	return sram_num_entries + PPE_DRAM_NUM_ENTRIES;
+}
+
 bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index)
 {
 	if (index >= eth->soc->num_ppe)
@@ -73,15 +88,22 @@ static u32 airoha_ppe_get_timestamp(struct airoha_ppe *ppe)
 
 static void airoha_ppe_hw_init(struct airoha_ppe *ppe)
 {
-	u32 sram_tb_size, sram_num_entries, dram_num_entries;
+	u32 sram_ppe_num_data_entries = PPE_SRAM_NUM_ENTRIES, sram_num_entries;
+	u32 sram_tb_size, dram_num_entries, sram_num_stats_entries;
 	struct airoha_eth *eth = ppe->eth;
-	u32 sram_num_stats_entries;
 	int i;
 
-	sram_tb_size = PPE_SRAM_NUM_ENTRIES * sizeof(struct airoha_foe_entry);
+	sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe);
+	sram_tb_size = sram_num_entries * sizeof(struct airoha_foe_entry);
 	dram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(PPE_DRAM_NUM_ENTRIES);
 
-	for (i = 0; i < PPE_NUM; i++) {
+	if (!airoha_ppe_get_num_stats_entries(ppe, &sram_num_stats_entries))
+		sram_ppe_num_data_entries -= sram_num_stats_entries;
+
+	sram_ppe_num_data_entries =
+		PPE_RAM_NUM_ENTRIES_SHIFT(sram_ppe_num_data_entries);
+
+	for (i = 0; i < eth->soc->num_ppe; i++) {
 		int p;
 
 		airoha_fe_wr(eth, REG_PPE_TB_BASE(i),
@@ -113,10 +135,16 @@ static void airoha_ppe_hw_init(struct airoha_ppe *ppe)
 
 		airoha_fe_rmw(eth, REG_PPE_TB_CFG(i),
 			      PPE_TB_CFG_SEARCH_MISS_MASK |
+			      PPE_SRAM_TB_NUM_ENTRY_MASK |
+			      PPE_DRAM_TB_NUM_ENTRY_MASK |
 			      PPE_TB_CFG_KEEPALIVE_MASK |
 			      PPE_TB_ENTRY_SIZE_MASK,
 			      FIELD_PREP(PPE_TB_CFG_SEARCH_MISS_MASK, 3) |
-			      FIELD_PREP(PPE_TB_ENTRY_SIZE_MASK, 0));
+			      FIELD_PREP(PPE_TB_ENTRY_SIZE_MASK, 0) |
+			      FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK,
+					 sram_ppe_num_data_entries) |
+			      FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK,
+					 dram_num_entries));
 
 		airoha_fe_wr(eth, REG_PPE_HASH_SEED(i), PPE_HASH_SEED);
 
@@ -129,43 +157,6 @@ static void airoha_ppe_hw_init(struct airoha_ppe *ppe)
 				      FIELD_PREP(FP1_EGRESS_MTU_MASK,
 						 AIROHA_MAX_MTU));
 	}
-
-	if (airoha_ppe_is_enabled(eth, 1)) {
-		sram_num_entries = PPE1_SRAM_NUM_ENTRIES;
-		if (!airoha_ppe_get_num_stats_entries(ppe,
-						      &sram_num_stats_entries))
-			sram_num_entries -= sram_num_stats_entries;
-		sram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(sram_num_entries);
-
-		airoha_fe_rmw(eth, REG_PPE_TB_CFG(0),
-			      PPE_SRAM_TB_NUM_ENTRY_MASK |
-			      PPE_DRAM_TB_NUM_ENTRY_MASK,
-			      FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK,
-					 sram_num_entries) |
-			      FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK,
-					 dram_num_entries));
-		airoha_fe_rmw(eth, REG_PPE_TB_CFG(1),
-			      PPE_SRAM_TB_NUM_ENTRY_MASK |
-			      PPE_DRAM_TB_NUM_ENTRY_MASK,
-			      FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK,
-					 sram_num_entries) |
-			      FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK,
-					 dram_num_entries));
-	} else {
-		sram_num_entries = PPE_SRAM_NUM_ENTRIES;
-		if (!airoha_ppe_get_total_num_stats_entries(ppe,
-							    &sram_num_stats_entries))
-			sram_num_entries -= sram_num_stats_entries;
-		sram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(sram_num_entries);
-
-		airoha_fe_rmw(eth, REG_PPE_TB_CFG(0),
-			      PPE_SRAM_TB_NUM_ENTRY_MASK |
-			      PPE_DRAM_TB_NUM_ENTRY_MASK,
-			      FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK,
-					 sram_num_entries) |
-			      FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK,
-					 dram_num_entries));
-	}
 }
 
 static void airoha_ppe_flow_mangle_eth(const struct flow_action_entry *act, void *eth)
@@ -464,9 +455,11 @@ static int airoha_ppe_foe_entry_set_ipv6_tuple(struct airoha_foe_entry *hwe,
 	return 0;
 }
 
-static u32 airoha_ppe_foe_get_entry_hash(struct airoha_foe_entry *hwe)
+static u32 airoha_ppe_foe_get_entry_hash(struct airoha_ppe *ppe,
+					 struct airoha_foe_entry *hwe)
 {
 	int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1);
+	u32 ppe_hash_mask = airoha_ppe_get_total_num_entries(ppe) - 1;
 	u32 hash, hv1, hv2, hv3;
 
 	switch (type) {
@@ -504,14 +497,14 @@ static u32 airoha_ppe_foe_get_entry_hash(struct airoha_foe_entry *hwe)
 	case PPE_PKT_TYPE_IPV6_6RD:
 	default:
 		WARN_ON_ONCE(1);
-		return PPE_HASH_MASK;
+		return ppe_hash_mask;
 	}
 
 	hash = (hv1 & hv2) | ((~hv1) & hv3);
 	hash = (hash >> 24) | ((hash & 0xffffff) << 8);
 	hash ^= hv1 ^ hv2 ^ hv3;
 	hash ^= hash >> 16;
-	hash &= PPE_NUM_ENTRIES - 1;
+	hash &= ppe_hash_mask;
 
 	return hash;
 }
@@ -614,9 +607,11 @@ static void airoha_ppe_foe_flow_stats_update(struct airoha_ppe *ppe,
 static struct airoha_foe_entry *
 airoha_ppe_foe_get_entry_locked(struct airoha_ppe *ppe, u32 hash)
 {
+	u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe);
+
 	lockdep_assert_held(&ppe_lock);
 
-	if (hash < PPE_SRAM_NUM_ENTRIES) {
+	if (hash < sram_num_entries) {
 		u32 *hwe = ppe->foe + hash * sizeof(struct airoha_foe_entry);
 		struct airoha_eth *eth = ppe->eth;
 		bool ppe2;
@@ -624,7 +619,7 @@ airoha_ppe_foe_get_entry_locked(struct airoha_ppe *ppe, u32 hash)
 		int i;
 
 		ppe2 = airoha_ppe_is_enabled(ppe->eth, 1) &&
-		       hash >= PPE1_SRAM_NUM_ENTRIES;
+		       hash >= PPE_SRAM_NUM_ENTRIES;
 		airoha_fe_wr(ppe->eth, REG_PPE_RAM_CTRL(ppe2),
 			     FIELD_PREP(PPE_SRAM_CTRL_ENTRY_MASK, hash) |
 			     PPE_SRAM_CTRL_REQ_MASK);
@@ -675,6 +670,7 @@ static int airoha_ppe_foe_commit_entry(struct airoha_ppe *ppe,
 				       struct airoha_foe_entry *e,
 				       u32 hash, bool rx_wlan)
 {
+	u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe);
 	struct airoha_foe_entry *hwe = ppe->foe + hash * sizeof(*hwe);
 	u32 ts = airoha_ppe_get_timestamp(ppe);
 	struct airoha_eth *eth = ppe->eth;
@@ -699,10 +695,10 @@ static int airoha_ppe_foe_commit_entry(struct airoha_ppe *ppe,
 	if (!rx_wlan)
 		airoha_ppe_foe_flow_stats_update(ppe, npu, hwe, hash);
 
-	if (hash < PPE_SRAM_NUM_ENTRIES) {
+	if (hash < sram_num_entries) {
 		dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe);
 		bool ppe2 = airoha_ppe_is_enabled(eth, 1) &&
-			    hash >= PPE1_SRAM_NUM_ENTRIES;
+			    hash >= PPE_SRAM_NUM_ENTRIES;
 
 		err = npu->ops.ppe_foe_commit_entry(npu, addr, sizeof(*hwe),
 						    hash, ppe2);
@@ -829,7 +825,7 @@ static void airoha_ppe_foe_insert_entry(struct airoha_ppe *ppe,
 	if (state == AIROHA_FOE_STATE_BIND)
 		goto unlock;
 
-	index = airoha_ppe_foe_get_entry_hash(hwe);
+	index = airoha_ppe_foe_get_entry_hash(ppe, hwe);
 	hlist_for_each_entry_safe(e, n, &ppe->foe_flow[index], list) {
 		if (e->type == FLOW_TYPE_L2_SUBFLOW) {
 			state = FIELD_GET(AIROHA_FOE_IB1_BIND_STATE, hwe->ib1);
@@ -889,7 +885,7 @@ static int airoha_ppe_foe_flow_commit_entry(struct airoha_ppe *ppe,
 	if (type == PPE_PKT_TYPE_BRIDGE)
 		return airoha_ppe_foe_l2_flow_commit_entry(ppe, e);
 
-	hash = airoha_ppe_foe_get_entry_hash(&e->data);
+	hash = airoha_ppe_foe_get_entry_hash(ppe, &e->data);
 	e->type = FLOW_TYPE_L4;
 	e->hash = 0xffff;
 
@@ -1292,17 +1288,15 @@ static int airoha_ppe_flow_offload_cmd(struct airoha_eth *eth,
 static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe,
 					 struct airoha_npu *npu)
 {
-	int i, sram_num_entries = PPE_SRAM_NUM_ENTRIES;
+	u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe);
 	struct airoha_foe_entry *hwe = ppe->foe;
+	int i;
 
-	if (airoha_ppe_is_enabled(ppe->eth, 1))
-		sram_num_entries = sram_num_entries / 2;
-
-	for (i = 0; i < sram_num_entries; i++)
+	for (i = 0; i < PPE_SRAM_NUM_ENTRIES; i++)
 		memset(&hwe[i], 0, sizeof(*hwe));
 
 	return npu->ops.ppe_flush_sram_entries(npu, ppe->foe_dma,
-					       PPE_SRAM_NUM_ENTRIES);
+					       sram_num_entries);
 }
 
 static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth)
@@ -1379,9 +1373,10 @@ void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
 			  u16 hash, bool rx_wlan)
 {
 	struct airoha_ppe *ppe = dev->priv;
+	u32 ppe_hash_mask = airoha_ppe_get_total_num_entries(ppe) - 1;
 	u16 now, diff;
 
-	if (hash > PPE_HASH_MASK)
+	if (hash > ppe_hash_mask)
 		return;
 
 	now = (u16)jiffies;
@@ -1471,7 +1466,7 @@ EXPORT_SYMBOL_GPL(airoha_ppe_put_dev);
 
 int airoha_ppe_init(struct airoha_eth *eth)
 {
-	u32 ppe_num_stats_entries;
+	u32 ppe_num_entries, ppe_num_stats_entries;
 	struct airoha_ppe *ppe;
 	int foe_size, err;
 
@@ -1482,18 +1477,18 @@ int airoha_ppe_init(struct airoha_eth *eth)
 	ppe->dev.ops.setup_tc_block_cb = airoha_ppe_setup_tc_block_cb;
 	ppe->dev.ops.check_skb = airoha_ppe_check_skb;
 	ppe->dev.priv = ppe;
+	ppe->eth = eth;
+	eth->ppe = ppe;
 
-	foe_size = PPE_NUM_ENTRIES * sizeof(struct airoha_foe_entry);
+	ppe_num_entries = airoha_ppe_get_total_num_entries(ppe);
+	foe_size = ppe_num_entries * sizeof(struct airoha_foe_entry);
 	ppe->foe = dmam_alloc_coherent(eth->dev, foe_size, &ppe->foe_dma,
 				       GFP_KERNEL);
 	if (!ppe->foe)
 		return -ENOMEM;
 
-	ppe->eth = eth;
-	eth->ppe = ppe;
-
 	ppe->foe_flow = devm_kzalloc(eth->dev,
-				     PPE_NUM_ENTRIES * sizeof(*ppe->foe_flow),
+				     ppe_num_entries * sizeof(*ppe->foe_flow),
 				     GFP_KERNEL);
 	if (!ppe->foe_flow)
 		return -ENOMEM;
@@ -1508,7 +1503,7 @@ int airoha_ppe_init(struct airoha_eth *eth)
 			return -ENOMEM;
 	}
 
-	ppe->foe_check_time = devm_kzalloc(eth->dev, PPE_NUM_ENTRIES,
+	ppe->foe_check_time = devm_kzalloc(eth->dev, ppe_num_entries,
 					   GFP_KERNEL);
 	if (!ppe->foe_check_time)
 		return -ENOMEM;
diff --git a/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c b/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c
index 05a756233f6a44fa51d1c57dd39d89c8ea488054..0112c41150bb05d1f99def4e58acd1a11e81696c 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c
@@ -53,9 +53,10 @@ static int airoha_ppe_debugfs_foe_show(struct seq_file *m, void *private,
 		[AIROHA_FOE_STATE_FIN] = "FIN",
 	};
 	struct airoha_ppe *ppe = m->private;
+	u32 ppe_num_entries = airoha_ppe_get_total_num_entries(ppe);
 	int i;
 
-	for (i = 0; i < PPE_NUM_ENTRIES; i++) {
+	for (i = 0; i < ppe_num_entries; i++) {
 		const char *state_str, *type_str = "UNKNOWN";
 		void *src_addr = NULL, *dest_addr = NULL;
 		u16 *src_port = NULL, *dest_port = NULL;
-- 
2.51.0
^ permalink raw reply related	[flat|nested] 27+ messages in thread
- * Re: [PATCH net-next 06/12] net: airoha: ppe: Move PPE memory info in airoha_eth_soc_data struct
  2025-10-15  7:15 ` [PATCH net-next 06/12] net: airoha: ppe: Move PPE memory info in airoha_eth_soc_data struct Lorenzo Bianconi
@ 2025-10-15 16:07   ` Simon Horman
  0 siblings, 0 replies; 27+ messages in thread
From: Simon Horman @ 2025-10-15 16:07 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, linux-arm-kernel, linux-mediatek, netdev,
	devicetree
On Wed, Oct 15, 2025 at 09:15:06AM +0200, Lorenzo Bianconi wrote:
> AN7583 SoC runs a single PPE device while EN7581 runs two of them.
> Moreover PPE SRAM in AN7583 SoC is reduced to 8K (while SRAM is 16K on
> EN7581). Take into account PPE memory layout during PPE configuration.
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
^ permalink raw reply	[flat|nested] 27+ messages in thread 
 
- * [PATCH net-next 07/12] net: airoha: ppe: Remove airoha_ppe_is_enabled() where not necessary
  2025-10-15  7:15 [PATCH net-next 00/12] net: airoha: Add AN7583 ethernet controller support Lorenzo Bianconi
                   ` (5 preceding siblings ...)
  2025-10-15  7:15 ` [PATCH net-next 06/12] net: airoha: ppe: Move PPE memory info in airoha_eth_soc_data struct Lorenzo Bianconi
@ 2025-10-15  7:15 ` Lorenzo Bianconi
  2025-10-15 16:07   ` Simon Horman
  2025-10-15  7:15 ` [PATCH net-next 08/12] net: airoha: ppe: Configure SRAM PPE entries via the cpu Lorenzo Bianconi
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 27+ messages in thread
From: Lorenzo Bianconi @ 2025-10-15  7:15 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Lorenzo Bianconi
  Cc: linux-arm-kernel, linux-mediatek, netdev, devicetree
Now each PPE has always PPE_STATS_NUM_ENTRIES entries so we do not need
to run airoha_ppe_is_enabled routine to check if the hash refers to
PPE1 or PPE2.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/airoha/airoha_ppe.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index 58306cf91daf9faeb4f1cc0092579654dde3cfb0..fcfd2d8826a9c2f8f94f1962c2b2a69f67f7f598 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -520,10 +520,8 @@ static int airoha_ppe_foe_get_flow_stats_index(struct airoha_ppe *ppe,
 	if (err)
 		return err;
 
-	*index = hash;
-	if (airoha_ppe_is_enabled(ppe->eth, 1) &&
-	    hash >= ppe_num_stats_entries)
-		*index = *index - PPE_STATS_NUM_ENTRIES;
+	*index = hash >= ppe_num_stats_entries ? hash - PPE_STATS_NUM_ENTRIES
+					       : hash;
 
 	return 0;
 }
@@ -613,13 +611,11 @@ airoha_ppe_foe_get_entry_locked(struct airoha_ppe *ppe, u32 hash)
 
 	if (hash < sram_num_entries) {
 		u32 *hwe = ppe->foe + hash * sizeof(struct airoha_foe_entry);
+		bool ppe2 = hash >= PPE_SRAM_NUM_ENTRIES;
 		struct airoha_eth *eth = ppe->eth;
-		bool ppe2;
 		u32 val;
 		int i;
 
-		ppe2 = airoha_ppe_is_enabled(ppe->eth, 1) &&
-		       hash >= PPE_SRAM_NUM_ENTRIES;
 		airoha_fe_wr(ppe->eth, REG_PPE_RAM_CTRL(ppe2),
 			     FIELD_PREP(PPE_SRAM_CTRL_ENTRY_MASK, hash) |
 			     PPE_SRAM_CTRL_REQ_MASK);
@@ -697,8 +693,7 @@ static int airoha_ppe_foe_commit_entry(struct airoha_ppe *ppe,
 
 	if (hash < sram_num_entries) {
 		dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe);
-		bool ppe2 = airoha_ppe_is_enabled(eth, 1) &&
-			    hash >= PPE_SRAM_NUM_ENTRIES;
+		bool ppe2 = hash >= PPE_SRAM_NUM_ENTRIES;
 
 		err = npu->ops.ppe_foe_commit_entry(npu, addr, sizeof(*hwe),
 						    hash, ppe2);
-- 
2.51.0
^ permalink raw reply related	[flat|nested] 27+ messages in thread
- * Re: [PATCH net-next 07/12] net: airoha: ppe: Remove airoha_ppe_is_enabled() where not necessary
  2025-10-15  7:15 ` [PATCH net-next 07/12] net: airoha: ppe: Remove airoha_ppe_is_enabled() where not necessary Lorenzo Bianconi
@ 2025-10-15 16:07   ` Simon Horman
  0 siblings, 0 replies; 27+ messages in thread
From: Simon Horman @ 2025-10-15 16:07 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, linux-arm-kernel, linux-mediatek, netdev,
	devicetree
On Wed, Oct 15, 2025 at 09:15:07AM +0200, Lorenzo Bianconi wrote:
> Now each PPE has always PPE_STATS_NUM_ENTRIES entries so we do not need
> to run airoha_ppe_is_enabled routine to check if the hash refers to
> PPE1 or PPE2.
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
^ permalink raw reply	[flat|nested] 27+ messages in thread 
 
- * [PATCH net-next 08/12] net: airoha: ppe: Configure SRAM PPE entries via the cpu
  2025-10-15  7:15 [PATCH net-next 00/12] net: airoha: Add AN7583 ethernet controller support Lorenzo Bianconi
                   ` (6 preceding siblings ...)
  2025-10-15  7:15 ` [PATCH net-next 07/12] net: airoha: ppe: Remove airoha_ppe_is_enabled() where not necessary Lorenzo Bianconi
@ 2025-10-15  7:15 ` Lorenzo Bianconi
  2025-10-15 15:47   ` Simon Horman
  2025-10-15  7:15 ` [PATCH net-next 09/12] net: airoha: ppe: Flush PPE SRAM table during PPE setup Lorenzo Bianconi
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 27+ messages in thread
From: Lorenzo Bianconi @ 2025-10-15  7:15 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Lorenzo Bianconi
  Cc: linux-arm-kernel, linux-mediatek, netdev, devicetree
Introduce airoha_ppe_foe_commit_sram_entry routine in order to configure
the SRAM PPE entries directly via the CPU instead of using the NPU APIs.
This is a preliminary patch to enable netfilter flowtable hw offload for
AN7583 SoC.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/airoha/airoha_ppe.c | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index fcfd2d8826a9c2f8f94f1962c2b2a69f67f7f598..0ee2e41489aaa9de9c1e99d242ee0bec11549750 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -662,6 +662,27 @@ static bool airoha_ppe_foe_compare_entry(struct airoha_flow_table_entry *e,
 	return !memcmp(&e->data.d, &hwe->d, len - sizeof(hwe->ib1));
 }
 
+static int airoha_ppe_foe_commit_sram_entry(struct airoha_ppe *ppe, u32 hash)
+{
+	struct airoha_foe_entry *hwe = ppe->foe + hash * sizeof(*hwe);
+	bool ppe2 = hash >= PPE_SRAM_NUM_ENTRIES;
+	u32 *ptr = (u32 *)hwe, val;
+	int i;
+
+	for (i = 0; i < sizeof(*hwe) / 4; i++)
+		airoha_fe_wr(ppe->eth, REG_PPE_RAM_ENTRY(ppe2, i), ptr[i]);
+
+	wmb();
+	airoha_fe_wr(ppe->eth, REG_PPE_RAM_CTRL(ppe2),
+		     FIELD_PREP(PPE_SRAM_CTRL_ENTRY_MASK, hash) |
+		     PPE_SRAM_CTRL_WR_MASK | PPE_SRAM_CTRL_REQ_MASK);
+
+	return read_poll_timeout_atomic(airoha_fe_rr, val,
+					val & PPE_SRAM_CTRL_ACK_MASK,
+					10, 100, false, ppe->eth,
+					REG_PPE_RAM_CTRL(ppe2));
+}
+
 static int airoha_ppe_foe_commit_entry(struct airoha_ppe *ppe,
 				       struct airoha_foe_entry *e,
 				       u32 hash, bool rx_wlan)
@@ -691,13 +712,8 @@ static int airoha_ppe_foe_commit_entry(struct airoha_ppe *ppe,
 	if (!rx_wlan)
 		airoha_ppe_foe_flow_stats_update(ppe, npu, hwe, hash);
 
-	if (hash < sram_num_entries) {
-		dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe);
-		bool ppe2 = hash >= PPE_SRAM_NUM_ENTRIES;
-
-		err = npu->ops.ppe_foe_commit_entry(npu, addr, sizeof(*hwe),
-						    hash, ppe2);
-	}
+	if (hash < sram_num_entries)
+		err = airoha_ppe_foe_commit_sram_entry(ppe, hash);
 unlock:
 	rcu_read_unlock();
 
-- 
2.51.0
^ permalink raw reply related	[flat|nested] 27+ messages in thread
- * Re: [PATCH net-next 08/12] net: airoha: ppe: Configure SRAM PPE entries via the cpu
  2025-10-15  7:15 ` [PATCH net-next 08/12] net: airoha: ppe: Configure SRAM PPE entries via the cpu Lorenzo Bianconi
@ 2025-10-15 15:47   ` Simon Horman
  2025-10-16  8:13     ` Lorenzo Bianconi
  0 siblings, 1 reply; 27+ messages in thread
From: Simon Horman @ 2025-10-15 15:47 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, linux-arm-kernel, linux-mediatek, netdev,
	devicetree
On Wed, Oct 15, 2025 at 09:15:08AM +0200, Lorenzo Bianconi wrote:
> Introduce airoha_ppe_foe_commit_sram_entry routine in order to configure
> the SRAM PPE entries directly via the CPU instead of using the NPU APIs.
> This is a preliminary patch to enable netfilter flowtable hw offload for
> AN7583 SoC.
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
>  drivers/net/ethernet/airoha/airoha_ppe.c | 30 +++++++++++++++++++++++-------
>  1 file changed, 23 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
> index fcfd2d8826a9c2f8f94f1962c2b2a69f67f7f598..0ee2e41489aaa9de9c1e99d242ee0bec11549750 100644
> --- a/drivers/net/ethernet/airoha/airoha_ppe.c
> +++ b/drivers/net/ethernet/airoha/airoha_ppe.c
> @@ -662,6 +662,27 @@ static bool airoha_ppe_foe_compare_entry(struct airoha_flow_table_entry *e,
>  	return !memcmp(&e->data.d, &hwe->d, len - sizeof(hwe->ib1));
>  }
>  
> +static int airoha_ppe_foe_commit_sram_entry(struct airoha_ppe *ppe, u32 hash)
> +{
> +	struct airoha_foe_entry *hwe = ppe->foe + hash * sizeof(*hwe);
> +	bool ppe2 = hash >= PPE_SRAM_NUM_ENTRIES;
> +	u32 *ptr = (u32 *)hwe, val;
> +	int i;
> +
> +	for (i = 0; i < sizeof(*hwe) / 4; i++)
> +		airoha_fe_wr(ppe->eth, REG_PPE_RAM_ENTRY(ppe2, i), ptr[i]);
I realise that a similar pattern it is already used elsewhere,
but '4' seems somewhat magic here.
...
^ permalink raw reply	[flat|nested] 27+ messages in thread
- * Re: [PATCH net-next 08/12] net: airoha: ppe: Configure SRAM PPE entries via the cpu
  2025-10-15 15:47   ` Simon Horman
@ 2025-10-16  8:13     ` Lorenzo Bianconi
  0 siblings, 0 replies; 27+ messages in thread
From: Lorenzo Bianconi @ 2025-10-16  8:13 UTC (permalink / raw)
  To: Simon Horman
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, linux-arm-kernel, linux-mediatek, netdev,
	devicetree
[-- Attachment #1: Type: text/plain, Size: 1581 bytes --]
> On Wed, Oct 15, 2025 at 09:15:08AM +0200, Lorenzo Bianconi wrote:
> > Introduce airoha_ppe_foe_commit_sram_entry routine in order to configure
> > the SRAM PPE entries directly via the CPU instead of using the NPU APIs.
> > This is a preliminary patch to enable netfilter flowtable hw offload for
> > AN7583 SoC.
> > 
> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > ---
> >  drivers/net/ethernet/airoha/airoha_ppe.c | 30 +++++++++++++++++++++++-------
> >  1 file changed, 23 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
> > index fcfd2d8826a9c2f8f94f1962c2b2a69f67f7f598..0ee2e41489aaa9de9c1e99d242ee0bec11549750 100644
> > --- a/drivers/net/ethernet/airoha/airoha_ppe.c
> > +++ b/drivers/net/ethernet/airoha/airoha_ppe.c
> > @@ -662,6 +662,27 @@ static bool airoha_ppe_foe_compare_entry(struct airoha_flow_table_entry *e,
> >  	return !memcmp(&e->data.d, &hwe->d, len - sizeof(hwe->ib1));
> >  }
> >  
> > +static int airoha_ppe_foe_commit_sram_entry(struct airoha_ppe *ppe, u32 hash)
> > +{
> > +	struct airoha_foe_entry *hwe = ppe->foe + hash * sizeof(*hwe);
> > +	bool ppe2 = hash >= PPE_SRAM_NUM_ENTRIES;
> > +	u32 *ptr = (u32 *)hwe, val;
> > +	int i;
> > +
> > +	for (i = 0; i < sizeof(*hwe) / 4; i++)
> > +		airoha_fe_wr(ppe->eth, REG_PPE_RAM_ENTRY(ppe2, i), ptr[i]);
> 
> I realise that a similar pattern it is already used elsewhere,
> but '4' seems somewhat magic here.
ack, I will fix it in v2.
Regards,
Lorenzo
> 
> ...
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply	[flat|nested] 27+ messages in thread
 
 
- * [PATCH net-next 09/12] net: airoha: ppe: Flush PPE SRAM table during PPE setup
  2025-10-15  7:15 [PATCH net-next 00/12] net: airoha: Add AN7583 ethernet controller support Lorenzo Bianconi
                   ` (7 preceding siblings ...)
  2025-10-15  7:15 ` [PATCH net-next 08/12] net: airoha: ppe: Configure SRAM PPE entries via the cpu Lorenzo Bianconi
@ 2025-10-15  7:15 ` Lorenzo Bianconi
  2025-10-15 16:08   ` Simon Horman
  2025-10-15  7:15 ` [PATCH net-next 10/12] net: airoha: Select default ppe cpu port in airoha_dev_init() Lorenzo Bianconi
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 27+ messages in thread
From: Lorenzo Bianconi @ 2025-10-15  7:15 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Lorenzo Bianconi
  Cc: linux-arm-kernel, linux-mediatek, netdev, devicetree
Rely on airoha_ppe_foe_commit_sram_entry routine to flush SRAM PPE table
entries. This patch allow moving PPE SRAM flush during PPE setup and
avoid dumping uninitialized values via the debugfs if no entries are
offloaded yet.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/airoha/airoha_ppe.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index 0ee2e41489aaa9de9c1e99d242ee0bec11549750..0315aafe2fd596e5f5b27d2a2b3fb198ff2ec19f 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -1296,18 +1296,22 @@ static int airoha_ppe_flow_offload_cmd(struct airoha_eth *eth,
 	return -EOPNOTSUPP;
 }
 
-static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe,
-					 struct airoha_npu *npu)
+static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe)
 {
 	u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe);
 	struct airoha_foe_entry *hwe = ppe->foe;
-	int i;
+	int i, err = 0;
+
+	for (i = 0; i < sram_num_entries; i++) {
+		int err;
 
-	for (i = 0; i < PPE_SRAM_NUM_ENTRIES; i++)
 		memset(&hwe[i], 0, sizeof(*hwe));
+		err = airoha_ppe_foe_commit_sram_entry(ppe, i);
+		if (err)
+			break;
+	}
 
-	return npu->ops.ppe_flush_sram_entries(npu, ppe->foe_dma,
-					       sram_num_entries);
+	return err;
 }
 
 static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth)
@@ -1345,10 +1349,6 @@ static int airoha_ppe_offload_setup(struct airoha_eth *eth)
 	}
 
 	airoha_ppe_hw_init(ppe);
-	err = airoha_ppe_flush_sram_entries(ppe, npu);
-	if (err)
-		goto error_npu_put;
-
 	airoha_ppe_foe_flow_stats_reset(ppe, npu);
 
 	rcu_assign_pointer(eth->npu, npu);
@@ -1519,6 +1519,10 @@ int airoha_ppe_init(struct airoha_eth *eth)
 	if (!ppe->foe_check_time)
 		return -ENOMEM;
 
+	err = airoha_ppe_flush_sram_entries(ppe);
+	if (err)
+		return err;
+
 	err = rhashtable_init(ð->flow_table, &airoha_flow_table_params);
 	if (err)
 		return err;
-- 
2.51.0
^ permalink raw reply related	[flat|nested] 27+ messages in thread
- * Re: [PATCH net-next 09/12] net: airoha: ppe: Flush PPE SRAM table during PPE setup
  2025-10-15  7:15 ` [PATCH net-next 09/12] net: airoha: ppe: Flush PPE SRAM table during PPE setup Lorenzo Bianconi
@ 2025-10-15 16:08   ` Simon Horman
  0 siblings, 0 replies; 27+ messages in thread
From: Simon Horman @ 2025-10-15 16:08 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, linux-arm-kernel, linux-mediatek, netdev,
	devicetree
On Wed, Oct 15, 2025 at 09:15:09AM +0200, Lorenzo Bianconi wrote:
> Rely on airoha_ppe_foe_commit_sram_entry routine to flush SRAM PPE table
> entries. This patch allow moving PPE SRAM flush during PPE setup and
> avoid dumping uninitialized values via the debugfs if no entries are
> offloaded yet.
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
^ permalink raw reply	[flat|nested] 27+ messages in thread 
 
- * [PATCH net-next 10/12] net: airoha: Select default ppe cpu port in airoha_dev_init()
  2025-10-15  7:15 [PATCH net-next 00/12] net: airoha: Add AN7583 ethernet controller support Lorenzo Bianconi
                   ` (8 preceding siblings ...)
  2025-10-15  7:15 ` [PATCH net-next 09/12] net: airoha: ppe: Flush PPE SRAM table during PPE setup Lorenzo Bianconi
@ 2025-10-15  7:15 ` Lorenzo Bianconi
  2025-10-15 15:54   ` Simon Horman
  2025-10-15  7:15 ` [PATCH net-next 11/12] net: airoha: Refactor src port configuration in airhoha_set_gdm2_loopback Lorenzo Bianconi
  2025-10-15  7:15 ` [PATCH net-next 12/12] net: airoha: Add AN7583 SoC support Lorenzo Bianconi
  11 siblings, 1 reply; 27+ messages in thread
From: Lorenzo Bianconi @ 2025-10-15  7:15 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Lorenzo Bianconi
  Cc: linux-arm-kernel, linux-mediatek, netdev, devicetree
Select PPE default cpu port in airoha_dev_init routine.
For PPE2 always use secondary cpu port. For PPE1 select cpu port
according to the running QDMA.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/airoha/airoha_eth.c | 38 ++++++++++++++------------------
 1 file changed, 16 insertions(+), 22 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 99e7fea52c6db9c4686fcef368f21e25f21ced58..5f6b5ab52e0265f7bb56b008ca653d64e04ff2d2 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -531,25 +531,6 @@ static int airoha_fe_init(struct airoha_eth *eth)
 	/* disable IFC by default */
 	airoha_fe_clear(eth, REG_FE_CSR_IFC_CFG, FE_IFC_EN_MASK);
 
-	airoha_fe_wr(eth, REG_PPE_DFT_CPORT0(0),
-		     FIELD_PREP(DFT_CPORT_MASK(7), FE_PSE_PORT_CDM1) |
-		     FIELD_PREP(DFT_CPORT_MASK(6), FE_PSE_PORT_CDM1) |
-		     FIELD_PREP(DFT_CPORT_MASK(5), FE_PSE_PORT_CDM1) |
-		     FIELD_PREP(DFT_CPORT_MASK(4), FE_PSE_PORT_CDM1) |
-		     FIELD_PREP(DFT_CPORT_MASK(3), FE_PSE_PORT_CDM1) |
-		     FIELD_PREP(DFT_CPORT_MASK(2), FE_PSE_PORT_CDM1) |
-		     FIELD_PREP(DFT_CPORT_MASK(1), FE_PSE_PORT_CDM1) |
-		     FIELD_PREP(DFT_CPORT_MASK(0), FE_PSE_PORT_CDM1));
-	airoha_fe_wr(eth, REG_PPE_DFT_CPORT0(1),
-		     FIELD_PREP(DFT_CPORT_MASK(7), FE_PSE_PORT_CDM2) |
-		     FIELD_PREP(DFT_CPORT_MASK(6), FE_PSE_PORT_CDM2) |
-		     FIELD_PREP(DFT_CPORT_MASK(5), FE_PSE_PORT_CDM2) |
-		     FIELD_PREP(DFT_CPORT_MASK(4), FE_PSE_PORT_CDM2) |
-		     FIELD_PREP(DFT_CPORT_MASK(3), FE_PSE_PORT_CDM2) |
-		     FIELD_PREP(DFT_CPORT_MASK(2), FE_PSE_PORT_CDM2) |
-		     FIELD_PREP(DFT_CPORT_MASK(1), FE_PSE_PORT_CDM2) |
-		     FIELD_PREP(DFT_CPORT_MASK(0), FE_PSE_PORT_CDM2));
-
 	/* enable 1:N vlan action, init vlan table */
 	airoha_fe_set(eth, REG_MC_VLAN_EN, MC_VLAN_EN_MASK);
 
@@ -1756,8 +1737,10 @@ static void airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
 static int airoha_dev_init(struct net_device *dev)
 {
 	struct airoha_gdm_port *port = netdev_priv(dev);
-	struct airoha_eth *eth = port->qdma->eth;
-	u32 pse_port;
+	struct airoha_qdma *qdma = port->qdma;
+	struct airoha_eth *eth = qdma->eth;
+	u32 pse_port, fe_cpu_port;
+	u8 ppe_id;
 
 	airoha_set_macaddr(port, dev->dev_addr);
 
@@ -1770,16 +1753,27 @@ static int airoha_dev_init(struct net_device *dev)
 		fallthrough;
 	case 2:
 		if (airoha_ppe_is_enabled(eth, 1)) {
+			/* For PPE2 always use secondary cpu port. */
+			fe_cpu_port = FE_PSE_PORT_CDM2;
 			pse_port = FE_PSE_PORT_PPE2;
 			break;
 		}
 		fallthrough;
-	default:
+	default: {
+		u8 qdma_id = qdma - ð->qdma[0];
+
+		/* For PPE1 select cpu port according to the running QDMA. */
+		fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1;
 		pse_port = FE_PSE_PORT_PPE1;
 		break;
 	}
+	}
 
 	airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id), pse_port);
+	ppe_id = pse_port == FE_PSE_PORT_PPE2 ? 1 : 0;
+	airoha_fe_rmw(eth, REG_PPE_DFT_CPORT0(ppe_id),
+		      DFT_CPORT_MASK(port->id),
+		      fe_cpu_port << __ffs(DFT_CPORT_MASK(port->id)));
 
 	return 0;
 }
-- 
2.51.0
^ permalink raw reply related	[flat|nested] 27+ messages in thread
- * Re: [PATCH net-next 10/12] net: airoha: Select default ppe cpu port in airoha_dev_init()
  2025-10-15  7:15 ` [PATCH net-next 10/12] net: airoha: Select default ppe cpu port in airoha_dev_init() Lorenzo Bianconi
@ 2025-10-15 15:54   ` Simon Horman
  2025-10-16  8:51     ` Lorenzo Bianconi
  0 siblings, 1 reply; 27+ messages in thread
From: Simon Horman @ 2025-10-15 15:54 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, linux-arm-kernel, linux-mediatek, netdev,
	devicetree
On Wed, Oct 15, 2025 at 09:15:10AM +0200, Lorenzo Bianconi wrote:
> Select PPE default cpu port in airoha_dev_init routine.
> For PPE2 always use secondary cpu port. For PPE1 select cpu port
> according to the running QDMA.
Hi Lorenzo,
I think this could benefit from a few words around 'why?'.
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
...
^ permalink raw reply	[flat|nested] 27+ messages in thread 
- * Re: [PATCH net-next 10/12] net: airoha: Select default ppe cpu port in airoha_dev_init()
  2025-10-15 15:54   ` Simon Horman
@ 2025-10-16  8:51     ` Lorenzo Bianconi
  0 siblings, 0 replies; 27+ messages in thread
From: Lorenzo Bianconi @ 2025-10-16  8:51 UTC (permalink / raw)
  To: Simon Horman
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, linux-arm-kernel, linux-mediatek, netdev,
	devicetree
[-- Attachment #1: Type: text/plain, Size: 496 bytes --]
On Oct 15, Simon Horman wrote:
> On Wed, Oct 15, 2025 at 09:15:10AM +0200, Lorenzo Bianconi wrote:
> > Select PPE default cpu port in airoha_dev_init routine.
> > For PPE2 always use secondary cpu port. For PPE1 select cpu port
> > according to the running QDMA.
> 
> Hi Lorenzo,
> 
> I think this could benefit from a few words around 'why?'.
Hi Simon,
ack. I will do it in v2.
Regards,
Lorenzo
> 
> > 
> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> 
> ...
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply	[flat|nested] 27+ messages in thread 
 
 
- * [PATCH net-next 11/12] net: airoha: Refactor src port configuration in airhoha_set_gdm2_loopback
  2025-10-15  7:15 [PATCH net-next 00/12] net: airoha: Add AN7583 ethernet controller support Lorenzo Bianconi
                   ` (9 preceding siblings ...)
  2025-10-15  7:15 ` [PATCH net-next 10/12] net: airoha: Select default ppe cpu port in airoha_dev_init() Lorenzo Bianconi
@ 2025-10-15  7:15 ` Lorenzo Bianconi
  2025-10-15 16:05   ` Simon Horman
  2025-10-15  7:15 ` [PATCH net-next 12/12] net: airoha: Add AN7583 SoC support Lorenzo Bianconi
  11 siblings, 1 reply; 27+ messages in thread
From: Lorenzo Bianconi @ 2025-10-15  7:15 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Lorenzo Bianconi
  Cc: linux-arm-kernel, linux-mediatek, netdev, devicetree
AN7583 chipset relies on different definitions for source-port
identifier used for hw offloading. In order to support hw offloading
in AN7583 controller, refactor src port configuration in
airhoha_set_gdm2_loopback routine and introduce get_src_port_id
callback.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/airoha/airoha_eth.c  | 75 +++++++++++++++++++++----------
 drivers/net/ethernet/airoha/airoha_eth.h  | 11 +++--
 drivers/net/ethernet/airoha/airoha_regs.h |  5 +--
 3 files changed, 60 insertions(+), 31 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 5f6b5ab52e0265f7bb56b008ca653d64e04ff2d2..76c82750b3ae89a9fa81c64d3b7c3578b369480c 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1682,11 +1682,14 @@ static int airoha_dev_set_macaddr(struct net_device *dev, void *p)
 	return 0;
 }
 
-static void airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
+static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
 {
 	u32 pse_port = port->id == 3 ? FE_PSE_PORT_GDM3 : FE_PSE_PORT_GDM4;
 	struct airoha_eth *eth = port->qdma->eth;
 	u32 chan = port->id == 3 ? 4 : 0;
+	/* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */
+	u32 nbq = port->id == 3 ? 4 : 0;
+	int src_port;
 
 	/* Forward the traffic to the proper GDM port */
 	airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port);
@@ -1709,29 +1712,23 @@ static void airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
 	airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2));
 	airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2));
 
-	if (port->id == 3) {
-		/* FIXME: handle XSI_PCE1_PORT */
-		airoha_fe_rmw(eth, REG_FE_WAN_PORT,
-			      WAN1_EN_MASK | WAN1_MASK | WAN0_MASK,
-			      FIELD_PREP(WAN0_MASK, HSGMII_LAN_PCIE0_SRCPORT));
-		airoha_fe_rmw(eth,
-			      REG_SP_DFT_CPORT(HSGMII_LAN_PCIE0_SRCPORT >> 3),
-			      SP_CPORT_PCIE0_MASK,
-			      FIELD_PREP(SP_CPORT_PCIE0_MASK,
-					 FE_PSE_PORT_CDM2));
-	} else {
-		/* FIXME: handle XSI_USB_PORT */
+	src_port = eth->soc->ops.get_src_port_id(port, nbq);
+	if (src_port < 0)
+		return src_port;
+
+	airoha_fe_rmw(eth, REG_FE_WAN_PORT,
+		      WAN1_EN_MASK | WAN1_MASK | WAN0_MASK,
+		      FIELD_PREP(WAN0_MASK, src_port));
+	airoha_fe_rmw(eth, REG_SP_DFT_CPORT(src_port >> 3),
+		      SP_CPORT_MASK(src_port & 0x7),
+		      FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(src_port & 0x7)));
+
+	if (port->id != 3)
 		airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6,
 			      FC_ID_OF_SRC_PORT24_MASK,
 			      FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2));
-		airoha_fe_rmw(eth, REG_FE_WAN_PORT,
-			      WAN1_EN_MASK | WAN1_MASK | WAN0_MASK,
-			      FIELD_PREP(WAN0_MASK, HSGMII_LAN_ETH_SRCPORT));
-		airoha_fe_rmw(eth,
-			      REG_SP_DFT_CPORT(HSGMII_LAN_ETH_SRCPORT >> 3),
-			      SP_CPORT_ETH_MASK,
-			      FIELD_PREP(SP_CPORT_ETH_MASK, FE_PSE_PORT_CDM2));
-	}
+
+	return 0;
 }
 
 static int airoha_dev_init(struct net_device *dev)
@@ -1748,8 +1745,13 @@ static int airoha_dev_init(struct net_device *dev)
 	case 3:
 	case 4:
 		/* If GDM2 is active we can't enable loopback */
-		if (!eth->ports[1])
-			airhoha_set_gdm2_loopback(port);
+		if (!eth->ports[1]) {
+			int err;
+
+			err = airhoha_set_gdm2_loopback(port);
+			if (err)
+				return err;
+		}
 		fallthrough;
 	case 2:
 		if (airoha_ppe_is_enabled(eth, 1)) {
@@ -3055,11 +3057,38 @@ static const char * const en7581_xsi_rsts_names[] = {
 	"xfp-mac",
 };
 
+static int airoha_en7581_get_src_port_id(struct airoha_gdm_port *port, int nbq)
+{
+	switch (port->id) {
+	case 3:
+		/* 7581 SoC supports PCIe serdes on GDM3 port */
+		if (nbq == 4)
+			return HSGMII_LAN_7581_PCIE0_SRCPORT;
+		if (nbq == 5)
+			return HSGMII_LAN_7581_PCIE1_SRCPORT;
+		break;
+	case 4:
+		/* 7581 SoC supports eth and usb serdes on GDM4 port */
+		if (!nbq)
+			return HSGMII_LAN_7581_ETH_SRCPORT;
+		if (nbq == 1)
+			return HSGMII_LAN_7581_USB_SRCPORT;
+		break;
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
 static const struct airoha_eth_soc_data en7581_soc_data = {
 	.version = 0x7581,
 	.xsi_rsts_names = en7581_xsi_rsts_names,
 	.num_xsi_rsts = ARRAY_SIZE(en7581_xsi_rsts_names),
 	.num_ppe = 2,
+	.ops = {
+		.get_src_port_id = airoha_en7581_get_src_port_id,
+	},
 };
 
 static const struct of_device_id of_airoha_match[] = {
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index df168d798699d50c70fa5f87764de24e85994dfd..1b83b935520cd736a1eb376eff937340ed99a49a 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -67,10 +67,10 @@ enum {
 };
 
 enum {
-	HSGMII_LAN_PCIE0_SRCPORT = 0x16,
-	HSGMII_LAN_PCIE1_SRCPORT,
-	HSGMII_LAN_ETH_SRCPORT,
-	HSGMII_LAN_USB_SRCPORT,
+	HSGMII_LAN_7581_PCIE0_SRCPORT	= 0x16,
+	HSGMII_LAN_7581_PCIE1_SRCPORT,
+	HSGMII_LAN_7581_ETH_SRCPORT,
+	HSGMII_LAN_7581_USB_SRCPORT,
 };
 
 enum {
@@ -555,6 +555,9 @@ struct airoha_eth_soc_data {
 	const char * const *xsi_rsts_names;
 	int num_xsi_rsts;
 	int num_ppe;
+	struct {
+		int (*get_src_port_id)(struct airoha_gdm_port *port, int nbq);
+	} ops;
 };
 
 struct airoha_eth {
diff --git a/drivers/net/ethernet/airoha/airoha_regs.h b/drivers/net/ethernet/airoha/airoha_regs.h
index 69c5a143db8c079be0a6ecf41081cd3f5048c090..cc230f61c0049a663c011556280af736284d018d 100644
--- a/drivers/net/ethernet/airoha/airoha_regs.h
+++ b/drivers/net/ethernet/airoha/airoha_regs.h
@@ -383,10 +383,7 @@
 #define REG_MC_VLAN_DATA		0x2108
 
 #define REG_SP_DFT_CPORT(_n)		(0x20e0 + ((_n) << 2))
-#define SP_CPORT_PCIE1_MASK		GENMASK(31, 28)
-#define SP_CPORT_PCIE0_MASK		GENMASK(27, 24)
-#define SP_CPORT_USB_MASK		GENMASK(7, 4)
-#define SP_CPORT_ETH_MASK		GENMASK(7, 4)
+#define SP_CPORT_MASK(_n)		GENMASK(3 + ((_n) << 2), ((_n) << 2))
 
 #define REG_SRC_PORT_FC_MAP6		0x2298
 #define FC_ID_OF_SRC_PORT27_MASK	GENMASK(28, 24)
-- 
2.51.0
^ permalink raw reply related	[flat|nested] 27+ messages in thread
- * Re: [PATCH net-next 11/12] net: airoha: Refactor src port configuration in airhoha_set_gdm2_loopback
  2025-10-15  7:15 ` [PATCH net-next 11/12] net: airoha: Refactor src port configuration in airhoha_set_gdm2_loopback Lorenzo Bianconi
@ 2025-10-15 16:05   ` Simon Horman
  2025-10-16  8:36     ` Lorenzo Bianconi
  0 siblings, 1 reply; 27+ messages in thread
From: Simon Horman @ 2025-10-15 16:05 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, linux-arm-kernel, linux-mediatek, netdev,
	devicetree
On Wed, Oct 15, 2025 at 09:15:11AM +0200, Lorenzo Bianconi wrote:
> AN7583 chipset relies on different definitions for source-port
> identifier used for hw offloading. In order to support hw offloading
> in AN7583 controller, refactor src port configuration in
> airhoha_set_gdm2_loopback routine and introduce get_src_port_id
> callback.
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
>  drivers/net/ethernet/airoha/airoha_eth.c  | 75 +++++++++++++++++++++----------
>  drivers/net/ethernet/airoha/airoha_eth.h  | 11 +++--
>  drivers/net/ethernet/airoha/airoha_regs.h |  5 +--
>  3 files changed, 60 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
> index 5f6b5ab52e0265f7bb56b008ca653d64e04ff2d2..76c82750b3ae89a9fa81c64d3b7c3578b369480c 100644
> --- a/drivers/net/ethernet/airoha/airoha_eth.c
> +++ b/drivers/net/ethernet/airoha/airoha_eth.c
> @@ -1682,11 +1682,14 @@ static int airoha_dev_set_macaddr(struct net_device *dev, void *p)
>  	return 0;
>  }
>  
> -static void airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
> +static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
>  {
>  	u32 pse_port = port->id == 3 ? FE_PSE_PORT_GDM3 : FE_PSE_PORT_GDM4;
>  	struct airoha_eth *eth = port->qdma->eth;
>  	u32 chan = port->id == 3 ? 4 : 0;
> +	/* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */
> +	u32 nbq = port->id == 3 ? 4 : 0;
> +	int src_port;
I think this code could benefit for names (defines) for port ids.
It's a bit clearer in airoha_en7581_get_src_port_id(). But the
numbers seem kind of magic in this function.
>  
>  	/* Forward the traffic to the proper GDM port */
>  	airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port);
> @@ -1709,29 +1712,23 @@ static void airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
>  	airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2));
>  	airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2));
>  
> -	if (port->id == 3) {
> -		/* FIXME: handle XSI_PCE1_PORT */
> -		airoha_fe_rmw(eth, REG_FE_WAN_PORT,
> -			      WAN1_EN_MASK | WAN1_MASK | WAN0_MASK,
> -			      FIELD_PREP(WAN0_MASK, HSGMII_LAN_PCIE0_SRCPORT));
> -		airoha_fe_rmw(eth,
> -			      REG_SP_DFT_CPORT(HSGMII_LAN_PCIE0_SRCPORT >> 3),
> -			      SP_CPORT_PCIE0_MASK,
> -			      FIELD_PREP(SP_CPORT_PCIE0_MASK,
> -					 FE_PSE_PORT_CDM2));
> -	} else {
> -		/* FIXME: handle XSI_USB_PORT */
> +	src_port = eth->soc->ops.get_src_port_id(port, nbq);
> +	if (src_port < 0)
> +		return src_port;
> +
> +	airoha_fe_rmw(eth, REG_FE_WAN_PORT,
> +		      WAN1_EN_MASK | WAN1_MASK | WAN0_MASK,
> +		      FIELD_PREP(WAN0_MASK, src_port));
> +	airoha_fe_rmw(eth, REG_SP_DFT_CPORT(src_port >> 3),
> +		      SP_CPORT_MASK(src_port & 0x7),
> +		      FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(src_port & 0x7)));
Likewise, 3 and 0x7 a bit magical here.
> +
> +	if (port->id != 3)
>  		airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6,
>  			      FC_ID_OF_SRC_PORT24_MASK,
>  			      FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2));
... and 2 here.
> -		airoha_fe_rmw(eth, REG_FE_WAN_PORT,
> -			      WAN1_EN_MASK | WAN1_MASK | WAN0_MASK,
> -			      FIELD_PREP(WAN0_MASK, HSGMII_LAN_ETH_SRCPORT));
> -		airoha_fe_rmw(eth,
> -			      REG_SP_DFT_CPORT(HSGMII_LAN_ETH_SRCPORT >> 3),
> -			      SP_CPORT_ETH_MASK,
> -			      FIELD_PREP(SP_CPORT_ETH_MASK, FE_PSE_PORT_CDM2));
> -	}
> +
> +	return 0;
>  }
...
> @@ -3055,11 +3057,38 @@ static const char * const en7581_xsi_rsts_names[] = {
>  	"xfp-mac",
>  };
>  
> +static int airoha_en7581_get_src_port_id(struct airoha_gdm_port *port, int nbq)
> +{
> +	switch (port->id) {
> +	case 3:
> +		/* 7581 SoC supports PCIe serdes on GDM3 port */
> +		if (nbq == 4)
> +			return HSGMII_LAN_7581_PCIE0_SRCPORT;
> +		if (nbq == 5)
> +			return HSGMII_LAN_7581_PCIE1_SRCPORT;
> +		break;
> +	case 4:
> +		/* 7581 SoC supports eth and usb serdes on GDM4 port */
> +		if (!nbq)
> +			return HSGMII_LAN_7581_ETH_SRCPORT;
> +		if (nbq == 1)
> +			return HSGMII_LAN_7581_USB_SRCPORT;
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return -EINVAL;
> +}
...
^ permalink raw reply	[flat|nested] 27+ messages in thread
- * Re: [PATCH net-next 11/12] net: airoha: Refactor src port configuration in airhoha_set_gdm2_loopback
  2025-10-15 16:05   ` Simon Horman
@ 2025-10-16  8:36     ` Lorenzo Bianconi
  0 siblings, 0 replies; 27+ messages in thread
From: Lorenzo Bianconi @ 2025-10-16  8:36 UTC (permalink / raw)
  To: Simon Horman
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, linux-arm-kernel, linux-mediatek, netdev,
	devicetree
[-- Attachment #1: Type: text/plain, Size: 4531 bytes --]
> On Wed, Oct 15, 2025 at 09:15:11AM +0200, Lorenzo Bianconi wrote:
> > AN7583 chipset relies on different definitions for source-port
> > identifier used for hw offloading. In order to support hw offloading
> > in AN7583 controller, refactor src port configuration in
> > airhoha_set_gdm2_loopback routine and introduce get_src_port_id
> > callback.
> > 
> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > ---
> >  drivers/net/ethernet/airoha/airoha_eth.c  | 75 +++++++++++++++++++++----------
> >  drivers/net/ethernet/airoha/airoha_eth.h  | 11 +++--
> >  drivers/net/ethernet/airoha/airoha_regs.h |  5 +--
> >  3 files changed, 60 insertions(+), 31 deletions(-)
> > 
> > diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
> > index 5f6b5ab52e0265f7bb56b008ca653d64e04ff2d2..76c82750b3ae89a9fa81c64d3b7c3578b369480c 100644
> > --- a/drivers/net/ethernet/airoha/airoha_eth.c
> > +++ b/drivers/net/ethernet/airoha/airoha_eth.c
> > @@ -1682,11 +1682,14 @@ static int airoha_dev_set_macaddr(struct net_device *dev, void *p)
> >  	return 0;
> >  }
> >  
> > -static void airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
> > +static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
> >  {
> >  	u32 pse_port = port->id == 3 ? FE_PSE_PORT_GDM3 : FE_PSE_PORT_GDM4;
> >  	struct airoha_eth *eth = port->qdma->eth;
> >  	u32 chan = port->id == 3 ? 4 : 0;
> > +	/* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */
> > +	u32 nbq = port->id == 3 ? 4 : 0;
> > +	int src_port;
> 
> I think this code could benefit for names (defines) for port ids.
> It's a bit clearer in airoha_en7581_get_src_port_id(). But the
> numbers seem kind of magic in this function.
ack, I will fix it in v2.
Regards,
Lorenzo
> 
> >  
> >  	/* Forward the traffic to the proper GDM port */
> >  	airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port);
> > @@ -1709,29 +1712,23 @@ static void airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
> >  	airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2));
> >  	airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2));
> >  
> > -	if (port->id == 3) {
> > -		/* FIXME: handle XSI_PCE1_PORT */
> > -		airoha_fe_rmw(eth, REG_FE_WAN_PORT,
> > -			      WAN1_EN_MASK | WAN1_MASK | WAN0_MASK,
> > -			      FIELD_PREP(WAN0_MASK, HSGMII_LAN_PCIE0_SRCPORT));
> > -		airoha_fe_rmw(eth,
> > -			      REG_SP_DFT_CPORT(HSGMII_LAN_PCIE0_SRCPORT >> 3),
> > -			      SP_CPORT_PCIE0_MASK,
> > -			      FIELD_PREP(SP_CPORT_PCIE0_MASK,
> > -					 FE_PSE_PORT_CDM2));
> > -	} else {
> > -		/* FIXME: handle XSI_USB_PORT */
> > +	src_port = eth->soc->ops.get_src_port_id(port, nbq);
> > +	if (src_port < 0)
> > +		return src_port;
> > +
> > +	airoha_fe_rmw(eth, REG_FE_WAN_PORT,
> > +		      WAN1_EN_MASK | WAN1_MASK | WAN0_MASK,
> > +		      FIELD_PREP(WAN0_MASK, src_port));
> > +	airoha_fe_rmw(eth, REG_SP_DFT_CPORT(src_port >> 3),
> > +		      SP_CPORT_MASK(src_port & 0x7),
> > +		      FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(src_port & 0x7)));
> 
> Likewise, 3 and 0x7 a bit magical here.
> 
> > +
> > +	if (port->id != 3)
> >  		airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6,
> >  			      FC_ID_OF_SRC_PORT24_MASK,
> >  			      FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2));
> 
> ... and 2 here.
> 
> > -		airoha_fe_rmw(eth, REG_FE_WAN_PORT,
> > -			      WAN1_EN_MASK | WAN1_MASK | WAN0_MASK,
> > -			      FIELD_PREP(WAN0_MASK, HSGMII_LAN_ETH_SRCPORT));
> > -		airoha_fe_rmw(eth,
> > -			      REG_SP_DFT_CPORT(HSGMII_LAN_ETH_SRCPORT >> 3),
> > -			      SP_CPORT_ETH_MASK,
> > -			      FIELD_PREP(SP_CPORT_ETH_MASK, FE_PSE_PORT_CDM2));
> > -	}
> > +
> > +	return 0;
> >  }
> 
> ...
> 
> > @@ -3055,11 +3057,38 @@ static const char * const en7581_xsi_rsts_names[] = {
> >  	"xfp-mac",
> >  };
> >  
> > +static int airoha_en7581_get_src_port_id(struct airoha_gdm_port *port, int nbq)
> > +{
> > +	switch (port->id) {
> > +	case 3:
> > +		/* 7581 SoC supports PCIe serdes on GDM3 port */
> > +		if (nbq == 4)
> > +			return HSGMII_LAN_7581_PCIE0_SRCPORT;
> > +		if (nbq == 5)
> > +			return HSGMII_LAN_7581_PCIE1_SRCPORT;
> > +		break;
> > +	case 4:
> > +		/* 7581 SoC supports eth and usb serdes on GDM4 port */
> > +		if (!nbq)
> > +			return HSGMII_LAN_7581_ETH_SRCPORT;
> > +		if (nbq == 1)
> > +			return HSGMII_LAN_7581_USB_SRCPORT;
> > +		break;
> > +	default:
> > +		break;
> > +	}
> > +
> > +	return -EINVAL;
> > +}
> 
> ...
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply	[flat|nested] 27+ messages in thread
 
 
- * [PATCH net-next 12/12] net: airoha: Add AN7583 SoC support
  2025-10-15  7:15 [PATCH net-next 00/12] net: airoha: Add AN7583 ethernet controller support Lorenzo Bianconi
                   ` (10 preceding siblings ...)
  2025-10-15  7:15 ` [PATCH net-next 11/12] net: airoha: Refactor src port configuration in airhoha_set_gdm2_loopback Lorenzo Bianconi
@ 2025-10-15  7:15 ` Lorenzo Bianconi
  11 siblings, 0 replies; 27+ messages in thread
From: Lorenzo Bianconi @ 2025-10-15  7:15 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Lorenzo Bianconi
  Cc: linux-arm-kernel, linux-mediatek, netdev, devicetree
Introduce support for AN7583 ethernet controller to airoha-eth dirver.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/airoha/airoha_eth.c | 66 +++++++++++++++++++++++++++++---
 drivers/net/ethernet/airoha/airoha_eth.h | 11 ++++++
 drivers/net/ethernet/airoha/airoha_ppe.c |  3 ++
 3 files changed, 75 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 76c82750b3ae89a9fa81c64d3b7c3578b369480c..1e432922c8418777d2a9ba482924ef5d8f98081a 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1686,9 +1686,7 @@ static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
 {
 	u32 pse_port = port->id == 3 ? FE_PSE_PORT_GDM3 : FE_PSE_PORT_GDM4;
 	struct airoha_eth *eth = port->qdma->eth;
-	u32 chan = port->id == 3 ? 4 : 0;
-	/* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */
-	u32 nbq = port->id == 3 ? 4 : 0;
+	u32 chan, nbq;
 	int src_port;
 
 	/* Forward the traffic to the proper GDM port */
@@ -1698,6 +1696,8 @@ static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
 	/* Enable GDM2 loopback */
 	airoha_fe_wr(eth, REG_GDM_TXCHN_EN(2), 0xffffffff);
 	airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff);
+
+	chan = port->id == 3 ? airoha_is_7581(eth) ? 4 : 3 : 0;
 	airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2),
 		      LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK,
 		      FIELD_PREP(LPBK_CHAN_MASK, chan) |
@@ -1712,6 +1712,8 @@ static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
 	airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2));
 	airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2));
 
+	/* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */
+	nbq = port->id == 3 && airoha_is_7581(eth) ? 4 : 0;
 	src_port = eth->soc->ops.get_src_port_id(port, nbq);
 	if (src_port < 0)
 		return src_port;
@@ -1723,7 +1725,7 @@ static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
 		      SP_CPORT_MASK(src_port & 0x7),
 		      FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(src_port & 0x7)));
 
-	if (port->id != 3)
+	if (port->id != 3 && airoha_is_7581(eth))
 		airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6,
 			      FC_ID_OF_SRC_PORT24_MASK,
 			      FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2));
@@ -1878,6 +1880,20 @@ static u32 airoha_get_dsa_tag(struct sk_buff *skb, struct net_device *dev)
 #endif
 }
 
+static int airoha_get_fe_port(struct airoha_gdm_port *port)
+{
+	struct airoha_qdma *qdma = port->qdma;
+	struct airoha_eth *eth = qdma->eth;
+
+	switch (eth->soc->version) {
+	case 0x7583:
+		return port->id == 3 ? FE_PSE_PORT_GDM3 : port->id;
+	case 0x7581:
+	default:
+		return port->id == 4 ? FE_PSE_PORT_GDM4 : port->id;
+	}
+}
+
 static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
 				   struct net_device *dev)
 {
@@ -1918,7 +1934,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
 		}
 	}
 
-	fport = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id;
+	fport = airoha_get_fe_port(port);
 	msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
 	       FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f);
 
@@ -3081,6 +3097,35 @@ static int airoha_en7581_get_src_port_id(struct airoha_gdm_port *port, int nbq)
 	return -EINVAL;
 }
 
+static const char * const an7583_xsi_rsts_names[] = {
+	"xsi-mac",
+	"hsi0-mac",
+	"hsi1-mac",
+	"xfp-mac",
+};
+
+static int airoha_an7583_get_src_port_id(struct airoha_gdm_port *port, int nbq)
+{
+	switch (port->id) {
+	case 3:
+		/* 7583 SoC supports eth serdes on GDM3 port */
+		if (!nbq)
+			return HSGMII_LAN_7583_ETH_SRCPORT;
+		break;
+	case 4:
+		/* 7583 SoC supports PCIe and USB serdes on GDM4 port */
+		if (!nbq)
+			return HSGMII_LAN_7583_PCIE_SRCPORT;
+		if (nbq == 1)
+			return HSGMII_LAN_7583_USB_SRCPORT;
+		break;
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
 static const struct airoha_eth_soc_data en7581_soc_data = {
 	.version = 0x7581,
 	.xsi_rsts_names = en7581_xsi_rsts_names,
@@ -3091,8 +3136,19 @@ static const struct airoha_eth_soc_data en7581_soc_data = {
 	},
 };
 
+static const struct airoha_eth_soc_data an7583_soc_data = {
+	.version = 0x7583,
+	.xsi_rsts_names = an7583_xsi_rsts_names,
+	.num_xsi_rsts = ARRAY_SIZE(an7583_xsi_rsts_names),
+	.num_ppe = 1,
+	.ops = {
+		.get_src_port_id = airoha_an7583_get_src_port_id,
+	},
+};
+
 static const struct of_device_id of_airoha_match[] = {
 	{ .compatible = "airoha,en7581-eth", .data = &en7581_soc_data },
+	{ .compatible = "airoha,an7583-eth", .data = &an7583_soc_data },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, of_airoha_match);
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index 1b83b935520cd736a1eb376eff937340ed99a49a..35fca0a0ea9793388fda2598f7bc830f821cd926 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -73,6 +73,12 @@ enum {
 	HSGMII_LAN_7581_USB_SRCPORT,
 };
 
+enum {
+	HSGMII_LAN_7583_ETH_SRCPORT	= 0x16,
+	HSGMII_LAN_7583_PCIE_SRCPORT	= 0x18,
+	HSGMII_LAN_7583_USB_SRCPORT,
+};
+
 enum {
 	XSI_PCIE0_VIP_PORT_MASK	= BIT(22),
 	XSI_PCIE1_VIP_PORT_MASK	= BIT(23),
@@ -622,6 +628,11 @@ static inline bool airoha_is_7581(struct airoha_eth *eth)
 	return eth->soc->version == 0x7581;
 }
 
+static inline bool airoha_is_7583(struct airoha_eth *eth)
+{
+	return eth->soc->version == 0x7583;
+}
+
 bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
 			      struct airoha_gdm_port *port);
 
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index 0315aafe2fd596e5f5b27d2a2b3fb198ff2ec19f..85bc5301f4b8cdfba4e582a0d8368910545c9a5b 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -36,6 +36,9 @@ static int airoha_ppe_get_num_stats_entries(struct airoha_ppe *ppe,
 					    u32 *num_stats)
 {
 #ifdef CONFIG_NET_AIROHA_FLOW_STATS
+	if (airoha_is_7583(ppe->eth))
+		return -EOPNOTSUPP;
+
 	*num_stats = PPE_STATS_NUM_ENTRIES;
 	return 0;
 #else
-- 
2.51.0
^ permalink raw reply related	[flat|nested] 27+ messages in thread