]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
airoha: backport additional patch for memory leak and multi-serdes rework
authorChristian Marangi <ansuelsmth@gmail.com>
Wed, 15 Apr 2026 08:13:11 +0000 (10:13 +0200)
committerChristian Marangi <ansuelsmth@gmail.com>
Wed, 15 Apr 2026 08:36:44 +0000 (10:36 +0200)
Backport upstream memory leak patch merged upstream and even more
preliminary patch for multi-serdes rewrk.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
17 files changed:
target/linux/airoha/patches-6.12/136-v7.1-net-airoha-Add-dma_rmb-and-READ_ONCE-in-airoha_qdma_.patch [new file with mode: 0644]
target/linux/airoha/patches-6.12/137-v7.1-net-airoha-Add-missing-PPE-configurations-in-airoha_.patch [new file with mode: 0644]
target/linux/airoha/patches-6.12/138-v7.1-net-airoha-Add-missing-RX_CPU_IDX-configuration-in-a.patch [new file with mode: 0644]
target/linux/airoha/patches-6.12/139-v7.1-net-airoha-Fix-FE_PSE_BUF_SET-configuration-if-PPE2-.patch [new file with mode: 0644]
target/linux/airoha/patches-6.12/140-v7.1-net-airoha-Fix-memory-leak-in-airoha_qdma_rx_process.patch [new file with mode: 0644]
target/linux/airoha/patches-6.12/141-v7.1-net-airoha-Fix-VIP-configuration-for-AN7583-SoC.patch [new file with mode: 0644]
target/linux/airoha/patches-6.12/142-01-v7.1-net-airoha-Rely-on-net_device-pointer-in-airoha_dev_.patch [new file with mode: 0644]
target/linux/airoha/patches-6.12/142-02-v7.1-net-airoha-Rely-on-net_device-pointer-in-HTB-callbac.patch [new file with mode: 0644]
target/linux/airoha/patches-6.12/142-03-v7.1-net-airoha-Rely-on-net_device-pointer-in-ETS-callbac.patch [new file with mode: 0644]
target/linux/airoha/patches-6.12/142-04-v7.1-net-airoha-Remove-PCE_MC_EN_MASK-bit-in-REG_FE_PCE_C.patch [new file with mode: 0644]
target/linux/airoha/patches-6.12/310-02-net-airoha-deassert-XSI-line-on-hw-init.patch
target/linux/airoha/patches-6.12/310-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch
target/linux/airoha/patches-6.12/310-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch
target/linux/airoha/patches-6.12/310-07-airoha-ethernet-drop-xsi-mac-reset.patch
target/linux/airoha/patches-6.12/310-10-net-airoha-add-phylink-support-for-GDM2-4.patch
target/linux/airoha/patches-6.12/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch
target/linux/airoha/patches-6.12/606-net-airoha-disable-external-phy-code-if-PCS_AIROHA-i.patch

