]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
airoha: replace multi serdes patch with upstream kernel version 23849/head
authorChristian Marangi <ansuelsmth@gmail.com>
Wed, 17 Jun 2026 17:47:16 +0000 (19:47 +0200)
committerChristian Marangi <ansuelsmth@gmail.com>
Fri, 19 Jun 2026 07:06:15 +0000 (09:06 +0200)
Now that multi serdes patch are accepted upstream, reorder the current
patch in the 1xx numbering and add the kernel version tag.

Also replace the downstream patch with the exact version merged upstream.

Downstream PCS implementation is updated with a new revision for the
ethernet code.

Update any patch affected by these changes.

Link: https://github.com/openwrt/openwrt/pull/23849
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
35 files changed:
target/linux/airoha/patches-6.18/126-v7.1-net-airoha-Make-flow-control-source-port-mapping-dep.patch
target/linux/airoha/patches-6.18/147-v7.1-net-airoha-Fix-PPE-cpu-port-configuration-for-GDM2-l.patch
target/linux/airoha/patches-6.18/161-01-v7.2-net-airoha-Introduce-airoha_gdm_dev-struct.patch [moved from target/linux/airoha/patches-6.18/920-01-net-airoha-Introduce-airoha_gdm_dev-struct.patch with 63% similarity]
target/linux/airoha/patches-6.18/161-02-v7.2-net-airoha-Move-airoha_qdma-pointer-in-airoha_gdm_de.patch [moved from target/linux/airoha/patches-6.18/920-02-net-airoha-Move-airoha_qdma-pointer-in-airoha_gdm_de.patch with 72% similarity]
target/linux/airoha/patches-6.18/161-03-v7.2-net-airoha-Rely-on-airoha_gdm_dev-pointer-in-airoha_.patch [moved from target/linux/airoha/patches-6.18/920-03-net-airoha-Rely-on-airoha_gdm_dev-pointer-in-airoha_.patch with 75% similarity]
target/linux/airoha/patches-6.18/161-04-v7.2-net-airoha-Move-qos_sq_bmap-in-airoha_gdm_dev-struct.patch [moved from target/linux/airoha/patches-6.18/920-04-net-airoha-Move-qos_sq_bmap-in-airoha_gdm_dev-struct.patch with 80% similarity]
target/linux/airoha/patches-6.18/161-05-v7.2-net-airoha-Move-cpu-fwd-_tx_packets-in-airoha_gdm_de.patch [moved from target/linux/airoha/patches-6.18/920-05-net-airoha-Move-cpu-fwd-_tx_packets-in-airoha_gdm_de.patch with 76% similarity]
target/linux/airoha/patches-6.18/161-06-v7.2-net-airoha-Rename-airoha_set_gdm2_loopback-in-airoha.patch [new file with mode: 0644]
target/linux/airoha/patches-6.18/162-v7.2-net-airoha-Fix-use-after-free-in-metadata-dst-teardo.patch [new file with mode: 0644]
target/linux/airoha/patches-6.18/163-v7.2-net-airoha-Report-extack-error-to-the-user-if-airoha.patch [new file with mode: 0644]
target/linux/airoha/patches-6.18/164-v7.2-net-airoha-Add-NULL-check-for-of_reserved_mem_lookup.patch [new file with mode: 0644]
target/linux/airoha/patches-6.18/165-01-v7.2-net-airoha-Remove-private-net_device-pointer-in-airo.patch [new file with mode: 0644]
target/linux/airoha/patches-6.18/165-02-v7.2-net-airoha-Support-multiple-net_devices-for-a-single.patch [moved from target/linux/airoha/patches-6.18/920-06-net-airoha-Support-multiple-net_devices-for-a-single.patch with 77% similarity]
target/linux/airoha/patches-6.18/165-03-v7.2-net-airoha-Do-not-stop-GDM-port-if-it-is-shared.patch [moved from target/linux/airoha/patches-6.18/920-07-net-airoha-Do-not-stop-GDM-port-if-it-is-shared.patch with 70% similarity]
target/linux/airoha/patches-6.18/165-04-v7.2-net-airoha-Introduce-WAN-device-flag.patch [moved from target/linux/airoha/patches-6.18/920-08-net-airoha-Introduce-WAN-device-flag.patch with 83% similarity]
target/linux/airoha/patches-6.18/165-05-v7.2-net-airoha-Support-multiple-LAN-WAN-interfaces-for-h.patch [moved from target/linux/airoha/patches-6.18/920-09-net-airoha-Support-multiple-LAN-WAN-interfaces-for-h.patch with 75% similarity]
target/linux/airoha/patches-6.18/166-v7.2-net-airoha-better-handle-MIBs-for-GDM-ports-with-mul.patch [moved from target/linux/airoha/patches-6.18/920-14-net-airoha-Better-handle-MIB-for-GDM-with-multiple-p.patch with 87% similarity]
target/linux/airoha/patches-6.18/167-v7.2-net-airoha-use-int-instead-of-atomic_t-for-qdma-user.patch [moved from target/linux/airoha/patches-6.18/916-01-net-airoha-use-int-instead-of-atomic_t-for-qdma-user.patch with 75% similarity]
target/linux/airoha/patches-6.18/168-v7.2-net-airoha-move-get_sport-callback-at-the-beginning-.patch [new file with mode: 0644]
target/linux/airoha/patches-6.18/169-v7.2-net-airoha-simplify-WAN-device-check-in-airoha_dev_i.patch [moved from target/linux/airoha/patches-6.18/922-net-airoha-simplify-WAN-device-check-in-airoha_dev_i.patch with 77% similarity]
target/linux/airoha/patches-6.18/310-02-net-airoha-deassert-XSI-line-on-hw-init.patch
target/linux/airoha/patches-6.18/310-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch [deleted file]
target/linux/airoha/patches-6.18/310-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch
target/linux/airoha/patches-6.18/310-07-airoha-ethernet-drop-xsi-mac-reset.patch
target/linux/airoha/patches-6.18/310-10-net-airoha-add-phylink-support-for-GDM2-3-4.patch [deleted file]
target/linux/airoha/patches-6.18/310-10-net-airoha-add-phylink-support.patch [new file with mode: 0644]
target/linux/airoha/patches-6.18/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch [deleted file]
target/linux/airoha/patches-6.18/606-net-airoha-disable-external-phy-code-if-PCS_AIROHA-i.patch [deleted file]
target/linux/airoha/patches-6.18/915-02-net-airoha-Set-hw-QoS-parameter-according-to-the-pac.patch
target/linux/airoha/patches-6.18/916-02-net-airoha-Implement-HW-GRO-TCP-support.patch
target/linux/airoha/patches-6.18/920-10-net-airoha-Rename-airoha_set_gdm2_loopback-in-airoha.patch [deleted file]
target/linux/airoha/patches-6.18/920-12-net-airoha-defer-GDM3-GDM4-WAN-mode-and-GDM2-loopbac.patch
target/linux/airoha/patches-6.18/920-13-net-airoha-Rework-MTU-configuration.patch
target/linux/airoha/patches-6.18/920-15-net-airoha-fix-wrong-airoha_get_fe_port.patch
target/linux/airoha/patches-6.18/921-net-airoha-move-get_sport-callback-at-the-beginning-.patch [deleted file]

index 7e078d086535d9733b054bd7fe0ba2aa496c90d3..6be83a301b0bba666cd8ff9ff187da01318709e4 100644 (file)
@@ -28,7 +28,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 -                            FC_ID_OF_SRC_PORT24_MASK,
 -                            FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2));
 +      if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) {
-+              u32 mask = FC_ID_OF_SRC_PORT_MASK(nbq);
++              u32 mask = FC_ID_OF_SRC_PORT_MASK(port->nbq);
 +
 +              airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, mask,
 +                            __field_prep(mask, AIROHA_GDM2_IDX));
index 417adfd7db518d8f6987394f6aceb6d6b53d5b9e..56ac972956323a244bd1f82680b034f2fe7e919b 100644 (file)
@@ -41,7 +41,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 +              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(nbq);
+               u32 mask = FC_ID_OF_SRC_PORT_MASK(port->nbq);
  
 @@ -1873,7 +1876,8 @@ static int airoha_dev_init(struct net_de
        }
similarity index 63%
rename from target/linux/airoha/patches-6.18/920-01-net-airoha-Introduce-airoha_gdm_dev-struct.patch
rename to target/linux/airoha/patches-6.18/161-01-v7.2-net-airoha-Introduce-airoha_gdm_dev-struct.patch
index f92593c504a29ae60329ae0337656c1480784da4..f6c5f766f217f0efa22887e0f6de2f7c06ada2d1 100644 (file)
@@ -1,8 +1,7 @@
-From e15783f7c987e199ecf80b3d858ed5a86d33c508 Mon Sep 17 00:00:00 2001
-Message-ID: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
+From ec6c391bcca748bca041d5db92ff3bc4c99b3572 Mon Sep 17 00:00:00 2001
 From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 1 Nov 2025 11:25:52 +0100
-Subject: [PATCH 01/13] net: airoha: Introduce airoha_gdm_dev struct
+Date: Wed, 27 May 2026 12:21:15 +0200
+Subject: [PATCH 1/6] net: airoha: Introduce airoha_gdm_dev struct
 
 EN7581 and AN7583 SoCs support connecting multiple external SerDes to GDM3
 or GDM4 ports via a hw arbiter that manages the traffic in a TDM manner.
@@ -17,6 +16,8 @@ connected to the same GDM port.
 
 Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20260527-airoha-eth-multi-serdes-preliminary-v1-1-ec6ed73ef7fc@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 ---
  drivers/net/ethernet/airoha/airoha_eth.c | 312 ++++++++++++++---------
  drivers/net/ethernet/airoha/airoha_eth.h |  13 +-
