]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net: airoha: Fix PPE cpu port configuration for GDM2 loopback path
authorLorenzo Bianconi <lorenzo@kernel.org>
Fri, 17 Apr 2026 15:24:41 +0000 (17:24 +0200)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 21 Apr 2026 12:46:22 +0000 (14:46 +0200)
When QoS loopback is enabled for GDM3 or GDM4, incoming packets are
forwarded to GDM2. However, the PPE cpu port for GDM2 is not configured
in this path, causing traffic originating from GDM3/GDM4, which may
be set up as WAN ports backed by QDMA1, to be incorrectly directed
to QDMA0 instead.
Configure the PPE cpu port for GDM2 when QoS loopback is active on
GDM3 or GDM4 to ensure traffic is routed to the correct QDMA instance.

Fixes: 9cd451d414f6 ("net: airoha: Add loopback support for GDM2")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260417-airoha-ppe-cpu-port-for-gdm2-loopback-v1-1-c7a9de0f6f57@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/airoha/airoha_eth.c
drivers/net/ethernet/airoha/airoha_eth.h
drivers/net/ethernet/airoha/airoha_ppe.c

index 19f67c7dd8e10544cedafe7d63fd8d1a3076c50d..376d91df5441155ed02dc5e9a22905fc3f217ccb 100644 (file)
@@ -1751,7 +1751,7 @@ static int airoha_set_gdm2_loopback(struct airoha_gdm_port *port)
 {
        struct airoha_eth *eth = port->qdma->eth;
        u32 val, pse_port, chan;
-       int src_port;
+       int i, src_port;
 
        /* Forward the traffic to the proper GDM port */
        pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3
@@ -1793,6 +1793,9 @@ static int airoha_set_gdm2_loopback(struct airoha_gdm_port *port)
                      SP_CPORT_MASK(val),
                      __field_prep(SP_CPORT_MASK(val), FE_PSE_PORT_CDM2));
 
+       for (i = 0; i < eth->soc->num_ppe; i++)
+               airoha_ppe_set_cpu_port(port, i, AIROHA_GDM2_IDX);
+
        if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) {
                u32 mask = FC_ID_OF_SRC_PORT_MASK(port->nbq);
 
@@ -1831,7 +1834,8 @@ static int airoha_dev_init(struct net_device *dev)
        }
 
        for (i = 0; i < eth->soc->num_ppe; i++)
-               airoha_ppe_set_cpu_port(port, i);
+               airoha_ppe_set_cpu_port(port, i,
+                                       airoha_get_fe_port(port));
 
        return 0;
 }
index 87b328cfefb08660eb83ef216a7dd02ba74d37a5..e389d2fe3b86f05d3ace1aaee8c640f6511b8d31 100644 (file)
@@ -654,7 +654,8 @@ int airoha_get_fe_port(struct airoha_gdm_port *port);
 bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
                              struct airoha_gdm_port *port);
 
-void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id);
+void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id,
+                            u8 fport);
 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);
index 859818676b69d288bf441216e01da102b02b4f90..5c9dff6bccd1e3a62e18c840d80ee864fded23f9 100644 (file)
@@ -85,10 +85,9 @@ static u32 airoha_ppe_get_timestamp(struct airoha_ppe *ppe)
        return FIELD_GET(AIROHA_FOE_IB1_BIND_TIMESTAMP, timestamp);
 }
 
-void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id)
+void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id, u8 fport)
 {
        struct airoha_qdma *qdma = port->qdma;
-       u8 fport = airoha_get_fe_port(port);
        struct airoha_eth *eth = qdma->eth;
        u8 qdma_id = qdma - &eth->qdma[0];
        u32 fe_cpu_port;
@@ -182,7 +181,8 @@ static void airoha_ppe_hw_init(struct airoha_ppe *ppe)
                        if (!port)
                                continue;
 
-                       airoha_ppe_set_cpu_port(port, i);
+                       airoha_ppe_set_cpu_port(port, i,
+                                               airoha_get_fe_port(port));
                }
        }
 }