]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: airoha: Refactor src port configuration in airhoha_set_gdm2_loopback
authorLorenzo Bianconi <lorenzo@kernel.org>
Fri, 17 Oct 2025 09:06:20 +0000 (11:06 +0200)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 21 Oct 2025 11:07:05 +0000 (13:07 +0200)
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.

Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-11-f28319666667@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_regs.h

index 4e338c126dd3fa16f040960ff7f26d8214a9d6f7..4671f906a68c794d2ad05fbf5777fe22405c3d8f 100644 (file)
@@ -1682,13 +1682,17 @@ 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;
+       u32 val, pse_port, chan = port->id == AIROHA_GDM3_IDX ? 4 : 0;
        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 == AIROHA_GDM3_IDX ? 4 : 0;
+       int src_port;
 
        /* Forward the traffic to the proper GDM port */
+       pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3
+                                              : FE_PSE_PORT_GDM4;
        airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port);
        airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC);
 
@@ -1709,29 +1713,25 @@ 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));
+       val = src_port & SP_CPORT_DFT_MASK;
+       airoha_fe_rmw(eth,
+                     REG_SP_DFT_CPORT(src_port >> fls(SP_CPORT_DFT_MASK)),
+                     SP_CPORT_MASK(val),
+                     FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(val)));
+
+       if (port->id != AIROHA_GDM3_IDX)
                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 +1748,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)) {
@@ -3069,11 +3074,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[] = {
index df168d798699d50c70fa5f87764de24e85994dfd..e09579da8c78a99ef07ee7eef7be3cd6c1b5be76 100644 (file)
@@ -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 {
@@ -99,6 +99,13 @@ enum {
        CRSN_25 = 0x19,
 };
 
+enum airoha_gdm_index {
+       AIROHA_GDM1_IDX = 1,
+       AIROHA_GDM2_IDX = 2,
+       AIROHA_GDM3_IDX = 3,
+       AIROHA_GDM4_IDX = 4,
+};
+
 enum {
        FE_PSE_PORT_CDM1,
        FE_PSE_PORT_GDM1,
@@ -555,6 +562,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 {
index 69c5a143db8c079be0a6ecf41081cd3f5048c090..ebcce00d9bc6f0b0dfe3cabeddaa59b26c7b289d 100644 (file)
 #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_DFT_MASK              GENMASK(2, 0)
+#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)