diff --git a/target/linux/airoha/patches-6.12/136-v7.1-net-airoha-Add-dma_rmb-and-READ_ONCE-in-airoha_qdma_.patch b/target/linux/airoha/patches-6.12/136-v7.1-net-airoha-Add-dma_rmb-and-READ_ONCE-in-airoha_qdma_.patch
new file mode 100644 (file)
index 0000000..6cceacf
--- /dev/null
@@ -0,0 +1,78 @@
+From 4ae0604a0673e11e2075b178387151fcad5111b5 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Tue, 7 Apr 2026 08:48:04 +0200
+Subject: [PATCH] net: airoha: Add dma_rmb() and READ_ONCE() in
+ airoha_qdma_rx_process()
+
+Add missing dma_rmb() in airoha_qdma_rx_process routine to make sure the
+DMA read operations are completed when the NIC reports the processing on
+the current descriptor is done. Moreover, add missing READ_ONCE() in
+airoha_qdma_rx_process() for DMA descriptor control fields in order to
+avoid any compiler reordering.
+
+Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20260407-airoha_qdma_rx_process-fix-reordering-v3-1-91c36e9da31f@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -584,7 +584,7 @@ static int airoha_qdma_fill_rx_queue(str
+ static int airoha_qdma_get_gdm_port(struct airoha_eth *eth,
+                                   struct airoha_qdma_desc *desc)
+ {
+-      u32 port, sport, msg1 = le32_to_cpu(desc->msg1);
++      u32 port, sport, msg1 = le32_to_cpu(READ_ONCE(desc->msg1));
+       sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1);
+       switch (sport) {
+@@ -612,21 +612,24 @@ static int airoha_qdma_rx_process(struct
+       while (done < budget) {
+               struct airoha_queue_entry *e = &q->entry[q->tail];
+               struct airoha_qdma_desc *desc = &q->desc[q->tail];
+-              u32 hash, reason, msg1 = le32_to_cpu(desc->msg1);
+-              struct page *page = virt_to_head_page(e->buf);
+-              u32 desc_ctrl = le32_to_cpu(desc->ctrl);
++              u32 hash, reason, msg1, desc_ctrl;
+               struct airoha_gdm_port *port;
+               int data_len, len, p;
++              struct page *page;
++              desc_ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
+               if (!(desc_ctrl & QDMA_DESC_DONE_MASK))
+                       break;
++              dma_rmb();
++
+               q->tail = (q->tail + 1) % q->ndesc;
+               q->queued--;
+               dma_sync_single_for_cpu(eth->dev, e->dma_addr,
+                                       SKB_WITH_OVERHEAD(q->buf_size), dir);
++              page = virt_to_head_page(e->buf);
+               len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl);
+               data_len = q->skb ? q->buf_size
+                                 : SKB_WITH_OVERHEAD(q->buf_size);
+@@ -670,8 +673,8 @@ static int airoha_qdma_rx_process(struct
+                        * DMA descriptor. Report DSA tag to the DSA stack
+                        * via skb dst info.
+                        */
+-                      u32 sptag = FIELD_GET(QDMA_ETH_RXMSG_SPTAG,
+-                                            le32_to_cpu(desc->msg0));
++                      u32 msg0 = le32_to_cpu(READ_ONCE(desc->msg0));
++                      u32 sptag = FIELD_GET(QDMA_ETH_RXMSG_SPTAG, msg0);
+                       if (sptag < ARRAY_SIZE(port->dsa_meta) &&
+                           port->dsa_meta[sptag])
+@@ -679,6 +682,7 @@ static int airoha_qdma_rx_process(struct
+                                                 &port->dsa_meta[sptag]->dst);
+               }
++              msg1 = le32_to_cpu(READ_ONCE(desc->msg1));
+               hash = FIELD_GET(AIROHA_RXD4_FOE_ENTRY, msg1);
+               if (hash != AIROHA_RXD4_FOE_ENTRY)
+                       skb_set_hash(q->skb, jhash_1word(hash, 0),
diff --git a/target/linux/airoha/patches-6.12/137-v7.1-net-airoha-Add-missing-PPE-configurations-in-airoha_.patch b/target/linux/airoha/patches-6.12/137-v7.1-net-airoha-Add-missing-PPE-configurations-in-airoha_.patch
new file mode 100644 (file)
index 0000000..a6089f9
--- /dev/null
@@ -0,0 +1,62 @@
+From b9d8b856689d2b968495d79fe653d87fcb8ad98c Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Sun, 12 Apr 2026 10:43:26 +0200
+Subject: [PATCH] net: airoha: Add missing PPE configurations in
+ airoha_ppe_hw_init()
+
+Add the following PPE configuration in airoha_ppe_hw_init routine:
+- 6RD hw offloading is currently not supported by Netfilter flowtable.
+  Disable explicitly PPE 6RD offloading in order to prevent PPE to learn
+  6RD flows and eventually interrupt the traffic.
+- Add missing PPE bind rate configuration for L3 and L2 traffic.
+  PPE bind rate configuration specifies the pps threshold to move a PPE
+  entry state from UNBIND to BIND. Without this configuration this value
+  is random.
+- Set ageing thresholds to the values used in the vendor SDK in order to
+  improve connection stability under load and avoid packet loss caused by
+  fast aging.
+
+Fixes: 00a7678310fe3 ("net: airoha: Introduce flowtable offload support")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260412-airoha_ppe_hw_init-missing-bits-v1-1-06ac670819e3@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/ethernet/airoha/airoha_ppe.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_ppe.c
++++ b/drivers/net/ethernet/airoha/airoha_ppe.c
+@@ -125,13 +125,13 @@ static void airoha_ppe_hw_init(struct ai
+               airoha_fe_rmw(eth, REG_PPE_BND_AGE0(i),
+                             PPE_BIND_AGE0_DELTA_NON_L4 |
+                             PPE_BIND_AGE0_DELTA_UDP,
+-                            FIELD_PREP(PPE_BIND_AGE0_DELTA_NON_L4, 1) |
+-                            FIELD_PREP(PPE_BIND_AGE0_DELTA_UDP, 12));
++                            FIELD_PREP(PPE_BIND_AGE0_DELTA_NON_L4, 60) |
++                            FIELD_PREP(PPE_BIND_AGE0_DELTA_UDP, 60));
+               airoha_fe_rmw(eth, REG_PPE_BND_AGE1(i),
+                             PPE_BIND_AGE1_DELTA_TCP_FIN |
+                             PPE_BIND_AGE1_DELTA_TCP,
+                             FIELD_PREP(PPE_BIND_AGE1_DELTA_TCP_FIN, 1) |
+-                            FIELD_PREP(PPE_BIND_AGE1_DELTA_TCP, 7));
++                            FIELD_PREP(PPE_BIND_AGE1_DELTA_TCP, 60));
+               airoha_fe_rmw(eth, REG_PPE_TB_HASH_CFG(i),
+                             PPE_SRAM_TABLE_EN_MASK |
+@@ -159,7 +159,15 @@ static void airoha_ppe_hw_init(struct ai
+                             FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK,
+                                        dram_num_entries));
++              airoha_fe_rmw(eth, REG_PPE_BIND_RATE(i),
++                            PPE_BIND_RATE_L2B_BIND_MASK |
++                            PPE_BIND_RATE_BIND_MASK,
++                            FIELD_PREP(PPE_BIND_RATE_L2B_BIND_MASK, 0x1e) |
++                            FIELD_PREP(PPE_BIND_RATE_BIND_MASK, 0x1e));
++
+               airoha_fe_wr(eth, REG_PPE_HASH_SEED(i), PPE_HASH_SEED);
++              airoha_fe_clear(eth, REG_PPE_PPE_FLOW_CFG(i),
++                              PPE_FLOW_CFG_IP6_6RD_MASK);
+               for (p = 0; p < ARRAY_SIZE(eth->ports); p++) {
+                       struct airoha_gdm_port *port = eth->ports[p];
diff --git a/target/linux/airoha/patches-6.12/138-v7.1-net-airoha-Add-missing-RX_CPU_IDX-configuration-in-a.patch b/target/linux/airoha/patches-6.12/138-v7.1-net-airoha-Add-missing-RX_CPU_IDX-configuration-in-a.patch
new file mode 100644 (file)
index 0000000..3805dfe
--- /dev/null
@@ -0,0 +1,34 @@
+From 656121b155030086b01cfce9bd31b0c925ee6860 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Wed, 8 Apr 2026 20:26:56 +0200
+Subject: [PATCH] net: airoha: Add missing RX_CPU_IDX() configuration in
+ airoha_qdma_cleanup_rx_queue()
+
+When the descriptor index written in REG_RX_CPU_IDX() is equal to the one
+stored in REG_RX_DMA_IDX(), the hw will stop since the QDMA RX ring is
+empty.
+Add missing REG_RX_CPU_IDX() configuration in airoha_qdma_cleanup_rx_queue
+routine during QDMA RX ring cleanup.
+
+Fixes: 514aac359987 ("net: airoha: Add missing cleanup bits in airoha_qdma_cleanup_rx_queue()")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20260408-airoha-cpu-idx-airoha_qdma_cleanup_rx_queue-v1-1-8efa64844308@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -824,6 +824,11 @@ static void airoha_qdma_cleanup_rx_queue
+       }
+       q->head = q->tail;
++      /* Set RX_DMA_IDX to RX_CPU_IDX to notify the hw the QDMA RX ring is
++       * empty.
++       */
++      airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK,
++                      FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head));
+       airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK,
+                       FIELD_PREP(RX_RING_DMA_IDX_MASK, q->tail));
+ }
diff --git a/target/linux/airoha/patches-6.12/139-v7.1-net-airoha-Fix-FE_PSE_BUF_SET-configuration-if-PPE2-.patch b/target/linux/airoha/patches-6.12/139-v7.1-net-airoha-Fix-FE_PSE_BUF_SET-configuration-if-PPE2-.patch
new file mode 100644 (file)
index 0000000..2053e0e
--- /dev/null
@@ -0,0 +1,45 @@
+From 02f72964395911e7a09bb2ea2fe6f79eda4ea2c2 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Wed, 8 Apr 2026 12:20:09 +0200
+Subject: [PATCH] net: airoha: Fix FE_PSE_BUF_SET configuration if PPE2 is
+ available
+
+airoha_fe_set routine is used to set specified bits to 1 in the selected
+register. In the FE_PSE_BUF_SET case this can due to a overestimation of
+the required buffers for I/O queues since we can miss to set some bits
+of PSE_ALLRSV_MASK subfield to 0. Fix the issue relying on airoha_fe_rmw
+routine instead.
+
+Fixes: 8e38e08f2c560 ("net: airoha: fix PSE memory configuration in airoha_fe_pse_ports_init()")
+Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20260408-airoha-reg_fe_pse_buf_set-v1-1-0c4fa8f4d1d9@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -293,16 +293,18 @@ static void airoha_fe_pse_ports_init(str
+               [FE_PSE_PORT_GDM4] = 2,
+               [FE_PSE_PORT_CDM5] = 2,
+       };
+-      u32 all_rsv;
+       int q;
+-      all_rsv = airoha_fe_get_pse_all_rsv(eth);
+       if (airoha_ppe_is_enabled(eth, 1)) {
++              u32 all_rsv;
++
+               /* hw misses PPE2 oq rsv */
++              all_rsv = airoha_fe_get_pse_all_rsv(eth);
+               all_rsv += PSE_RSV_PAGES *
+                          pse_port_num_queues[FE_PSE_PORT_PPE2];
++              airoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, PSE_ALLRSV_MASK,
++                            FIELD_PREP(PSE_ALLRSV_MASK, all_rsv));
+       }
+-      airoha_fe_set(eth, REG_FE_PSE_BUF_SET, all_rsv);
+       /* CMD1 */
+       for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM1]; q++)
diff --git a/target/linux/airoha/patches-6.12/140-v7.1-net-airoha-Fix-memory-leak-in-airoha_qdma_rx_process.patch b/target/linux/airoha/patches-6.12/140-v7.1-net-airoha-Fix-memory-leak-in-airoha_qdma_rx_process.patch
new file mode 100644 (file)
index 0000000..9d331d8
--- /dev/null
@@ -0,0 +1,37 @@
+From 285fa6b1e03cff78ead0383e1b259c44b95faf90 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Thu, 2 Apr 2026 14:57:10 +0200
+Subject: [PATCH] net: airoha: Fix memory leak in airoha_qdma_rx_process()
+
+If an error occurs on the subsequents buffers belonging to the
+non-linear part of the skb (e.g. due to an error in the payload length
+reported by the NIC or if we consumed all the available fragments for
+the skb), the page_pool fragment will not be linked to the skb so it will
+not return to the pool in the airoha_qdma_rx_process() error path. Fix the
+memory leak partially reverting commit 'd6d2b0e1538d ("net: airoha: Fix
+page recycling in airoha_qdma_rx_process()")' and always running
+page_pool_put_full_page routine in the airoha_qdma_rx_process() error
+path.
+
+Fixes: d6d2b0e1538d ("net: airoha: Fix page recycling in airoha_qdma_rx_process()")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260402-airoha_qdma_rx_process-mem-leak-fix-v1-1-b5706f402d3c@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -703,9 +703,8 @@ free_frag:
+               if (q->skb) {
+                       dev_kfree_skb(q->skb);
+                       q->skb = NULL;
+-              } else {
+-                      page_pool_put_full_page(q->page_pool, page, true);
+               }
++              page_pool_put_full_page(q->page_pool, page, true);
+       }
+       airoha_qdma_fill_rx_queue(q);
diff --git a/target/linux/airoha/patches-6.12/141-v7.1-net-airoha-Fix-VIP-configuration-for-AN7583-SoC.patch b/target/linux/airoha/patches-6.12/141-v7.1-net-airoha-Fix-VIP-configuration-for-AN7583-SoC.patch
new file mode 100644 (file)
index 0000000..23dcf6e
--- /dev/null
@@ -0,0 +1,164 @@
+From 1acdfbdb516b32165a8ecd1d5f8c68e4eac64637 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Sun, 12 Apr 2026 09:57:29 +0200
+Subject: [PATCH] net: airoha: Fix VIP configuration for AN7583 SoC
+
+EN7581 and AN7583 SoCs have different VIP definitions. Introduce
+get_vip_port callback in airoha_eth_soc_data struct in order to take
+into account EN7581 and AN7583 VIP register layout and definition
+differences.
+Introduce nbq parameter in airoha_gdm_port struct. At the moment nbq
+is set statically to value previously used in airhoha_set_gdm2_loopback
+routine and it will be read from device tree in subsequent patches.
+
+Fixes: e4e5ce823bdd ("net: airoha: Add AN7583 SoC support")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20260412-airoha-7583-vip-fix-v1-1-c35e02b054bb@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 66 ++++++++++++++++++------
+ drivers/net/ethernet/airoha/airoha_eth.h |  2 +
+ 2 files changed, 51 insertions(+), 17 deletions(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -107,19 +107,7 @@ static int airoha_set_vip_for_gdm_port(s
+       struct airoha_eth *eth = port->qdma->eth;
+       u32 vip_port;
+-      switch (port->id) {
+-      case AIROHA_GDM3_IDX:
+-              /* FIXME: handle XSI_PCIE1_PORT */
+-              vip_port = XSI_PCIE0_VIP_PORT_MASK;
+-              break;
+-      case AIROHA_GDM4_IDX:
+-              /* FIXME: handle XSI_USB_PORT */
+-              vip_port = XSI_ETH_VIP_PORT_MASK;
+-              break;
+-      default:
+-              return 0;
+-      }
+-
++      vip_port = eth->soc->ops.get_vip_port(port, port->nbq);
+       if (enable) {
+               airoha_fe_set(eth, REG_FE_VIP_PORT_EN, vip_port);
+               airoha_fe_set(eth, REG_FE_IFC_PORT_EN, vip_port);
+@@ -1738,7 +1726,7 @@ static int airoha_dev_set_macaddr(struct
+ static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
+ {
+       struct airoha_eth *eth = port->qdma->eth;
+-      u32 val, pse_port, chan, nbq;
++      u32 val, pse_port, chan;
+       int src_port;
+       /* Forward the traffic to the proper GDM port */
+@@ -1768,9 +1756,7 @@ static int airhoha_set_gdm2_loopback(str
+       airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(AIROHA_GDM2_IDX));
+       airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(AIROHA_GDM2_IDX));
+-      /* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */
+-      nbq = port->id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
+-      src_port = eth->soc->ops.get_src_port_id(port, nbq);
++      src_port = eth->soc->ops.get_src_port_id(port, port->nbq);
+       if (src_port < 0)
+               return src_port;
+@@ -2962,6 +2948,8 @@ static int airoha_alloc_gdm_port(struct
+       port->eth = eth;
+       port->dev = dev;
+       port->id = id;
++      /* XXX: Read nbq from DTS */
++      port->nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
+       eth->ports[p] = port;
+       return airoha_metadata_dst_alloc(port);
+@@ -3158,6 +3146,28 @@ static int airoha_en7581_get_src_port_id
+       return -EINVAL;
+ }
++static u32 airoha_en7581_get_vip_port(struct airoha_gdm_port *port, int nbq)
++{
++      switch (port->id) {
++      case AIROHA_GDM3_IDX:
++              if (nbq == 4)
++                      return XSI_PCIE0_VIP_PORT_MASK;
++              if (nbq == 5)
++                      return XSI_PCIE1_VIP_PORT_MASK;
++              break;
++      case AIROHA_GDM4_IDX:
++              if (!nbq)
++                      return XSI_ETH_VIP_PORT_MASK;
++              if (nbq == 1)
++                      return XSI_USB_VIP_PORT_MASK;
++              break;
++      default:
++              break;
++      }
++
++      return 0;
++}
++
+ static const char * const an7583_xsi_rsts_names[] = {
+       "xsi-mac",
+       "hsi0-mac",
+@@ -3187,6 +3197,26 @@ static int airoha_an7583_get_src_port_id
+       return -EINVAL;
+ }
++static u32 airoha_an7583_get_vip_port(struct airoha_gdm_port *port, int nbq)
++{
++      switch (port->id) {
++      case AIROHA_GDM3_IDX:
++              if (!nbq)
++                      return XSI_ETH_VIP_PORT_MASK;
++              break;
++      case AIROHA_GDM4_IDX:
++              if (!nbq)
++                      return XSI_PCIE0_VIP_PORT_MASK;
++              if (nbq == 1)
++                      return XSI_USB_VIP_PORT_MASK;
++              break;
++      default:
++              break;
++      }
++
++      return 0;
++}
++
+ static const struct airoha_eth_soc_data en7581_soc_data = {
+       .version = 0x7581,
+       .xsi_rsts_names = en7581_xsi_rsts_names,
+@@ -3194,6 +3224,7 @@ static const struct airoha_eth_soc_data
+       .num_ppe = 2,
+       .ops = {
+               .get_src_port_id = airoha_en7581_get_src_port_id,
++              .get_vip_port = airoha_en7581_get_vip_port,
+       },
+ };
+@@ -3204,6 +3235,7 @@ static const struct airoha_eth_soc_data
+       .num_ppe = 1,
+       .ops = {
+               .get_src_port_id = airoha_an7583_get_src_port_id,
++              .get_vip_port = airoha_an7583_get_vip_port,
+       },
+ };
+--- a/drivers/net/ethernet/airoha/airoha_eth.h
++++ b/drivers/net/ethernet/airoha/airoha_eth.h
+@@ -537,6 +537,7 @@ struct airoha_gdm_port {
+       struct airoha_eth *eth;
+       struct net_device *dev;
+       int id;
++      int nbq;
+       struct airoha_hw_stats stats;
+@@ -577,6 +578,7 @@ struct airoha_eth_soc_data {
+       int num_ppe;
+       struct {
+               int (*get_src_port_id)(struct airoha_gdm_port *port, int nbq);
++              u32 (*get_vip_port)(struct airoha_gdm_port *port, int nbq);
+       } ops;
+ };
diff --git a/target/linux/airoha/patches-6.12/142-01-v7.1-net-airoha-Rely-on-net_device-pointer-in-airoha_dev_.patch b/target/linux/airoha/patches-6.12/142-01-v7.1-net-airoha-Rely-on-net_device-pointer-in-airoha_dev_.patch
new file mode 100644 (file)
index 0000000..d09272a
--- /dev/null
@@ -0,0 +1,64 @@
+From 360d745a5319f09849a94dee0974c8ead721e392 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Sun, 12 Apr 2026 19:13:12 +0200
+Subject: [PATCH 1/4] net: airoha: Rely on net_device pointer in
+ airoha_dev_setup_tc_block signature
+
+Remove airoha_gdm_port dependency in airoha_dev_setup_tc_block routine
+signature and rely on net_device pointer instead. Please note this patch
+does not introduce any logical change and it is a preliminary patch to
+support multiple net_devices connected to the GDM3 or GDM4 ports 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/20260412-airoha-multi-serdes-preliminary-patch-v1-1-08d5b670ca8f@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -2683,7 +2683,7 @@ static int airoha_dev_setup_tc_block_cb(
+       }
+ }
+-static int airoha_dev_setup_tc_block(struct airoha_gdm_port *port,
++static int airoha_dev_setup_tc_block(struct net_device *dev,
+                                    struct flow_block_offload *f)
+ {
+       flow_setup_cb_t *cb = airoha_dev_setup_tc_block_cb;
+@@ -2696,12 +2696,12 @@ static int airoha_dev_setup_tc_block(str
+       f->driver_block_list = &block_cb_list;
+       switch (f->command) {
+       case FLOW_BLOCK_BIND:
+-              block_cb = flow_block_cb_lookup(f->block, cb, port->dev);
++              block_cb = flow_block_cb_lookup(f->block, cb, dev);
+               if (block_cb) {
+                       flow_block_cb_incref(block_cb);
+                       return 0;
+               }
+-              block_cb = flow_block_cb_alloc(cb, port->dev, port->dev, NULL);
++              block_cb = flow_block_cb_alloc(cb, dev, dev, NULL);
+               if (IS_ERR(block_cb))
+                       return PTR_ERR(block_cb);
+@@ -2710,7 +2710,7 @@ static int airoha_dev_setup_tc_block(str
+               list_add_tail(&block_cb->driver_list, &block_cb_list);
+               return 0;
+       case FLOW_BLOCK_UNBIND:
+-              block_cb = flow_block_cb_lookup(f->block, cb, port->dev);
++              block_cb = flow_block_cb_lookup(f->block, cb, dev);
+               if (!block_cb)
+                       return -ENOENT;
+@@ -2809,7 +2809,7 @@ static int airoha_dev_tc_setup(struct ne
+               return airoha_tc_setup_qdisc_htb(port, type_data);
+       case TC_SETUP_BLOCK:
+       case TC_SETUP_FT:
+-              return airoha_dev_setup_tc_block(port, type_data);
++              return airoha_dev_setup_tc_block(dev, type_data);
+       default:
+               return -EOPNOTSUPP;
+       }
diff --git a/target/linux/airoha/patches-6.12/142-02-v7.1-net-airoha-Rely-on-net_device-pointer-in-HTB-callbac.patch b/target/linux/airoha/patches-6.12/142-02-v7.1-net-airoha-Rely-on-net_device-pointer-in-HTB-callbac.patch
new file mode 100644 (file)
index 0000000..76651db
--- /dev/null
@@ -0,0 +1,163 @@
+From 8baf4bf72ef94c955ef89d4644f1986603ee8320 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Sun, 12 Apr 2026 19:13:13 +0200
+Subject: [PATCH 2/4] net: airoha: Rely on net_device pointer in HTB callbacks
+
+Remove airoha_gdm_port dependency in HTB tc callback signatures and rely
+on net_device pointer instead. Please note this patch does not introduce
+any logical change and it is a preliminary patch in order to support
+multiple net_devices connected to the same GDM3 or GDM4 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/20260412-airoha-multi-serdes-preliminary-patch-v1-2-08d5b670ca8f@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 45 +++++++++++++-----------
+ 1 file changed, 24 insertions(+), 21 deletions(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -2488,10 +2488,11 @@ static int airoha_qdma_set_trtcm_token_b
+                                          mode, val);
+ }
+-static int airoha_qdma_set_tx_rate_limit(struct airoha_gdm_port *port,
++static int airoha_qdma_set_tx_rate_limit(struct net_device *dev,
+                                        int channel, u32 rate,
+                                        u32 bucket_size)
+ {
++      struct airoha_gdm_port *port = netdev_priv(dev);
+       int i, err;
+       for (i = 0; i <= TRTCM_PEAK_MODE; i++) {
+@@ -2511,21 +2512,20 @@ static int airoha_qdma_set_tx_rate_limit
+       return 0;
+ }
+-static int airoha_tc_htb_alloc_leaf_queue(struct airoha_gdm_port *port,
++static int airoha_tc_htb_alloc_leaf_queue(struct net_device *dev,
+                                         struct tc_htb_qopt_offload *opt)
+ {
+       u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
+       u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */
+-      struct net_device *dev = port->dev;
+-      int num_tx_queues = dev->real_num_tx_queues;
+-      int err;
++      int err, num_tx_queues = dev->real_num_tx_queues;
++      struct airoha_gdm_port *port = netdev_priv(dev);
+       if (opt->parent_classid != TC_HTB_CLASSID_ROOT) {
+               NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid");
+               return -EINVAL;
+       }
+-      err = airoha_qdma_set_tx_rate_limit(port, 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");
+@@ -2537,7 +2537,7 @@ static int airoha_tc_htb_alloc_leaf_queu
+       err = netif_set_real_num_tx_queues(dev, num_tx_queues + 1);
+       if (err) {
+-              airoha_qdma_set_tx_rate_limit(port, channel, 0, opt->quantum);
++              airoha_qdma_set_tx_rate_limit(dev, channel, 0, opt->quantum);
+               NL_SET_ERR_MSG_MOD(opt->extack,
+                                  "failed setting real_num_tx_queues");
+               return err;
+@@ -2724,44 +2724,47 @@ static int airoha_dev_setup_tc_block(str
+       }
+ }
+-static void airoha_tc_remove_htb_queue(struct airoha_gdm_port *port, int queue)
++static void airoha_tc_remove_htb_queue(struct net_device *dev, int queue)
+ {
+-      struct net_device *dev = port->dev;
++      struct airoha_gdm_port *port = netdev_priv(dev);
+       netif_set_real_num_tx_queues(dev, dev->real_num_tx_queues - 1);
+-      airoha_qdma_set_tx_rate_limit(port, queue + 1, 0, 0);
++      airoha_qdma_set_tx_rate_limit(dev, queue + 1, 0, 0);
+       clear_bit(queue, port->qos_sq_bmap);
+ }
+-static int airoha_tc_htb_delete_leaf_queue(struct airoha_gdm_port *port,
++static int airoha_tc_htb_delete_leaf_queue(struct net_device *dev,
+                                          struct tc_htb_qopt_offload *opt)
+ {
+       u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
++      struct airoha_gdm_port *port = netdev_priv(dev);
+       if (!test_bit(channel, port->qos_sq_bmap)) {
+               NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
+               return -EINVAL;
+       }
+-      airoha_tc_remove_htb_queue(port, channel);
++      airoha_tc_remove_htb_queue(dev, channel);
+       return 0;
+ }
+-static int airoha_tc_htb_destroy(struct airoha_gdm_port *port)
++static int airoha_tc_htb_destroy(struct net_device *dev)
+ {
++      struct airoha_gdm_port *port = netdev_priv(dev);
+       int q;
+       for_each_set_bit(q, port->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS)
+-              airoha_tc_remove_htb_queue(port, q);
++              airoha_tc_remove_htb_queue(dev, q);
+       return 0;
+ }
+-static int airoha_tc_get_htb_get_leaf_queue(struct airoha_gdm_port *port,
++static int airoha_tc_get_htb_get_leaf_queue(struct net_device *dev,
+                                           struct tc_htb_qopt_offload *opt)
+ {
+       u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
++      struct airoha_gdm_port *port = netdev_priv(dev);
+       if (!test_bit(channel, port->qos_sq_bmap)) {
+               NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
+@@ -2773,23 +2776,23 @@ static int airoha_tc_get_htb_get_leaf_qu
+       return 0;
+ }
+-static int airoha_tc_setup_qdisc_htb(struct airoha_gdm_port *port,
++static int airoha_tc_setup_qdisc_htb(struct net_device *dev,
+                                    struct tc_htb_qopt_offload *opt)
+ {
+       switch (opt->command) {
+       case TC_HTB_CREATE:
+               break;
+       case TC_HTB_DESTROY:
+-              return airoha_tc_htb_destroy(port);
++              return airoha_tc_htb_destroy(dev);
+       case TC_HTB_NODE_MODIFY:
+       case TC_HTB_LEAF_ALLOC_QUEUE:
+-              return airoha_tc_htb_alloc_leaf_queue(port, opt);
++              return airoha_tc_htb_alloc_leaf_queue(dev, opt);
+       case TC_HTB_LEAF_DEL:
+       case TC_HTB_LEAF_DEL_LAST:
+       case TC_HTB_LEAF_DEL_LAST_FORCE:
+-              return airoha_tc_htb_delete_leaf_queue(port, opt);
++              return airoha_tc_htb_delete_leaf_queue(dev, opt);
+       case TC_HTB_LEAF_QUERY_QUEUE:
+-              return airoha_tc_get_htb_get_leaf_queue(port, opt);
++              return airoha_tc_get_htb_get_leaf_queue(dev, opt);
+       default:
+               return -EOPNOTSUPP;
+       }
+@@ -2806,7 +2809,7 @@ static int airoha_dev_tc_setup(struct ne
+       case TC_SETUP_QDISC_ETS:
+               return airoha_tc_setup_qdisc_ets(port, type_data);
+       case TC_SETUP_QDISC_HTB:
+-              return airoha_tc_setup_qdisc_htb(port, type_data);
++              return airoha_tc_setup_qdisc_htb(dev, type_data);
+       case TC_SETUP_BLOCK:
+       case TC_SETUP_FT:
+               return airoha_dev_setup_tc_block(dev, type_data);
diff --git a/target/linux/airoha/patches-6.12/142-03-v7.1-net-airoha-Rely-on-net_device-pointer-in-ETS-callbac.patch b/target/linux/airoha/patches-6.12/142-03-v7.1-net-airoha-Rely-on-net_device-pointer-in-ETS-callbac.patch
new file mode 100644 (file)
index 0000000..a8b1571
--- /dev/null
@@ -0,0 +1,118 @@
+From ae32f80018f0f0f4ebc7a0a70d4092d08a1545e8 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Sun, 12 Apr 2026 19:13:14 +0200
+Subject: [PATCH 3/4] net: airoha: Rely on net_device pointer in ETS callbacks
+
+Remove airoha_gdm_port dependency in ETS tc callback signatures and rely
+on net_device pointer instead. Please note this patch does not introduce
+any logical change and it is a preliminary patch in order to support
+multiple net_devices connected to the same GDM3 or GDM4 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/20260412-airoha-multi-serdes-preliminary-patch-v1-3-08d5b670ca8f@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 30 +++++++++++-------------
+ 1 file changed, 14 insertions(+), 16 deletions(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -2134,10 +2134,11 @@ airoha_ethtool_get_rmon_stats(struct net
+       } while (u64_stats_fetch_retry(&port->stats.syncp, start));
+ }
+-static int airoha_qdma_set_chan_tx_sched(struct airoha_gdm_port *port,
++static int airoha_qdma_set_chan_tx_sched(struct net_device *dev,
+                                        int channel, enum tx_sched_mode mode,
+                                        const u16 *weights, u8 n_weights)
+ {
++      struct airoha_gdm_port *port = netdev_priv(dev);
+       int i;
+       for (i = 0; i < AIROHA_NUM_TX_RING; i++)
+@@ -2169,17 +2170,15 @@ static int airoha_qdma_set_chan_tx_sched
+       return 0;
+ }
+-static int airoha_qdma_set_tx_prio_sched(struct airoha_gdm_port *port,
+-                                       int channel)
++static int airoha_qdma_set_tx_prio_sched(struct net_device *dev, int channel)
+ {
+       static const u16 w[AIROHA_NUM_QOS_QUEUES] = {};
+-      return airoha_qdma_set_chan_tx_sched(port, channel, TC_SCH_SP, w,
++      return airoha_qdma_set_chan_tx_sched(dev, channel, TC_SCH_SP, w,
+                                            ARRAY_SIZE(w));
+ }
+-static int airoha_qdma_set_tx_ets_sched(struct airoha_gdm_port *port,
+-                                      int channel,
++static int airoha_qdma_set_tx_ets_sched(struct net_device *dev, int channel,
+                                       struct tc_ets_qopt_offload *opt)
+ {
+       struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params;
+@@ -2220,20 +2219,21 @@ static int airoha_qdma_set_tx_ets_sched(
+       else if (nstrict < AIROHA_NUM_QOS_QUEUES - 1)
+               mode = nstrict + 1;
+-      return airoha_qdma_set_chan_tx_sched(port, channel, mode, w,
++      return airoha_qdma_set_chan_tx_sched(dev, channel, mode, w,
+                                            ARRAY_SIZE(w));
+ }
+-static int airoha_qdma_get_tx_ets_stats(struct airoha_gdm_port *port,
+-                                      int channel,
++static int airoha_qdma_get_tx_ets_stats(struct net_device *dev, int channel,
+                                       struct tc_ets_qopt_offload *opt)
+ {
++      struct airoha_gdm_port *port = netdev_priv(dev);
+       u64 cpu_tx_packets = airoha_qdma_rr(port->qdma,
+                                           REG_CNTR_VAL(channel << 1));
+       u64 fwd_tx_packets = airoha_qdma_rr(port->qdma,
+                                           REG_CNTR_VAL((channel << 1) + 1));
+       u64 tx_packets = (cpu_tx_packets - port->cpu_tx_packets) +
+                        (fwd_tx_packets - port->fwd_tx_packets);
++
+       _bstats_update(opt->stats.bstats, 0, tx_packets);
+       port->cpu_tx_packets = cpu_tx_packets;
+@@ -2242,7 +2242,7 @@ static int airoha_qdma_get_tx_ets_stats(
+       return 0;
+ }
+-static int airoha_tc_setup_qdisc_ets(struct airoha_gdm_port *port,
++static int airoha_tc_setup_qdisc_ets(struct net_device *dev,
+                                    struct tc_ets_qopt_offload *opt)
+ {
+       int channel;
+@@ -2255,12 +2255,12 @@ static int airoha_tc_setup_qdisc_ets(str
+       switch (opt->command) {
+       case TC_ETS_REPLACE:
+-              return airoha_qdma_set_tx_ets_sched(port, channel, opt);
++              return airoha_qdma_set_tx_ets_sched(dev, channel, opt);
+       case TC_ETS_DESTROY:
+               /* PRIO is default qdisc scheduler */
+-              return airoha_qdma_set_tx_prio_sched(port, channel);
++              return airoha_qdma_set_tx_prio_sched(dev, channel);
+       case TC_ETS_STATS:
+-              return airoha_qdma_get_tx_ets_stats(port, channel, opt);
++              return airoha_qdma_get_tx_ets_stats(dev, channel, opt);
+       default:
+               return -EOPNOTSUPP;
+       }
+@@ -2803,11 +2803,9 @@ static int airoha_tc_setup_qdisc_htb(str
+ static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type,
+                              void *type_data)
+ {
+-      struct airoha_gdm_port *port = netdev_priv(dev);
+-
+       switch (type) {
+       case TC_SETUP_QDISC_ETS:
+-              return airoha_tc_setup_qdisc_ets(port, type_data);
++              return airoha_tc_setup_qdisc_ets(dev, type_data);
+       case TC_SETUP_QDISC_HTB:
+               return airoha_tc_setup_qdisc_htb(dev, type_data);
+       case TC_SETUP_BLOCK:
diff --git a/target/linux/airoha/patches-6.12/142-04-v7.1-net-airoha-Remove-PCE_MC_EN_MASK-bit-in-REG_FE_PCE_C.patch b/target/linux/airoha/patches-6.12/142-04-v7.1-net-airoha-Remove-PCE_MC_EN_MASK-bit-in-REG_FE_PCE_C.patch
new file mode 100644 (file)
index 0000000..3067915
--- /dev/null
@@ -0,0 +1,33 @@
+From 34e1a98ff2a87cf4b8de3ccebe9d45273f014aeb Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Sun, 12 Apr 2026 11:56:25 +0200
+Subject: [PATCH 4/4] net: airoha: Remove PCE_MC_EN_MASK bit in REG_FE_PCE_CFG
+ configuration
+
+PCE_MC_EN_MASK bit in REG_FE_PCE_CFG configuration performed in
+airoha_fe_init() is used to duplicate multicast packets and send a copy
+to the CPU when the traffic is offloaded. This is necessary just if
+it is requested by the user. Disable multicast packets duplication by
+default.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20260412-airoha_fe_init_remove_mc_en_bit-v1-1-7b6a5a25a74d@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -448,9 +448,8 @@ static int airoha_fe_init(struct airoha_
+                     FIELD_PREP(PSE_IQ_RES2_P5_MASK, 0x40) |
+                     FIELD_PREP(PSE_IQ_RES2_P4_MASK, 0x34));
+-      /* enable FE copy engine for MC/KA/DPI */
+-      airoha_fe_wr(eth, REG_FE_PCE_CFG,
+-                   PCE_DPI_EN_MASK | PCE_KA_EN_MASK | PCE_MC_EN_MASK);
++      /* enable FE copy engine for KA/DPI */
++      airoha_fe_wr(eth, REG_FE_PCE_CFG, PCE_DPI_EN_MASK | PCE_KA_EN_MASK);
+       /* set vip queue selection to ring 1 */
+       airoha_fe_rmw(eth, REG_CDM_FWD_CFG(1), CDM_VIP_QSEL_MASK,
+                     FIELD_PREP(CDM_VIP_QSEL_MASK, 0x4));
index 7c7f51e5ccd54d671d58949fbbebae8f382b7885..fa1c9e56690f960054a2d0f81fe3ef82d5b8c8b0 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
-@@ -1425,6 +1425,10 @@ static int airoha_hw_init(struct platfor
+@@ -1422,6 +1422,10 @@ static int airoha_hw_init(struct platfor
        if (err)
                return err;
  
index 2407246861ac363feb5312e448bbf667e996cc2a..069faaaf15d1ba16132942d07b9ef9c1622e5757 100644 (file)
@@ -16,7 +16,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
-@@ -588,8 +588,11 @@ static int airoha_qdma_get_gdm_port(stru
+@@ -577,8 +577,11 @@ static int airoha_qdma_get_gdm_port(stru
  
        sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1);
        switch (sport) {
index 8c2718334dea958756faff6b7acdf3f8d9459fd1..7c4d4b17d50f6f7c615d65aef5925f9a7be77606 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
-@@ -514,8 +514,10 @@ static int airoha_fe_init(struct airoha_
+@@ -503,8 +503,10 @@ static int airoha_fe_init(struct airoha_
                      FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) |
                      FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22));
  
@@ -28,7 +28,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
  
        airoha_fe_crsn_qsel_init(eth);
  
-@@ -1657,7 +1659,8 @@ static int airoha_dev_open(struct net_de
+@@ -1654,7 +1656,8 @@ static int airoha_dev_open(struct net_de
        if (err)
                return err;
  
index 166c1efd266ff80daa1d7e2cdecd066b9c6185cb..f5f1d06137a97e1dea07f22cb049891f5a9586b8 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
-@@ -3127,7 +3127,6 @@ static void airoha_remove(struct platfor
+@@ -3125,7 +3125,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",
-@@ -3159,7 +3158,6 @@ static int airoha_en7581_get_src_port_id
+@@ -3179,7 +3178,6 @@ static u32 airoha_en7581_get_vip_port(st
  }
  
  static const char * const an7583_xsi_rsts_names[] = {
index ed12c5684a5503a64426165b25b9d3e7062c85ff..035311cda18b3ded8ca59e8d92eca2cc957beedf 100644 (file)
@@ -35,7 +35,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
  static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
  {
        struct airoha_eth *eth = port->qdma->eth;
-@@ -1654,6 +1660,17 @@ static int airoha_dev_open(struct net_de
+@@ -1651,6 +1657,17 @@ static int airoha_dev_open(struct net_de
        struct airoha_qdma *qdma = port->qdma;
        u32 pse_port = FE_PSE_PORT_PPE1;
  
@@ -53,7 +53,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
        netif_tx_start_all_queues(dev);
        err = airoha_set_vip_for_gdm_port(port, true);
        if (err)
-@@ -1718,6 +1735,11 @@ static int airoha_dev_stop(struct net_de
+@@ -1715,6 +1732,11 @@ static int airoha_dev_stop(struct net_de
                }
        }
  
@@ -65,7 +65,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
        return 0;
  }
  
-@@ -2849,6 +2871,20 @@ static const struct ethtool_ops airoha_e
+@@ -2845,6 +2867,20 @@ static const struct ethtool_ops airoha_e
        .get_link               = ethtool_op_get_link,
  };
  
@@ -86,7 +86,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
  static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port)
  {
        int i;
-@@ -2893,6 +2929,99 @@ bool airoha_is_valid_gdm_port(struct air
+@@ -2889,6 +2925,99 @@ bool airoha_is_valid_gdm_port(struct air
        return false;
  }
  
@@ -186,8 +186,8 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
  static int airoha_alloc_gdm_port(struct airoha_eth *eth,
                                 struct device_node *np)
  {
-@@ -2964,6 +3093,12 @@ static int airoha_alloc_gdm_port(struct
-       port->id = id;
+@@ -2962,6 +3091,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)) {
@@ -199,7 +199,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
        return airoha_metadata_dst_alloc(port);
  }
  
-@@ -3093,6 +3228,10 @@ error_napi_stop:
+@@ -3091,6 +3226,10 @@ error_napi_stop:
  
                if (port->dev->reg_state == NETREG_REGISTERED)
                        unregister_netdev(port->dev);
@@ -210,7 +210,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
                airoha_metadata_dst_free(port);
        }
        airoha_hw_cleanup(eth);
-@@ -3119,6 +3258,10 @@ static void airoha_remove(struct platfor
+@@ -3117,6 +3256,10 @@ static void airoha_remove(struct platfor
  
                unregister_netdev(port->dev);
                airoha_metadata_dst_free(port);
@@ -223,9 +223,9 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
  
 --- a/drivers/net/ethernet/airoha/airoha_eth.h
 +++ b/drivers/net/ethernet/airoha/airoha_eth.h
-@@ -538,6 +538,10 @@ struct airoha_gdm_port {
-       struct net_device *dev;
+@@ -539,6 +539,10 @@ struct airoha_gdm_port {
        int id;
+       int nbq;
  
 +      struct phylink *phylink;
 +      struct phylink_config phylink_config;
index db0e9b4f48aedc59dab2cad9a2dd5f6cfbc701b5..05e219a97f5b14f31e05d01edcb70f4fbe520a8b 100644 (file)
@@ -14,7 +14,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
-@@ -599,6 +599,9 @@ static int airoha_qdma_get_gdm_port(stru
+@@ -588,6 +588,9 @@ static int airoha_qdma_get_gdm_port(stru
        case 0x18:
                port = 3; /* GDM4 */
                break;
index b3897784dd4b689be706c573ea79f9b69f10eb72..5bed5930496d3ab941431f2837a370b033c30a10 100644 (file)
@@ -28,7 +28,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
  
  static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
  {
-@@ -1663,6 +1665,7 @@ static int airoha_dev_open(struct net_de
+@@ -1660,6 +1662,7 @@ static int airoha_dev_open(struct net_de
        struct airoha_qdma *qdma = port->qdma;
        u32 pse_port = FE_PSE_PORT_PPE1;
  
@@ -36,7 +36,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
        if (airhoa_is_phy_external(port)) {
                err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0);
                if (err) {
-@@ -1673,6 +1676,7 @@ static int airoha_dev_open(struct net_de
+@@ -1670,6 +1673,7 @@ static int airoha_dev_open(struct net_de
  
                phylink_start(port->phylink);
        }
@@ -44,7 +44,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
  
        netif_tx_start_all_queues(dev);
        err = airoha_set_vip_for_gdm_port(port, true);
-@@ -1738,10 +1742,12 @@ static int airoha_dev_stop(struct net_de
+@@ -1735,10 +1739,12 @@ static int airoha_dev_stop(struct net_de
                }
        }
  
@@ -57,7 +57,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
  
        return 0;
  }
-@@ -2874,6 +2880,7 @@ static const struct ethtool_ops airoha_e
+@@ -2870,6 +2876,7 @@ static const struct ethtool_ops airoha_e
        .get_link               = ethtool_op_get_link,
  };
  
@@ -65,7 +65,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
  static struct phylink_pcs *airoha_phylink_mac_select_pcs(struct phylink_config *config,
                                                         phy_interface_t interface)
  {
-@@ -2887,6 +2894,7 @@ static void airoha_mac_config(struct phy
+@@ -2883,6 +2890,7 @@ static void airoha_mac_config(struct phy
                              const struct phylink_link_state *state)
  {
  }
@@ -73,7 +73,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
  
  static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port)
  {
-@@ -2932,6 +2940,7 @@ bool airoha_is_valid_gdm_port(struct air
+@@ -2928,6 +2936,7 @@ bool airoha_is_valid_gdm_port(struct air
        return false;
  }
  
@@ -81,7 +81,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
  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)
-@@ -3024,6 +3033,7 @@ static int airoha_setup_phylink(struct n
+@@ -3020,6 +3029,7 @@ static int airoha_setup_phylink(struct n
  
        return 0;
  }
@@ -89,8 +89,8 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
  
  static int airoha_alloc_gdm_port(struct airoha_eth *eth,
                                 struct device_node *np)
-@@ -3096,11 +3106,13 @@ static int airoha_alloc_gdm_port(struct
-       port->id = id;
+@@ -3094,11 +3104,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)
@@ -103,7 +103,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
  
        return airoha_metadata_dst_alloc(port);
  }
-@@ -3231,10 +3243,12 @@ error_napi_stop:
+@@ -3229,10 +3241,12 @@ error_napi_stop:
  
                if (port->dev->reg_state == NETREG_REGISTERED)
                        unregister_netdev(port->dev);
@@ -116,7 +116,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
                airoha_metadata_dst_free(port);
        }
        airoha_hw_cleanup(eth);
-@@ -3261,10 +3275,12 @@ static void airoha_remove(struct platfor
+@@ -3259,10 +3273,12 @@ static void airoha_remove(struct platfor
  
                unregister_netdev(port->dev);
                airoha_metadata_dst_free(port);
@@ -131,9 +131,9 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
  
 --- a/drivers/net/ethernet/airoha/airoha_eth.h
 +++ b/drivers/net/ethernet/airoha/airoha_eth.h
-@@ -538,9 +538,11 @@ struct airoha_gdm_port {
-       struct net_device *dev;
+@@ -539,9 +539,11 @@ struct airoha_gdm_port {
        int id;
+       int nbq;
  
 +#if defined(CONFIG_PCS_AIROHA)
        struct phylink *phylink;