@@ -25,18 +26,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 
 --- a/drivers/net/ethernet/airoha/airoha_eth.c
 +++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -483,8 +483,9 @@ static bool airoha_fe_lro_is_enabled(str
-                            LRO_RXQ_EN_MASK);
- }
--static void airoha_dev_lro_enable(struct airoha_gdm_port *port)
-+static void airoha_dev_lro_enable(struct airoha_gdm_dev *dev)
- {
-+      struct airoha_gdm_port *port = dev->port;
-       struct airoha_qdma *qdma = port->qdma;
-       struct airoha_eth *eth = qdma->eth;
-       int qdma_id = qdma - &eth->qdma[0];
-@@ -843,6 +844,7 @@ static int airoha_qdma_rx_process(struct
+@@ -600,6 +600,7 @@ static int airoha_qdma_rx_process(struct
                struct airoha_qdma_desc *desc = &q->desc[q->tail];
                u32 hash, reason, msg1, desc_ctrl;
                struct airoha_gdm_port *port;
@@ -44,21 +34,29 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                int data_len, len, p;
                struct page *page;
  
-@@ -869,8 +871,12 @@ static int airoha_qdma_rx_process(struct
+@@ -626,6 +627,10 @@ static int airoha_qdma_rx_process(struct
                        goto free_frag;
  
                port = eth->ports[p];
 +              if (!port->dev)
 +                      goto free_frag;
 +
-+              netdev = netdev_from_priv(port->dev);
++              netdev = port->dev->dev;
                if (!q->skb) { /* first buffer */
--                      q->skb = airoha_qdma_build_rx_skb(q, desc, e, port->dev);
-+                      q->skb = airoha_qdma_build_rx_skb(q, desc, e, netdev);
-                       if (!q->skb)
-                               goto free_frag;
+                       q->skb = napi_build_skb(e->buf - AIROHA_RX_HEADROOM,
+                                               q->buf_size);
+@@ -635,8 +640,8 @@ static int airoha_qdma_rx_process(struct
+                       skb_reserve(q->skb, AIROHA_RX_HEADROOM);
+                       __skb_put(q->skb, len);
+                       skb_mark_for_recycle(q->skb);
+-                      q->skb->dev = port->dev;
+-                      q->skb->protocol = eth_type_trans(q->skb, port->dev);
++                      q->skb->dev = netdev;
++                      q->skb->protocol = eth_type_trans(q->skb, netdev);
+                       q->skb->ip_summed = CHECKSUM_UNNECESSARY;
+                       skb_record_rx_queue(q->skb, qid);
                } else { /* scattered frame */
-@@ -888,7 +894,7 @@ static int airoha_qdma_rx_process(struct
+@@ -654,7 +659,7 @@ static int airoha_qdma_rx_process(struct
                if (FIELD_GET(QDMA_DESC_MORE_MASK, desc_ctrl))
                        continue;
  
@@ -67,55 +65,33 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                        /* PPE module requires untagged packets to work
                         * properly and it provides DSA port index via the
                         * DMA descriptor. Report DSA tag to the DSA stack
-@@ -1091,6 +1097,7 @@ static void airoha_qdma_wake_netdev_txqs
+@@ -848,6 +853,7 @@ static void airoha_qdma_wake_netdev_txqs
  
        for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
                struct airoha_gdm_port *port = eth->ports[i];
-+              struct net_device *netdev;
++              struct airoha_gdm_dev *dev;
                int j;
  
                if (!port)
-@@ -1099,11 +1106,12 @@ static void airoha_qdma_wake_netdev_txqs
+@@ -856,11 +862,12 @@ static void airoha_qdma_wake_netdev_txqs
                if (port->qdma != qdma)
                        continue;
  
 -              for (j = 0; j < port->dev->num_tx_queues; j++) {
-+              netdev = netdev_from_priv(port->dev);
-+              for (j = 0; j < netdev->num_tx_queues; j++) {
++              dev = port->dev;
++              for (j = 0; j < dev->dev->num_tx_queues; j++) {
                        if (airoha_qdma_get_txq(qdma, j) != qid)
                                continue;
  
 -                      netif_wake_subqueue(port->dev, j);
-+                      netif_wake_subqueue(netdev, j);
++                      netif_wake_subqueue(dev->dev, j);
                }
        }
        q->txq_stopped = false;
-@@ -1947,9 +1955,10 @@ static void airoha_update_hw_stats(struc
+@@ -1700,19 +1707,20 @@ static void airoha_update_hw_stats(struc
        spin_unlock(&port->stats.lock);
  }
  
--static void airoha_update_netdev_features(struct airoha_gdm_port *port)
-+static void airoha_update_netdev_features(struct airoha_gdm_dev *dev)
- {
--      struct airoha_eth *eth = port->eth;
-+      struct airoha_gdm_port *port = dev->port;
-+      struct airoha_eth *eth = dev->eth;
-       int i;
-       for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
-@@ -1959,7 +1968,7 @@ static void airoha_update_netdev_feature
-               if (!p)
-                       continue;
--              netdev = p->dev;
-+              netdev = netdev_from_priv(p->dev);
-               if (netdev->reg_state != NETREG_REGISTERED)
-                       continue;
-@@ -1967,10 +1976,11 @@ static void airoha_update_netdev_feature
-       }
- }
 -static int airoha_dev_open(struct net_device *dev)
 +static int airoha_dev_open(struct net_device *netdev)
  {
@@ -125,35 +101,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +      struct airoha_gdm_dev *dev = netdev_priv(netdev);
 +      struct airoha_gdm_port *port = dev->port;
        struct airoha_qdma *qdma = port->qdma;
-       struct airoha_eth *eth = qdma->eth;
-       int qdma_id = qdma - &eth->qdma[0];
-@@ -1981,31 +1991,32 @@ static int airoha_dev_open(struct net_de
-        * the same QDMA if LRO is enabled on any device sharing it.
-        */
-       if (qdma->users && airoha_fe_lro_is_enabled(eth, qdma_id)) {
--              netdev_warn(dev, "required to disable HW GRO on QDMA%d\n",
-+              netdev_warn(netdev, "required to disable HW GRO on QDMA%d\n",
-                           qdma_id);
-               return -EBUSY;
-       }
- #if defined(CONFIG_PCS_AIROHA)
-       if (airhoa_is_phy_external(port)) {
--              err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0);
-+              err = phylink_of_phy_connect(dev->phylink,
-+                                           netdev->dev.of_node, 0);
-               if (err) {
--                      netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
--                                 err);
-+                      netdev_err(netdev, "%s: could not attach PHY: %d\n",
-+                                 __func__, err);
-                       return err;
-               }
--              phylink_start(port->phylink);
-+              phylink_start(dev->phylink);
-       }
- #endif
+       u32 pse_port = FE_PSE_PORT_PPE1;
  
 -      netif_tx_start_all_queues(dev);
 +      netif_tx_start_all_queues(netdev);
@@ -161,24 +109,12 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        if (err)
                return err;
  
-       /* It seems GDM3 and GDM4 needs SPORT enabled to correctly work */
--      if (netdev_uses_dsa(dev) || port->id > 2)
-+      if (netdev_uses_dsa(netdev) || port->id > 2)
-               airoha_fe_set(eth, REG_GDM_INGRESS_CFG(port->id),
+-      if (netdev_uses_dsa(dev))
++      if (netdev_uses_dsa(netdev))
+               airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
                              GDM_STAG_EN_MASK);
        else
-@@ -2029,25 +2040,26 @@ static int airoha_dev_open(struct net_de
-       airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id),
-                                   pse_port);
--      if (dev->features & NETIF_F_GRO_HW)
--              airoha_dev_lro_enable(port);
-+      if (netdev->features & NETIF_F_GRO_HW)
-+              airoha_dev_lro_enable(dev);
--      airoha_update_netdev_features(port);
-+      airoha_update_netdev_features(dev);
+@@ -1740,16 +1748,17 @@ static int airoha_dev_open(struct net_de
        return 0;
  }
  
@@ -189,7 +125,6 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +      struct airoha_gdm_dev *dev = netdev_priv(netdev);
 +      struct airoha_gdm_port *port = dev->port;
        struct airoha_qdma *qdma = port->qdma;
-       struct airoha_eth *eth = qdma->eth;
        int i;
  
 -      netif_tx_disable(dev);
@@ -200,24 +135,9 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +      for (i = 0; i < netdev->num_tx_queues; i++)
 +              netdev_tx_reset_subqueue(netdev, i);
  
-       airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id),
+       airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
                                    FE_PSE_PORT_DROP);
-@@ -2065,28 +2077,29 @@ static int airoha_dev_stop(struct net_de
-               }
-       }
--      airoha_update_netdev_features(port);
-+      airoha_update_netdev_features(dev);
- #if defined(CONFIG_PCS_AIROHA)
-       if (airhoa_is_phy_external(port)) {
--              phylink_stop(port->phylink);
--              phylink_disconnect_phy(port->phylink);
-+              phylink_stop(dev->phylink);
-+              phylink_disconnect_phy(dev->phylink);
-       }
- #endif
+@@ -1770,16 +1779,17 @@ static int airoha_dev_stop(struct net_de
        return 0;
  }
  
@@ -239,7 +159,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        return 0;
  }
-@@ -2152,16 +2165,17 @@ static int airoha_set_gdm2_loopback(stru
+@@ -1845,16 +1855,17 @@ static int airoha_set_gdm2_loopback(stru
        return 0;
  }
  
@@ -257,12 +177,12 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        port->qdma = &eth->qdma[!airoha_is_lan_gdm_port(port)];
 -      port->dev->irq = port->qdma->irq_banks[0].irq;
 -      airoha_set_macaddr(port, dev->dev_addr);
-+      netdev->irq = port->qdma->irq_banks[0].irq;
++      dev->dev->irq = port->qdma->irq_banks[0].irq;
 +      airoha_set_macaddr(port, netdev->dev_addr);
  
        switch (port->id) {
        case AIROHA_GDM3_IDX:
-@@ -2186,10 +2200,11 @@ static int airoha_dev_init(struct net_de
+@@ -1879,10 +1890,11 @@ static int airoha_dev_init(struct net_de
        return 0;
  }
  
@@ -276,7 +196,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        unsigned int start;
  
        airoha_update_hw_stats(port);
-@@ -2208,36 +2223,39 @@ static void airoha_dev_get_stats64(struc
+@@ -1901,36 +1913,39 @@ static void airoha_dev_get_stats64(struc
        } while (u64_stats_fetch_retry(&port->stats.syncp, start));
  }
  
@@ -323,46 +243,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  }
  
  static u32 airoha_get_dsa_tag(struct sk_buff *skb, struct net_device *dev)
-@@ -2300,10 +2318,11 @@ int airoha_get_fe_port(struct airoha_gdm
-       }
- }
--static netdev_features_t airoha_dev_fix_features(struct net_device *dev,
-+static netdev_features_t airoha_dev_fix_features(struct net_device *netdev,
-                                                netdev_features_t features)
- {
--      struct airoha_gdm_port *port = netdev_priv(dev);
-+      struct airoha_gdm_dev *dev = netdev_priv(netdev);
-+      struct airoha_gdm_port *port = dev->port;
-       struct airoha_qdma *qdma = port->qdma;
-       if (qdma->users > 1)
-@@ -2312,11 +2331,12 @@ static netdev_features_t airoha_dev_fix_
-       return features;
- }
--static int airoha_dev_set_features(struct net_device *dev,
-+static int airoha_dev_set_features(struct net_device *netdev,
-                                  netdev_features_t features)
- {
--      netdev_features_t diff = dev->features ^ features;
--      struct airoha_gdm_port *port = netdev_priv(dev);
-+      netdev_features_t diff = netdev->features ^ features;
-+      struct airoha_gdm_dev *dev = netdev_priv(netdev);
-+      struct airoha_gdm_port *port = dev->port;
-       struct airoha_qdma *qdma = port->qdma;
-       struct airoha_eth *eth = qdma->eth;
-       int qdma_id = qdma - &eth->qdma[0];
-@@ -2325,7 +2345,7 @@ static int airoha_dev_set_features(struc
-               return 0;
-       if (features & NETIF_F_GRO_HW)
--              airoha_dev_lro_enable(port);
-+              airoha_dev_lro_enable(dev);
-       else
-               airoha_fe_lro_disable(eth, qdma_id);
-@@ -2333,9 +2353,10 @@ static int airoha_dev_set_features(struc
+@@ -1994,9 +2009,10 @@ int airoha_get_fe_port(struct airoha_gdm
  }
  
  static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
@@ -375,7 +256,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        struct airoha_qdma *qdma = port->qdma;
        u32 nr_frags, tag, msg0, msg1, len;
        struct airoha_queue_entry *e;
-@@ -2348,7 +2369,7 @@ static netdev_tx_t airoha_dev_xmit(struc
+@@ -2009,7 +2025,7 @@ static netdev_tx_t airoha_dev_xmit(struc
        u8 fport;
  
        qid = airoha_qdma_get_txq(qdma, skb_get_queue_mapping(skb));
@@ -384,7 +265,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK,
                          qid / AIROHA_NUM_QOS_QUEUES) |
-@@ -2384,7 +2405,7 @@ static netdev_tx_t airoha_dev_xmit(struc
+@@ -2045,7 +2061,7 @@ static netdev_tx_t airoha_dev_xmit(struc
  
        spin_lock_bh(&q->lock);
  
@@ -393,7 +274,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        nr_frags = 1 + skb_shinfo(skb)->nr_frags;
  
        if (q->queued + nr_frags >= q->ndesc) {
-@@ -2408,9 +2429,9 @@ static netdev_tx_t airoha_dev_xmit(struc
+@@ -2069,9 +2085,9 @@ static netdev_tx_t airoha_dev_xmit(struc
                dma_addr_t addr;
                u32 val;
  
@@ -405,7 +286,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                        goto error_unmap;
  
                list_move_tail(&e->list, &tx_list);
-@@ -2459,7 +2480,7 @@ static netdev_tx_t airoha_dev_xmit(struc
+@@ -2120,7 +2136,7 @@ static netdev_tx_t airoha_dev_xmit(struc
  
  error_unmap:
        list_for_each_entry(e, &tx_list, list) {
@@ -414,7 +295,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                                 DMA_TO_DEVICE);
                e->dma_addr = 0;
        }
-@@ -2468,25 +2489,27 @@ error_unmap:
+@@ -2129,25 +2145,27 @@ error_unmap:
        spin_unlock_bh(&q->lock);
  error:
        dev_kfree_skb_any(skb);
@@ -447,7 +328,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        unsigned int start;
  
        airoha_update_hw_stats(port);
-@@ -2514,11 +2537,12 @@ static const struct ethtool_rmon_hist_ra
+@@ -2175,11 +2193,12 @@ static const struct ethtool_rmon_hist_ra
  };
  
  static void
@@ -462,7 +343,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        struct airoha_hw_stats *hw_stats = &port->stats;
        unsigned int start;
  
-@@ -2543,11 +2567,12 @@ airoha_ethtool_get_rmon_stats(struct net
+@@ -2204,11 +2223,12 @@ airoha_ethtool_get_rmon_stats(struct net
        } while (u64_stats_fetch_retry(&port->stats.syncp, start));
  }
  
@@ -477,7 +358,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        int i;
  
        for (i = 0; i < AIROHA_NUM_TX_RING; i++)
-@@ -2632,10 +2657,12 @@ static int airoha_qdma_set_tx_ets_sched(
+@@ -2293,10 +2313,12 @@ static int airoha_qdma_set_tx_ets_sched(
                                             ARRAY_SIZE(w));
  }
  
@@ -492,7 +373,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        u64 cpu_tx_packets = airoha_qdma_rr(port->qdma,
                                            REG_CNTR_VAL(channel << 1));
        u64 fwd_tx_packets = airoha_qdma_rr(port->qdma,
-@@ -2897,11 +2924,12 @@ static int airoha_qdma_set_trtcm_token_b
+@@ -2558,11 +2580,12 @@ static int airoha_qdma_set_trtcm_token_b
                                           mode, val);
  }
  
@@ -507,7 +388,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        int i, err;
  
        for (i = 0; i <= TRTCM_PEAK_MODE; i++) {
-@@ -2921,20 +2949,22 @@ static int airoha_qdma_set_tx_rate_limit
+@@ -2582,20 +2605,22 @@ static int airoha_qdma_set_tx_rate_limit
        return 0;
  }
  
@@ -534,7 +415,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        if (err) {
                NL_SET_ERR_MSG_MOD(opt->extack,
                                   "failed configuring htb offload");
-@@ -2944,9 +2974,10 @@ static int airoha_tc_htb_alloc_leaf_queu
+@@ -2605,9 +2630,10 @@ static int airoha_tc_htb_alloc_leaf_queu
        if (opt->command == TC_HTB_NODE_MODIFY)
                return 0;
  
@@ -547,7 +428,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                NL_SET_ERR_MSG_MOD(opt->extack,
                                   "failed setting real_num_tx_queues");
                return err;
-@@ -3036,11 +3067,12 @@ static int airoha_tc_matchall_act_valida
+@@ -2697,11 +2723,12 @@ static int airoha_tc_matchall_act_valida
        return 0;
  }
  
@@ -562,7 +443,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        u32 rate = 0, bucket_size = 0;
  
        switch (f->command) {
-@@ -3075,18 +3107,19 @@ static int airoha_dev_tc_matchall(struct
+@@ -2736,18 +2763,19 @@ static int airoha_dev_tc_matchall(struct
  static int airoha_dev_setup_tc_block_cb(enum tc_setup_type type,
                                        void *type_data, void *cb_priv)
  {
@@ -586,7 +467,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        default:
                return -EOPNOTSUPP;
        }
-@@ -3133,47 +3166,51 @@ static int airoha_dev_setup_tc_block(str
+@@ -2794,47 +2822,51 @@ static int airoha_dev_setup_tc_block(str
        }
  }
  
@@ -650,7 +531,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        if (!test_bit(channel, port->qos_sq_bmap)) {
                NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
-@@ -3209,8 +3246,8 @@ static int airoha_tc_setup_qdisc_htb(str
+@@ -2870,8 +2902,8 @@ static int airoha_tc_setup_qdisc_htb(str
        return 0;
  }
  
@@ -661,7 +542,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  {
        switch (type) {
        case TC_SETUP_QDISC_ETS:
-@@ -3283,13 +3320,18 @@ static void airoha_metadata_dst_free(str
+@@ -2937,25 +2969,81 @@ static void airoha_metadata_dst_free(str
        }
  }
  
@@ -683,95 +564,8 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                        return true;
        }
  
-@@ -3301,8 +3343,9 @@ static void airoha_mac_link_up(struct ph
-                              unsigned int mode, phy_interface_t interface,
-                              int speed, int duplex, bool tx_pause, bool rx_pause)
- {
--      struct airoha_gdm_port *port = container_of(config, struct airoha_gdm_port,
--                                                  phylink_config);
-+      struct airoha_gdm_dev *dev = container_of(config, struct airoha_gdm_dev,
-+                                                phylink_config);
-+      struct airoha_gdm_port *port = dev->port;
-       struct airoha_qdma *qdma = port->qdma;
-       struct airoha_eth *eth = qdma->eth;
-       u32 frag_size_tx, frag_size_rx;
-@@ -3358,65 +3401,121 @@ static int airoha_fill_available_pcs(str
-                                       &num_available_pcs);
- }
--static int airoha_setup_phylink(struct net_device *dev)
-+static int airoha_setup_phylink(struct net_device *netdev)
- {
--      struct airoha_gdm_port *port = netdev_priv(dev);
--      struct device_node *np = dev->dev.of_node;
-+      struct airoha_gdm_dev *dev = netdev_priv(netdev);
-+      struct device_node *np = netdev->dev.of_node;
-       phy_interface_t phy_mode;
-       struct phylink *phylink;
-       int err;
-       err = of_get_phy_mode(np, &phy_mode);
-       if (err) {
--              dev_err(&dev->dev, "incorrect phy-mode\n");
-+              dev_err(&netdev->dev, "incorrect phy-mode\n");
-               return err;
-       }
--      port->phylink_config.dev = &dev->dev;
--      port->phylink_config.type = PHYLINK_NETDEV;
--      port->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
--                                              MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD |
--                                              MAC_5000FD | MAC_10000FD;
-+      dev->phylink_config.dev = &netdev->dev;
-+      dev->phylink_config.type = PHYLINK_NETDEV;
-+      dev->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
-+                                             MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD |
-+                                             MAC_5000FD | MAC_10000FD;
--      err = fwnode_phylink_pcs_parse(dev_fwnode(&dev->dev), NULL,
--                                     &port->phylink_config.num_available_pcs);
-+      err = fwnode_phylink_pcs_parse(dev_fwnode(&netdev->dev), NULL,
-+                                     &dev->phylink_config.num_available_pcs);
-       if (err)
-               return err;
--      port->phylink_config.fill_available_pcs = airoha_fill_available_pcs;
-+      dev->phylink_config.fill_available_pcs = airoha_fill_available_pcs;
-       __set_bit(PHY_INTERFACE_MODE_SGMII,
--                port->phylink_config.supported_interfaces);
-+                dev->phylink_config.supported_interfaces);
-       __set_bit(PHY_INTERFACE_MODE_1000BASEX,
--                port->phylink_config.supported_interfaces);
-+                dev->phylink_config.supported_interfaces);
-       __set_bit(PHY_INTERFACE_MODE_2500BASEX,
--                port->phylink_config.supported_interfaces);
-+                dev->phylink_config.supported_interfaces);
-       __set_bit(PHY_INTERFACE_MODE_10GBASER,
--                port->phylink_config.supported_interfaces);
-+                dev->phylink_config.supported_interfaces);
-       __set_bit(PHY_INTERFACE_MODE_USXGMII,
--                port->phylink_config.supported_interfaces);
-+                dev->phylink_config.supported_interfaces);
--      phy_interface_copy(port->phylink_config.pcs_interfaces,
--                         port->phylink_config.supported_interfaces);
-+      phy_interface_copy(dev->phylink_config.pcs_interfaces,
-+                         dev->phylink_config.supported_interfaces);
--      phylink = phylink_create(&port->phylink_config,
-+      phylink = phylink_create(&dev->phylink_config,
-                                of_fwnode_handle(np),
-                                phy_mode, &airoha_phylink_ops);
-       if (IS_ERR(phylink))
-               return PTR_ERR(phylink);
--      port->phylink = phylink;
-+      dev->phylink = phylink;
-       return err;
+       return false;
  }
- #endif
  
 +static int airoha_alloc_gdm_device(struct airoha_eth *eth,
 +                                 struct airoha_gdm_port *port,
@@ -793,9 +587,11 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +      netdev->ethtool_ops = &airoha_ethtool_ops;
 +      netdev->max_mtu = AIROHA_MAX_MTU;
 +      netdev->watchdog_timeo = 5 * HZ;
-+      netdev->hw_features = AIROHA_HW_FEATURES | NETIF_F_GRO_HW;
-+      netdev->features |= AIROHA_HW_FEATURES;
-+      netdev->vlan_features = AIROHA_HW_FEATURES;
++      netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | NETIF_F_TSO6 |
++                            NETIF_F_IPV6_CSUM | NETIF_F_SG | NETIF_F_TSO |
++                            NETIF_F_HW_TC;
++      netdev->features |= netdev->hw_features;
++      netdev->vlan_features = netdev->hw_features;
 +      netdev->dev.of_node = np;
 +      SET_NETDEV_DEV(netdev, eth->dev);
 +
@@ -815,18 +611,11 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +      }
 +
 +      dev = netdev_priv(netdev);
++      dev->dev = netdev;
 +      dev->port = port;
 +      port->dev = dev;
 +      dev->eth = eth;
 +
-+#if defined(CONFIG_PCS_AIROHA)
-+      if (airhoa_is_phy_external(port)) {
-+              err = airoha_setup_phylink(netdev);
-+              if (err)
-+                      return err;
-+      }
-+#endif
-+
 +      return 0;
 +}
 +
@@ -839,7 +628,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        int err, p;
        u32 id;
  
-@@ -3438,58 +3537,22 @@ static int airoha_alloc_gdm_port(struct
+@@ -2977,53 +3065,22 @@ static int airoha_alloc_gdm_port(struct
                return -EINVAL;
        }
  
@@ -857,17 +646,20 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 -      dev->ethtool_ops = &airoha_ethtool_ops;
 -      dev->max_mtu = AIROHA_MAX_MTU;
 -      dev->watchdog_timeo = 5 * HZ;
--      dev->hw_features = AIROHA_HW_FEATURES | NETIF_F_GRO_HW;
--      dev->features |= AIROHA_HW_FEATURES;
--      dev->vlan_features = AIROHA_HW_FEATURES;
+-      dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
+-                         NETIF_F_TSO6 | NETIF_F_IPV6_CSUM |
+-                         NETIF_F_SG | NETIF_F_TSO |
+-                         NETIF_F_HW_TC;
+-      dev->features |= dev->hw_features;
+-      dev->vlan_features = dev->hw_features;
 -      dev->dev.of_node = np;
 -      SET_NETDEV_DEV(dev, eth->dev);
--
 -      /* reserve hw queues for HTB offloading */
 -      err = netif_set_real_num_tx_queues(dev, AIROHA_NUM_TX_RING);
 -      if (err)
 -              return err;
+-
 -      err = of_get_ethdev_address(np, dev);
 -      if (err) {
 -              if (err == -EPROBE_DEFER)
@@ -888,32 +680,25 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        port->nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
        eth->ports[p] = port;
  
--#if defined(CONFIG_PCS_AIROHA)
--      if (airhoa_is_phy_external(port)) {
--              err = airoha_setup_phylink(dev);
--              if (err)
--                      return err;
--      }
--#endif
+-      return airoha_metadata_dst_alloc(port);
 +      err = airoha_metadata_dst_alloc(port);
 +      if (err)
 +              return err;
--      return airoha_metadata_dst_alloc(port);
++
 +      return airoha_alloc_gdm_device(eth, port, np);
  }
  
  static int airoha_register_gdm_devices(struct airoha_eth *eth)
-@@ -3503,7 +3566,7 @@ static int airoha_register_gdm_devices(s
+@@ -3037,7 +3094,7 @@ static int airoha_register_gdm_devices(s
                if (!port)
                        continue;
  
 -              err = register_netdev(port->dev);
-+              err = register_netdev(netdev_from_priv(port->dev));
++              err = register_netdev(port->dev->dev);
                if (err)
                        return err;
        }
-@@ -3612,16 +3675,22 @@ error_napi_stop:
+@@ -3146,12 +3203,14 @@ error_napi_stop:
  
        for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
                struct airoha_gdm_port *port = eth->ports[i];
@@ -922,25 +707,15 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                if (!port)
                        continue;
  
--              if (port->dev->reg_state == NETREG_REGISTERED) {
-+              dev = port->dev;
-+              if (dev) {
-+                      struct net_device *netdev = netdev_from_priv(dev);
-+
-+                      if (netdev->reg_state == NETREG_REGISTERED) {
- #if defined(CONFIG_PCS_AIROHA)
--                      if (airhoa_is_phy_external(port))
--                              phylink_destroy(port->phylink);
-+                              if (airhoa_is_phy_external(port))
-+                                      phylink_destroy(dev->phylink);
- #endif
+-              if (port->dev->reg_state == NETREG_REGISTERED)
 -                      unregister_netdev(port->dev);
-+                              unregister_netdev(netdev);
-+                      }
-               }
++              dev = port->dev;
++              if (dev && dev->dev->reg_state == NETREG_REGISTERED)
++                      unregister_netdev(dev->dev);
                airoha_metadata_dst_free(port);
        }
-@@ -3643,15 +3712,19 @@ static void airoha_remove(struct platfor
+       airoha_hw_cleanup(eth);
+@@ -3172,11 +3231,14 @@ static void airoha_remove(struct platfor
  
        for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
                struct airoha_gdm_port *port = eth->ports[i];
@@ -949,49 +724,34 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                if (!port)
                        continue;
  
- #if defined(CONFIG_PCS_AIROHA)
-               if (airhoa_is_phy_external(port))
--                      phylink_destroy(port->phylink);
-+                      phylink_destroy(dev->phylink);
- #endif
 -              unregister_netdev(port->dev);
-+
 +              dev = port->dev;
 +              if (dev)
-+                      unregister_netdev(netdev_from_priv(dev));
++                      unregister_netdev(dev->dev);
                airoha_metadata_dst_free(port);
        }
        airoha_hw_cleanup(eth);
 --- a/drivers/net/ethernet/airoha/airoha_eth.h
 +++ b/drivers/net/ethernet/airoha/airoha_eth.h
-@@ -547,17 +547,21 @@ struct airoha_qdma {
+@@ -535,10 +535,15 @@ struct airoha_qdma {
        struct airoha_queue q_rx[AIROHA_NUM_RX_RING];
  };
  
--struct airoha_gdm_port {
--      struct airoha_qdma *qdma;
 +struct airoha_gdm_dev {
 +      struct airoha_gdm_port *port;
-       struct airoha_eth *eth;
--      struct net_device *dev;
--      int id;
--      int nbq;
- #if defined(CONFIG_PCS_AIROHA)
-       struct phylink *phylink;
-       struct phylink_config phylink_config;
- #endif
++      struct net_device *dev;
++      struct airoha_eth *eth;
 +};
 +
-+struct airoha_gdm_port {
-+      struct airoha_qdma *qdma;
+ struct airoha_gdm_port {
+       struct airoha_qdma *qdma;
+-      struct airoha_eth *eth;
+-      struct net_device *dev;
 +      struct airoha_gdm_dev *dev;
-+      int id;
-+      int nbq;
-       struct airoha_hw_stats stats;
+       int id;
+       int nbq;
  
-@@ -691,8 +695,8 @@ static inline bool airoha_qdma_is_lro_qu
+@@ -662,8 +667,8 @@ static inline bool airoha_is_7583(struct
  }
  
  int airoha_get_fe_port(struct airoha_gdm_port *port);
@@ -1004,14 +764,14 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                             u8 fport);
 --- a/drivers/net/ethernet/airoha/airoha_ppe.c
 +++ b/drivers/net/ethernet/airoha/airoha_ppe.c
-@@ -299,12 +299,12 @@ static void airoha_ppe_foe_set_bridge_ad
+@@ -298,12 +298,12 @@ static void airoha_ppe_foe_set_bridge_ad
  
  static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
                                        struct airoha_foe_entry *hwe,
 -                                      struct net_device *dev, int type,
 +                                      struct net_device *netdev, int type,
                                        struct airoha_flow_data *data,
-                                       int l4proto, u8 dsfield)
+                                       int l4proto)
  {
        u32 qdata = FIELD_PREP(AIROHA_FOE_SHAPER_ID, 0x7f), ports_pad, val;
 -      int wlan_etype = -EINVAL, dsa_port = airoha_get_dsa_port(&dev);
@@ -1019,7 +779,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        struct airoha_foe_mac_info_common *l2;
        u8 smac_id = 0xf;
  
-@@ -320,10 +320,11 @@ static int airoha_ppe_foe_entry_prepare(
+@@ -319,10 +319,11 @@ static int airoha_ppe_foe_entry_prepare(
        hwe->ib1 = val;
  
        val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f);
@@ -1033,14 +793,14 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                        val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, info.idx) |
                               FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT,
                                          FE_PSE_PORT_CDM4);
-@@ -333,12 +334,14 @@ static int airoha_ppe_foe_entry_prepare(
+@@ -332,12 +333,14 @@ static int airoha_ppe_foe_entry_prepare(
                                     FIELD_PREP(AIROHA_FOE_MAC_WDMA_WCID,
                                                info.wcid);
                } else {
 -                      struct airoha_gdm_port *port = netdev_priv(dev);
 +                      struct airoha_gdm_dev *dev = netdev_priv(netdev);
-                       u8 pse_port, channel, priority;
 +                      struct airoha_gdm_port *port;
+                       u8 pse_port, channel;
  
 -                      if (!airoha_is_valid_gdm_port(eth, port))
 +                      if (!airoha_is_valid_gdm_dev(eth, dev))
@@ -1050,33 +810,12 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                        if (dsa_port >= 0 || eth->ports[1])
                                pse_port = port->id == 4 ? FE_PSE_PORT_GDM4
                                                         : port->id;
-@@ -1484,8 +1487,8 @@ void airoha_ppe_check_skb(struct airoha_
+@@ -1473,7 +1476,7 @@ void airoha_ppe_check_skb(struct airoha_
  void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port)
  {
-+      struct net_device *dev = netdev_from_priv(port->dev);
        struct airoha_eth *eth = port->qdma->eth;
 -      struct net_device *dev = port->dev;
++      struct net_device *dev = port->dev->dev;
        const u8 *addr = dev->dev_addr;
        u32 val;
  
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -2760,6 +2760,17 @@ static inline void *netdev_priv(const st
-       return (void *)dev->priv;
- }
-+/**
-+ * netdev_from_priv() - get network device from priv
-+ * @priv: network device private data
-+ *
-+ * Returns: net_device to which @priv belongs
-+ */
-+static inline struct net_device *netdev_from_priv(const void *priv)
-+{
-+      return container_of(priv, struct net_device, priv);
-+}
-+
- /* Set the sysfs physical device reference for the network logical device
-  * if set prior to registration will cause a symlink during initialization.
-  */
similarity index 72%
rename from target/linux/airoha/patches-6.18/920-02-net-airoha-Move-airoha_qdma-pointer-in-airoha_gdm_de.patch
rename to target/linux/airoha/patches-6.18/161-02-v7.2-net-airoha-Move-airoha_qdma-pointer-in-airoha_gdm_de.patch
index b95371056fc105bceaf8f17490d039315f5b6dfd..78388f5c63040b7aec061cae34e179b384bf7b25 100644 (file)
@@ -1,10 +1,7 @@
-From f62cea6483cc55360863d66300790a5fb9de5f7c Mon Sep 17 00:00:00 2001
-Message-ID: <f62cea6483cc55360863d66300790a5fb9de5f7c.1779348625.git.lorenzo@kernel.org>
-In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
-References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
+From 528c5153a557f69482d91609a2a002ded22a3441 Mon Sep 17 00:00:00 2001
 From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 24 Feb 2026 18:43:05 +0100
-Subject: [PATCH 02/13] net: airoha: Move airoha_qdma pointer in airoha_gdm_dev
+Date: Wed, 27 May 2026 12:21:16 +0200
+Subject: [PATCH 2/6] net: airoha: Move airoha_qdma pointer in airoha_gdm_dev
  struct
 
 Move airoha_qdma pointer from airoha_gdm_port struct to airoha_gdm_dev
@@ -16,6 +13,8 @@ to the same GDM{3,4} port via an external hw arbiter.
 
 Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20260527-airoha-eth-multi-serdes-preliminary-v1-2-ec6ed73ef7fc@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 ---
  drivers/net/ethernet/airoha/airoha_eth.c | 105 +++++++++++------------
  drivers/net/ethernet/airoha/airoha_eth.h |   9 +-
@@ -24,9 +23,9 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 
 --- a/drivers/net/ethernet/airoha/airoha_eth.c
 +++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -81,9 +81,10 @@ static bool airhoa_is_phy_external(struc
+@@ -71,9 +71,10 @@ static void airoha_qdma_irq_disable(stru
+       airoha_qdma_set_irqmask(irq_bank, index, mask, 0);
  }
- #endif
  
 -static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
 +static void airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr)
@@ -37,7 +36,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        u32 val, reg;
  
        reg = airoha_is_lan_gdm_port(port) ? REG_FE_LAN_MAC_H
-@@ -95,7 +96,7 @@ static void airoha_set_macaddr(struct ai
+@@ -85,7 +86,7 @@ static void airoha_set_macaddr(struct ai
        airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), val);
        airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), val);
  
@@ -46,7 +45,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  }
  
  static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr,
-@@ -111,10 +112,10 @@ static void airoha_set_gdm_port_fwd_cfg(
+@@ -101,10 +102,10 @@ static void airoha_set_gdm_port_fwd_cfg(
                      FIELD_PREP(GDM_UCFQ_MASK, val));
  }
  
@@ -60,24 +59,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        u32 vip_port;
  
        vip_port = eth->soc->ops.get_vip_port(port, port->nbq);
-@@ -485,8 +486,7 @@ static bool airoha_fe_lro_is_enabled(str
- static void airoha_dev_lro_enable(struct airoha_gdm_dev *dev)
- {
--      struct airoha_gdm_port *port = dev->port;
--      struct airoha_qdma *qdma = port->qdma;
-+      struct airoha_qdma *qdma = dev->qdma;
-       struct airoha_eth *eth = qdma->eth;
-       int qdma_id = qdma - &eth->qdma[0];
-       int i, lro_queue_index = 0;
-@@ -1097,13 +1097,18 @@ static void airoha_qdma_wake_netdev_txqs
-       for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
-               struct airoha_gdm_port *port = eth->ports[i];
-+              struct airoha_gdm_dev *dev;
-               struct net_device *netdev;
-               int j;
+@@ -859,10 +860,13 @@ static void airoha_qdma_wake_netdev_txqs
                if (!port)
                        continue;
  
@@ -89,8 +71,11 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +              if (dev->qdma != qdma)
                        continue;
  
-               netdev = netdev_from_priv(port->dev);
-@@ -1811,9 +1816,10 @@ static void airoha_qdma_stop_napi(struct
+-              dev = port->dev;
+               for (j = 0; j < dev->dev->num_tx_queues; j++) {
+                       if (airoha_qdma_get_txq(qdma, j) != qid)
+                               continue;
+@@ -1563,9 +1567,10 @@ static void airoha_qdma_stop_napi(struct
        }
  }
  
@@ -103,17 +88,13 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        u32 val, i = 0;
  
        spin_lock(&port->stats.lock);
-@@ -1981,7 +1987,7 @@ static int airoha_dev_open(struct net_de
+@@ -1712,11 +1717,11 @@ static int airoha_dev_open(struct net_de
        int err, len = ETH_HLEN + netdev->mtu + ETH_FCS_LEN;
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
        struct airoha_gdm_port *port = dev->port;
 -      struct airoha_qdma *qdma = port->qdma;
 +      struct airoha_qdma *qdma = dev->qdma;
-       struct airoha_eth *eth = qdma->eth;
-       int qdma_id = qdma - &eth->qdma[0];
        u32 pse_port = FE_PSE_PORT_PPE1;
-@@ -2011,7 +2017,7 @@ static int airoha_dev_open(struct net_de
- #endif
  
        netif_tx_start_all_queues(netdev);
 -      err = airoha_set_vip_for_gdm_port(port, true);
@@ -121,13 +102,12 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        if (err)
                return err;
  
-@@ -2052,12 +2058,12 @@ static int airoha_dev_stop(struct net_de
+@@ -1752,11 +1757,11 @@ static int airoha_dev_stop(struct net_de
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
        struct airoha_gdm_port *port = dev->port;
 -      struct airoha_qdma *qdma = port->qdma;
 +      struct airoha_qdma *qdma = dev->qdma;
-       struct airoha_eth *eth = qdma->eth;
        int i;
  
        netif_tx_disable(netdev);
@@ -136,7 +116,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        for (i = 0; i < netdev->num_tx_queues; i++)
                netdev_tx_reset_subqueue(netdev, i);
  
-@@ -2092,21 +2098,21 @@ static int airoha_dev_stop(struct net_de
+@@ -1782,21 +1787,21 @@ static int airoha_dev_stop(struct net_de
  static int airoha_dev_set_macaddr(struct net_device *netdev, void *p)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -162,7 +142,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        u32 val, pse_port, chan;
        int i, src_port;
  
-@@ -2153,7 +2159,7 @@ static int airoha_set_gdm2_loopback(stru
+@@ -1843,7 +1848,7 @@ static int airoha_set_gdm2_loopback(stru
                      __field_prep(SP_CPORT_MASK(val), FE_PSE_PORT_CDM2));
  
        for (i = 0; i < eth->soc->num_ppe; i++)
@@ -170,21 +150,21 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +              airoha_ppe_set_cpu_port(dev, i, AIROHA_GDM2_IDX);
  
        if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) {
-               u32 mask = FC_ID_OF_SRC_PORT_MASK(nbq);
-@@ -2173,9 +2179,9 @@ static int airoha_dev_init(struct net_de
+               u32 mask = FC_ID_OF_SRC_PORT_MASK(port->nbq);
+@@ -1863,9 +1868,9 @@ static int airoha_dev_init(struct net_de
        int i;
  
        /* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
 -      port->qdma = &eth->qdma[!airoha_is_lan_gdm_port(port)];
--      netdev->irq = port->qdma->irq_banks[0].irq;
+-      dev->dev->irq = port->qdma->irq_banks[0].irq;
 -      airoha_set_macaddr(port, netdev->dev_addr);
 +      dev->qdma = &eth->qdma[!airoha_is_lan_gdm_port(port)];
-+      netdev->irq = dev->qdma->irq_banks[0].irq;
++      dev->dev->irq = dev->qdma->irq_banks[0].irq;
 +      airoha_set_macaddr(dev, netdev->dev_addr);
  
        switch (port->id) {
        case AIROHA_GDM3_IDX:
-@@ -2184,7 +2190,7 @@ static int airoha_dev_init(struct net_de
+@@ -1874,7 +1879,7 @@ static int airoha_dev_init(struct net_de
                if (!eth->ports[1]) {
                        int err;
  
@@ -193,7 +173,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                        if (err)
                                return err;
                }
-@@ -2194,8 +2200,7 @@ static int airoha_dev_init(struct net_de
+@@ -1884,8 +1889,7 @@ static int airoha_dev_init(struct net_de
        }
  
        for (i = 0; i < eth->soc->num_ppe; i++)
@@ -203,7 +183,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        return 0;
  }
-@@ -2207,7 +2212,7 @@ static void airoha_dev_get_stats64(struc
+@@ -1897,7 +1901,7 @@ static void airoha_dev_get_stats64(struc
        struct airoha_gdm_port *port = dev->port;
        unsigned int start;
  
@@ -212,7 +192,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        do {
                start = u64_stats_fetch_begin(&port->stats.syncp);
                storage->rx_packets = port->stats.rx_ok_pkts;
-@@ -2227,8 +2232,8 @@ static int airoha_dev_change_mtu(struct
+@@ -1917,8 +1921,8 @@ static int airoha_dev_change_mtu(struct
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
        struct airoha_gdm_port *port = dev->port;
@@ -222,7 +202,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id),
                      GDM_LONG_LEN_MASK,
-@@ -2302,10 +2307,10 @@ static u32 airoha_get_dsa_tag(struct sk_
+@@ -1992,10 +1996,10 @@ static u32 airoha_get_dsa_tag(struct sk_
  #endif
  }
  
@@ -236,27 +216,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        switch (eth->soc->version) {
        case 0x7583:
-@@ -2322,8 +2327,7 @@ static netdev_features_t airoha_dev_fix_
-                                                netdev_features_t features)
- {
-       struct airoha_gdm_dev *dev = netdev_priv(netdev);
--      struct airoha_gdm_port *port = dev->port;
--      struct airoha_qdma *qdma = port->qdma;
-+      struct airoha_qdma *qdma = dev->qdma;
-       if (qdma->users > 1)
-               features &= ~NETIF_F_GRO_HW;
-@@ -2336,8 +2340,7 @@ static int airoha_dev_set_features(struc
- {
-       netdev_features_t diff = netdev->features ^ features;
-       struct airoha_gdm_dev *dev = netdev_priv(netdev);
--      struct airoha_gdm_port *port = dev->port;
--      struct airoha_qdma *qdma = port->qdma;
-+      struct airoha_qdma *qdma = dev->qdma;
-       struct airoha_eth *eth = qdma->eth;
-       int qdma_id = qdma - &eth->qdma[0];
-@@ -2356,8 +2359,7 @@ static netdev_tx_t airoha_dev_xmit(struc
+@@ -2012,8 +2016,7 @@ static netdev_tx_t airoha_dev_xmit(struc
                                   struct net_device *netdev)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -266,7 +226,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        u32 nr_frags, tag, msg0, msg1, len;
        struct airoha_queue_entry *e;
        struct netdev_queue *txq;
-@@ -2395,7 +2397,7 @@ static netdev_tx_t airoha_dev_xmit(struc
+@@ -2051,7 +2054,7 @@ static netdev_tx_t airoha_dev_xmit(struc
                }
        }
  
@@ -275,7 +235,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
               FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f);
  
-@@ -2498,8 +2500,7 @@ static void airoha_ethtool_get_drvinfo(s
+@@ -2154,8 +2157,7 @@ static void airoha_ethtool_get_drvinfo(s
                                       struct ethtool_drvinfo *info)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -285,7 +245,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver));
        strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info));
-@@ -2512,7 +2513,7 @@ static void airoha_ethtool_get_mac_stats
+@@ -2168,7 +2170,7 @@ static void airoha_ethtool_get_mac_stats
        struct airoha_gdm_port *port = dev->port;
        unsigned int start;
  
@@ -294,7 +254,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        do {
                start = u64_stats_fetch_begin(&port->stats.syncp);
                stats->FramesTransmittedOK = port->stats.tx_ok_pkts;
-@@ -2552,7 +2553,7 @@ airoha_ethtool_get_rmon_stats(struct net
+@@ -2208,7 +2210,7 @@ airoha_ethtool_get_rmon_stats(struct net
                     ARRAY_SIZE(hw_stats->rx_len) + 1);
  
        *ranges = airoha_ethtool_rmon_ranges;
@@ -303,7 +263,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        do {
                int i;
  
-@@ -2572,18 +2573,17 @@ static int airoha_qdma_set_chan_tx_sched
+@@ -2228,18 +2230,17 @@ static int airoha_qdma_set_chan_tx_sched
                                         const u16 *weights, u8 n_weights)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -324,7 +284,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                               TWRR_RW_CMD_MASK |
                               FIELD_PREP(TWRR_CHAN_IDX_MASK, channel) |
                               FIELD_PREP(TWRR_QUEUE_IDX_MASK, i) |
-@@ -2591,13 +2591,12 @@ static int airoha_qdma_set_chan_tx_sched
+@@ -2247,13 +2248,12 @@ static int airoha_qdma_set_chan_tx_sched
                err = read_poll_timeout(airoha_qdma_rr, status,
                                        status & TWRR_RW_CMD_DONE,
                                        USEC_PER_MSEC, 10 * USEC_PER_MSEC,
@@ -340,7 +300,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                        CHAN_QOS_MODE_MASK(channel),
                        __field_prep(CHAN_QOS_MODE_MASK(channel), mode));
  
-@@ -2663,9 +2662,9 @@ static int airoha_qdma_get_tx_ets_stats(
+@@ -2319,9 +2319,9 @@ static int airoha_qdma_get_tx_ets_stats(
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
        struct airoha_gdm_port *port = dev->port;
  
@@ -352,7 +312,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                                            REG_CNTR_VAL((channel << 1) + 1));
        u64 tx_packets = (cpu_tx_packets - port->cpu_tx_packets) +
                         (fwd_tx_packets - port->fwd_tx_packets);
-@@ -2929,17 +2928,16 @@ static int airoha_qdma_set_tx_rate_limit
+@@ -2585,17 +2585,16 @@ static int airoha_qdma_set_tx_rate_limit
                                         u32 bucket_size)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -372,7 +332,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                                                         REG_EGRESS_TRTCM_CFG,
                                                         i, rate, bucket_size);
                if (err)
-@@ -2989,11 +2987,11 @@ static int airoha_tc_htb_alloc_leaf_queu
+@@ -2645,11 +2644,11 @@ static int airoha_tc_htb_alloc_leaf_queu
        return 0;
  }
  
@@ -386,7 +346,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        int i;
  
        for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
-@@ -3072,7 +3070,6 @@ static int airoha_dev_tc_matchall(struct
+@@ -2728,7 +2727,6 @@ static int airoha_dev_tc_matchall(struct
  {
        enum trtcm_unit_type unit_type = TRTCM_BYTE_UNIT;
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -394,7 +354,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        u32 rate = 0, bucket_size = 0;
  
        switch (f->command) {
-@@ -3097,7 +3094,7 @@ static int airoha_dev_tc_matchall(struct
+@@ -2753,7 +2751,7 @@ static int airoha_dev_tc_matchall(struct
                fallthrough;
        }
        case TC_CLSMATCHALL_DESTROY:
@@ -403,7 +363,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                                                unit_type);
        default:
                return -EOPNOTSUPP;
-@@ -3109,8 +3106,7 @@ static int airoha_dev_setup_tc_block_cb(
+@@ -2765,8 +2763,7 @@ static int airoha_dev_setup_tc_block_cb(
  {
        struct net_device *netdev = cb_priv;
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -413,26 +373,15 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        if (!tc_can_offload(netdev))
                return -EOPNOTSUPP;
-@@ -3346,7 +3342,7 @@ static void airoha_mac_link_up(struct ph
-       struct airoha_gdm_dev *dev = container_of(config, struct airoha_gdm_dev,
-                                                 phylink_config);
-       struct airoha_gdm_port *port = dev->port;
--      struct airoha_qdma *qdma = port->qdma;
-+      struct airoha_qdma *qdma = dev->qdma;
-       struct airoha_eth *eth = qdma->eth;
-       u32 frag_size_tx, frag_size_rx;
 --- a/drivers/net/ethernet/airoha/airoha_eth.h
 +++ b/drivers/net/ethernet/airoha/airoha_eth.h
-@@ -549,6 +549,7 @@ struct airoha_qdma {
+@@ -537,12 +537,12 @@ struct airoha_qdma {
  
  struct airoha_gdm_dev {
        struct airoha_gdm_port *port;
 +      struct airoha_qdma *qdma;
+       struct net_device *dev;
        struct airoha_eth *eth;
- #if defined(CONFIG_PCS_AIROHA)
-@@ -558,7 +559,6 @@ struct airoha_gdm_dev {
  };
  
  struct airoha_gdm_port {
@@ -440,8 +389,8 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        struct airoha_gdm_dev *dev;
        int id;
        int nbq;
-@@ -694,19 +694,18 @@ static inline bool airoha_qdma_is_lro_qu
-       return !!(AIROHA_RXQ_LRO_EN_MASK & BIT(qid));
+@@ -666,19 +666,18 @@ static inline bool airoha_is_7583(struct
+       return eth->soc->version == 0x7583;
  }
  
 -int airoha_get_fe_port(struct airoha_gdm_port *port);
@@ -465,7 +414,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                                                  u32 hash);
 --- a/drivers/net/ethernet/airoha/airoha_ppe.c
 +++ b/drivers/net/ethernet/airoha/airoha_ppe.c
-@@ -85,9 +85,9 @@ static u32 airoha_ppe_get_timestamp(stru
+@@ -84,9 +84,9 @@ static u32 airoha_ppe_get_timestamp(stru
                             AIROHA_FOE_IB1_BIND_TIMESTAMP);
  }
  
@@ -477,7 +426,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        struct airoha_eth *eth = qdma->eth;
        u8 qdma_id = qdma - &eth->qdma[0];
        u32 fe_cpu_port;
-@@ -181,8 +181,8 @@ static void airoha_ppe_hw_init(struct ai
+@@ -180,8 +180,8 @@ static void airoha_ppe_hw_init(struct ai
                        if (!port)
                                continue;
  
@@ -488,18 +437,18 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                }
        }
  }
-@@ -1485,11 +1485,12 @@ void airoha_ppe_check_skb(struct airoha_
+@@ -1473,11 +1473,12 @@ void airoha_ppe_check_skb(struct airoha_
        airoha_ppe_foe_insert_entry(ppe, skb, hash, rx_wlan);
  }
  
 -void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port)
 +void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev)
  {
--      struct net_device *dev = netdev_from_priv(port->dev);
 -      struct airoha_eth *eth = port->qdma->eth;
+-      struct net_device *dev = port->dev->dev;
 -      const u8 *addr = dev->dev_addr;
-+      struct net_device *netdev = netdev_from_priv(dev);
 +      struct airoha_gdm_port *port = dev->port;
++      struct net_device *netdev = dev->dev;
 +      struct airoha_eth *eth = dev->eth;
 +      const u8 *addr = netdev->dev_addr;
        u32 val;
similarity index 75%
rename from target/linux/airoha/patches-6.18/920-03-net-airoha-Rely-on-airoha_gdm_dev-pointer-in-airoha_.patch
rename to target/linux/airoha/patches-6.18/161-03-v7.2-net-airoha-Rely-on-airoha_gdm_dev-pointer-in-airoha_.patch
index 64ed102d3a63ef99555435434b49f62061c7c7f0..072089fe8b916c9814c2dec788567316c8388677 100644 (file)
@@ -1,10 +1,7 @@
-From 32bfd008c19f9ad55514181d8cd02e14bf384475 Mon Sep 17 00:00:00 2001
-Message-ID: <32bfd008c19f9ad55514181d8cd02e14bf384475.1779348625.git.lorenzo@kernel.org>
-In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
-References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
+From eca4f59b536780a56bd22db03fe5465e8e978f36 Mon Sep 17 00:00:00 2001
 From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 13 Dec 2025 10:06:45 +0100
-Subject: [PATCH 03/13] net: airoha: Rely on airoha_gdm_dev pointer in
+Date: Wed, 27 May 2026 12:21:17 +0200
+Subject: [PATCH 3/6] net: airoha: Rely on airoha_gdm_dev pointer in
  airoha_is_lan_gdm_port()
 
 Rename airoha_is_lan_gdm_port in airoha_is_lan_gdm_dev. Moreover, rely
@@ -15,6 +12,8 @@ the same GDM{3,4} port via an external hw arbiter.
 
 Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20260527-airoha-eth-multi-serdes-preliminary-v1-3-ec6ed73ef7fc@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 ---
  drivers/net/ethernet/airoha/airoha_eth.c | 6 ++----
  drivers/net/ethernet/airoha/airoha_eth.h | 4 +++-
@@ -23,7 +22,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 
 --- a/drivers/net/ethernet/airoha/airoha_eth.c
 +++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -83,12 +83,10 @@ static bool airhoa_is_phy_external(struc
+@@ -73,12 +73,10 @@ static void airoha_qdma_irq_disable(stru
  
  static void airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr)
  {
@@ -37,18 +36,18 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        val = (addr[0] << 16) | (addr[1] << 8) | addr[2];
        airoha_fe_wr(eth, reg, val);
  
-@@ -2179,7 +2177,7 @@ static int airoha_dev_init(struct net_de
+@@ -1868,7 +1866,7 @@ static int airoha_dev_init(struct net_de
        int i;
  
        /* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
 -      dev->qdma = &eth->qdma[!airoha_is_lan_gdm_port(port)];
 +      dev->qdma = &eth->qdma[!airoha_is_lan_gdm_dev(dev)];
-       netdev->irq = dev->qdma->irq_banks[0].irq;
+       dev->dev->irq = dev->qdma->irq_banks[0].irq;
        airoha_set_macaddr(dev, netdev->dev_addr);
  
 --- a/drivers/net/ethernet/airoha/airoha_eth.h
 +++ b/drivers/net/ethernet/airoha/airoha_eth.h
-@@ -663,8 +663,10 @@ static inline u16 airoha_qdma_get_txq(st
+@@ -647,8 +647,10 @@ static inline u16 airoha_qdma_get_txq(st
        return qid % ARRAY_SIZE(qdma->q_tx);
  }
  
@@ -62,7 +61,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
         * phy module.
 --- a/drivers/net/ethernet/airoha/airoha_ppe.c
 +++ b/drivers/net/ethernet/airoha/airoha_ppe.c
-@@ -367,7 +367,7 @@ static int airoha_ppe_foe_entry_prepare(
+@@ -362,7 +362,7 @@ static int airoha_ppe_foe_entry_prepare(
                        /* For downlink traffic consume SRAM memory for hw
                         * forwarding descriptors queue.
                         */
similarity index 80%
rename from target/linux/airoha/patches-6.18/920-04-net-airoha-Move-qos_sq_bmap-in-airoha_gdm_dev-struct.patch
rename to target/linux/airoha/patches-6.18/161-04-v7.2-net-airoha-Move-qos_sq_bmap-in-airoha_gdm_dev-struct.patch
index 3bbcaab93669f9ce3a1bd6b9373df3669b4994bc..b35b1b0a6986f2c1179aea185b8dcfd40368e973 100644 (file)
@@ -1,10 +1,7 @@
-From 634d75285db77f3385aa85a1bf2b185396225100 Mon Sep 17 00:00:00 2001
-Message-ID: <634d75285db77f3385aa85a1bf2b185396225100.1779348625.git.lorenzo@kernel.org>
-In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
-References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
+From 069626af6dfaa26b82119900f4aff1fec38d5983 Mon Sep 17 00:00:00 2001
 From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 10 Apr 2026 14:35:32 +0200
-Subject: [PATCH 04/13] net: airoha: Move qos_sq_bmap in airoha_gdm_dev struct
+Date: Wed, 27 May 2026 12:21:18 +0200
+Subject: [PATCH 4/6] net: airoha: Move qos_sq_bmap in airoha_gdm_dev struct
 
 Since now multiple net_devices connected to different QDMA blocks can
 share the same GDM port, qos_sq_bmap field can be overwritten with the
@@ -14,7 +11,10 @@ airoha_gdm_port struct to airoha_gdm_dev one.
 Add qos_channel_map bitmap in airoha_qdma struct to track if a shared
 QDMA channel is already in use by another net_device.
 
+Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20260527-airoha-eth-multi-serdes-preliminary-v1-4-ec6ed73ef7fc@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 ---
  drivers/net/ethernet/airoha/airoha_eth.c | 58 +++++++++++++++---------
  drivers/net/ethernet/airoha/airoha_eth.h |  6 ++-
@@ -22,7 +22,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 
 --- a/drivers/net/ethernet/airoha/airoha_eth.c
 +++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -2945,30 +2945,46 @@ static int airoha_qdma_set_tx_rate_limit
+@@ -2602,30 +2602,40 @@ static int airoha_qdma_set_tx_rate_limit
        return 0;
  }
  
@@ -36,7 +36,6 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 -      int err, num_tx_queues = netdev->real_num_tx_queues;
 -      struct airoha_gdm_dev *dev = netdev_priv(netdev);
 -      struct airoha_gdm_port *port = dev->port;
-+      int err;
  
        if (opt->parent_classid != TC_HTB_CLASSID_ROOT) {
                NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid");
@@ -46,13 +45,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 -      err = airoha_qdma_set_tx_rate_limit(netdev, channel, rate,
 -                                          opt->quantum);
 -      if (err) {
-+      err = airoha_qdma_set_tx_rate_limit(dev, channel, rate, opt->quantum);
-+      if (err)
-               NL_SET_ERR_MSG_MOD(opt->extack,
-                                  "failed configuring htb offload");
--              return err;
-+
-+      return err;
++      return airoha_qdma_set_tx_rate_limit(dev, channel, rate, opt->quantum);
 +}
 +
 +static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
@@ -67,7 +60,9 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +       * in use by another net_device running on the same QDMA block.
 +       */
 +      if (test_and_set_bit(channel, qdma->qos_channel_map)) {
-+              NL_SET_ERR_MSG_MOD(opt->extack,
+               NL_SET_ERR_MSG_MOD(opt->extack,
+-                                 "failed configuring htb offload");
+-              return err;
 +                                 "qdma qos channel already in use");
 +              return -EBUSY;
        }
@@ -80,7 +75,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        err = netif_set_real_num_tx_queues(netdev, num_tx_queues + 1);
        if (err) {
-@@ -2976,13 +2992,17 @@ static int airoha_tc_htb_alloc_leaf_queu
+@@ -2633,13 +2643,17 @@ static int airoha_tc_htb_alloc_leaf_queu
                                              opt->quantum);
                NL_SET_ERR_MSG_MOD(opt->extack,
                                   "failed setting real_num_tx_queues");
@@ -100,7 +95,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  }
  
  static int airoha_qdma_set_rx_meter(struct airoha_gdm_dev *dev,
-@@ -3163,11 +3183,13 @@ static int airoha_dev_setup_tc_block(str
+@@ -2820,11 +2834,13 @@ static int airoha_dev_setup_tc_block(str
  static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -116,7 +111,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  }
  
  static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev,
-@@ -3175,9 +3197,8 @@ static int airoha_tc_htb_delete_leaf_que
+@@ -2832,9 +2848,8 @@ static int airoha_tc_htb_delete_leaf_que
  {
        u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -127,7 +122,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
                return -EINVAL;
        }
-@@ -3190,10 +3211,9 @@ static int airoha_tc_htb_delete_leaf_que
+@@ -2847,10 +2862,9 @@ static int airoha_tc_htb_delete_leaf_que
  static int airoha_tc_htb_destroy(struct net_device *netdev)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -139,7 +134,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                airoha_tc_remove_htb_queue(netdev, q);
  
        return 0;
-@@ -3204,9 +3224,8 @@ static int airoha_tc_get_htb_get_leaf_qu
+@@ -2861,9 +2875,8 @@ static int airoha_tc_get_htb_get_leaf_qu
  {
        u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -150,7 +145,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
                return -EINVAL;
        }
-@@ -3225,6 +3244,7 @@ static int airoha_tc_setup_qdisc_htb(str
+@@ -2882,6 +2895,7 @@ static int airoha_tc_setup_qdisc_htb(str
        case TC_HTB_DESTROY:
                return airoha_tc_htb_destroy(dev);
        case TC_HTB_NODE_MODIFY:
@@ -160,7 +155,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        case TC_HTB_LEAF_DEL:
 --- a/drivers/net/ethernet/airoha/airoha_eth.h
 +++ b/drivers/net/ethernet/airoha/airoha_eth.h
-@@ -545,6 +545,8 @@ struct airoha_qdma {
+@@ -533,6 +533,8 @@ struct airoha_qdma {
  
        struct airoha_queue q_tx[AIROHA_NUM_TX_RING];
        struct airoha_queue q_rx[AIROHA_NUM_RX_RING];
@@ -169,16 +164,16 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  };
  
  struct airoha_gdm_dev {
-@@ -556,6 +558,8 @@ struct airoha_gdm_dev {
-       struct phylink *phylink;
-       struct phylink_config phylink_config;
- #endif
+@@ -540,6 +542,8 @@ struct airoha_gdm_dev {
+       struct airoha_qdma *qdma;
+       struct net_device *dev;
+       struct airoha_eth *eth;
 +
 +      DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS);
  };
  
  struct airoha_gdm_port {
-@@ -565,8 +569,6 @@ struct airoha_gdm_port {
+@@ -549,8 +553,6 @@ struct airoha_gdm_port {
  
        struct airoha_hw_stats stats;
  
similarity index 76%
rename from target/linux/airoha/patches-6.18/920-05-net-airoha-Move-cpu-fwd-_tx_packets-in-airoha_gdm_de.patch
rename to target/linux/airoha/patches-6.18/161-05-v7.2-net-airoha-Move-cpu-fwd-_tx_packets-in-airoha_gdm_de.patch
index dfe8662b5639912a40bb693cd9f73d864610abc4..cb62a387b612efdf7c3489e48787d906ffd675ad 100644 (file)
@@ -1,11 +1,8 @@
-From 00272dbf6a52241a21145631f22dc5f03891078b Mon Sep 17 00:00:00 2001
-Message-ID: <00272dbf6a52241a21145631f22dc5f03891078b.1779348625.git.lorenzo@kernel.org>
-In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
-References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
+From 962c17dd287887aa87a6f30d64239d7e1e4e05fa Mon Sep 17 00:00:00 2001
 From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 10 Apr 2026 14:47:08 +0200
-Subject: [PATCH 05/13] net: airoha: Move {cpu,fwd}_tx_packets in
airoha_gdm_dev struct
+Date: Wed, 27 May 2026 12:21:19 +0200
+Subject: [PATCH 5/6] net: airoha: Move {cpu,fwd}_tx_packets in airoha_gdm_dev
+ struct
 
 Since now multiple net_devices connected to different QDMA blocks can
 share the same GDM port, cpu_tx_packets and fwd_tx_packets fields can
@@ -13,7 +10,10 @@ be overwritten with the value from a different QDMA block. In order to
 fix the issue move cpu_tx_packets and fwd_tx_packets fields from
 airoha_gdm_port struct to airoha_gdm_dev one.
 
+Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20260527-airoha-eth-multi-serdes-preliminary-v1-5-ec6ed73ef7fc@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 ---
  drivers/net/ethernet/airoha/airoha_eth.c | 16 +++++++---------
  drivers/net/ethernet/airoha/airoha_eth.h |  7 +++----
@@ -21,7 +21,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 
 --- a/drivers/net/ethernet/airoha/airoha_eth.c
 +++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -2658,19 +2658,17 @@ static int airoha_qdma_get_tx_ets_stats(
+@@ -2315,19 +2315,17 @@ static int airoha_qdma_get_tx_ets_stats(
                                        struct tc_ets_qopt_offload *opt)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -50,8 +50,8 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  }
 --- a/drivers/net/ethernet/airoha/airoha_eth.h
 +++ b/drivers/net/ethernet/airoha/airoha_eth.h
-@@ -560,6 +560,9 @@ struct airoha_gdm_dev {
- #endif
+@@ -544,6 +544,9 @@ struct airoha_gdm_dev {
+       struct airoha_eth *eth;
  
        DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS);
 +      /* qos stats counters */
@@ -60,7 +60,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  };
  
  struct airoha_gdm_port {
-@@ -569,10 +572,6 @@ struct airoha_gdm_port {
+@@ -553,10 +556,6 @@ struct airoha_gdm_port {
  
        struct airoha_hw_stats stats;
  
diff --git a/target/linux/airoha/patches-6.18/161-06-v7.2-net-airoha-Rename-airoha_set_gdm2_loopback-in-airoha.patch b/target/linux/airoha/patches-6.18/161-06-v7.2-net-airoha-Rename-airoha_set_gdm2_loopback-in-airoha.patch
new file mode 100644 (file)
index 0000000..eaf4d8e
--- /dev/null
@@ -0,0 +1,38 @@
+From 842a7ee50d68d66afef4536bf3abdaaed2e0e5f5 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Wed, 27 May 2026 12:21:20 +0200
+Subject: [PATCH 6/6] net: airoha: Rename airoha_set_gdm2_loopback in
+ airoha_enable_gdm2_loopback
+
+This is a preliminary patch in order to allow the user to select if the
+configured device will be used as hw lan or wan.
+Please not this patch does not introduce any logical changes, just
+cosmetic ones.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20260527-airoha-eth-multi-serdes-preliminary-v1-6-ec6ed73ef7fc@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -1796,7 +1796,7 @@ static int airoha_dev_set_macaddr(struct
+       return 0;
+ }
+-static int airoha_set_gdm2_loopback(struct airoha_gdm_dev *dev)
++static int airoha_enable_gdm2_loopback(struct airoha_gdm_dev *dev)
+ {
+       struct airoha_gdm_port *port = dev->port;
+       struct airoha_eth *eth = dev->eth;
+@@ -1877,7 +1877,7 @@ static int airoha_dev_init(struct net_de
+               if (!eth->ports[1]) {
+                       int err;
+-                      err = airoha_set_gdm2_loopback(dev);
++                      err = airoha_enable_gdm2_loopback(dev);
+                       if (err)
+                               return err;
+               }
diff --git a/target/linux/airoha/patches-6.18/162-v7.2-net-airoha-Fix-use-after-free-in-metadata-dst-teardo.patch b/target/linux/airoha/patches-6.18/162-v7.2-net-airoha-Fix-use-after-free-in-metadata-dst-teardo.patch
new file mode 100644 (file)
index 0000000..7ea6058
--- /dev/null
@@ -0,0 +1,37 @@
+From b38cae85d1c45ff189d7ecb6ac36f41cdc3d84d0 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Tue, 2 Jun 2026 11:21:04 +0200
+Subject: [PATCH] net: airoha: Fix use-after-free in metadata dst teardown
+
+airoha_metadata_dst_free() runs metadata_dst_free() which frees the
+metadata_dst with kfree() immediately, bypassing the RCU grace period.
+In the RX path, skb_dst_set_noref() sets a non-refcounted pointer from
+the skb to the metadata_dst. This function requires RCU read-side
+protection and the dst must remain valid until all RCU readers complete.
+Since metadata_dst_free() calls kfree() directly, an use-after-free can
+occur if any skb still holds a noref pointer to the dst when the driver
+tears it down.
+Replace metadata_dst_free() with dst_release() which properly goes
+through the refcount path: when the refcount drops to zero, it schedules
+the actual free via call_rcu_hurry(), ensuring all RCU readers have
+completed before the memory is freed.
+
+Fixes: af3cf757d5c9 ("net: airoha: Move DSA tag in DMA descriptor")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20260602-airoha-mtk-metadata-uaf-fix-v1-1-3aaa99d83351@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -2972,7 +2972,7 @@ static void airoha_metadata_dst_free(str
+               if (!port->dsa_meta[i])
+                       continue;
+-              metadata_dst_free(port->dsa_meta[i]);
++              dst_release(&port->dsa_meta[i]->dst);
+       }
+ }
diff --git a/target/linux/airoha/patches-6.18/163-v7.2-net-airoha-Report-extack-error-to-the-user-if-airoha.patch b/target/linux/airoha/patches-6.18/163-v7.2-net-airoha-Report-extack-error-to-the-user-if-airoha.patch
new file mode 100644 (file)
index 0000000..6e4807b
--- /dev/null
@@ -0,0 +1,40 @@
+From 144969cd80c5227c2b19fe5f644d6eebd61be586 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Wed, 3 Jun 2026 12:30:01 +0200
+Subject: [PATCH] net: airoha: Report extack error to the user if
+ airoha_tc_htb_modify_queue() fails
+
+Report an extack error message in airoha_tc_htb_modify_queue routine if
+airoha_qdma_set_tx_rate_limit() fails.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com>
+Link: https://patch.msgid.link/20260603-airoha_tc_htb_modify_queue-err-message-v1-1-33ec3ab997d9@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -2605,13 +2605,19 @@ static int airoha_tc_htb_modify_queue(st
+ {
+       u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
+       u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */
++      int err;
+       if (opt->parent_classid != TC_HTB_CLASSID_ROOT) {
+               NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid");
+               return -EINVAL;
+       }
+-      return airoha_qdma_set_tx_rate_limit(dev, channel, rate, opt->quantum);
++      err = airoha_qdma_set_tx_rate_limit(dev, channel, rate, opt->quantum);
++      if (err)
++              NL_SET_ERR_MSG_MOD(opt->extack,
++                                 "failed configuring htb offload");
++
++      return err;
+ }
+ static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
diff --git a/target/linux/airoha/patches-6.18/164-v7.2-net-airoha-Add-NULL-check-for-of_reserved_mem_lookup.patch b/target/linux/airoha/patches-6.18/164-v7.2-net-airoha-Add-NULL-check-for-of_reserved_mem_lookup.patch
new file mode 100644 (file)
index 0000000..8301981
--- /dev/null
@@ -0,0 +1,41 @@
+From f9f25118faa4dd2b6e3d14a03d123bbdbd59925d Mon Sep 17 00:00:00 2001
+From: ZhaoJinming <zhaojinming@uniontech.com>
+Date: Thu, 4 Jun 2026 15:03:52 +0800
+Subject: [PATCH] net: airoha: Add NULL check for of_reserved_mem_lookup() in
+ airoha_qdma_init_hfwd_queues()
+
+of_reserved_mem_lookup() may return NULL if the reserved memory region
+referenced by the "memory-region" phandle is not found in the reserved
+memory table (e.g. due to a misconfigured DTS or a removed
+memory-region node).  The current code dereferences the returned
+pointer without checking for NULL, leading to a kernel NULL pointer
+dereference at the following lines:
+
+    dma_addr = rmem->base;                          // line 1156
+    num_desc = div_u64(rmem->size, buf_size);       // line 1160
+
+Add a NULL check after of_reserved_mem_lookup() and return -ENODEV if
+the lookup fails, which is consistent with the existing error handling
+for of_parse_phandle() failure in the same code block.
+
+Fixes: 3a1ce9e3d01b ("net: airoha: Add the capability to allocate hwfd buffers via reserved-memory")
+Cc: stable@vger.kernel.org
+Signed-off-by: ZhaoJinming <zhaojinming@uniontech.com>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -1159,6 +1159,9 @@ static int airoha_qdma_init_hfwd_queues(
+               rmem = of_reserved_mem_lookup(np);
+               of_node_put(np);
++              if (!rmem)
++                      return -ENODEV;
++
+               dma_addr = rmem->base;
+               /* Compute the number of hw descriptors according to the
+                * reserved memory size and the payload buffer size
diff --git a/target/linux/airoha/patches-6.18/165-01-v7.2-net-airoha-Remove-private-net_device-pointer-in-airo.patch b/target/linux/airoha/patches-6.18/165-01-v7.2-net-airoha-Remove-private-net_device-pointer-in-airo.patch
new file mode 100644 (file)
index 0000000..f4da9bf
--- /dev/null
@@ -0,0 +1,125 @@
+From 4408f520680990042a1e6bfdf3cef217a1abf152 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Wed, 3 Jun 2026 08:00:16 +0200
+Subject: [PATCH 1/5] net: airoha: Remove private net_device pointer in
+ airoha_gdm_dev struct
+
+Remove redundant net_device pointer inside airoha_gdm_dev struct and
+rely on netdev_from_priv routine instead. Please note this patch does
+not introduce any logical change, just code refactoring.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20260603-airoha-eth-multi-serdes-v9-2-5d476bc2f426@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 23 ++++++++++++++---------
+ drivers/net/ethernet/airoha/airoha_eth.h |  1 -
+ drivers/net/ethernet/airoha/airoha_ppe.c |  2 +-
+ 3 files changed, 15 insertions(+), 11 deletions(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -629,7 +629,7 @@ static int airoha_qdma_rx_process(struct
+               if (!port->dev)
+                       goto free_frag;
+-              netdev = port->dev->dev;
++              netdev = netdev_from_priv(port->dev);
+               if (!q->skb) { /* first buffer */
+                       q->skb = napi_build_skb(e->buf - AIROHA_RX_HEADROOM,
+                                               q->buf_size);
+@@ -853,6 +853,7 @@ static void airoha_qdma_wake_netdev_txqs
+       for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
+               struct airoha_gdm_port *port = eth->ports[i];
+               struct airoha_gdm_dev *dev;
++              struct net_device *netdev;
+               int j;
+               if (!port)
+@@ -865,11 +866,12 @@ static void airoha_qdma_wake_netdev_txqs
+               if (dev->qdma != qdma)
+                       continue;
+-              for (j = 0; j < dev->dev->num_tx_queues; j++) {
++              netdev = netdev_from_priv(dev);
++              for (j = 0; j < netdev->num_tx_queues; j++) {
+                       if (airoha_qdma_get_txq(qdma, j) != qid)
+                               continue;
+-                      netif_wake_subqueue(dev->dev, j);
++                      netif_wake_subqueue(netdev, j);
+               }
+       }
+       q->txq_stopped = false;
+@@ -1870,7 +1872,7 @@ static int airoha_dev_init(struct net_de
+       /* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
+       dev->qdma = &eth->qdma[!airoha_is_lan_gdm_dev(dev)];
+-      dev->dev->irq = dev->qdma->irq_banks[0].irq;
++      netdev->irq = dev->qdma->irq_banks[0].irq;
+       airoha_set_macaddr(dev, netdev->dev_addr);
+       switch (port->id) {
+@@ -3047,7 +3049,6 @@ static int airoha_alloc_gdm_device(struc
+       }
+       dev = netdev_priv(netdev);
+-      dev->dev = netdev;
+       dev->port = port;
+       port->dev = dev;
+       dev->eth = eth;
+@@ -3110,7 +3111,7 @@ static int airoha_register_gdm_devices(s
+               if (!port)
+                       continue;
+-              err = register_netdev(port->dev->dev);
++              err = register_netdev(netdev_from_priv(port->dev));
+               if (err)
+                       return err;
+       }
+@@ -3225,8 +3226,12 @@ error_napi_stop:
+                       continue;
+               dev = port->dev;
+-              if (dev && dev->dev->reg_state == NETREG_REGISTERED)
+-                      unregister_netdev(dev->dev);
++              if (dev) {
++                      struct net_device *netdev = netdev_from_priv(dev);
++
++                      if (netdev->reg_state == NETREG_REGISTERED)
++                              unregister_netdev(netdev);
++              }
+               airoha_metadata_dst_free(port);
+       }
+       airoha_hw_cleanup(eth);
+@@ -3254,7 +3259,7 @@ static void airoha_remove(struct platfor
+               dev = port->dev;
+               if (dev)
+-                      unregister_netdev(dev->dev);
++                      unregister_netdev(netdev_from_priv(dev));
+               airoha_metadata_dst_free(port);
+       }
+       airoha_hw_cleanup(eth);
+--- a/drivers/net/ethernet/airoha/airoha_eth.h
++++ b/drivers/net/ethernet/airoha/airoha_eth.h
+@@ -540,7 +540,6 @@ struct airoha_qdma {
+ struct airoha_gdm_dev {
+       struct airoha_gdm_port *port;
+       struct airoha_qdma *qdma;
+-      struct net_device *dev;
+       struct airoha_eth *eth;
+       DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS);
+--- a/drivers/net/ethernet/airoha/airoha_ppe.c
++++ b/drivers/net/ethernet/airoha/airoha_ppe.c
+@@ -1475,8 +1475,8 @@ void airoha_ppe_check_skb(struct airoha_
+ void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev)
+ {
++      struct net_device *netdev = netdev_from_priv(dev);
+       struct airoha_gdm_port *port = dev->port;
+-      struct net_device *netdev = dev->dev;
+       struct airoha_eth *eth = dev->eth;
+       const u8 *addr = netdev->dev_addr;
+       u32 val;
similarity index 77%
rename from target/linux/airoha/patches-6.18/920-06-net-airoha-Support-multiple-net_devices-for-a-single.patch
rename to target/linux/airoha/patches-6.18/165-02-v7.2-net-airoha-Support-multiple-net_devices-for-a-single.patch
index 870b24371b5f32c44860bd32575ed0e2727170c4..922d1057f5bb52cfa40b3192c2ad5196b774ffad 100644 (file)
@@ -1,11 +1,8 @@
-From 8eb0a71bfbe92b6fbc668c5d9ebdcbf6523a89ad Mon Sep 17 00:00:00 2001
-Message-ID: <8eb0a71bfbe92b6fbc668c5d9ebdcbf6523a89ad.1779348625.git.lorenzo@kernel.org>
-In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
-References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
+From a9c2ca61fec7706574c009d8f1898ca392368f89 Mon Sep 17 00:00:00 2001
 From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 1 Nov 2025 11:27:48 +0100
-Subject: [PATCH 06/13] net: airoha: Support multiple net_devices for a single
FE GDM port
+Date: Wed, 3 Jun 2026 08:00:17 +0200
+Subject: [PATCH 2/5] net: airoha: Support multiple net_devices for a single FE
+ GDM port
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
@@ -48,15 +45,17 @@ logics for the net_device type connected to GDM3 or GDM4.
 
 Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20260603-airoha-eth-multi-serdes-v9-3-5d476bc2f426@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 ---
- drivers/net/ethernet/airoha/airoha_eth.c | 274 +++++++++++++++++------
- drivers/net/ethernet/airoha/airoha_eth.h |  10 +-
- drivers/net/ethernet/airoha/airoha_ppe.c |  13 +-
- 3 files changed, 228 insertions(+), 69 deletions(-)
+ drivers/net/ethernet/airoha/airoha_eth.c | 280 +++++++++++++++++------
+ drivers/net/ethernet/airoha/airoha_eth.h |   8 +-
+ drivers/net/ethernet/airoha/airoha_ppe.c |  26 ++-
+ 3 files changed, 237 insertions(+), 77 deletions(-)
 
 --- a/drivers/net/ethernet/airoha/airoha_eth.c
 +++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -116,7 +116,7 @@ static int airoha_set_vip_for_gdm_port(s
+@@ -106,7 +106,7 @@ static int airoha_set_vip_for_gdm_port(s
        struct airoha_eth *eth = dev->eth;
        u32 vip_port;
  
@@ -65,7 +64,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        if (enable) {
                airoha_fe_set(eth, REG_FE_VIP_PORT_EN, vip_port);
                airoha_fe_set(eth, REG_FE_IFC_PORT_EN, vip_port);
-@@ -646,30 +646,26 @@ static int airoha_qdma_fill_rx_queue(str
+@@ -566,24 +566,26 @@ static int airoha_qdma_fill_rx_queue(str
        return nframes;
  }
  
@@ -80,14 +79,8 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
 -      sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1);
 -      switch (sport) {
--      case 0x18:
--              port = 3; /* GDM4 */
--              break;
--      case 0x16:
--              port = 2; /* GDM3 */
--              break;
 -      case 0x10 ... 0x14:
--              port = 0; /* GDM1 */
+-              port = 0;
 -              break;
 -      case 0x2 ... 0x4:
 -              port = sport - 1;
@@ -97,11 +90,11 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 -      }
 +      if (eth->soc->ops.get_dev_from_sport(desc, &p, &d))
 +              return ERR_PTR(-ENODEV);
-+
-+      if (p >= ARRAY_SIZE(eth->ports))
-+              return ERR_PTR(-ENODEV);
  
 -      return port >= ARRAY_SIZE(eth->ports) ? -EINVAL : port;
++      if (p >= ARRAY_SIZE(eth->ports))
++              return ERR_PTR(-ENODEV);
++
 +      port = eth->ports[p];
 +      if (!port)
 +              return ERR_PTR(-ENODEV);
@@ -112,8 +105,8 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +      return port->devs[d] ? port->devs[d] : ERR_PTR(-ENODEV);
  }
  
- static struct sk_buff *airoha_qdma_lro_rx_skb(struct airoha_queue *q,
-@@ -841,9 +837,9 @@ static int airoha_qdma_rx_process(struct
+ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
+@@ -598,9 +600,9 @@ static int airoha_qdma_rx_process(struct
                struct airoha_queue_entry *e = &q->entry[q->tail];
                struct airoha_qdma_desc *desc = &q->desc[q->tail];
                u32 hash, reason, msg1, desc_ctrl;
@@ -125,7 +118,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                struct page *page;
  
                desc_ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
-@@ -864,15 +860,11 @@ static int airoha_qdma_rx_process(struct
+@@ -621,15 +623,11 @@ static int airoha_qdma_rx_process(struct
                if (!len || data_len < len)
                        goto free_frag;
  
@@ -142,9 +135,9 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 -              netdev = netdev_from_priv(port->dev);
 +              netdev = netdev_from_priv(dev);
                if (!q->skb) { /* first buffer */
-                       q->skb = airoha_qdma_build_rx_skb(q, desc, e, netdev);
-                       if (!q->skb)
-@@ -893,6 +885,8 @@ static int airoha_qdma_rx_process(struct
+                       q->skb = napi_build_skb(e->buf - AIROHA_RX_HEADROOM,
+                                               q->buf_size);
+@@ -659,6 +657,8 @@ static int airoha_qdma_rx_process(struct
                        continue;
  
                if (netdev_uses_dsa(netdev)) {
@@ -153,7 +146,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                        /* PPE module requires untagged packets to work
                         * properly and it provides DSA port index via the
                         * DMA descriptor. Report DSA tag to the DSA stack
-@@ -1095,26 +1089,29 @@ static void airoha_qdma_wake_netdev_txqs
+@@ -852,26 +852,29 @@ static void airoha_qdma_wake_netdev_txqs
  
        for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
                struct airoha_gdm_port *port = eth->ports[i];
@@ -178,7 +171,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +                      if (!dev)
 +                              continue;
  
--              netdev = netdev_from_priv(port->dev);
+-              netdev = netdev_from_priv(dev);
 -              for (j = 0; j < netdev->num_tx_queues; j++) {
 -                      if (airoha_qdma_get_txq(qdma, j) != qid)
 +                      if (dev->qdma != qdma)
@@ -195,58 +188,21 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                }
        }
        q->txq_stopped = false;
-@@ -1961,22 +1958,32 @@ static void airoha_update_hw_stats(struc
- static void airoha_update_netdev_features(struct airoha_gdm_dev *dev)
- {
--      struct airoha_gdm_port *port = dev->port;
-       struct airoha_eth *eth = dev->eth;
-       int i;
-       for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
--              struct airoha_gdm_port *p = eth->ports[i];
--              struct net_device *netdev;
-+              struct airoha_gdm_port *port = eth->ports[i];
-+              int j;
--              if (!p)
-+              if (!port)
-                       continue;
--              netdev = netdev_from_priv(p->dev);
--              if (netdev->reg_state != NETREG_REGISTERED)
--                      continue;
-+              for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
-+                      struct airoha_gdm_dev *iter_dev = port->devs[j];
-+                      struct net_device *netdev;
-+
-+                      if (!iter_dev || iter_dev == dev)
-+                              continue;
-+
-+                      if (iter_dev->qdma != dev->qdma)
-+                              continue;
-+
-+                      netdev = netdev_from_priv(iter_dev);
-+                      if (netdev->reg_state != NETREG_REGISTERED)
-+                              continue;
--              netdev_update_features(netdev);
-+                      netdev_update_features(netdev);
-+              }
-       }
- }
-@@ -2037,7 +2044,8 @@ static int airoha_dev_open(struct net_de
+@@ -1745,11 +1748,9 @@ static int airoha_dev_open(struct net_de
                        GLOBAL_CFG_RX_DMA_EN_MASK);
-       qdma->users++;
+       atomic_inc(&qdma->users);
  
--      if (port->id == AIROHA_GDM2_IDX && airoha_ppe_is_enabled(eth, 1)) {
+-      if (port->id == AIROHA_GDM2_IDX &&
+-          airoha_ppe_is_enabled(qdma->eth, 1)) {
+-              /* For PPE2 always use secondary cpu port. */
 +      if (!airoha_is_lan_gdm_dev(dev) &&
-+          airoha_ppe_is_enabled(eth, 1)) {
-               /* For PPE2 always use secondary cpu port. */
++          airoha_ppe_is_enabled(qdma->eth, 1))
                pse_port = FE_PSE_PORT_PPE2;
-       }
-@@ -2143,7 +2151,7 @@ static int airoha_set_gdm2_loopback(stru
+-      }
+       airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
+                                   pse_port);
+@@ -1837,7 +1838,7 @@ static int airoha_enable_gdm2_loopback(s
        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));
  
@@ -255,16 +211,16 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        if (src_port < 0)
                return src_port;
  
-@@ -2160,7 +2168,7 @@ static int airoha_set_gdm2_loopback(stru
+@@ -1854,7 +1855,7 @@ static int airoha_enable_gdm2_loopback(s
                airoha_ppe_set_cpu_port(dev, i, AIROHA_GDM2_IDX);
  
        if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) {
--              u32 mask = FC_ID_OF_SRC_PORT_MASK(nbq);
+-              u32 mask = FC_ID_OF_SRC_PORT_MASK(port->nbq);
 +              u32 mask = FC_ID_OF_SRC_PORT_MASK(dev->nbq);
  
                airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, mask,
                              __field_prep(mask, AIROHA_GDM2_IDX));
-@@ -2174,7 +2182,7 @@ static int airoha_dev_init(struct net_de
+@@ -1868,7 +1869,7 @@ static int airoha_dev_init(struct net_de
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
        struct airoha_gdm_port *port = dev->port;
        struct airoha_eth *eth = dev->eth;
@@ -273,7 +229,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        /* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
        dev->qdma = &eth->qdma[!airoha_is_lan_gdm_dev(dev)];
-@@ -2197,8 +2205,8 @@ static int airoha_dev_init(struct net_de
+@@ -1891,8 +1892,8 @@ static int airoha_dev_init(struct net_de
                break;
        }
  
@@ -284,7 +240,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        return 0;
  }
-@@ -2396,7 +2404,8 @@ static netdev_tx_t airoha_dev_xmit(struc
+@@ -2058,7 +2059,8 @@ static netdev_tx_t airoha_dev_xmit(struc
        }
  
        fport = airoha_get_fe_port(dev);
@@ -294,7 +250,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
               FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f);
  
        q = &qdma->q_tx[qid];
-@@ -3339,12 +3348,15 @@ bool airoha_is_valid_gdm_dev(struct airo
+@@ -2994,12 +2996,15 @@ bool airoha_is_valid_gdm_dev(struct airo
  
        for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
                struct airoha_gdm_port *port = eth->ports[i];
@@ -312,7 +268,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        }
  
        return false;
-@@ -3468,10 +3480,11 @@ static int airoha_setup_phylink(struct n
+@@ -3007,10 +3012,11 @@ bool airoha_is_valid_gdm_dev(struct airo
  
  static int airoha_alloc_gdm_device(struct airoha_eth *eth,
                                   struct airoha_gdm_port *port,
@@ -326,15 +282,15 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        int err;
  
        netdev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*dev),
-@@ -3489,7 +3502,6 @@ static int airoha_alloc_gdm_device(struc
-       netdev->hw_features = AIROHA_HW_FEATURES | NETIF_F_GRO_HW;
-       netdev->features |= AIROHA_HW_FEATURES;
-       netdev->vlan_features = AIROHA_HW_FEATURES;
+@@ -3030,7 +3036,6 @@ static int airoha_alloc_gdm_device(struc
+                             NETIF_F_HW_TC;
+       netdev->features |= netdev->hw_features;
+       netdev->vlan_features = netdev->hw_features;
 -      netdev->dev.of_node = np;
        SET_NETDEV_DEV(netdev, eth->dev);
  
        /* reserve hw queues for HTB offloading */
-@@ -3507,10 +3519,24 @@ static int airoha_alloc_gdm_device(struc
+@@ -3048,10 +3053,24 @@ static int airoha_alloc_gdm_device(struc
                         netdev->dev_addr);
        }
  
@@ -358,9 +314,9 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +      dev->nbq = nbq;
 +      port->devs[index] = dev;
  
- #if defined(CONFIG_PCS_AIROHA)
-       if (airhoa_is_phy_external(port)) {
-@@ -3528,7 +3554,8 @@ static int airoha_alloc_gdm_port(struct
+       return 0;
+ }
+@@ -3061,7 +3080,8 @@ static int airoha_alloc_gdm_port(struct
  {
        const __be32 *id_ptr = of_get_property(np, "reg", NULL);
        struct airoha_gdm_port *port;
@@ -370,7 +326,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        u32 id;
  
        if (!id_ptr) {
-@@ -3556,15 +3583,51 @@ static int airoha_alloc_gdm_port(struct
+@@ -3089,15 +3109,51 @@ static int airoha_alloc_gdm_port(struct
        u64_stats_init(&port->stats.syncp);
        spin_lock_init(&port->stats.lock);
        port->id = id;
@@ -425,7 +381,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  }
  
  static int airoha_register_gdm_devices(struct airoha_eth *eth)
-@@ -3573,14 +3636,22 @@ static int airoha_register_gdm_devices(s
+@@ -3106,14 +3162,22 @@ static int airoha_register_gdm_devices(s
  
        for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
                struct airoha_gdm_port *port = eth->ports[i];
@@ -452,7 +408,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        }
  
        set_bit(DEV_STATE_REGISTERED, &eth->state);
-@@ -3687,15 +3758,19 @@ error_napi_stop:
+@@ -3220,17 +3284,22 @@ error_napi_stop:
  
        for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
                struct airoha_gdm_port *port = eth->ports[i];
@@ -473,18 +429,13 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +                              continue;
  
 +                      netdev = netdev_from_priv(dev);
-                       if (netdev->reg_state == NETREG_REGISTERED) {
- #if defined(CONFIG_PCS_AIROHA)
-                               if (airhoa_is_phy_external(port))
-@@ -3703,6 +3778,7 @@ error_napi_stop:
- #endif
+                       if (netdev->reg_state == NETREG_REGISTERED)
                                unregister_netdev(netdev);
-                       }
 +                      of_node_put(netdev->dev.of_node);
                }
                airoha_metadata_dst_free(port);
        }
-@@ -3724,19 +3800,27 @@ static void airoha_remove(struct platfor
+@@ -3252,14 +3321,22 @@ static void airoha_remove(struct platfor
  
        for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
                struct airoha_gdm_port *port = eth->ports[i];
@@ -494,6 +445,9 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                if (!port)
                        continue;
  
+-              dev = port->dev;
+-              if (dev)
+-                      unregister_netdev(netdev_from_priv(dev));
 +              for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
 +                      struct airoha_gdm_dev *dev = port->devs[j];
 +                      struct net_device *netdev;
@@ -501,16 +455,6 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +                      if (!dev)
 +                              continue;
 +
- #if defined(CONFIG_PCS_AIROHA)
--              if (airhoa_is_phy_external(port))
--                      phylink_destroy(dev->phylink);
-+                      if (airhoa_is_phy_external(port))
-+                              phylink_destroy(dev->phylink);
- #endif
--              dev = port->dev;
--              if (dev)
--                      unregister_netdev(netdev_from_priv(dev));
 +                      netdev = netdev_from_priv(dev);
 +                      unregister_netdev(netdev);
 +                      of_node_put(netdev->dev.of_node);
@@ -518,7 +462,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                airoha_metadata_dst_free(port);
        }
        airoha_hw_cleanup(eth);
-@@ -3798,6 +3882,39 @@ static u32 airoha_en7581_get_vip_port(st
+@@ -3322,6 +3399,39 @@ static u32 airoha_en7581_get_vip_port(st
        return 0;
  }
  
@@ -556,9 +500,9 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +}
 +
  static const char * const an7583_xsi_rsts_names[] = {
+       "xsi-mac",
        "hsi0-mac",
-       "hsi1-mac",
-@@ -3846,6 +3963,36 @@ static u32 airoha_an7583_get_vip_port(st
+@@ -3371,6 +3481,36 @@ static u32 airoha_an7583_get_vip_port(st
        return 0;
  }
  
@@ -595,7 +539,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  static const struct airoha_eth_soc_data en7581_soc_data = {
        .version = 0x7581,
        .xsi_rsts_names = en7581_xsi_rsts_names,
-@@ -3854,6 +4001,7 @@ static const struct airoha_eth_soc_data
+@@ -3379,6 +3519,7 @@ static const struct airoha_eth_soc_data
        .ops = {
                .get_sport = airoha_en7581_get_sport,
                .get_vip_port = airoha_en7581_get_vip_port,
@@ -603,7 +547,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        },
  };
  
-@@ -3865,6 +4013,7 @@ static const struct airoha_eth_soc_data
+@@ -3390,6 +3531,7 @@ static const struct airoha_eth_soc_data
        .ops = {
                .get_sport = airoha_an7583_get_sport,
                .get_vip_port = airoha_an7583_get_vip_port,
@@ -621,7 +565,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  #define AIROHA_MAX_NUM_QDMA           2
  #define AIROHA_MAX_NUM_IRQ_BANKS      4
  #define AIROHA_MAX_DSA_PORTS          7
-@@ -563,12 +564,13 @@ struct airoha_gdm_dev {
+@@ -546,12 +547,13 @@ struct airoha_gdm_dev {
        /* qos stats counters */
        u64 cpu_tx_packets;
        u64 fwd_tx_packets;
@@ -637,7 +581,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        struct airoha_hw_stats stats;
  
-@@ -604,6 +606,8 @@ struct airoha_eth_soc_data {
+@@ -587,6 +589,8 @@ struct airoha_eth_soc_data {
        struct {
                int (*get_sport)(struct airoha_gdm_port *port, int nbq);
                u32 (*get_vip_port)(struct airoha_gdm_port *port, int nbq);
@@ -648,7 +592,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
 --- a/drivers/net/ethernet/airoha/airoha_ppe.c
 +++ b/drivers/net/ethernet/airoha/airoha_ppe.c
-@@ -168,9 +168,7 @@ static void airoha_ppe_hw_init(struct ai
+@@ -167,9 +167,7 @@ static void airoha_ppe_hw_init(struct ai
                airoha_fe_clear(eth, REG_PPE_PPE_FLOW_CFG(i),
                                PPE_FLOW_CFG_IP6_6RD_MASK);
  
@@ -659,7 +603,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                        airoha_fe_rmw(eth, REG_PPE_MTU(i, p),
                                      FP0_EGRESS_MTU_MASK |
                                      FP1_EGRESS_MTU_MASK,
-@@ -178,11 +176,27 @@ static void airoha_ppe_hw_init(struct ai
+@@ -177,11 +175,27 @@ static void airoha_ppe_hw_init(struct ai
                                                 AIROHA_MAX_MTU) |
                                      FIELD_PREP(FP1_EGRESS_MTU_MASK,
                                                 AIROHA_MAX_MTU));
similarity index 70%
rename from target/linux/airoha/patches-6.18/920-07-net-airoha-Do-not-stop-GDM-port-if-it-is-shared.patch
rename to target/linux/airoha/patches-6.18/165-03-v7.2-net-airoha-Do-not-stop-GDM-port-if-it-is-shared.patch
index 7dc33792bd8f11a714231b87946b9be3a7f10893..cc8627fe541bc84e5e037247dcf1fa20dfcbe315 100644 (file)
@@ -1,10 +1,7 @@
-From de856a5b802cf030c8e242e98df3bc88446a4ea1 Mon Sep 17 00:00:00 2001
-Message-ID: <de856a5b802cf030c8e242e98df3bc88446a4ea1.1779348625.git.lorenzo@kernel.org>
-In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
-References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
+From 99b9d095d71e5cb84121dacce2ac217aad9b174f Mon Sep 17 00:00:00 2001
 From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 20 Mar 2026 11:09:40 +0100
-Subject: [PATCH 07/13] net: airoha: Do not stop GDM port if it is shared
+Date: Wed, 3 Jun 2026 08:00:18 +0200
+Subject: [PATCH 3/5] net: airoha: Do not stop GDM port if it is shared
 
 Theoretically, in the current codebase, two independent net_devices can
 be connected to the same GDM port so we need to check the GDM port is not
@@ -16,6 +13,8 @@ GDM port.
 
 Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20260603-airoha-eth-multi-serdes-v9-4-5d476bc2f426@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 ---
  drivers/net/ethernet/airoha/airoha_eth.c | 59 +++++++++++++++++++-----
  drivers/net/ethernet/airoha/airoha_eth.h |  1 +
@@ -23,27 +22,25 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 
 --- a/drivers/net/ethernet/airoha/airoha_eth.c
 +++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -1992,10 +1992,10 @@ static int airoha_dev_open(struct net_de
+@@ -1723,8 +1723,8 @@ static int airoha_dev_open(struct net_de
        int err, len = ETH_HLEN + netdev->mtu + ETH_FCS_LEN;
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
        struct airoha_gdm_port *port = dev->port;
 +      u32 cur_len, pse_port = FE_PSE_PORT_PPE1;
        struct airoha_qdma *qdma = dev->qdma;
-       struct airoha_eth *eth = qdma->eth;
-       int qdma_id = qdma - &eth->qdma[0];
 -      u32 pse_port = FE_PSE_PORT_PPE1;
  
-       /* HW LRO is configured on the QDMA and it is shared between
-        * all the devices using it. Refuse to open a second device on
-@@ -2034,10 +2034,20 @@ static int airoha_dev_open(struct net_de
-               airoha_fe_clear(eth, REG_GDM_INGRESS_CFG(port->id),
+       netif_tx_start_all_queues(netdev);
+       err = airoha_set_vip_for_gdm_port(dev, true);
+@@ -1738,10 +1738,20 @@ static int airoha_dev_open(struct net_de
+               airoha_fe_clear(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
                                GDM_STAG_EN_MASK);
  
--      airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id),
+-      airoha_fe_rmw(qdma->eth, REG_GDM_LEN_CFG(port->id),
 -                    GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK,
 -                    FIELD_PREP(GDM_SHORT_LEN_MASK, 60) |
 -                    FIELD_PREP(GDM_LONG_LEN_MASK, len));
-+      cur_len = airoha_fe_get(eth, REG_GDM_LEN_CFG(port->id),
++      cur_len = airoha_fe_get(qdma->eth, REG_GDM_LEN_CFG(port->id),
 +                              GDM_LONG_LEN_MASK);
 +      if (!port->users || len > cur_len) {
 +              /* Opening a sibling net_device with a larger MTU updates the
@@ -51,7 +48,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +               * multiple net_devices with different MTUs to share the same
 +               * GDM port.
 +               */
-+              airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id),
++              airoha_fe_rmw(qdma->eth, REG_GDM_LEN_CFG(port->id),
 +                            GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK,
 +                            FIELD_PREP(GDM_SHORT_LEN_MASK, 60) |
 +                            FIELD_PREP(GDM_LONG_LEN_MASK, len));
@@ -60,7 +57,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG,
                        GLOBAL_CFG_TX_DMA_EN_MASK |
-@@ -2060,6 +2070,30 @@ static int airoha_dev_open(struct net_de
+@@ -1757,6 +1767,30 @@ static int airoha_dev_open(struct net_de
        return 0;
  }
  
@@ -91,21 +88,22 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  static int airoha_dev_stop(struct net_device *netdev)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
-@@ -2073,8 +2107,11 @@ static int airoha_dev_stop(struct net_de
+@@ -1769,8 +1803,12 @@ static int airoha_dev_stop(struct net_de
        for (i = 0; i < netdev->num_tx_queues; i++)
                netdev_tx_reset_subqueue(netdev, i);
  
--      airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id),
+-      airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
 -                                  FE_PSE_PORT_DROP);
 +      if (--port->users)
-+              airoha_set_port_mtu(eth, port);
++              airoha_set_port_mtu(dev->eth, port);
 +      else
-+              airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id),
++              airoha_set_gdm_port_fwd_cfg(qdma->eth,
++                                          REG_GDM_FWD_CFG(port->id),
 +                                          FE_PSE_PORT_DROP);
  
-       if (!--qdma->users) {
+       if (atomic_dec_and_test(&qdma->users)) {
                airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG,
-@@ -2238,13 +2275,10 @@ static int airoha_dev_change_mtu(struct
+@@ -1925,13 +1963,10 @@ static int airoha_dev_change_mtu(struct
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
        struct airoha_gdm_port *port = dev->port;
@@ -123,7 +121,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  }
 --- a/drivers/net/ethernet/airoha/airoha_eth.h
 +++ b/drivers/net/ethernet/airoha/airoha_eth.h
-@@ -571,6 +571,7 @@ struct airoha_gdm_dev {
+@@ -554,6 +554,7 @@ struct airoha_gdm_dev {
  struct airoha_gdm_port {
        struct airoha_gdm_dev *devs[AIROHA_MAX_NUM_GDM_DEVS];
        int id;
similarity index 83%
rename from target/linux/airoha/patches-6.18/920-08-net-airoha-Introduce-WAN-device-flag.patch
rename to target/linux/airoha/patches-6.18/165-04-v7.2-net-airoha-Introduce-WAN-device-flag.patch
index a21fa3f05bd7210097baa9d81b981566e211e423..35e864e30d53642dcecd53a7b946409f9fba970f 100644 (file)
@@ -1,10 +1,7 @@
-From c4f3077948eda05a6b9d1a11304d82c3e0300151 Mon Sep 17 00:00:00 2001
-Message-ID: <c4f3077948eda05a6b9d1a11304d82c3e0300151.1779348625.git.lorenzo@kernel.org>
-In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
-References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
+From 7758cb462ff72b10d71e72bca8cf65179a1264e8 Mon Sep 17 00:00:00 2001
 From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 3 Apr 2026 12:07:27 +0200
-Subject: [PATCH 08/13] net: airoha: Introduce WAN device flag
+Date: Wed, 3 Jun 2026 08:00:19 +0200
+Subject: [PATCH 4/5] net: airoha: Introduce WAN device flag
 
 Introduce WAN flag to specify if a given device is used to transmit/receive
 WAN or LAN traffic. Current codebase supports specifying LAN/WAN device
@@ -21,15 +18,17 @@ officially supported since PCS/external phy is not merged mainline yet
 
 Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20260603-airoha-eth-multi-serdes-v9-5-5d476bc2f426@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 ---
- drivers/net/ethernet/airoha/airoha_eth.c | 72 +++++++++++++++++++-----
+ drivers/net/ethernet/airoha/airoha_eth.c | 73 +++++++++++++++++++-----
  drivers/net/ethernet/airoha/airoha_eth.h | 13 ++---
  drivers/net/ethernet/airoha/airoha_ppe.c |  2 +-
- 3 files changed, 65 insertions(+), 22 deletions(-)
+ 3 files changed, 66 insertions(+), 22 deletions(-)
 
 --- a/drivers/net/ethernet/airoha/airoha_eth.c
 +++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -2214,36 +2214,81 @@ static int airoha_set_gdm2_loopback(stru
+@@ -1902,36 +1902,81 @@ static int airoha_enable_gdm2_loopback(s
        return 0;
  }
  
@@ -86,7 +85,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 -              if (!eth->ports[1]) {
 -                      int err;
 -
--                      err = airoha_set_gdm2_loopback(dev);
+-                      err = airoha_enable_gdm2_loopback(dev);
 -                      if (err)
 -                              return err;
 -              }
@@ -119,7 +118,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +          (port->id == AIROHA_GDM3_IDX || port->id == AIROHA_GDM4_IDX)) {
 +              int err;
 +
-+              err = airoha_set_gdm2_loopback(dev);
++              err = airoha_enable_gdm2_loopback(dev);
 +              if (err)
 +                      return err;
 +      }
@@ -128,7 +127,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  }
 --- a/drivers/net/ethernet/airoha/airoha_eth.h
 +++ b/drivers/net/ethernet/airoha/airoha_eth.h
-@@ -550,6 +550,10 @@ struct airoha_qdma {
+@@ -538,6 +538,10 @@ struct airoha_qdma {
        DECLARE_BITMAP(qos_channel_map, AIROHA_NUM_QOS_CHANNELS);
  };
  
@@ -139,7 +138,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  struct airoha_gdm_dev {
        struct airoha_gdm_port *port;
        struct airoha_qdma *qdma;
-@@ -565,6 +569,7 @@ struct airoha_gdm_dev {
+@@ -548,6 +552,7 @@ struct airoha_gdm_dev {
        u64 cpu_tx_packets;
        u64 fwd_tx_packets;
  
@@ -147,7 +146,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        int nbq;
  };
  
-@@ -671,13 +676,7 @@ static inline u16 airoha_qdma_get_txq(st
+@@ -654,13 +659,7 @@ static inline u16 airoha_qdma_get_txq(st
  
  static inline bool airoha_is_lan_gdm_dev(struct airoha_gdm_dev *dev)
  {
@@ -164,7 +163,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  static inline bool airoha_is_7581(struct airoha_eth *eth)
 --- a/drivers/net/ethernet/airoha/airoha_ppe.c
 +++ b/drivers/net/ethernet/airoha/airoha_ppe.c
-@@ -356,7 +356,7 @@ static int airoha_ppe_foe_entry_prepare(
+@@ -355,7 +355,7 @@ static int airoha_ppe_foe_entry_prepare(
                                return -EINVAL;
  
                        port = dev->port;
similarity index 75%
rename from target/linux/airoha/patches-6.18/920-09-net-airoha-Support-multiple-LAN-WAN-interfaces-for-h.patch
rename to target/linux/airoha/patches-6.18/165-05-v7.2-net-airoha-Support-multiple-LAN-WAN-interfaces-for-h.patch
index 553bd3cbf57533c62805f67ae2da85ee0708fbc5..a4041bb3dbd2502d4c00e5a7daa7c0710db5c96a 100644 (file)
@@ -1,38 +1,42 @@
-From 144f0e6e55896625e3411aad02399a5ebb48d8f9 Mon Sep 17 00:00:00 2001
-Message-ID: <144f0e6e55896625e3411aad02399a5ebb48d8f9.1779348625.git.lorenzo@kernel.org>
-In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
-References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
+From ef2aee987174b51573645b4bdacedf610e89ce1a Mon Sep 17 00:00:00 2001
 From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 13 Apr 2026 17:38:51 +0200
-Subject: [PATCH 09/13] net: airoha: Support multiple LAN/WAN interfaces for hw
+Date: Wed, 3 Jun 2026 08:00:20 +0200
+Subject: [PATCH 5/5] net: airoha: Support multiple LAN/WAN interfaces for hw
  MAC address configuration
 
 The EN7581 and AN7583 SoCs provide registers to configure hardware LAN/WAN
-MAC addresses, used to determine whether received traffic is destined for
-this host or should be forwarded to another device.
+MAC addresses. These registers are used during FE hw acceleration to
+determine whether received traffic is destined to this host (L3 traffic)
+or should be switched to another device (L2 traffic).
 The SoC hardware design assumes all interfaces configured as LAN (or WAN)
-share a common upper MAC address, which is programmed into the
-REG_FE_{LAN,WAN}_MAC_H register. The lower bytes of 'local' addresses can
-be expressed as a range via the REG_FE_MAC_LMIN and REG_FE_MAC_LMAX
-registers.
+share the MAC address MSBs, which are programmed into the
+REG_FE_{LAN,WAN}_MAC_H register. The LSBs of 'local' mac addresses can be
+expressed as a range via the REG_FE_MAC_LMIN and REG_FE_MAC_LMAX
+registers. In order to properly accelerate the traffic, FE module requires
+the user to configure the REG_FE_{LAN,WAN}_MAC_H register respecting this
+limitation. Please note a misconfiguration in REG_FE_{LAN,WAN}_MAC_H
+will still allow the user to log into the device for debugging.
 Previously, only a single interface was considered when programming these
 registers. Extend the logic to derive the correct minimum and maximum
 values for REG_FE_MAC_LMIN/REG_FE_MAC_LMAX when two or more interfaces are
-configured as LAN or WAN.
+configured as LAN or WAN. Since this functionality was not available
+before this series, no regression is introduced.
 
 Tested-by: Madhur Agrawal <madhur.agrawal@airoha.com>
 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20260603-airoha-eth-multi-serdes-v9-6-5d476bc2f426@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 ---
- drivers/net/ethernet/airoha/airoha_eth.c | 77 ++++++++++++++++++++----
+ drivers/net/ethernet/airoha/airoha_eth.c | 77 +++++++++++++++++++++---
  drivers/net/ethernet/airoha/airoha_eth.h |  2 +-
  drivers/net/ethernet/airoha/airoha_ppe.c |  4 +-
- 3 files changed, 68 insertions(+), 15 deletions(-)
+ 3 files changed, 71 insertions(+), 12 deletions(-)
 
 --- a/drivers/net/ethernet/airoha/airoha_eth.c
 +++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -81,20 +81,76 @@ static bool airhoa_is_phy_external(struc
+@@ -71,20 +71,76 @@ static void airoha_qdma_irq_disable(stru
+       airoha_qdma_set_irqmask(irq_bank, index, mask, 0);
  }
- #endif
  
 -static void airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr)
 +static int airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr)
@@ -105,15 +109,15 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 -      airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), val);
 +      airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), lmin);
 +      airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), lmax);
-+
-+      airoha_ppe_init_upd_mem(dev, addr);
  
 -      airoha_ppe_init_upd_mem(dev);
++      airoha_ppe_init_upd_mem(dev, addr);
++
 +      return 0;
  }
  
  static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr,
-@@ -2141,13 +2197,18 @@ static int airoha_dev_stop(struct net_de
+@@ -1829,13 +1885,18 @@ static int airoha_dev_stop(struct net_de
  static int airoha_dev_set_macaddr(struct net_device *netdev, void *p)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -136,7 +140,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  }
 --- a/drivers/net/ethernet/airoha/airoha_eth.h
 +++ b/drivers/net/ethernet/airoha/airoha_eth.h
-@@ -712,7 +712,7 @@ void airoha_ppe_check_skb(struct airoha_
+@@ -683,7 +683,7 @@ void airoha_ppe_check_skb(struct airoha_
  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);
@@ -147,7 +151,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                                                  u32 hash);
 --- a/drivers/net/ethernet/airoha/airoha_ppe.c
 +++ b/drivers/net/ethernet/airoha/airoha_ppe.c
-@@ -1499,12 +1499,10 @@ void airoha_ppe_check_skb(struct airoha_
+@@ -1487,12 +1487,10 @@ void airoha_ppe_check_skb(struct airoha_
        airoha_ppe_foe_insert_entry(ppe, skb, hash, rx_wlan);
  }
  
similarity index 87%
rename from target/linux/airoha/patches-6.18/920-14-net-airoha-Better-handle-MIB-for-GDM-with-multiple-p.patch
rename to target/linux/airoha/patches-6.18/166-v7.2-net-airoha-better-handle-MIBs-for-GDM-ports-with-mul.patch
index 1aec4e91fcf3b722d9741b178a1eefd02a54bd28..474cbe9a1b16fc0a7a4c57d84ac3d0abd24668b9 100644 (file)
@@ -1,29 +1,31 @@
-From 9652322e0b47eacfef497828f6476a2a3169fd13 Mon Sep 17 00:00:00 2001
-Message-ID: <9652322e0b47eacfef497828f6476a2a3169fd13.1779351672.git.lorenzo@kernel.org>
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sat, 17 Jan 2026 14:46:12 +0100
-Subject: [PATCH] net: airoha: Better handle MIB for GDM with multiple port
- attached
-
-In the context of a GDM that can have multiple port attached (GDM3/4)
-the HW counter (MIB) are global for the GDM port. This cause duplicated
-stats reported to the kernel for the related interface.
+From 8f4695fb67b259b2cae0be1eef55859bfc559058 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Thu, 11 Jun 2026 12:43:00 +0200
+Subject: [PATCH] net: airoha: better handle MIBs for GDM ports with multiple
+ devs attached
 
+In the context of a GDM port that can have multiple net_devices attached
+(GDM3 and GDM4), the HW counters (MIBs) are global for the GDM port.
+This cause duplicated stats reported to the kernel for the related
+net_device.
 The SoC supports a split MIB feature where each counter is tracked based
 on the relevant HW channel (NBQ) to account for this scenario and
 provide a way to select the related counter on accessing the MIB
 registers.
-
 Enable this feature for GDM3 and GDM4 and configure the relevant HW
 channel before updating the HW stats to report correct HW counter to the
 kernel for the related interface.
+Move the stats struct from port to dev since HW counter are now specific
+to the network device instead of the GDM port. Refactor
+airoha_update_hw_stats() to take airoha_eth and airoha_gdm_port
+parameters since the function operates on the entire port.
 
-Also move the stats struct from port to dev since HW counter are
-now specific to the network interface instead of the GDM port.
-
-Co-developed-by: Brown Huang <Brown.huang@airoha.com>
-Signed-off-by: Brown Huang <Brown.huang@airoha.com>
+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>
+Link: https://patch.msgid.link/20260611-airoha-eth-multi-serdes-stats-v1-1-42442ae42064@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 ---
  drivers/net/ethernet/airoha/airoha_eth.c | 191 +++++++++++++----------
  drivers/net/ethernet/airoha/airoha_eth.h |   7 +-
@@ -31,9 +33,9 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
 
 --- a/drivers/net/ethernet/airoha/airoha_eth.c
 +++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -640,6 +640,14 @@ static int airoha_fe_init(struct airoha_
-       airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM4_IDX),
-                     GDM_PAD_EN_MASK | GDM_STRIP_CRC_MASK);
+@@ -556,6 +556,14 @@ static int airoha_fe_init(struct airoha_
+       airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM3_IDX), GDM_PAD_EN_MASK);
+       airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM4_IDX), GDM_PAD_EN_MASK);
  
 +      /* Enable split for MIB counters for GDM3 and GDM4 */
 +      airoha_fe_set(eth, REG_FE_GDM_MIB_CFG(AIROHA_GDM3_IDX),
@@ -46,7 +48,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
        airoha_fe_crsn_qsel_init(eth);
  
        airoha_fe_clear(eth, REG_FE_CPORT_CFG, FE_CPORT_QUEUE_XFC_MASK);
-@@ -1872,149 +1880,169 @@ static void airoha_qdma_stop_napi(struct
+@@ -1629,149 +1637,169 @@ static void airoha_qdma_stop_napi(struct
        }
  }
  
@@ -59,14 +61,14 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
  
 -      spin_lock(&port->stats.lock);
 -      u64_stats_update_begin(&port->stats.syncp);
-+      u64_stats_update_begin(&dev->stats.syncp);
-+
 +      /* Read relevant MIB for GDM with multiple port attached */
 +      if (port->id == AIROHA_GDM3_IDX || port->id == AIROHA_GDM4_IDX)
 +              airoha_fe_rmw(eth, REG_FE_GDM_MIB_CFG(port->id),
 +                            FE_TX_MIB_ID_MASK | FE_RX_MIB_ID_MASK,
 +                            FIELD_PREP(FE_TX_MIB_ID_MASK, dev->nbq) |
 +                            FIELD_PREP(FE_RX_MIB_ID_MASK, dev->nbq));
++
++      u64_stats_update_begin(&dev->stats.syncp);
  
        /* TX */
        val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_PKT_CNT_H(port->id));
@@ -245,7 +247,9 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
 +
 +      u64_stats_update_end(&dev->stats.syncp);
 +}
-+
+-      /* reset mib counters */
+-      airoha_fe_set(eth, REG_FE_GDM_MIB_CLEAR(port->id),
 +static void airoha_update_hw_stats(struct airoha_gdm_dev *dev)
 +{
 +      struct airoha_gdm_port *port = dev->port;
@@ -257,9 +261,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
 +              if (port->devs[i])
 +                      airoha_dev_get_hw_stats(port->devs[i]);
 +      }
--      /* reset mib counters */
--      airoha_fe_set(eth, REG_FE_GDM_MIB_CLEAR(port->id),
++
 +      /* Reset MIB counters */
 +      airoha_fe_set(dev->eth, REG_FE_GDM_MIB_CLEAR(port->id),
                      FE_GDM_MIB_RX_CLEAR_MASK | FE_GDM_MIB_TX_CLEAR_MASK);
@@ -269,8 +271,8 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
 +      spin_unlock(&port->stats_lock);
  }
  
- static void airoha_update_netdev_features(struct airoha_gdm_dev *dev)
-@@ -2418,23 +2446,22 @@ static void airoha_dev_get_stats64(struc
+ static int airoha_dev_open(struct net_device *netdev)
+@@ -2046,23 +2074,22 @@ static void airoha_dev_get_stats64(struc
                                   struct rtnl_link_stats64 *storage)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -306,7 +308,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
  }
  
  static int airoha_dev_change_mtu(struct net_device *netdev, int mtu)
-@@ -2723,20 +2750,19 @@ static void airoha_ethtool_get_mac_stats
+@@ -2313,20 +2340,19 @@ static void airoha_ethtool_get_mac_stats
                                         struct ethtool_eth_mac_stats *stats)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -336,7 +338,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
  }
  
  static const struct ethtool_rmon_hist_range airoha_ethtool_rmon_ranges[] = {
-@@ -2756,8 +2782,7 @@ airoha_ethtool_get_rmon_stats(struct net
+@@ -2346,8 +2372,7 @@ airoha_ethtool_get_rmon_stats(struct net
                              const struct ethtool_rmon_hist_range **ranges)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -346,7 +348,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
        unsigned int start;
  
        BUILD_BUG_ON(ARRAY_SIZE(airoha_ethtool_rmon_ranges) !=
-@@ -2770,7 +2795,7 @@ airoha_ethtool_get_rmon_stats(struct net
+@@ -2360,7 +2385,7 @@ airoha_ethtool_get_rmon_stats(struct net
        do {
                int i;
  
@@ -355,7 +357,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
                stats->fragments = hw_stats->rx_fragment;
                stats->jabbers = hw_stats->rx_jabber;
                for (i = 0; i < ARRAY_SIZE(airoha_ethtool_rmon_ranges) - 1;
-@@ -2778,7 +2803,7 @@ airoha_ethtool_get_rmon_stats(struct net
+@@ -2368,7 +2393,7 @@ airoha_ethtool_get_rmon_stats(struct net
                        stats->hist[i] = hw_stats->rx_len[i];
                        stats->hist_tx[i] = hw_stats->tx_len[i];
                }
@@ -364,7 +366,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
  }
  
  static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
-@@ -3849,6 +3874,7 @@ static int airoha_alloc_gdm_device(struc
+@@ -3208,6 +3233,7 @@ static int airoha_alloc_gdm_device(struc
  
        netdev->dev.of_node = of_node_get(np);
        dev = netdev_priv(netdev);
@@ -372,7 +374,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
        dev->port = port;
        dev->eth = eth;
        dev->nbq = nbq;
-@@ -3896,9 +3922,8 @@ static int airoha_alloc_gdm_port(struct
+@@ -3247,9 +3273,8 @@ static int airoha_alloc_gdm_port(struct
        if (!port)
                return -ENOMEM;
  
@@ -385,7 +387,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
        err = airoha_metadata_dst_alloc(port);
 --- a/drivers/net/ethernet/airoha/airoha_eth.h
 +++ b/drivers/net/ethernet/airoha/airoha_eth.h
-@@ -228,8 +228,6 @@ struct airoha_tx_irq_queue {
+@@ -215,8 +215,6 @@ struct airoha_tx_irq_queue {
  };
  
  struct airoha_hw_stats {
@@ -394,7 +396,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
        struct u64_stats_sync syncp;
  
        /* get_stats64 */
-@@ -573,6 +571,8 @@ struct airoha_gdm_dev {
+@@ -554,6 +552,8 @@ struct airoha_gdm_dev {
  
        u32 flags;
        int nbq;
@@ -403,7 +405,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
  };
  
  struct airoha_gdm_port {
-@@ -580,7 +580,8 @@ struct airoha_gdm_port {
+@@ -561,7 +561,8 @@ struct airoha_gdm_port {
        int id;
        int users;
  
similarity index 75%
rename from target/linux/airoha/patches-6.18/916-01-net-airoha-use-int-instead-of-atomic_t-for-qdma-user.patch
rename to target/linux/airoha/patches-6.18/167-v7.2-net-airoha-use-int-instead-of-atomic_t-for-qdma-user.patch
index 5d4ecf6606943b27efb7224fd156304617d9f769..46c18073e5800884fb6118979c5193fd1604371a 100644 (file)
@@ -1,5 +1,4 @@
 From a459b560e58be327689e9bd8c0a6be9a4f163366 Mon Sep 17 00:00:00 2001
-Message-ID: <a459b560e58be327689e9bd8c0a6be9a4f163366.1781641894.git.lorenzo@kernel.org>
 From: Lorenzo Bianconi <lorenzo@kernel.org>
 Date: Thu, 11 Jun 2026 23:55:51 +0200
 Subject: [PATCH] net: airoha: use int instead of atomic_t for qdma users
@@ -18,18 +17,18 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 
 --- a/drivers/net/ethernet/airoha/airoha_eth.c
 +++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -1761,7 +1761,7 @@ static int airoha_dev_open(struct net_de
+@@ -1840,7 +1840,7 @@ static int airoha_dev_open(struct net_de
        airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG,
                        GLOBAL_CFG_TX_DMA_EN_MASK |
                        GLOBAL_CFG_RX_DMA_EN_MASK);
 -      atomic_inc(&qdma->users);
 +      qdma->users++;
  
-       if (port->id == AIROHA_GDM2_IDX &&
-           airoha_ppe_is_enabled(qdma->eth, 1)) {
-@@ -1788,7 +1788,7 @@ static int airoha_dev_stop(struct net_de
-       airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
-                                   FE_PSE_PORT_DROP);
+       if (!airoha_is_lan_gdm_dev(dev) &&
+           airoha_ppe_is_enabled(qdma->eth, 1))
+@@ -1894,7 +1894,7 @@ static int airoha_dev_stop(struct net_de
+                                           REG_GDM_FWD_CFG(port->id),
+                                           FE_PSE_PORT_DROP);
  
 -      if (atomic_dec_and_test(&qdma->users)) {
 +      if (!--qdma->users) {
@@ -38,7 +37,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                                  GLOBAL_CFG_RX_DMA_EN_MASK);
 --- a/drivers/net/ethernet/airoha/airoha_eth.h
 +++ b/drivers/net/ethernet/airoha/airoha_eth.h
-@@ -525,7 +525,7 @@ struct airoha_qdma {
+@@ -524,7 +524,7 @@ struct airoha_qdma {
        struct airoha_eth *eth;
        void __iomem *regs;
  
diff --git a/target/linux/airoha/patches-6.18/168-v7.2-net-airoha-move-get_sport-callback-at-the-beginning-.patch b/target/linux/airoha/patches-6.18/168-v7.2-net-airoha-move-get_sport-callback-at-the-beginning-.patch
new file mode 100644 (file)
index 0000000..da75698
--- /dev/null
@@ -0,0 +1,50 @@
+From aeb62be4d3b18b76551bf7806e30d72e5c3bbade Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Mon, 8 Jun 2026 23:24:15 +0200
+Subject: [PATCH] net: airoha: move get_sport() callback at the beginning of
+ airoha_enable_gdm2_loopback()
+
+Move the get_sport() callback invocation at the beginning of
+airoha_enable_gdm2_loopback() routine in order to avoid leaving the
+hardware in a partially configured state if get_sport() fails.
+Previously, get_sport() was called after GDM2 forwarding, loopback,
+channel, length, VIP and IFC registers had already been programmed.
+A failure at that point would return an error leaving GDM2 with
+loopback enabled but WAN port, PPE CPU port and flow control mappings
+not configured.
+Performing the get_sport() lookup before any register write guarantees
+the routine either completes the full configuration sequence or exits
+with no side effects on the hardware.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260608-airoha_enable_gdm2_loopback-minor-change-v1-1-1787a0f42b31@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -1936,6 +1936,10 @@ static int airoha_enable_gdm2_loopback(s
+       u32 val, pse_port, chan;
+       int i, src_port;
++      src_port = eth->soc->ops.get_sport(port, dev->nbq);
++      if (src_port < 0)
++              return src_port;
++
+       airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),
+                                   FE_PSE_PORT_DROP);
+       airoha_fe_clear(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),
+@@ -1965,10 +1969,6 @@ static int airoha_enable_gdm2_loopback(s
+       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));
+-      src_port = eth->soc->ops.get_sport(port, dev->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));
similarity index 77%
rename from target/linux/airoha/patches-6.18/922-net-airoha-simplify-WAN-device-check-in-airoha_dev_i.patch
rename to target/linux/airoha/patches-6.18/169-v7.2-net-airoha-simplify-WAN-device-check-in-airoha_dev_i.patch
index c9e788e3e15019d8e8cdb19978d2d3bf1e1e5844..e2ce9978b871443afd0a6e4375fb85ae416ba7f6 100644 (file)
@@ -1,7 +1,6 @@
-From 3d67e4ba79bd4b40f520d26af098f133b5f551d4 Mon Sep 17 00:00:00 2001
-Message-ID: <3d67e4ba79bd4b40f520d26af098f133b5f551d4.1781097105.git.lorenzo@kernel.org>
+From 9912dfa2d46aef4cd708246aa6b39b49213f5e62 Mon Sep 17 00:00:00 2001
 From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 6 Jun 2026 08:53:03 +0200
+Date: Wed, 10 Jun 2026 15:25:13 +0200
 Subject: [PATCH] net: airoha: simplify WAN device check in airoha_dev_init()
 
 airoha_register_gdm_devices() iterates eth->ports[] in order, so GDM2's
@@ -13,13 +12,16 @@ Remove the redundant check and rely solely on airoha_get_wan_gdm_dev()
 which handles both the GDM2-present and GDM2-absent cases.
 
 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com>
+Link: https://patch.msgid.link/20260610-airoha-eth-simplify-dev-init-v2-1-8f244e69b0d4@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 ---
  drivers/net/ethernet/airoha/airoha_eth.c | 12 ++----------
  1 file changed, 2 insertions(+), 10 deletions(-)
 
 --- a/drivers/net/ethernet/airoha/airoha_eth.c
 +++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -2407,18 +2407,10 @@ static int airoha_dev_init(struct net_de
+@@ -2035,18 +2035,10 @@ static int airoha_dev_init(struct net_de
  
        switch (port->id) {
        case AIROHA_GDM3_IDX:
index a75e06f944a34822d3369a1f856c37028aa15a0c..61cd51ca60cec3875b50a663798042a489ea30e5 100644 (file)
@@ -13,7 +13,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
 
 --- a/drivers/net/ethernet/airoha/airoha_eth.c
 +++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -1487,6 +1487,10 @@ static int airoha_hw_init(struct platfor
+@@ -1568,6 +1568,10 @@ static int airoha_hw_init(struct platfor
        if (err)
                return err;
  
diff --git a/target/linux/airoha/patches-6.18/310-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch b/target/linux/airoha/patches-6.18/310-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch
deleted file mode 100644 (file)
index d5a2ba9..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-From ad29054f9b0e96e30a5d0bb6967d1204b8ea8bd1 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 17 Jan 2025 10:12:02 +0100
-Subject: [PATCH 3/9] net: airoha: add reference for SPORT GDM4 in
- qdma_get_gdm_port
-
-Add SPORT reference in get gdm port as the on receive the SPORT 0x18 is
-assigned for the GDM4 port.
-
-While at it also add comments to better identify GDM1 ports.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- drivers/net/ethernet/airoha/airoha_eth.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/airoha/airoha_eth.c
-+++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -574,8 +574,11 @@ static int airoha_qdma_get_gdm_port(stru
-       sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1);
-       switch (sport) {
-+      case 0x18:
-+              port = 3; /* GDM4 */
-+              break;
-       case 0x10 ... 0x14:
--              port = 0;
-+              port = 0; /* GDM1 */
-               break;
-       case 0x2 ... 0x4:
-               port = sport - 1;
index cd774e11eace72b6558d8bc9ac00d7c27cf3bc5f..2de3c8d1a89f115d22316f2f3aee40e2e3c93e39 100644 (file)
@@ -15,7 +15,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
 
 --- a/drivers/net/ethernet/airoha/airoha_eth.c
 +++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -498,8 +498,10 @@ static int airoha_fe_init(struct airoha_
+@@ -553,8 +553,10 @@ static int airoha_fe_init(struct airoha_
                      FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) |
                      FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22));
  
@@ -26,15 +26,15 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
 +      airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM4_IDX),
 +                    GDM_PAD_EN_MASK | GDM_STRIP_CRC_MASK);
  
-       airoha_fe_crsn_qsel_init(eth);
-@@ -1719,7 +1721,8 @@ static int airoha_dev_open(struct net_de
+       /* Enable split for MIB counters for GDM3 and GDM4 */
+       airoha_fe_set(eth, REG_FE_GDM_MIB_CFG(AIROHA_GDM3_IDX),
+@@ -1819,7 +1821,8 @@ static int airoha_dev_open(struct net_de
        if (err)
                return err;
  
--      if (netdev_uses_dsa(dev))
+-      if (netdev_uses_dsa(netdev))
 +      /* It seems GDM3 and GDM4 needs SPORT enabled to correctly work */
-+      if (netdev_uses_dsa(dev) || port->id > 2)
++      if (netdev_uses_dsa(netdev) || port->id > 2)
                airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
                              GDM_STAG_EN_MASK);
        else
index 0ecba241d808af11f610abb4d0825344e362a1a4..d6560370d28c16ad3f0818bb4f975d83e9480270 100644 (file)
@@ -15,7 +15,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
 
 --- a/drivers/net/ethernet/airoha/airoha_eth.c
 +++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -3196,7 +3196,6 @@ static void airoha_remove(struct platfor
+@@ -3511,7 +3511,6 @@ static void airoha_remove(struct platfor
  }
  
  static const char * const en7581_xsi_rsts_names[] = {
@@ -23,7 +23,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
        "hsi0-mac",
        "hsi1-mac",
        "hsi-mac",
-@@ -3250,7 +3249,6 @@ static u32 airoha_en7581_get_vip_port(st
+@@ -3598,7 +3597,6 @@ static int airoha_en7581_get_dev_from_sp
  }
  
  static const char * const an7583_xsi_rsts_names[] = {
diff --git a/target/linux/airoha/patches-6.18/310-10-net-airoha-add-phylink-support-for-GDM2-3-4.patch b/target/linux/airoha/patches-6.18/310-10-net-airoha-add-phylink-support-for-GDM2-3-4.patch
deleted file mode 100644 (file)
index 7421c01..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-From ee93671d30d7741a39026c2aaaa6a7729929c347 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 17 Jan 2025 13:23:13 +0100
-Subject: [PATCH 2/2] net: airoha: add phylink support for GDM2/3/4
-
-Add phylink support for GDM2/3/4 port that require configuration of the
-PCS to make the external PHY or attached SFP cage work.
-
-These needs to be defined in the GDM port node using the pcs-handle
-property.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- drivers/net/ethernet/airoha/Kconfig       |   1 +
- drivers/net/ethernet/airoha/airoha_eth.c  | 146 +++++++++++++++++++++-
- drivers/net/ethernet/airoha/airoha_eth.h  |   3 +
- drivers/net/ethernet/airoha/airoha_regs.h |  12 ++
- 4 files changed, 161 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/airoha/Kconfig
-+++ b/drivers/net/ethernet/airoha/Kconfig
-@@ -20,6 +20,7 @@ config NET_AIROHA
-       depends on NET_DSA || !NET_DSA
-       select NET_AIROHA_NPU
-       select PAGE_POOL
-+      select PHYLINK
-       help
-         This driver supports the gigabit ethernet MACs in the
-         Airoha SoC family.
---- a/drivers/net/ethernet/airoha/airoha_eth.c
-+++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -8,6 +8,7 @@
- #include <linux/of_reserved_mem.h>
- #include <linux/platform_device.h>
- #include <linux/tcp.h>
-+#include <linux/pcs/pcs.h>
- #include <linux/u64_stats_sync.h>
- #include <net/dst_metadata.h>
- #include <net/page_pool/helpers.h>
-@@ -71,6 +72,11 @@ static void airoha_qdma_irq_disable(stru
-       airoha_qdma_set_irqmask(irq_bank, index, mask, 0);
- }
-+static bool airhoa_is_phy_external(struct airoha_gdm_port *port)
-+{
-+      return port->id != 1;
-+}
-+
- static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
- {
-       struct airoha_eth *eth = port->qdma->eth;
-@@ -1716,6 +1722,17 @@ static int airoha_dev_open(struct net_de
-       struct airoha_qdma *qdma = port->qdma;
-       u32 pse_port = FE_PSE_PORT_PPE1;
-+      if (airhoa_is_phy_external(port)) {
-+              err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0);
-+              if (err) {
-+                      netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
-+                                 err);
-+                      return err;
-+              }
-+
-+              phylink_start(port->phylink);
-+      }
-+
-       netif_tx_start_all_queues(dev);
-       err = airoha_set_vip_for_gdm_port(port, true);
-       if (err)
-@@ -1777,6 +1794,11 @@ static int airoha_dev_stop(struct net_de
-               }
-       }
-+      if (airhoa_is_phy_external(port)) {
-+              phylink_stop(port->phylink);
-+              phylink_disconnect_phy(port->phylink);
-+      }
-+
-       return 0;
- }
-@@ -2916,6 +2938,11 @@ static const struct ethtool_ops airoha_e
-       .get_link               = ethtool_op_get_link,
- };
-+static void airoha_mac_config(struct phylink_config *config, unsigned int mode,
-+                            const struct phylink_link_state *state)
-+{
-+}
-+
- static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port)
- {
-       int i;
-@@ -2960,6 +2987,119 @@ bool airoha_is_valid_gdm_port(struct air
-       return false;
- }
-+static void airoha_mac_link_up(struct phylink_config *config, struct phy_device *phy,
-+                             unsigned int mode, phy_interface_t interface,
-+                             int speed, int duplex, bool tx_pause, bool rx_pause)
-+{
-+      struct airoha_gdm_port *port = container_of(config, struct airoha_gdm_port,
-+                                                  phylink_config);
-+      struct airoha_qdma *qdma = port->qdma;
-+      struct airoha_eth *eth = qdma->eth;
-+      u32 frag_size_tx, frag_size_rx;
-+
-+      if (port->id != 4)
-+              return;
-+
-+      switch (speed) {
-+      case SPEED_10000:
-+      case SPEED_5000:
-+              frag_size_tx = 8;
-+              frag_size_rx = 8;
-+              break;
-+      case SPEED_2500:
-+              frag_size_tx = 2;
-+              frag_size_rx = 1;
-+              break;
-+      default:
-+              frag_size_tx = 1;
-+              frag_size_rx = 0;
-+      }
-+
-+      /* Configure TX/RX frag based on speed */
-+      airoha_fe_rmw(eth, REG_GDMA4_TMBI_FRAG,
-+                    GDMA4_SGMII0_TX_FRAG_SIZE_MASK,
-+                    FIELD_PREP(GDMA4_SGMII0_TX_FRAG_SIZE_MASK,
-+                               frag_size_tx));
-+
-+      airoha_fe_rmw(eth, REG_GDMA4_RMBI_FRAG,
-+                    GDMA4_SGMII0_RX_FRAG_SIZE_MASK,
-+                    FIELD_PREP(GDMA4_SGMII0_RX_FRAG_SIZE_MASK,
-+                               frag_size_rx));
-+}
-+
-+static void airoha_mac_link_down(struct phylink_config *config, unsigned int mode,
-+                               phy_interface_t interface)
-+{
-+}
-+
-+static const struct phylink_mac_ops airoha_phylink_ops = {
-+      .mac_config = airoha_mac_config,
-+      .mac_link_up = airoha_mac_link_up,
-+      .mac_link_down = airoha_mac_link_down,
-+};
-+
-+static int airoha_fill_available_pcs(struct phylink_config *config,
-+                                   struct phylink_pcs **available_pcs,
-+                                   unsigned int num_available_pcs)
-+{
-+      struct device *dev = config->dev;
-+
-+      return fwnode_phylink_pcs_parse(dev_fwnode(dev), available_pcs,
-+                                      &num_available_pcs);
-+}
-+
-+static int airoha_setup_phylink(struct net_device *dev)
-+{
-+      struct airoha_gdm_port *port = netdev_priv(dev);
-+      struct device_node *np = dev->dev.of_node;
-+      phy_interface_t phy_mode;
-+      struct phylink *phylink;
-+      int err;
-+
-+      err = of_get_phy_mode(np, &phy_mode);
-+      if (err) {
-+              dev_err(&dev->dev, "incorrect phy-mode\n");
-+              return err;
-+      }
-+
-+      port->phylink_config.dev = &dev->dev;
-+      port->phylink_config.type = PHYLINK_NETDEV;
-+      port->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
-+                                              MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD |
-+                                              MAC_5000FD | MAC_10000FD;
-+
-+      err = fwnode_phylink_pcs_parse(dev_fwnode(&dev->dev), NULL,
-+                                     &port->phylink_config.num_available_pcs);
-+      if (err)
-+              return err;
-+
-+      port->phylink_config.fill_available_pcs = airoha_fill_available_pcs;
-+
-+      __set_bit(PHY_INTERFACE_MODE_SGMII,
-+                port->phylink_config.supported_interfaces);
-+      __set_bit(PHY_INTERFACE_MODE_1000BASEX,
-+                port->phylink_config.supported_interfaces);
-+      __set_bit(PHY_INTERFACE_MODE_2500BASEX,
-+                port->phylink_config.supported_interfaces);
-+      __set_bit(PHY_INTERFACE_MODE_10GBASER,
-+                port->phylink_config.supported_interfaces);
-+      __set_bit(PHY_INTERFACE_MODE_USXGMII,
-+                port->phylink_config.supported_interfaces);
-+
-+      phy_interface_copy(port->phylink_config.pcs_interfaces,
-+                         port->phylink_config.supported_interfaces);
-+
-+      phylink = phylink_create(&port->phylink_config,
-+                               of_fwnode_handle(np),
-+                               phy_mode, &airoha_phylink_ops);
-+      if (IS_ERR(phylink))
-+              return PTR_ERR(phylink);
-+
-+      port->phylink = phylink;
-+
-+      return err;
-+}
-+
- static int airoha_alloc_gdm_port(struct airoha_eth *eth,
-                                struct device_node *np)
- {
-@@ -3033,6 +3173,12 @@ static int airoha_alloc_gdm_port(struct
-       port->nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
-       eth->ports[p] = port;
-+      if (airhoa_is_phy_external(port)) {
-+              err = airoha_setup_phylink(dev);
-+              if (err)
-+                      return err;
-+      }
-+
-       return airoha_metadata_dst_alloc(port);
- }
-@@ -3160,8 +3306,11 @@ error_napi_stop:
-               if (!port)
-                       continue;
--              if (port->dev->reg_state == NETREG_REGISTERED)
-+              if (port->dev->reg_state == NETREG_REGISTERED) {
-+                      if (airhoa_is_phy_external(port))
-+                              phylink_destroy(port->phylink);
-                       unregister_netdev(port->dev);
-+              }
-               airoha_metadata_dst_free(port);
-       }
-       airoha_hw_cleanup(eth);
-@@ -3186,6 +3335,8 @@ static void airoha_remove(struct platfor
-               if (!port)
-                       continue;
-+              if (airhoa_is_phy_external(port))
-+                      phylink_destroy(port->phylink);
-               unregister_netdev(port->dev);
-               airoha_metadata_dst_free(port);
-       }
---- a/drivers/net/ethernet/airoha/airoha_eth.h
-+++ b/drivers/net/ethernet/airoha/airoha_eth.h
-@@ -542,6 +542,9 @@ struct airoha_gdm_port {
-       int id;
-       int nbq;
-+      struct phylink *phylink;
-+      struct phylink_config phylink_config;
-+
-       struct airoha_hw_stats stats;
-       DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS);
---- a/drivers/net/ethernet/airoha/airoha_regs.h
-+++ b/drivers/net/ethernet/airoha/airoha_regs.h
-@@ -358,6 +358,18 @@
- #define IP_FRAGMENT_PORT_MASK         GENMASK(8, 5)
- #define IP_FRAGMENT_NBQ_MASK          GENMASK(4, 0)
-+#define REG_GDMA4_TMBI_FRAG           0x2028
-+#define GDMA4_SGMII1_TX_WEIGHT_MASK   GENMASK(31, 26)
-+#define GDMA4_SGMII1_TX_FRAG_SIZE_MASK        GENMASK(25, 16)
-+#define GDMA4_SGMII0_TX_WEIGHT_MASK   GENMASK(15, 10)
-+#define GDMA4_SGMII0_TX_FRAG_SIZE_MASK        GENMASK(9, 0)
-+
-+#define REG_GDMA4_RMBI_FRAG           0x202c
-+#define GDMA4_SGMII1_RX_WEIGHT_MASK   GENMASK(31, 26)
-+#define GDMA4_SGMII1_RX_FRAG_SIZE_MASK        GENMASK(25, 16)
-+#define GDMA4_SGMII0_RX_WEIGHT_MASK   GENMASK(15, 10)
-+#define GDMA4_SGMII0_RX_FRAG_SIZE_MASK        GENMASK(9, 0)
-+
- #define REG_MC_VLAN_EN                        0x2100
- #define MC_VLAN_EN_MASK                       BIT(0)
diff --git a/target/linux/airoha/patches-6.18/310-10-net-airoha-add-phylink-support.patch b/target/linux/airoha/patches-6.18/310-10-net-airoha-add-phylink-support.patch
new file mode 100644 (file)
index 0000000..de636ba
--- /dev/null
@@ -0,0 +1,361 @@
+From beb56181a370b003b12f657239b510435cae2c9d Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Fri, 17 Jan 2025 13:23:13 +0100
+Subject: [PATCH] net: airoha: add phylink support
+
+Add phylink support for each GDM port. For GDM1 add the internal interface
+mode as the only supported mode. For GDM2/3/4 add the required
+configuration of the PCS to make the external PHY or attached SFP cage
+work.
+
+These needs to be defined in the GDM port node using the pcs-handle
+property.
+
+Update and provide a .get/set_link_ksettings function that use phylink
+for ethtool OPs now that we fully support phylink.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/net/ethernet/airoha/Kconfig       |   1 +
+ drivers/net/ethernet/airoha/airoha_eth.c  | 193 +++++++++++++++++++++-
+ drivers/net/ethernet/airoha/airoha_eth.h  |   7 +-
+ drivers/net/ethernet/airoha/airoha_regs.h |  12 ++
+ 4 files changed, 206 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/ethernet/airoha/Kconfig
++++ b/drivers/net/ethernet/airoha/Kconfig
+@@ -20,6 +20,7 @@ config NET_AIROHA
+       depends on NET_DSA || !NET_DSA
+       select NET_AIROHA_NPU
+       select PAGE_POOL
++      select PHYLINK
+       help
+         This driver supports the gigabit ethernet MACs in the
+         Airoha SoC family.
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -8,6 +8,7 @@
+ #include <linux/of_reserved_mem.h>
+ #include <linux/platform_device.h>
+ #include <linux/tcp.h>
++#include <linux/pcs/pcs.h>
+ #include <linux/u64_stats_sync.h>
+ #include <net/dst_metadata.h>
+ #include <net/page_pool/helpers.h>
+@@ -1794,7 +1795,7 @@ static void airoha_update_hw_stats(struc
+       struct airoha_gdm_port *port = dev->port;
+       int i;
+-      spin_lock(&port->stats_lock);
++      spin_lock(&port->lock);
+       for (i = 0; i < ARRAY_SIZE(port->devs); i++) {
+               if (port->devs[i])
+@@ -1805,7 +1806,7 @@ static void airoha_update_hw_stats(struc
+       airoha_fe_set(dev->eth, REG_FE_GDM_MIB_CLEAR(port->id),
+                     FE_GDM_MIB_RX_CLEAR_MASK | FE_GDM_MIB_TX_CLEAR_MASK);
+-      spin_unlock(&port->stats_lock);
++      spin_unlock(&port->lock);
+ }
+ static int airoha_dev_open(struct net_device *netdev)
+@@ -1816,6 +1817,14 @@ static int airoha_dev_open(struct net_de
+       u32 cur_len, pse_port = FE_PSE_PORT_PPE1;
+       struct airoha_qdma *qdma = dev->qdma;
++      err = phylink_of_phy_connect(dev->phylink, netdev->dev.of_node, 0);
++      if (err) {
++              netdev_err(netdev, "could not attach PHY: %d\n", err);
++              return err;
++      }
++
++      phylink_start(dev->phylink);
++
+       netif_tx_start_all_queues(netdev);
+       err = airoha_set_vip_for_gdm_port(dev, true);
+       if (err)
+@@ -1914,6 +1923,9 @@ static int airoha_dev_stop(struct net_de
+               }
+       }
++      phylink_stop(dev->phylink);
++      phylink_disconnect_phy(dev->phylink);
++
+       return 0;
+ }
+@@ -2395,6 +2407,24 @@ airoha_ethtool_get_rmon_stats(struct net
+       } while (u64_stats_fetch_retry(&dev->stats.syncp, start));
+ }
++static int
++airoha_ethtool_get_link_ksettings(struct net_device *netdev,
++                                struct ethtool_link_ksettings *cmd)
++{
++      struct airoha_gdm_dev *dev = netdev_priv(netdev);
++
++      return phylink_ethtool_ksettings_get(dev->phylink, cmd);
++}
++
++static int
++airoha_ethtool_set_link_ksettings(struct net_device *netdev,
++                                const struct ethtool_link_ksettings *cmd)
++{
++      struct airoha_gdm_dev *dev = netdev_priv(netdev);
++
++      return phylink_ethtool_ksettings_set(dev->phylink, cmd);
++}
++
+ static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
+                                        int channel, enum tx_sched_mode mode,
+                                        const u16 *weights, u8 n_weights)
+@@ -3119,7 +3149,8 @@ static const struct ethtool_ops airoha_e
+       .get_drvinfo            = airoha_ethtool_get_drvinfo,
+       .get_eth_mac_stats      = airoha_ethtool_get_mac_stats,
+       .get_rmon_stats         = airoha_ethtool_get_rmon_stats,
+-      .get_link_ksettings     = phy_ethtool_get_link_ksettings,
++      .get_link_ksettings     = airoha_ethtool_get_link_ksettings,
++      .set_link_ksettings     = airoha_ethtool_set_link_ksettings,
+       .get_link               = ethtool_op_get_link,
+ };
+@@ -3175,6 +3206,159 @@ bool airoha_is_valid_gdm_dev(struct airo
+       return false;
+ }
++/* Nothing to do in MAC, everything is handled in PCS */
++static void airoha_mac_config(struct phylink_config *config, unsigned int mode,
++                            const struct phylink_link_state *state)
++{
++}
++
++static void airoha_mac_link_up(struct phylink_config *config, struct phy_device *phy,
++                             unsigned int mode, phy_interface_t interface,
++                             int speed, int duplex, bool tx_pause, bool rx_pause)
++{
++      struct airoha_gdm_dev *dev = container_of(config, struct airoha_gdm_dev,
++                                                phylink_config);
++      struct airoha_gdm_port *port = dev->port;
++      struct airoha_eth *eth = dev->eth;
++      u32 frag_size_tx, frag_size_rx;
++      u32 mask, val;
++
++      /* TX/RX frag is configured only for GDM4 */
++      if (port->id != AIROHA_GDM4_IDX)
++              return;
++
++      switch (speed) {
++      case SPEED_10000:
++      case SPEED_5000:
++              frag_size_tx = 8;
++              frag_size_rx = 8;
++              break;
++      case SPEED_2500:
++              frag_size_tx = 2;
++              frag_size_rx = 1;
++              break;
++      default:
++              frag_size_tx = 1;
++              frag_size_rx = 0;
++      }
++
++      spin_lock(&port->lock);
++
++      /* Configure TX/RX frag based on speed */
++      if (dev->nbq == 1) {
++              mask = GDM4_SGMII1_TX_FRAG_SIZE_MASK;
++              val = FIELD_PREP(GDM4_SGMII1_TX_FRAG_SIZE_MASK,
++                               frag_size_tx);
++      }  else {
++              mask = GDM4_SGMII0_TX_FRAG_SIZE_MASK;
++              val = FIELD_PREP(GDM4_SGMII0_TX_FRAG_SIZE_MASK,
++                               frag_size_tx);
++      }
++      airoha_fe_rmw(eth, REG_FE_GDM4_TMBI_FRAG, mask, val);
++
++      if (dev->nbq == 1) {
++              mask = GDM4_SGMII1_RX_FRAG_SIZE_MASK;
++              val = FIELD_PREP(GDM4_SGMII1_RX_FRAG_SIZE_MASK,
++                               frag_size_rx);
++      } else {
++              mask = GDM4_SGMII0_RX_FRAG_SIZE_MASK;
++              val = FIELD_PREP(GDM4_SGMII0_RX_FRAG_SIZE_MASK,
++                               frag_size_rx);
++      }
++      airoha_fe_rmw(eth, REG_FE_GDM4_RMBI_FRAG, mask, val);
++
++      spin_unlock(&port->lock);
++}
++
++/* Nothing to do in MAC, everything is handled in PCS */
++static void airoha_mac_link_down(struct phylink_config *config, unsigned int mode,
++                               phy_interface_t interface)
++{
++}
++
++static const struct phylink_mac_ops airoha_phylink_ops = {
++      .mac_config = airoha_mac_config,
++      .mac_link_up = airoha_mac_link_up,
++      .mac_link_down = airoha_mac_link_down,
++};
++
++static int airoha_fill_available_pcs(struct phylink_config *config,
++                                   struct phylink_pcs **available_pcs,
++                                   unsigned int num_possible_pcs)
++{
++      struct device *dev = config->dev;
++
++      return fwnode_phylink_pcs_parse(dev_fwnode(dev), available_pcs,
++                                      &num_possible_pcs);
++}
++
++static int airoha_setup_phylink(struct net_device *netdev)
++{
++      struct airoha_gdm_dev *dev = netdev_priv(netdev);
++      struct device_node *np = netdev->dev.of_node;
++      struct airoha_gdm_port *port = dev->port;
++      struct phylink_config *config;
++      phy_interface_t phy_mode;
++      struct phylink *phylink;
++      int err;
++
++      err = of_get_phy_mode(np, &phy_mode);
++      if (err) {
++              dev_err(&netdev->dev, "incorrect phy-mode\n");
++              return err;
++      }
++
++      config = &dev->phylink_config;
++      config->dev = &netdev->dev;
++      config->type = PHYLINK_NETDEV;
++
++      /*
++       * GDM1 only supports internal for Embedded Switch
++       * and doesn't require a PCS.
++       */
++      if (port->id == AIROHA_GDM1_IDX) {
++              config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
++                                         MAC_10000FD;
++
++              __set_bit(PHY_INTERFACE_MODE_INTERNAL,
++                        config->supported_interfaces);
++      } else {
++              config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
++                                         MAC_10 | MAC_100 | MAC_1000 |
++                                         MAC_2500FD | MAC_5000FD | MAC_10000FD;
++
++              err = fwnode_phylink_pcs_parse(dev_fwnode(config->dev), NULL,
++                                             &dev->phylink_config.num_available_pcs);
++              if (err)
++                      return err;
++
++              config->fill_available_pcs = airoha_fill_available_pcs;
++
++              __set_bit(PHY_INTERFACE_MODE_SGMII,
++                        config->supported_interfaces);
++              __set_bit(PHY_INTERFACE_MODE_1000BASEX,
++                        config->supported_interfaces);
++              __set_bit(PHY_INTERFACE_MODE_2500BASEX,
++                        config->supported_interfaces);
++              __set_bit(PHY_INTERFACE_MODE_10GBASER,
++                        config->supported_interfaces);
++              __set_bit(PHY_INTERFACE_MODE_USXGMII,
++                        config->supported_interfaces);
++
++              phy_interface_copy(config->pcs_interfaces,
++                                 config->supported_interfaces);
++      }
++
++      phylink = phylink_create(config, of_fwnode_handle(np),
++                               phy_mode, &airoha_phylink_ops);
++      if (IS_ERR(phylink))
++              return PTR_ERR(phylink);
++
++      dev->phylink = phylink;
++
++      return 0;
++}
++
+ static int airoha_alloc_gdm_device(struct airoha_eth *eth,
+                                  struct airoha_gdm_port *port,
+                                  int nbq, struct device_node *np)
+@@ -3238,7 +3422,7 @@ static int airoha_alloc_gdm_device(struc
+       dev->nbq = nbq;
+       port->devs[index] = dev;
+-      return 0;
++      return airoha_setup_phylink(netdev);
+ }
+ static int airoha_alloc_gdm_port(struct airoha_eth *eth,
+@@ -3273,7 +3457,7 @@ static int airoha_alloc_gdm_port(struct
+               return -ENOMEM;
+       port->id = id;
+-      spin_lock_init(&port->stats_lock);
++      spin_lock_init(&port->lock);
+       eth->ports[p] = port;
+       err = airoha_metadata_dst_alloc(port);
+@@ -3464,6 +3648,8 @@ error_napi_stop:
+                       netdev = netdev_from_priv(dev);
+                       if (netdev->reg_state == NETREG_REGISTERED)
+                               unregister_netdev(netdev);
++                      if (dev->phylink)
++                              phylink_destroy(dev->phylink);
+                       of_node_put(netdev->dev.of_node);
+               }
+               airoha_metadata_dst_free(port);
+@@ -3500,6 +3686,7 @@ static void airoha_remove(struct platfor
+                       netdev = netdev_from_priv(dev);
+                       unregister_netdev(netdev);
++                      phylink_destroy(dev->phylink);
+                       of_node_put(netdev->dev.of_node);
+               }
+               airoha_metadata_dst_free(port);
+--- a/drivers/net/ethernet/airoha/airoha_eth.h
++++ b/drivers/net/ethernet/airoha/airoha_eth.h
+@@ -554,6 +554,9 @@ struct airoha_gdm_dev {
+       int nbq;
+       struct airoha_hw_stats stats;
++
++      struct phylink *phylink;
++      struct phylink_config phylink_config;
+ };
+ struct airoha_gdm_port {
+@@ -561,8 +564,8 @@ struct airoha_gdm_port {
+       int id;
+       int users;
+-      /* protect concurrent hw_stats accesses */
+-      spinlock_t stats_lock;
++      /* protect concurrent hw_stats and frag register accesses */
++      spinlock_t lock;
+       struct metadata_dst *dsa_meta[AIROHA_MAX_DSA_PORTS];
+ };
+--- a/drivers/net/ethernet/airoha/airoha_regs.h
++++ b/drivers/net/ethernet/airoha/airoha_regs.h
+@@ -358,6 +358,18 @@
+ #define IP_FRAGMENT_PORT_MASK         GENMASK(8, 5)
+ #define IP_FRAGMENT_NBQ_MASK          GENMASK(4, 0)
++#define REG_FE_GDM4_TMBI_FRAG         0x2028
++#define GDM4_SGMII1_TX_WEIGHT_MASK    GENMASK(31, 26)
++#define GDM4_SGMII1_TX_FRAG_SIZE_MASK GENMASK(25, 16)
++#define GDM4_SGMII0_TX_WEIGHT_MASK    GENMASK(15, 10)
++#define GDM4_SGMII0_TX_FRAG_SIZE_MASK GENMASK(9, 0)
++
++#define REG_FE_GDM4_RMBI_FRAG         0x202c
++#define GDM4_SGMII1_RX_WEIGHT_MASK    GENMASK(31, 26)
++#define GDM4_SGMII1_RX_FRAG_SIZE_MASK GENMASK(25, 16)
++#define GDM4_SGMII0_RX_WEIGHT_MASK    GENMASK(15, 10)
++#define GDM4_SGMII0_RX_FRAG_SIZE_MASK GENMASK(9, 0)
++
+ #define REG_MC_VLAN_EN                        0x2100
+ #define MC_VLAN_EN_MASK                       BIT(0)
diff --git a/target/linux/airoha/patches-6.18/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch b/target/linux/airoha/patches-6.18/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch
deleted file mode 100644 (file)
index b78cc34..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-From 6548e580509397a622b7c504a79de93414771459 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 25 Jun 2025 00:04:36 +0200
-Subject: [PATCH 6/6] net: ethernet: airoha: define sport value for GDM3
-
-On Airoha AN7583, the Serdes Ethernet goes through the GDM3 port.
-To correctly receive packet for QDMA, add the sport value to identify
-packet from GDM3 port.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- drivers/net/ethernet/airoha/airoha_eth.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/net/ethernet/airoha/airoha_eth.c
-+++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -585,6 +585,9 @@ static int airoha_qdma_get_gdm_port(stru
-       case 0x18:
-               port = 3; /* GDM4 */
-               break;
-+      case 0x16:
-+              port = 2; /* GDM3 */
-+              break;
-       case 0x10 ... 0x14:
-               port = 0; /* GDM1 */
-               break;
diff --git a/target/linux/airoha/patches-6.18/606-net-airoha-disable-external-phy-code-if-PCS_AIROHA-i.patch b/target/linux/airoha/patches-6.18/606-net-airoha-disable-external-phy-code-if-PCS_AIROHA-i.patch
deleted file mode 100644 (file)
index d43d330..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-From 843e2892f2d9353bf039e0dfb5442a600e75009e Mon Sep 17 00:00:00 2001
-From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Date: Thu, 9 Oct 2025 23:46:08 +0300
-Subject: [PATCH] net: airoha: disable external phy code if PCS_AIROHA is not
- enabled
-
-External phy code breaks building for EN7523, so disable it if
-PCS_AIROHA is not selected.
-
-Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
----
- drivers/net/ethernet/airoha/airoha_eth.c | 16 ++++++++++++++++
- drivers/net/ethernet/airoha/airoha_eth.h |  2 ++
- 2 files changed, 18 insertions(+)
-
---- a/drivers/net/ethernet/airoha/airoha_eth.c
-+++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -72,10 +72,12 @@ static void airoha_qdma_irq_disable(stru
-       airoha_qdma_set_irqmask(irq_bank, index, mask, 0);
- }
-+#if defined(CONFIG_PCS_AIROHA)
- static bool airhoa_is_phy_external(struct airoha_gdm_port *port)
- {
-       return port->id != 1;
- }
-+#endif
- static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
- {
-@@ -1725,6 +1727,7 @@ static int airoha_dev_open(struct net_de
-       struct airoha_qdma *qdma = port->qdma;
-       u32 pse_port = FE_PSE_PORT_PPE1;
-+#if defined(CONFIG_PCS_AIROHA)
-       if (airhoa_is_phy_external(port)) {
-               err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0);
-               if (err) {
-@@ -1735,6 +1738,7 @@ static int airoha_dev_open(struct net_de
-               phylink_start(port->phylink);
-       }
-+#endif
-       netif_tx_start_all_queues(dev);
-       err = airoha_set_vip_for_gdm_port(port, true);
-@@ -1797,10 +1801,12 @@ static int airoha_dev_stop(struct net_de
-               }
-       }
-+#if defined(CONFIG_PCS_AIROHA)
-       if (airhoa_is_phy_external(port)) {
-               phylink_stop(port->phylink);
-               phylink_disconnect_phy(port->phylink);
-       }
-+#endif
-       return 0;
- }
-@@ -2990,6 +2996,7 @@ bool airoha_is_valid_gdm_port(struct air
-       return false;
- }
-+#if defined(CONFIG_PCS_AIROHA)
- static void airoha_mac_link_up(struct phylink_config *config, struct phy_device *phy,
-                              unsigned int mode, phy_interface_t interface,
-                              int speed, int duplex, bool tx_pause, bool rx_pause)
-@@ -3102,6 +3109,7 @@ static int airoha_setup_phylink(struct n
-       return err;
- }
-+#endif
- static int airoha_alloc_gdm_port(struct airoha_eth *eth,
-                                struct device_node *np)
-@@ -3176,11 +3184,13 @@ static int airoha_alloc_gdm_port(struct
-       port->nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
-       eth->ports[p] = port;
-+#if defined(CONFIG_PCS_AIROHA)
-       if (airhoa_is_phy_external(port)) {
-               err = airoha_setup_phylink(dev);
-               if (err)
-                       return err;
-       }
-+#endif
-       return airoha_metadata_dst_alloc(port);
- }
-@@ -3310,8 +3320,10 @@ error_napi_stop:
-                       continue;
-               if (port->dev->reg_state == NETREG_REGISTERED) {
-+#if defined(CONFIG_PCS_AIROHA)
-                       if (airhoa_is_phy_external(port))
-                               phylink_destroy(port->phylink);
-+#endif
-                       unregister_netdev(port->dev);
-               }
-               airoha_metadata_dst_free(port);
-@@ -3338,8 +3350,10 @@ static void airoha_remove(struct platfor
-               if (!port)
-                       continue;
-+#if defined(CONFIG_PCS_AIROHA)
-               if (airhoa_is_phy_external(port))
-                       phylink_destroy(port->phylink);
-+#endif
-               unregister_netdev(port->dev);
-               airoha_metadata_dst_free(port);
-       }
---- a/drivers/net/ethernet/airoha/airoha_eth.h
-+++ b/drivers/net/ethernet/airoha/airoha_eth.h
-@@ -542,8 +542,10 @@ struct airoha_gdm_port {
-       int id;
-       int nbq;
-+#if defined(CONFIG_PCS_AIROHA)
-       struct phylink *phylink;
-       struct phylink_config phylink_config;
-+#endif
-       struct airoha_hw_stats stats;
index 6acc99da3e6a5b009d7695902e03fa7e8cc214bd..7670611c013d72664c764d7d1b540eaaa517338e 100644 (file)
@@ -25,25 +25,25 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
  #include "airoha_regs.h"
  #include "airoha_eth.h"
-@@ -300,7 +301,7 @@ static int airoha_ppe_foe_entry_prepare(
+@@ -314,7 +315,7 @@ static int airoha_ppe_foe_entry_prepare(
                                        struct airoha_foe_entry *hwe,
-                                       struct net_device *dev, int type,
+                                       struct net_device *netdev, int type,
                                        struct airoha_flow_data *data,
 -                                      int l4proto)
 +                                      int l4proto, u8 dsfield)
  {
        u32 qdata = FIELD_PREP(AIROHA_FOE_SHAPER_ID, 0x7f), ports_pad, val;
-       int wlan_etype = -EINVAL, dsa_port = airoha_get_dsa_port(&dev);
-@@ -333,7 +334,7 @@ static int airoha_ppe_foe_entry_prepare(
-                                               info.wcid);
+       int wlan_etype = -EINVAL, dsa_port = airoha_get_dsa_port(&netdev);
+@@ -349,7 +350,7 @@ static int airoha_ppe_foe_entry_prepare(
                } else {
-                       struct airoha_gdm_port *port = netdev_priv(dev);
+                       struct airoha_gdm_dev *dev = netdev_priv(netdev);
+                       struct airoha_gdm_port *port;
 -                      u8 pse_port, channel;
 +                      u8 pse_port, channel, priority;
  
-                       if (!airoha_is_valid_gdm_port(eth, port))
+                       if (!airoha_is_valid_gdm_dev(eth, dev))
                                return -EINVAL;
-@@ -352,9 +353,13 @@ static int airoha_ppe_foe_entry_prepare(
+@@ -369,9 +370,13 @@ static int airoha_ppe_foe_entry_prepare(
                         */
                        channel = dsa_port >= 0 ? dsa_port : port->id;
                        channel = channel % AIROHA_NUM_QOS_CHANNELS;
@@ -58,7 +58,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                               AIROHA_FOE_IB2_PSE_QOS;
                        /* For downlink traffic consume SRAM memory for hw
                         * forwarding descriptors queue.
-@@ -1046,9 +1051,9 @@ static int airoha_ppe_flow_offload_repla
+@@ -1063,9 +1068,9 @@ static int airoha_ppe_flow_offload_repla
        struct net_device *odev = NULL;
        struct flow_action_entry *act;
        struct airoha_foe_entry hwe;
@@ -69,7 +69,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        if (rhashtable_lookup(&eth->flow_table, &f->cookie,
                              airoha_flow_table_params))
-@@ -1078,6 +1083,13 @@ static int airoha_ppe_flow_offload_repla
+@@ -1095,6 +1100,13 @@ static int airoha_ppe_flow_offload_repla
                return -EOPNOTSUPP;
        }
  
@@ -83,7 +83,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        switch (addr_type) {
        case 0:
                offload_type = PPE_PKT_TYPE_BRIDGE;
-@@ -1143,7 +1155,7 @@ static int airoha_ppe_flow_offload_repla
+@@ -1160,7 +1172,7 @@ static int airoha_ppe_flow_offload_repla
                return -EINVAL;
  
        err = airoha_ppe_foe_entry_prepare(eth, &hwe, odev, offload_type,
index 7598a22199cb6b73a4e1bf4deaf729084e57d3de..16513e3c25849cc32a8776188025420828ed001c 100644 (file)
@@ -24,7 +24,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  #include <uapi/linux/ppp_defs.h>
  
  #include "airoha_regs.h"
-@@ -439,6 +441,73 @@ static void airoha_fe_crsn_qsel_init(str
+@@ -487,6 +489,73 @@ static void airoha_fe_crsn_qsel_init(str
                                 CDM_CRSN_QSEL_Q1));
  }
  
@@ -70,9 +70,9 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +                           LRO_RXQ_EN_MASK);
 +}
 +
-+static void airoha_dev_lro_enable(struct airoha_gdm_port *port)
++static void airoha_dev_lro_enable(struct airoha_gdm_dev *dev)
 +{
-+      struct airoha_qdma *qdma = port->qdma;
++      struct airoha_qdma *qdma = dev->qdma;
 +      struct airoha_eth *eth = qdma->eth;
 +      int qdma_id = qdma - &eth->qdma[0];
 +      int i, lro_queue_index = 0;
@@ -98,7 +98,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  static int airoha_fe_init(struct airoha_eth *eth)
  {
        airoha_fe_maccr_init(eth);
-@@ -558,6 +627,7 @@ static int airoha_qdma_fill_rx_queue(str
+@@ -614,6 +683,7 @@ static int airoha_qdma_fill_rx_queue(str
                e->dma_addr = page_pool_get_dma_addr(page) + offset;
                e->dma_len = SKB_WITH_OVERHEAD(AIROHA_RX_LEN(q->buf_size));
  
@@ -106,8 +106,8 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                val = FIELD_PREP(QDMA_DESC_LEN_MASK, e->dma_len);
                WRITE_ONCE(desc->ctrl, cpu_to_le32(val));
                WRITE_ONCE(desc->addr, cpu_to_le32(e->dma_addr));
-@@ -603,12 +673,169 @@ static int airoha_qdma_get_gdm_port(stru
-       return port >= ARRAY_SIZE(eth->ports) ? -EINVAL : port;
+@@ -655,12 +725,169 @@ airoha_qdma_get_gdm_dev(struct airoha_et
+       return port->devs[d] ? port->devs[d] : ERR_PTR(-ENODEV);
  }
  
 +static struct sk_buff *airoha_qdma_lro_rx_skb(struct airoha_queue *q,
@@ -279,27 +279,27 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        int done = 0;
  
        while (done < budget) {
-@@ -643,18 +870,9 @@ static int airoha_qdma_rx_process(struct
+@@ -696,18 +923,9 @@ static int airoha_qdma_rx_process(struct
  
-               port = eth->ports[p];
+               netdev = netdev_from_priv(dev);
                if (!q->skb) { /* first buffer */
 -                      q->skb = napi_build_skb(e->buf - AIROHA_RX_HEADROOM,
 -                                              q->buf_size);
-+                      q->skb = airoha_qdma_build_rx_skb(q, desc, e, port->dev);
++                      q->skb = airoha_qdma_build_rx_skb(q, desc, e, netdev);
                        if (!q->skb)
                                goto free_frag;
 -
 -                      skb_reserve(q->skb, AIROHA_RX_HEADROOM);
 -                      __skb_put(q->skb, len);
 -                      skb_mark_for_recycle(q->skb);
--                      q->skb->dev = port->dev;
--                      q->skb->protocol = eth_type_trans(q->skb, port->dev);
+-                      q->skb->dev = netdev;
+-                      q->skb->protocol = eth_type_trans(q->skb, netdev);
 -                      q->skb->ip_summed = CHECKSUM_UNNECESSARY;
 -                      skb_record_rx_queue(q->skb, qid);
                } else { /* scattered frame */
                        struct skb_shared_info *shinfo = skb_shinfo(q->skb);
                        int nr_frags = shinfo->nr_frags;
-@@ -743,12 +961,10 @@ static int airoha_qdma_rx_napi_poll(stru
+@@ -798,12 +1016,10 @@ static int airoha_qdma_rx_napi_poll(stru
  static int airoha_qdma_init_rx_queue(struct airoha_queue *q,
                                     struct airoha_qdma *qdma, int ndesc)
  {
@@ -313,7 +313,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                .nid = NUMA_NO_NODE,
                .dev = qdma->eth->dev,
                .napi = &q->napi,
-@@ -756,9 +972,10 @@ static int airoha_qdma_init_rx_queue(str
+@@ -811,9 +1027,10 @@ static int airoha_qdma_init_rx_queue(str
        struct airoha_eth *eth = qdma->eth;
        int qid = q - &qdma->q_rx[0], thr;
        dma_addr_t dma_addr;
@@ -325,7 +325,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        q->entry = devm_kzalloc(eth->dev, ndesc * sizeof(*q->entry),
                                GFP_KERNEL);
-@@ -770,6 +987,9 @@ static int airoha_qdma_init_rx_queue(str
+@@ -825,6 +1042,9 @@ static int airoha_qdma_init_rx_queue(str
        if (!q->desc)
                return -ENOMEM;
  
@@ -335,7 +335,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        q->page_pool = page_pool_create(&pp_params);
        if (IS_ERR(q->page_pool)) {
                int err = PTR_ERR(q->page_pool);
-@@ -778,6 +998,7 @@ static int airoha_qdma_init_rx_queue(str
+@@ -833,6 +1053,7 @@ static int airoha_qdma_init_rx_queue(str
                return err;
        }
  
@@ -343,7 +343,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        q->ndesc = ndesc;
        netif_napi_add(eth->napi_dev, &q->napi, airoha_qdma_rx_napi_poll);
  
-@@ -791,7 +1012,12 @@ static int airoha_qdma_init_rx_queue(str
+@@ -846,7 +1067,12 @@ static int airoha_qdma_init_rx_queue(str
                        FIELD_PREP(RX_RING_THR_MASK, thr));
        airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK,
                        FIELD_PREP(RX_RING_DMA_IDX_MASK, q->head));
@@ -357,7 +357,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        airoha_qdma_fill_rx_queue(q);
  
-@@ -813,6 +1039,7 @@ static void airoha_qdma_cleanup_rx_queue
+@@ -868,6 +1094,7 @@ static void airoha_qdma_cleanup_rx_queue
                                        page_pool_get_dma_dir(q->page_pool));
                page_pool_put_full_page(q->page_pool, page, false);
                /* Reset DMA descriptor */
@@ -365,56 +365,67 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                WRITE_ONCE(desc->ctrl, 0);
                WRITE_ONCE(desc->addr, 0);
                WRITE_ONCE(desc->data, 0);
-@@ -1720,13 +1947,45 @@ static void airoha_update_hw_stats(struc
-       spin_unlock(&port->stats.lock);
+@@ -1809,6 +2036,37 @@ static void airoha_update_hw_stats(struc
+       spin_unlock(&port->lock);
  }
  
-+static void airoha_update_netdev_features(struct airoha_gdm_port *port)
++static void airoha_update_netdev_features(struct airoha_gdm_dev *dev)
 +{
-+      struct airoha_eth *eth = port->eth;
++      struct airoha_eth *eth = dev->eth;
 +      int i;
 +
 +      for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
-+              struct airoha_gdm_port *p = eth->ports[i];
-+              struct net_device *netdev;
++              struct airoha_gdm_port *port = dev->port;
++              int j;
 +
-+              if (!p)
++              if (!port)
 +                      continue;
 +
-+              netdev = p->dev;
-+              if (netdev->reg_state != NETREG_REGISTERED)
-+                      continue;
++              for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
++                      struct airoha_gdm_dev *iter_dev = port->devs[j];
++                      struct net_device *netdev;
++
++                      if (!iter_dev || iter_dev == dev)
++                              continue;
++
++                      if (iter_dev->qdma != dev->qdma)
++                              continue;
++
++                      netdev = netdev_from_priv(iter_dev);
++                      if (netdev->reg_state != NETREG_REGISTERED)
++                              continue;
 +
-+              netdev_update_features(netdev);
++                      netdev_update_features(netdev);
++              }
 +      }
 +}
 +
- static int airoha_dev_open(struct net_device *dev)
+ static int airoha_dev_open(struct net_device *netdev)
  {
-       int err, len = ETH_HLEN + dev->mtu + ETH_FCS_LEN;
-       struct airoha_gdm_port *port = netdev_priv(dev);
-       struct airoha_qdma *qdma = port->qdma;
+       int err, len = ETH_HLEN + netdev->mtu + ETH_FCS_LEN;
+@@ -1816,6 +2074,18 @@ static int airoha_dev_open(struct net_de
+       struct airoha_gdm_port *port = dev->port;
+       u32 cur_len, pse_port = FE_PSE_PORT_PPE1;
+       struct airoha_qdma *qdma = dev->qdma;
 +      struct airoha_eth *eth = qdma->eth;
 +      int qdma_id = qdma - &eth->qdma[0];
-       u32 pse_port = FE_PSE_PORT_PPE1;
++
 +      /* HW LRO is configured on the QDMA and it is shared between
 +       * all the devices using it. Refuse to open a second device on
 +       * the same QDMA if LRO is enabled on any device sharing it.
 +       */
 +      if (qdma->users && airoha_fe_lro_is_enabled(eth, qdma_id)) {
-+              netdev_warn(dev, "required to disable HW GRO on QDMA%d\n",
++              netdev_warn(netdev, "required to disable HW GRO on QDMA%d\n",
 +                          qdma_id);
 +              return -EBUSY;
 +      }
-+
- #if defined(CONFIG_PCS_AIROHA)
-       if (airhoa_is_phy_external(port)) {
-               err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0);
-@@ -1747,13 +2006,13 @@ static int airoha_dev_open(struct net_de
+       err = phylink_of_phy_connect(dev->phylink, netdev->dev.of_node, 0);
+       if (err) {
+@@ -1832,13 +2102,13 @@ static int airoha_dev_open(struct net_de
  
        /* It seems GDM3 and GDM4 needs SPORT enabled to correctly work */
-       if (netdev_uses_dsa(dev) || port->id > 2)
+       if (netdev_uses_dsa(netdev) || port->id > 2)
 -              airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
 +              airoha_fe_set(eth, REG_GDM_INGRESS_CFG(port->id),
                              GDM_STAG_EN_MASK);
@@ -423,68 +434,77 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +              airoha_fe_clear(eth, REG_GDM_INGRESS_CFG(port->id),
                                GDM_STAG_EN_MASK);
  
--      airoha_fe_rmw(qdma->eth, REG_GDM_LEN_CFG(port->id),
-+      airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id),
-                     GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK,
-                     FIELD_PREP(GDM_SHORT_LEN_MASK, 60) |
-                     FIELD_PREP(GDM_LONG_LEN_MASK, len));
-@@ -1763,14 +2022,18 @@ static int airoha_dev_open(struct net_de
-                       GLOBAL_CFG_RX_DMA_EN_MASK);
+-      cur_len = airoha_fe_get(qdma->eth, REG_GDM_LEN_CFG(port->id),
++      cur_len = airoha_fe_get(eth, REG_GDM_LEN_CFG(port->id),
+                               GDM_LONG_LEN_MASK);
+       if (!port->users || len > cur_len) {
+               /* Opening a sibling net_device with a larger MTU updates the
+@@ -1846,7 +2116,7 @@ static int airoha_dev_open(struct net_de
+                * multiple net_devices with different MTUs to share the same
+                * GDM port.
+                */
+-              airoha_fe_rmw(qdma->eth, REG_GDM_LEN_CFG(port->id),
++              airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id),
+                             GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK,
+                             FIELD_PREP(GDM_SHORT_LEN_MASK, 60) |
+                             FIELD_PREP(GDM_LONG_LEN_MASK, len));
+@@ -1859,11 +2129,16 @@ static int airoha_dev_open(struct net_de
        qdma->users++;
  
--      if (port->id == AIROHA_GDM2_IDX &&
--          airoha_ppe_is_enabled(qdma->eth, 1)) {
-+      if (port->id == AIROHA_GDM2_IDX && airoha_ppe_is_enabled(eth, 1)) {
-               /* For PPE2 always use secondary cpu port. */
+       if (!airoha_is_lan_gdm_dev(dev) &&
+-          airoha_ppe_is_enabled(qdma->eth, 1))
++          airoha_ppe_is_enabled(eth, 1))
                pse_port = FE_PSE_PORT_PPE2;
-       }
 -      airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
 +      airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id),
                                    pse_port);
  
-+      if (dev->features & NETIF_F_GRO_HW)
-+              airoha_dev_lro_enable(port);
++      if (netdev->features & NETIF_F_GRO_HW)
++              airoha_dev_lro_enable(dev);
 +
-+      airoha_update_netdev_features(port);
++      airoha_update_netdev_features(dev);
 +
        return 0;
  }
  
-@@ -1778,6 +2041,7 @@ static int airoha_dev_stop(struct net_de
- {
-       struct airoha_gdm_port *port = netdev_priv(dev);
-       struct airoha_qdma *qdma = port->qdma;
+@@ -1896,6 +2171,7 @@ static int airoha_dev_stop(struct net_de
+       struct airoha_gdm_dev *dev = netdev_priv(netdev);
+       struct airoha_gdm_port *port = dev->port;
+       struct airoha_qdma *qdma = dev->qdma;
 +      struct airoha_eth *eth = qdma->eth;
        int i;
  
-       netif_tx_disable(dev);
-@@ -1785,7 +2049,7 @@ static int airoha_dev_stop(struct net_de
-       for (i = 0; i < dev->num_tx_queues; i++)
-               netdev_tx_reset_subqueue(dev, i);
+       netif_tx_disable(netdev);
+@@ -1904,9 +2180,9 @@ static int airoha_dev_stop(struct net_de
+               netdev_tx_reset_subqueue(netdev, i);
  
--      airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
-+      airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id),
-                                   FE_PSE_PORT_DROP);
+       if (--port->users)
+-              airoha_set_port_mtu(dev->eth, port);
++              airoha_set_port_mtu(eth, port);
+       else
+-              airoha_set_gdm_port_fwd_cfg(qdma->eth,
++              airoha_set_gdm_port_fwd_cfg(eth,
+                                           REG_GDM_FWD_CFG(port->id),
+                                           FE_PSE_PORT_DROP);
  
-       if (!--qdma->users) {
-@@ -1801,6 +2065,8 @@ static int airoha_dev_stop(struct net_de
+@@ -1923,6 +2199,8 @@ static int airoha_dev_stop(struct net_de
                }
        }
  
-+      airoha_update_netdev_features(port);
++      airoha_update_netdev_features(dev);
 +
- #if defined(CONFIG_PCS_AIROHA)
-       if (airhoa_is_phy_external(port)) {
-               phylink_stop(port->phylink);
-@@ -2034,6 +2300,38 @@ int airoha_get_fe_port(struct airoha_gdm
+       phylink_stop(dev->phylink);
+       phylink_disconnect_phy(dev->phylink);
+@@ -2195,6 +2473,38 @@ int airoha_get_fe_port(struct airoha_gdm
        }
  }
  
-+static netdev_features_t airoha_dev_fix_features(struct net_device *dev,
++static netdev_features_t airoha_dev_fix_features(struct net_device *netdev,
 +                                               netdev_features_t features)
 +{
-+      struct airoha_gdm_port *port = netdev_priv(dev);
-+      struct airoha_qdma *qdma = port->qdma;
++      struct airoha_gdm_dev *dev = netdev_priv(netdev);
++      struct airoha_qdma *qdma = dev->qdma;
 +
 +      if (qdma->users > 1)
 +              features &= ~NETIF_F_GRO_HW;
@@ -492,12 +512,12 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +      return features;
 +}
 +
-+static int airoha_dev_set_features(struct net_device *dev,
++static int airoha_dev_set_features(struct net_device *netdev,
 +                                 netdev_features_t features)
 +{
-+      netdev_features_t diff = dev->features ^ features;
-+      struct airoha_gdm_port *port = netdev_priv(dev);
-+      struct airoha_qdma *qdma = port->qdma;
++      netdev_features_t diff = netdev->features ^ features;
++      struct airoha_gdm_dev *dev = netdev_priv(netdev);
++      struct airoha_qdma *qdma = dev->qdma;
 +      struct airoha_eth *eth = qdma->eth;
 +      int qdma_id = qdma - &eth->qdma[0];
 +
@@ -505,7 +525,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +              return 0;
 +
 +      if (features & NETIF_F_GRO_HW)
-+              airoha_dev_lro_enable(port);
++              airoha_dev_lro_enable(dev);
 +      else
 +              airoha_fe_lro_disable(eth, qdma_id);
 +
@@ -513,9 +533,9 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +}
 +
  static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
-                                  struct net_device *dev)
+                                  struct net_device *netdev)
  {
-@@ -2933,6 +3231,8 @@ static const struct net_device_ops airoh
+@@ -3139,6 +3449,8 @@ static const struct net_device_ops airoh
        .ndo_stop               = airoha_dev_stop,
        .ndo_change_mtu         = airoha_dev_change_mtu,
        .ndo_select_queue       = airoha_dev_select_queue,
@@ -524,25 +544,24 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        .ndo_start_xmit         = airoha_dev_xmit,
        .ndo_get_stats64        = airoha_dev_get_stats64,
        .ndo_set_mac_address    = airoha_dev_set_macaddr,
-@@ -3150,12 +3450,9 @@ static int airoha_alloc_gdm_port(struct
-       dev->ethtool_ops = &airoha_ethtool_ops;
-       dev->max_mtu = AIROHA_MAX_MTU;
-       dev->watchdog_timeo = 5 * HZ;
--      dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
--                         NETIF_F_TSO6 | NETIF_F_IPV6_CSUM |
--                         NETIF_F_SG | NETIF_F_TSO |
--                         NETIF_F_HW_TC;
--      dev->features |= dev->hw_features;
--      dev->vlan_features = dev->hw_features;
-+      dev->hw_features = AIROHA_HW_FEATURES | NETIF_F_GRO_HW;
-+      dev->features |= AIROHA_HW_FEATURES;
-+      dev->vlan_features = AIROHA_HW_FEATURES;
-       dev->dev.of_node = np;
-       SET_NETDEV_DEV(dev, eth->dev);
+@@ -3380,11 +3692,9 @@ static int airoha_alloc_gdm_device(struc
+       netdev->ethtool_ops = &airoha_ethtool_ops;
+       netdev->max_mtu = AIROHA_MAX_MTU;
+       netdev->watchdog_timeo = 5 * HZ;
+-      netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | NETIF_F_TSO6 |
+-                            NETIF_F_IPV6_CSUM | NETIF_F_SG | NETIF_F_TSO |
+-                            NETIF_F_HW_TC;
+-      netdev->features |= netdev->hw_features;
+-      netdev->vlan_features = netdev->hw_features;
++      netdev->hw_features = AIROHA_HW_FEATURES | NETIF_F_LRO;
++      netdev->features |= AIROHA_HW_FEATURES;
++      netdev->vlan_features = AIROHA_HW_FEATURES;
+       SET_NETDEV_DEV(netdev, eth->dev);
  
+       /* reserve hw queues for HTB offloading */
 --- a/drivers/net/ethernet/airoha/airoha_eth.h
 +++ b/drivers/net/ethernet/airoha/airoha_eth.h
-@@ -43,6 +43,18 @@
+@@ -44,6 +44,18 @@
         (_n) == 15 ? 128 :             \
         (_n) ==  0 ? 1024 : 16)
  
@@ -561,7 +580,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  #define PSE_RSV_PAGES                 128
  #define PSE_QUEUE_RSV_PAGES           64
  
-@@ -666,6 +678,18 @@ static inline bool airoha_is_7583(struct
+@@ -676,6 +688,18 @@ static inline bool airoha_is_7583(struct
        return eth->soc->version == 0x7583;
  }
  
@@ -577,9 +596,9 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +      return !!(AIROHA_RXQ_LRO_EN_MASK & BIT(qid));
 +}
 +
- 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);
+ int airoha_get_fe_port(struct airoha_gdm_dev *dev);
+ bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
+                            struct airoha_gdm_dev *dev);
 --- a/drivers/net/ethernet/airoha/airoha_regs.h
 +++ b/drivers/net/ethernet/airoha/airoha_regs.h
 @@ -122,6 +122,20 @@
diff --git a/target/linux/airoha/patches-6.18/920-10-net-airoha-Rename-airoha_set_gdm2_loopback-in-airoha.patch b/target/linux/airoha/patches-6.18/920-10-net-airoha-Rename-airoha_set_gdm2_loopback-in-airoha.patch
deleted file mode 100644 (file)
index 92ce90e..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-From 917f959d54efd09719bd5047aa4b9543615e131e Mon Sep 17 00:00:00 2001
-Message-ID: <917f959d54efd09719bd5047aa4b9543615e131e.1779348625.git.lorenzo@kernel.org>
-In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
-References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Fri, 19 Dec 2025 23:12:32 +0100
-Subject: [PATCH 10/13] net: airoha: Rename airoha_set_gdm2_loopback in
- airoha_enable_gdm2_loopback
-
-This is a preliminary patch in order to allow the user to select if the
-configured device will be used as hw lan or wan.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- drivers/net/ethernet/airoha/airoha_eth.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/airoha/airoha_eth.c
-+++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -2213,7 +2213,7 @@ static int airoha_dev_set_macaddr(struct
-       return 0;
- }
--static int airoha_set_gdm2_loopback(struct airoha_gdm_dev *dev)
-+static int airoha_enable_gdm2_loopback(struct airoha_gdm_dev *dev)
- {
-       struct airoha_gdm_port *port = dev->port;
-       struct airoha_eth *eth = dev->eth;
-@@ -2346,7 +2346,7 @@ static int airoha_dev_init(struct net_de
-           (port->id == AIROHA_GDM3_IDX || port->id == AIROHA_GDM4_IDX)) {
-               int err;
--              err = airoha_set_gdm2_loopback(dev);
-+              err = airoha_enable_gdm2_loopback(dev);
-               if (err)
-                       return err;
-       }
index 2c16f2ac02dfb4b0ef3548da225d2ab63be2372d..77b37d54832618d55eb93d82face53dad14fc5d2 100644 (file)
@@ -19,7 +19,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 
 --- a/drivers/net/ethernet/airoha/airoha_eth.c
 +++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -540,7 +540,7 @@ static bool airoha_fe_lro_is_enabled(str
+@@ -533,7 +533,7 @@ static bool airoha_fe_lro_is_enabled(str
  
  static void airoha_dev_lro_enable(struct airoha_gdm_dev *dev)
  {
@@ -28,7 +28,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        struct airoha_eth *eth = qdma->eth;
        int qdma_id = qdma - &eth->qdma[0];
        int i, lro_queue_index = 0;
-@@ -1158,7 +1158,7 @@ static void airoha_qdma_wake_netdev_txqs
+@@ -1159,7 +1159,7 @@ static void airoha_qdma_wake_netdev_txqs
                        if (!dev)
                                continue;
  
@@ -37,7 +37,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                                continue;
  
                        netdev = netdev_from_priv(dev);
-@@ -2031,7 +2031,8 @@ static void airoha_update_netdev_feature
+@@ -2055,7 +2055,8 @@ static void airoha_update_netdev_feature
                        if (!iter_dev || iter_dev == dev)
                                continue;
  
@@ -47,7 +47,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                                continue;
  
                        netdev = netdev_from_priv(iter_dev);
-@@ -2043,20 +2044,57 @@ static void airoha_update_netdev_feature
+@@ -2067,20 +2068,57 @@ static void airoha_update_netdev_feature
        }
  }
  
@@ -108,7 +108,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        if (qdma->users && airoha_fe_lro_is_enabled(eth, qdma_id)) {
                netdev_warn(netdev, "required to disable HW GRO on QDMA%d\n",
                            qdma_id);
-@@ -2105,10 +2143,7 @@ static int airoha_dev_open(struct net_de
+@@ -2123,10 +2161,7 @@ static int airoha_dev_open(struct net_de
        }
        port->users++;
  
@@ -119,8 +119,8 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +      airoha_qdma_start(qdma);
  
        if (!airoha_is_lan_gdm_dev(dev) &&
-           airoha_ppe_is_enabled(eth, 1)) {
-@@ -2154,8 +2189,7 @@ static int airoha_dev_stop(struct net_de
+           airoha_ppe_is_enabled(eth, 1))
+@@ -2170,8 +2205,7 @@ static int airoha_dev_stop(struct net_de
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
        struct airoha_gdm_port *port = dev->port;
@@ -130,7 +130,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        int i;
  
        netif_tx_disable(netdev);
-@@ -2163,25 +2197,14 @@ static int airoha_dev_stop(struct net_de
+@@ -2179,26 +2213,14 @@ static int airoha_dev_stop(struct net_de
        for (i = 0; i < netdev->num_tx_queues; i++)
                netdev_tx_reset_subqueue(netdev, i);
  
@@ -139,9 +139,9 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 -              airoha_set_port_mtu(eth, port);
 +              airoha_set_port_mtu(dev->eth, port);
        else
--              airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id),
+-              airoha_set_gdm_port_fwd_cfg(eth,
 +              airoha_set_gdm_port_fwd_cfg(qdma->eth,
-+                                          REG_GDM_FWD_CFG(port->id),
+                                           REG_GDM_FWD_CFG(port->id),
                                            FE_PSE_PORT_DROP);
 -
 -      if (!--qdma->users) {
@@ -160,8 +160,8 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 +      airoha_qdma_stop(qdma);
        airoha_update_netdev_features(dev);
  
- #if defined(CONFIG_PCS_AIROHA)
-@@ -2275,6 +2298,53 @@ static int airoha_enable_gdm2_loopback(s
+       phylink_stop(dev->phylink);
+@@ -2288,6 +2310,53 @@ static int airoha_enable_gdm2_loopback(s
        return 0;
  }
  
@@ -215,7 +215,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  static struct airoha_gdm_dev *
  airoha_get_wan_gdm_dev(struct airoha_eth *eth)
  {
-@@ -2301,15 +2371,30 @@ airoha_get_wan_gdm_dev(struct airoha_eth
+@@ -2314,15 +2383,30 @@ airoha_get_wan_gdm_dev(struct airoha_eth
  static void airoha_dev_set_qdma(struct airoha_gdm_dev *dev)
  {
        struct net_device *netdev = netdev_from_priv(dev);
@@ -248,7 +248,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  }
  
  static int airoha_dev_init(struct net_device *netdev)
-@@ -2473,8 +2558,9 @@ static netdev_features_t airoha_dev_fix_
+@@ -2477,8 +2561,9 @@ static netdev_features_t airoha_dev_fix_
                                                 netdev_features_t features)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -259,7 +259,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        if (qdma->users > 1)
                features &= ~NETIF_F_GRO_HW;
  
-@@ -2486,9 +2572,8 @@ static int airoha_dev_set_features(struc
+@@ -2490,9 +2575,8 @@ static int airoha_dev_set_features(struc
  {
        netdev_features_t diff = netdev->features ^ features;
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -271,7 +271,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        if (!(diff & NETIF_F_GRO_HW))
                return 0;
-@@ -2496,7 +2581,7 @@ static int airoha_dev_set_features(struc
+@@ -2500,7 +2584,7 @@ static int airoha_dev_set_features(struc
        if (features & NETIF_F_GRO_HW)
                airoha_dev_lro_enable(dev);
        else
@@ -280,7 +280,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        return 0;
  }
-@@ -2505,9 +2590,9 @@ static netdev_tx_t airoha_dev_xmit(struc
+@@ -2509,9 +2593,9 @@ static netdev_tx_t airoha_dev_xmit(struc
                                   struct net_device *netdev)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -291,7 +291,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        struct netdev_queue *txq;
        struct airoha_queue *q;
        LIST_HEAD(tx_list);
-@@ -2516,6 +2601,8 @@ static netdev_tx_t airoha_dev_xmit(struc
+@@ -2520,6 +2604,8 @@ static netdev_tx_t airoha_dev_xmit(struc
        u16 index;
        u8 fport;
  
@@ -300,7 +300,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        qid = airoha_qdma_get_txq(qdma, skb_get_queue_mapping(skb));
        tag = airoha_get_dsa_tag(skb, netdev);
  
-@@ -2562,6 +2649,8 @@ static netdev_tx_t airoha_dev_xmit(struc
+@@ -2566,6 +2652,8 @@ static netdev_tx_t airoha_dev_xmit(struc
                netif_tx_stop_queue(txq);
                q->txq_stopped = true;
                spin_unlock_bh(&q->lock);
@@ -309,7 +309,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                return NETDEV_TX_BUSY;
        }
  
-@@ -2624,6 +2713,7 @@ static netdev_tx_t airoha_dev_xmit(struc
+@@ -2628,6 +2716,7 @@ static netdev_tx_t airoha_dev_xmit(struc
                                FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
  
        spin_unlock_bh(&q->lock);
@@ -317,7 +317,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        return NETDEV_TX_OK;
  
-@@ -2639,6 +2729,7 @@ error_unmap:
+@@ -2643,6 +2732,7 @@ error_unmap:
  error:
        dev_kfree_skb_any(skb);
        netdev->stats.tx_dropped++;
@@ -325,7 +325,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        return NETDEV_TX_OK;
  }
-@@ -2720,17 +2811,19 @@ static int airoha_qdma_set_chan_tx_sched
+@@ -2740,17 +2830,19 @@ static int airoha_qdma_set_chan_tx_sched
                                         const u16 *weights, u8 n_weights)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -347,7 +347,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                               TWRR_RW_CMD_MASK |
                               FIELD_PREP(TWRR_CHAN_IDX_MASK, channel) |
                               FIELD_PREP(TWRR_QUEUE_IDX_MASK, i) |
-@@ -2738,12 +2831,12 @@ static int airoha_qdma_set_chan_tx_sched
+@@ -2758,12 +2850,12 @@ static int airoha_qdma_set_chan_tx_sched
                err = read_poll_timeout(airoha_qdma_rr, status,
                                        status & TWRR_RW_CMD_DONE,
                                        USEC_PER_MSEC, 10 * USEC_PER_MSEC,
@@ -362,7 +362,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                        CHAN_QOS_MODE_MASK(channel),
                        __field_prep(CHAN_QOS_MODE_MASK(channel), mode));
  
-@@ -2807,13 +2900,15 @@ static int airoha_qdma_get_tx_ets_stats(
+@@ -2827,13 +2919,15 @@ static int airoha_qdma_get_tx_ets_stats(
                                        struct tc_ets_qopt_offload *opt)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -384,7 +384,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        _bstats_update(opt->stats.bstats, 0, tx_packets);
        dev->cpu_tx_packets = cpu_tx_packets;
-@@ -3073,16 +3168,18 @@ static int airoha_qdma_set_tx_rate_limit
+@@ -3093,16 +3187,18 @@ static int airoha_qdma_set_tx_rate_limit
                                         u32 bucket_size)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -405,7 +405,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                                                         REG_EGRESS_TRTCM_CFG,
                                                         i, rate, bucket_size);
                if (err)
-@@ -3118,11 +3215,12 @@ static int airoha_tc_htb_alloc_leaf_queu
+@@ -3138,11 +3234,12 @@ static int airoha_tc_htb_alloc_leaf_queu
        u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
        int err, num_tx_queues = netdev->real_num_tx_queues;
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -419,7 +419,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        if (test_and_set_bit(channel, qdma->qos_channel_map)) {
                NL_SET_ERR_MSG_MOD(opt->extack,
                                   "qdma qos channel already in use");
-@@ -3156,7 +3254,7 @@ static int airoha_qdma_set_rx_meter(stru
+@@ -3176,7 +3273,7 @@ static int airoha_qdma_set_rx_meter(stru
                                    u32 rate, u32 bucket_size,
                                    enum trtcm_unit_type unit_type)
  {
@@ -428,7 +428,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        int i;
  
        for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
-@@ -3330,11 +3428,12 @@ static int airoha_dev_setup_tc_block(str
+@@ -3350,11 +3447,12 @@ static int airoha_dev_setup_tc_block(str
  static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -442,7 +442,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        clear_bit(queue, qdma->qos_channel_map);
        clear_bit(queue, dev->qos_sq_bmap);
  }
-@@ -3355,6 +3454,95 @@ static int airoha_tc_htb_delete_leaf_que
+@@ -3375,6 +3473,95 @@ static int airoha_tc_htb_delete_leaf_que
        return 0;
  }
  
@@ -538,7 +538,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  static int airoha_tc_htb_destroy(struct net_device *netdev)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
-@@ -3363,6 +3551,8 @@ static int airoha_tc_htb_destroy(struct
+@@ -3383,6 +3570,8 @@ static int airoha_tc_htb_destroy(struct
        for_each_set_bit(q, dev->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS)
                airoha_tc_remove_htb_queue(netdev, q);
  
@@ -547,7 +547,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        return 0;
  }
  
-@@ -3382,24 +3572,33 @@ static int airoha_tc_get_htb_get_leaf_qu
+@@ -3402,24 +3591,33 @@ static int airoha_tc_get_htb_get_leaf_qu
        return 0;
  }
  
@@ -588,16 +588,6 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        default:
                return -EOPNOTSUPP;
        }
-@@ -3509,8 +3708,8 @@ static void airoha_mac_link_up(struct ph
- {
-       struct airoha_gdm_dev *dev = container_of(config, struct airoha_gdm_dev,
-                                                 phylink_config);
-+      struct airoha_qdma *qdma = airoha_qdma_deref(dev);
-       struct airoha_gdm_port *port = dev->port;
--      struct airoha_qdma *qdma = dev->qdma;
-       struct airoha_eth *eth = qdma->eth;
-       u32 frag_size_tx, frag_size_rx;
 --- a/drivers/net/ethernet/airoha/airoha_regs.h
 +++ b/drivers/net/ethernet/airoha/airoha_regs.h
 @@ -402,6 +402,7 @@
@@ -610,7 +600,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
 --- a/drivers/net/ethernet/airoha/airoha_eth.h
 +++ b/drivers/net/ethernet/airoha/airoha_eth.h
-@@ -552,11 +552,12 @@ struct airoha_qdma {
+@@ -550,11 +550,12 @@ struct airoha_qdma {
  
  enum airoha_priv_flags {
        AIROHA_PRIV_F_WAN = BIT(0),
@@ -623,8 +613,8 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 -      struct airoha_qdma *qdma;
        struct airoha_eth *eth;
  
- #if defined(CONFIG_PCS_AIROHA)
-@@ -705,6 +706,16 @@ int airoha_get_fe_port(struct airoha_gdm
+       DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS);
+@@ -704,6 +705,16 @@ int airoha_get_fe_port(struct airoha_gdm
  bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
                             struct airoha_gdm_dev *dev);
  
index d17c537daa21dd60ad9851f3d6e034f772b8ab0f..2e854b6f4929089747d21b0a07ac10a694e6aebc 100644 (file)
@@ -16,7 +16,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 
 --- a/drivers/net/ethernet/airoha/airoha_eth.c
 +++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -188,10 +188,15 @@ static void airoha_fe_maccr_init(struct
+@@ -181,10 +181,15 @@ static void airoha_fe_maccr_init(struct
  {
        int p;
  
@@ -33,7 +33,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        airoha_fe_rmw(eth, REG_CDM_VLAN_CTRL(1), CDM_VLAN_MASK,
                      FIELD_PREP(CDM_VLAN_MASK, 0x8100));
-@@ -2078,15 +2083,25 @@ static void airoha_qdma_stop(struct airo
+@@ -2102,15 +2107,25 @@ static void airoha_qdma_stop(struct airo
        }
  }
  
@@ -62,7 +62,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        /* HW LRO is configured on the QDMA and it is shared between
         * all the devices using it. Refuse to open a second device on
-@@ -2128,19 +2143,7 @@ static int airoha_dev_open(struct net_de
+@@ -2146,19 +2161,7 @@ static int airoha_dev_open(struct net_de
                airoha_fe_clear(eth, REG_GDM_INGRESS_CFG(port->id),
                                GDM_STAG_EN_MASK);
  
@@ -83,7 +83,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        port->users++;
  
        airoha_qdma_start(qdma);
-@@ -2161,30 +2164,6 @@ static int airoha_dev_open(struct net_de
+@@ -2177,30 +2180,6 @@ static int airoha_dev_open(struct net_de
        return 0;
  }
  
@@ -114,7 +114,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  static int airoha_dev_stop(struct net_device *netdev)
  {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
-@@ -2199,7 +2178,7 @@ static int airoha_dev_stop(struct net_de
+@@ -2215,7 +2194,7 @@ static int airoha_dev_stop(struct net_de
  
        qdma = airoha_qdma_deref(dev);
        if (--port->users)
@@ -123,7 +123,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        else
                airoha_set_gdm_port_fwd_cfg(qdma->eth,
                                            REG_GDM_FWD_CFG(port->id),
-@@ -2258,10 +2237,6 @@ static int airoha_enable_gdm2_loopback(s
+@@ -2274,10 +2253,6 @@ static int airoha_enable_gdm2_loopback(s
                      FIELD_PREP(LPBK_CHAN_MASK, chan) |
                      LBK_GAP_MODE_MASK | LBK_LEN_MODE_MASK |
                      LBK_CHAN_MODE_MASK | LPBK_EN_MASK);
@@ -134,7 +134,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        /* Forward the traffic to the proper GDM port */
        pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3
                                               : FE_PSE_PORT_GDM4;
-@@ -2469,7 +2444,7 @@ static int airoha_dev_change_mtu(struct
+@@ -2472,7 +2447,7 @@ static int airoha_dev_change_mtu(struct
  
        WRITE_ONCE(netdev->mtu, mtu);
        if (port->users)
@@ -143,7 +143,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        return 0;
  }
-@@ -3471,6 +3446,7 @@ static void airoha_disable_qos_for_gdm34
+@@ -3490,6 +3465,7 @@ static void airoha_disable_qos_for_gdm34
  
        dev->flags &= ~AIROHA_PRIV_F_WAN;
        airoha_dev_set_qdma(dev);
@@ -151,7 +151,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        airoha_set_macaddr(dev, netdev->dev_addr);
        if (netif_running(netdev))
-@@ -3519,6 +3495,7 @@ static int airoha_enable_qos_for_gdm34(s
+@@ -3538,6 +3514,7 @@ static int airoha_enable_qos_for_gdm34(s
        if (err)
                goto error_disable_loopback;
  
@@ -169,7 +169,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  #define AIROHA_MAX_PACKET_SIZE                2048
  #define AIROHA_NUM_QOS_CHANNELS               4
  #define AIROHA_NUM_QOS_QUEUES         8
-@@ -716,6 +717,7 @@ airoha_qdma_deref(struct airoha_gdm_dev
+@@ -715,6 +716,7 @@ airoha_qdma_deref(struct airoha_gdm_dev
                                         lockdep_is_held(&flow_offload_mutex));
  }
  
index 2df1996d19a80fb3d2759a09f86ba5930ca732f5..a0a1ed01350cbc1f653f785dde8ce6e29cb79125 100644 (file)
@@ -18,7 +18,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
 
 --- a/drivers/net/ethernet/airoha/airoha_eth.c
 +++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -2543,17 +2543,9 @@ static u32 airoha_get_dsa_tag(struct sk_
+@@ -2519,17 +2519,9 @@ static u32 airoha_get_dsa_tag(struct sk_
  int airoha_get_fe_port(struct airoha_gdm_dev *dev)
  {
        struct airoha_gdm_port *port = dev->port;
diff --git a/target/linux/airoha/patches-6.18/921-net-airoha-move-get_sport-callback-at-the-beginning-.patch b/target/linux/airoha/patches-6.18/921-net-airoha-move-get_sport-callback-at-the-beginning-.patch
deleted file mode 100644 (file)
index 9cd99c7..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-From 18aa76cd820c412358dc36d115b8e02d24a78f39 Mon Sep 17 00:00:00 2001
-Message-ID: <18aa76cd820c412358dc36d115b8e02d24a78f39.1780942778.git.lorenzo@kernel.org>
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 8 Jun 2026 20:10:35 +0200
-Subject: [PATCH] net: airoha: move get_sport() callback at the beginning of
- airoha_enable_gdm2_loopback()
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- drivers/net/ethernet/airoha/airoha_eth.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/net/ethernet/airoha/airoha_eth.c
-+++ b/drivers/net/ethernet/airoha/airoha_eth.c
-@@ -2250,6 +2250,10 @@ static int airoha_enable_gdm2_loopback(s
-       u32 val, pse_port, chan;
-       int i, src_port;
-+      src_port = eth->soc->ops.get_sport(port, dev->nbq);
-+      if (src_port < 0)
-+              return src_port;
-+
-       airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),
-                                   FE_PSE_PORT_DROP);
-       airoha_fe_clear(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),
-@@ -2275,10 +2279,6 @@ static int airoha_enable_gdm2_loopback(s
-       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));
--      src_port = eth->soc->ops.get_sport(port, dev->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));