]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: airoha: Fix VIP configuration for AN7583 SoC
authorLorenzo Bianconi <lorenzo@kernel.org>
Sun, 12 Apr 2026 07:57:29 +0000 (09:57 +0200)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 14 Apr 2026 11:26:23 +0000 (13:26 +0200)
EN7581 and AN7583 SoCs have different VIP definitions. Introduce
get_vip_port callback in airoha_eth_soc_data struct in order to take
into account EN7581 and AN7583 VIP register layout and definition
differences.
Introduce nbq parameter in airoha_gdm_port struct. At the moment nbq
is set statically to value previously used in airhoha_set_gdm2_loopback
routine and it will be read from device tree in subsequent patches.

Fixes: e4e5ce823bdd ("net: airoha: Add AN7583 SoC support")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260412-airoha-7583-vip-fix-v1-1-c35e02b054bb@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/airoha/airoha_eth.c
drivers/net/ethernet/airoha/airoha_eth.h

index 9e995094c32af500dab6b3e3752ab6be67f919c5..f484835af703cb2b78543661ec1a68802ac78922 100644 (file)
@@ -107,19 +107,7 @@ static int airoha_set_vip_for_gdm_port(struct airoha_gdm_port *port,
        struct airoha_eth *eth = port->qdma->eth;
        u32 vip_port;
 
-       switch (port->id) {
-       case AIROHA_GDM3_IDX:
-               /* FIXME: handle XSI_PCIE1_PORT */
-               vip_port = XSI_PCIE0_VIP_PORT_MASK;
-               break;
-       case AIROHA_GDM4_IDX:
-               /* FIXME: handle XSI_USB_PORT */
-               vip_port = XSI_ETH_VIP_PORT_MASK;
-               break;
-       default:
-               return 0;
-       }
-
+       vip_port = eth->soc->ops.get_vip_port(port, port->nbq);
        if (enable) {
                airoha_fe_set(eth, REG_FE_VIP_PORT_EN, vip_port);
                airoha_fe_set(eth, REG_FE_IFC_PORT_EN, vip_port);
@@ -1710,7 +1698,7 @@ static int airoha_dev_set_macaddr(struct net_device *dev, void *p)
 static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
 {
        struct airoha_eth *eth = port->qdma->eth;
-       u32 val, pse_port, chan, nbq;
+       u32 val, pse_port, chan;
        int src_port;
 
        /* Forward the traffic to the proper GDM port */
@@ -1740,9 +1728,7 @@ static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
        airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(AIROHA_GDM2_IDX));
        airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(AIROHA_GDM2_IDX));
 
-       /* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */
-       nbq = port->id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
-       src_port = eth->soc->ops.get_src_port_id(port, nbq);
+       src_port = eth->soc->ops.get_src_port_id(port, port->nbq);
        if (src_port < 0)
                return src_port;
 
@@ -2951,6 +2937,8 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth,
        port->qdma = qdma;
        port->dev = dev;
        port->id = id;
+       /* XXX: Read nbq from DTS */
+       port->nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
        eth->ports[p] = port;
 
        return airoha_metadata_dst_alloc(port);
@@ -3152,6 +3140,28 @@ static int airoha_en7581_get_src_port_id(struct airoha_gdm_port *port, int nbq)
        return -EINVAL;
 }
 
+static u32 airoha_en7581_get_vip_port(struct airoha_gdm_port *port, int nbq)
+{
+       switch (port->id) {
+       case AIROHA_GDM3_IDX:
+               if (nbq == 4)
+                       return XSI_PCIE0_VIP_PORT_MASK;
+               if (nbq == 5)
+                       return XSI_PCIE1_VIP_PORT_MASK;
+               break;
+       case AIROHA_GDM4_IDX:
+               if (!nbq)
+                       return XSI_ETH_VIP_PORT_MASK;
+               if (nbq == 1)
+                       return XSI_USB_VIP_PORT_MASK;
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
 static const char * const an7583_xsi_rsts_names[] = {
        "xsi-mac",
        "hsi0-mac",
@@ -3181,6 +3191,26 @@ static int airoha_an7583_get_src_port_id(struct airoha_gdm_port *port, int nbq)
        return -EINVAL;
 }
 
+static u32 airoha_an7583_get_vip_port(struct airoha_gdm_port *port, int nbq)
+{
+       switch (port->id) {
+       case AIROHA_GDM3_IDX:
+               if (!nbq)
+                       return XSI_ETH_VIP_PORT_MASK;
+               break;
+       case AIROHA_GDM4_IDX:
+               if (!nbq)
+                       return XSI_PCIE0_VIP_PORT_MASK;
+               if (nbq == 1)
+                       return XSI_USB_VIP_PORT_MASK;
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
 static const struct airoha_eth_soc_data en7581_soc_data = {
        .version = 0x7581,
        .xsi_rsts_names = en7581_xsi_rsts_names,
@@ -3188,6 +3218,7 @@ static const struct airoha_eth_soc_data en7581_soc_data = {
        .num_ppe = 2,
        .ops = {
                .get_src_port_id = airoha_en7581_get_src_port_id,
+               .get_vip_port = airoha_en7581_get_vip_port,
        },
 };
 
@@ -3198,6 +3229,7 @@ static const struct airoha_eth_soc_data an7583_soc_data = {
        .num_ppe = 1,
        .ops = {
                .get_src_port_id = airoha_an7583_get_src_port_id,
+               .get_vip_port = airoha_an7583_get_vip_port,
        },
 };
 
index a97903569335ff119891a4867c094ce982b24754..8bcd809e6f53e275770f1fc25d00b9baed8bf132 100644 (file)
@@ -536,6 +536,7 @@ struct airoha_gdm_port {
        struct airoha_qdma *qdma;
        struct net_device *dev;
        int id;
+       int nbq;
 
        struct airoha_hw_stats stats;
 
@@ -576,6 +577,7 @@ struct airoha_eth_soc_data {
        int num_ppe;
        struct {
                int (*get_src_port_id)(struct airoha_gdm_port *port, int nbq);
+               u32 (*get_vip_port)(struct airoha_gdm_port *port, int nbq);
        } ops;
 };