]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
kernel: improve mtk_eth_soc performance
authorFelix Fietkau <nbd@nbd.name>
Mon, 14 Jul 2025 09:55:10 +0000 (11:55 +0200)
committerFelix Fietkau <nbd@nbd.name>
Tue, 9 Sep 2025 04:33:56 +0000 (06:33 +0200)
- shrink data structures
- avoid unnecessary divisions
- support GSO fraglist on tx

Reapply with fixed patch

Signed-off-by: Felix Fietkau <nbd@nbd.name>
22 files changed:
target/linux/generic/hack-6.12/730-net-ethernet-mtk_eth_soc-add-hw-dump-for-forced-rese.patch
target/linux/generic/hack-6.6/730-net-ethernet-mtk_eth_soc-add-hw-dump-for-forced-rese.patch
target/linux/generic/pending-6.12/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch [deleted file]
target/linux/generic/pending-6.12/732-03-net-ethernet-mtk_eth_soc-optimize-dma-ring-address-i.patch [new file with mode: 0644]
target/linux/generic/pending-6.12/732-04-net-ethernet-mtk_eth_soc-shrink-struct-mtk_tx_buf.patch [new file with mode: 0644]
target/linux/generic/pending-6.12/732-05-net-ethernet-mtk_eth_soc-add-support-for-sending-fra.patch [new file with mode: 0644]
target/linux/generic/pending-6.12/733-01-net-ethernet-mtk_eth_soc-use-napi_build_skb.patch
target/linux/generic/pending-6.12/734-net-ethernet-mediatek-enlarge-DMA-reserve-buffer.patch
target/linux/generic/pending-6.12/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch
target/linux/generic/pending-6.12/738-01-net-ethernet-mtk_eth_soc-reduce-rx-ring-size-for-older.patch
target/linux/generic/pending-6.12/738-02-net-ethernet-mtk_eth_soc-do-not-enable-page-pool-sta.patch
target/linux/generic/pending-6.12/742-net-ethernet-mtk_eth_soc-fix-tx-vlan-tag-for-llc-pac.patch
target/linux/generic/pending-6.6/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch [deleted file]
target/linux/generic/pending-6.6/732-03-net-ethernet-mtk_eth_soc-optimize-dma-ring-address-i.patch [new file with mode: 0644]
target/linux/generic/pending-6.6/732-04-net-ethernet-mtk_eth_soc-shrink-struct-mtk_tx_buf.patch [new file with mode: 0644]
target/linux/generic/pending-6.6/732-05-net-ethernet-mtk_eth_soc-add-support-for-sending-fra.patch [new file with mode: 0644]
target/linux/generic/pending-6.6/733-01-net-ethernet-mtk_eth_soc-use-napi_build_skb.patch
target/linux/generic/pending-6.6/734-net-ethernet-mediatek-enlarge-DMA-reserve-buffer.patch
target/linux/generic/pending-6.6/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch
target/linux/generic/pending-6.6/738-01-net-ethernet-mtk_eth_soc-reduce-rx-ring-size-for-older.patch
target/linux/generic/pending-6.6/738-02-net-ethernet-mtk_eth_soc-do-not-enable-page-pool-sta.patch
target/linux/generic/pending-6.6/742-net-ethernet-mtk_eth_soc-fix-tx-vlan-tag-for-llc-pac.patch

index ffc21ee2ff7345b9c3d2a521429a0ca6eb14b0c7..2244531b6c7828093ed9ab61bf940cc5901eefdb 100644 (file)
@@ -13,7 +13,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -66,6 +66,7 @@ static const struct mtk_reg_map mtk_reg_
+@@ -74,6 +74,7 @@ static const struct mtk_reg_map mtk_reg_
                .rx_ptr         = 0x1900,
                .rx_cnt_cfg     = 0x1904,
                .qcrx_ptr       = 0x1908,
@@ -21,7 +21,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
                .glo_cfg        = 0x1a04,
                .rst_idx        = 0x1a08,
                .delay_irq      = 0x1a0c,
-@@ -132,6 +133,7 @@ static const struct mtk_reg_map mt7986_r
+@@ -140,6 +141,7 @@ static const struct mtk_reg_map mt7986_r
                .rx_ptr         = 0x4500,
                .rx_cnt_cfg     = 0x4504,
                .qcrx_ptr       = 0x4508,
@@ -29,7 +29,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
                .glo_cfg        = 0x4604,
                .rst_idx        = 0x4608,
                .delay_irq      = 0x460c,
-@@ -183,6 +185,7 @@ static const struct mtk_reg_map mt7988_r
+@@ -191,6 +193,7 @@ static const struct mtk_reg_map mt7988_r
                .rx_ptr         = 0x4500,
                .rx_cnt_cfg     = 0x4504,
                .qcrx_ptr       = 0x4508,
@@ -37,7 +37,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
                .glo_cfg        = 0x4604,
                .rst_idx        = 0x4608,
                .delay_irq      = 0x460c,
-@@ -3909,6 +3912,56 @@ static void mtk_set_mcr_max_rx(struct mt
+@@ -4050,6 +4053,56 @@ static void mtk_set_mcr_max_rx(struct mt
                mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
  }
  
@@ -94,7 +94,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
  static void mtk_hw_reset(struct mtk_eth *eth)
  {
        u32 val;
-@@ -4388,6 +4441,8 @@ static void mtk_pending_work(struct work
+@@ -4529,6 +4582,8 @@ static void mtk_pending_work(struct work
        rtnl_lock();
        set_bit(MTK_RESETTING, &eth->state);
  
@@ -105,7 +105,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
        /* Run again reset preliminary configuration in order to avoid any
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1191,6 +1191,7 @@ struct mtk_reg_map {
+@@ -1185,6 +1185,7 @@ struct mtk_reg_map {
                u32     rx_ptr;         /* rx base pointer */
                u32     rx_cnt_cfg;     /* rx max count configuration */
                u32     qcrx_ptr;       /* rx cpu pointer */
index 25d824bce67f811298af28623479abc46cc9f2db..f6d6574ded4953c3d6b2d8cca72e1f4978dd5346 100644 (file)
@@ -13,7 +13,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -66,6 +66,7 @@ static const struct mtk_reg_map mtk_reg_
+@@ -71,6 +71,7 @@ static const struct mtk_reg_map mtk_reg_
                .rx_ptr         = 0x1900,
                .rx_cnt_cfg     = 0x1904,
                .qcrx_ptr       = 0x1908,
@@ -21,7 +21,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
                .glo_cfg        = 0x1a04,
                .rst_idx        = 0x1a08,
                .delay_irq      = 0x1a0c,
-@@ -132,6 +133,7 @@ static const struct mtk_reg_map mt7986_r
+@@ -137,6 +138,7 @@ static const struct mtk_reg_map mt7986_r
                .rx_ptr         = 0x4500,
                .rx_cnt_cfg     = 0x4504,
                .qcrx_ptr       = 0x4508,
@@ -29,7 +29,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
                .glo_cfg        = 0x4604,
                .rst_idx        = 0x4608,
                .delay_irq      = 0x460c,
-@@ -183,6 +185,7 @@ static const struct mtk_reg_map mt7988_r
+@@ -188,6 +190,7 @@ static const struct mtk_reg_map mt7988_r
                .rx_ptr         = 0x4500,
                .rx_cnt_cfg     = 0x4504,
                .qcrx_ptr       = 0x4508,
@@ -37,7 +37,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
                .glo_cfg        = 0x4604,
                .rst_idx        = 0x4608,
                .delay_irq      = 0x460c,
-@@ -3907,6 +3910,56 @@ static void mtk_set_mcr_max_rx(struct mt
+@@ -3935,6 +3938,56 @@ static void mtk_set_mcr_max_rx(struct mt
                mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
  }
  
@@ -94,7 +94,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
  static void mtk_hw_reset(struct mtk_eth *eth)
  {
        u32 val;
-@@ -4382,6 +4435,8 @@ static void mtk_pending_work(struct work
+@@ -4410,6 +4463,8 @@ static void mtk_pending_work(struct work
        rtnl_lock();
        set_bit(MTK_RESETTING, &eth->state);
  
@@ -105,7 +105,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
        /* Run again reset preliminary configuration in order to avoid any
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1191,6 +1191,7 @@ struct mtk_reg_map {
+@@ -1185,6 +1185,7 @@ struct mtk_reg_map {
                u32     rx_ptr;         /* rx base pointer */
                u32     rx_cnt_cfg;     /* rx max count configuration */
                u32     qcrx_ptr;       /* rx cpu pointer */
diff --git a/target/linux/generic/pending-6.12/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch b/target/linux/generic/pending-6.12/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch
deleted file mode 100644 (file)
index bd7a1b9..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 28 Oct 2022 12:54:48 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: set NETIF_F_ALL_TSO
-
-Significantly improves performance by avoiding unnecessary segmentation
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -49,8 +49,7 @@
- #define MTK_HW_FEATURES               (NETIF_F_IP_CSUM | \
-                                NETIF_F_RXCSUM | \
-                                NETIF_F_HW_VLAN_CTAG_TX | \
--                               NETIF_F_SG | NETIF_F_TSO | \
--                               NETIF_F_TSO6 | \
-+                               NETIF_F_SG | NETIF_F_ALL_TSO | \
-                                NETIF_F_IPV6_CSUM |\
-                                NETIF_F_HW_TC)
- #define MTK_HW_FEATURES_MT7628        (NETIF_F_SG | NETIF_F_RXCSUM)
diff --git a/target/linux/generic/pending-6.12/732-03-net-ethernet-mtk_eth_soc-optimize-dma-ring-address-i.patch b/target/linux/generic/pending-6.12/732-03-net-ethernet-mtk_eth_soc-optimize-dma-ring-address-i.patch
new file mode 100644 (file)
index 0000000..c7cf329
--- /dev/null
@@ -0,0 +1,486 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Tue, 15 Oct 2024 12:52:56 +0200
+Subject: [PATCH] net: ethernet: mtk_eth_soc: optimize dma ring address/index
+ calculation
+
+Since DMA descriptor sizes are all power of 2, we can avoid costly integer
+division in favor or simple shifts.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -43,6 +43,11 @@ MODULE_PARM_DESC(msg_level, "Message lev
+                                 offsetof(struct mtk_hw_stats, xdp_stats.x) / \
+                                 sizeof(u64) }
++#define RX_DESC_OFS(eth, i) \
++      ((i) << (eth)->soc->rx.desc_shift)
++#define TX_DESC_OFS(eth, i) \
++      ((i) << (eth)->soc->tx.desc_shift)
++
+ static const struct mtk_reg_map mtk_reg_map = {
+       .tx_irq_mask            = 0x1a1c,
+       .tx_irq_status          = 0x1a18,
+@@ -1160,14 +1165,14 @@ static int mtk_init_fq_dma(struct mtk_et
+               eth->scratch_ring = eth->sram_base;
+       else
+               eth->scratch_ring = dma_alloc_coherent(eth->dma_dev,
+-                                                     cnt * soc->tx.desc_size,
++                                                     TX_DESC_OFS(eth, cnt),
+                                                      &eth->phy_scratch_ring,
+                                                      GFP_KERNEL);
+       if (unlikely(!eth->scratch_ring))
+               return -ENOMEM;
+-      phy_ring_tail = eth->phy_scratch_ring + soc->tx.desc_size * (cnt - 1);
++      phy_ring_tail = eth->phy_scratch_ring + TX_DESC_OFS(eth, cnt - 1);
+       for (j = 0; j < DIV_ROUND_UP(soc->tx.fq_dma_size, MTK_FQ_DMA_LENGTH); j++) {
+               len = min_t(int, cnt - j * MTK_FQ_DMA_LENGTH, MTK_FQ_DMA_LENGTH);
+@@ -1186,11 +1191,11 @@ static int mtk_init_fq_dma(struct mtk_et
+               for (i = 0; i < len; i++) {
+                       struct mtk_tx_dma_v2 *txd;
+-                      txd = eth->scratch_ring + (j * MTK_FQ_DMA_LENGTH + i) * soc->tx.desc_size;
++                      txd = eth->scratch_ring + TX_DESC_OFS(eth, j * MTK_FQ_DMA_LENGTH + i);
+                       txd->txd1 = dma_addr + i * MTK_QDMA_PAGE_SIZE;
+                       if (j * MTK_FQ_DMA_LENGTH + i < cnt)
+                               txd->txd2 = eth->phy_scratch_ring +
+-                                          (j * MTK_FQ_DMA_LENGTH + i + 1) * soc->tx.desc_size;
++                                          TX_DESC_OFS(eth, j * MTK_FQ_DMA_LENGTH + i + 1);
+                       txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
+                       if (MTK_HAS_CAPS(soc->caps, MTK_36BIT_DMA))
+@@ -1220,9 +1225,9 @@ static void *mtk_qdma_phys_to_virt(struc
+ }
+ static struct mtk_tx_buf *mtk_desc_to_tx_buf(struct mtk_tx_ring *ring,
+-                                           void *txd, u32 txd_size)
++                                           void *txd, u32 txd_shift)
+ {
+-      int idx = (txd - ring->dma) / txd_size;
++      int idx = (txd - ring->dma) >> txd_shift;
+       return &ring->buf[idx];
+ }
+@@ -1233,9 +1238,9 @@ static struct mtk_tx_dma *qdma_to_pdma(s
+       return ring->dma_pdma - (struct mtk_tx_dma *)ring->dma + dma;
+ }
+-static int txd_to_idx(struct mtk_tx_ring *ring, void *dma, u32 txd_size)
++static int txd_to_idx(struct mtk_tx_ring *ring, void *dma, u32 txd_shift)
+ {
+-      return (dma - ring->dma) / txd_size;
++      return (dma - ring->dma) >> txd_shift;
+ }
+ static void mtk_tx_unmap(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf,
+@@ -1443,7 +1448,7 @@ static int mtk_tx_map(struct sk_buff *sk
+       if (itxd == ring->last_free)
+               return -ENOMEM;
+-      itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_size);
++      itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_shift);
+       memset(itx_buf, 0, sizeof(*itx_buf));
+       txd_info.addr = dma_map_single(eth->dma_dev, skb->data, txd_info.size,
+@@ -1497,7 +1502,7 @@ static int mtk_tx_map(struct sk_buff *sk
+                       mtk_tx_set_dma_desc(dev, txd, &txd_info);
+                       tx_buf = mtk_desc_to_tx_buf(ring, txd,
+-                                                  soc->tx.desc_size);
++                                                  soc->tx.desc_shift);
+                       if (new_desc)
+                               memset(tx_buf, 0, sizeof(*tx_buf));
+                       tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
+@@ -1540,7 +1545,7 @@ static int mtk_tx_map(struct sk_buff *sk
+       } else {
+               int next_idx;
+-              next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->tx.desc_size),
++              next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->tx.desc_shift),
+                                        ring->dma_size);
+               mtk_w32(eth, next_idx, MT7628_TX_CTX_IDX0);
+       }
+@@ -1549,7 +1554,7 @@ static int mtk_tx_map(struct sk_buff *sk
+ err_dma:
+       do {
+-              tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_size);
++              tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_shift);
+               /* unmap dma */
+               mtk_tx_unmap(eth, tx_buf, NULL, false);
+@@ -1715,7 +1720,7 @@ static struct mtk_rx_ring *mtk_get_rx_ri
+               ring = &eth->rx_ring[i];
+               idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
+-              rxd = ring->dma + idx * eth->soc->rx.desc_size;
++              rxd = ring->dma + RX_DESC_OFS(eth, idx);
+               if (rxd->rxd2 & RX_DMA_DONE) {
+                       ring->calc_idx_update = true;
+                       return ring;
+@@ -1883,7 +1888,7 @@ static int mtk_xdp_submit_frame(struct m
+       }
+       htxd = txd;
+-      tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->tx.desc_size);
++      tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->tx.desc_shift);
+       memset(tx_buf, 0, sizeof(*tx_buf));
+       htx_buf = tx_buf;
+@@ -1902,7 +1907,7 @@ static int mtk_xdp_submit_frame(struct m
+                               goto unmap;
+                       tx_buf = mtk_desc_to_tx_buf(ring, txd,
+-                                                  soc->tx.desc_size);
++                                                  soc->tx.desc_shift);
+                       memset(tx_buf, 0, sizeof(*tx_buf));
+                       n_desc++;
+               }
+@@ -1940,7 +1945,7 @@ static int mtk_xdp_submit_frame(struct m
+       } else {
+               int idx;
+-              idx = txd_to_idx(ring, txd, soc->tx.desc_size);
++              idx = txd_to_idx(ring, txd, soc->tx.desc_shift);
+               mtk_w32(eth, NEXT_DESP_IDX(idx, ring->dma_size),
+                       MT7628_TX_CTX_IDX0);
+       }
+@@ -1951,7 +1956,7 @@ static int mtk_xdp_submit_frame(struct m
+ unmap:
+       while (htxd != txd) {
+-              tx_buf = mtk_desc_to_tx_buf(ring, htxd, soc->tx.desc_size);
++              tx_buf = mtk_desc_to_tx_buf(ring, htxd, soc->tx.desc_shift);
+               mtk_tx_unmap(eth, tx_buf, NULL, false);
+               htxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
+@@ -2083,7 +2088,7 @@ static int mtk_poll_rx(struct napi_struc
+                       goto rx_done;
+               idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
+-              rxd = ring->dma + idx * eth->soc->rx.desc_size;
++              rxd = ring->dma + RX_DESC_OFS(eth, idx);
+               data = ring->data[idx];
+               if (!mtk_rx_get_desc(eth, &trxd, rxd))
+@@ -2347,7 +2352,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
+                       break;
+               tx_buf = mtk_desc_to_tx_buf(ring, desc,
+-                                          eth->soc->tx.desc_size);
++                                          eth->soc->tx.desc_shift);
+               if (!tx_buf->data)
+                       break;
+@@ -2398,7 +2403,7 @@ static int mtk_poll_tx_pdma(struct mtk_e
+               }
+               mtk_tx_unmap(eth, tx_buf, &bq, true);
+-              desc = ring->dma + cpu * eth->soc->tx.desc_size;
++              desc = ring->dma + TX_DESC_OFS(eth, cpu);
+               ring->last_free = desc;
+               atomic_inc(&ring->free_count);
+@@ -2516,7 +2521,7 @@ static int mtk_tx_alloc(struct mtk_eth *
+ {
+       const struct mtk_soc_data *soc = eth->soc;
+       struct mtk_tx_ring *ring = &eth->tx_ring;
+-      int i, sz = soc->tx.desc_size;
++      int i, sz = TX_DESC_OFS(eth, 1);
+       struct mtk_tx_dma_v2 *txd;
+       int ring_size;
+       u32 ofs, val;
+@@ -2563,7 +2568,7 @@ static int mtk_tx_alloc(struct mtk_eth *
+        * descriptors in ring->dma_pdma.
+        */
+       if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
+-              ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
++              ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, TX_DESC_OFS(eth, ring_size),
+                                                   &ring->phys_pdma, GFP_KERNEL);
+               if (!ring->dma_pdma)
+                       goto no_tx_mem;
+@@ -2578,7 +2583,7 @@ static int mtk_tx_alloc(struct mtk_eth *
+       atomic_set(&ring->free_count, ring_size - 2);
+       ring->next_free = ring->dma;
+       ring->last_free = (void *)txd;
+-      ring->last_free_ptr = (u32)(ring->phys + ((ring_size - 1) * sz));
++      ring->last_free_ptr = (u32)(ring->phys + TX_DESC_OFS(eth, ring_size - 1));
+       ring->thresh = MAX_SKB_FRAGS;
+       /* make sure that all changes to the dma ring are flushed before we
+@@ -2590,7 +2595,7 @@ static int mtk_tx_alloc(struct mtk_eth *
+               mtk_w32(eth, ring->phys, soc->reg_map->qdma.ctx_ptr);
+               mtk_w32(eth, ring->phys, soc->reg_map->qdma.dtx_ptr);
+               mtk_w32(eth,
+-                      ring->phys + ((ring_size - 1) * sz),
++                      ring->phys + TX_DESC_OFS(eth, ring_size - 1),
+                       soc->reg_map->qdma.crx_ptr);
+               mtk_w32(eth, ring->last_free_ptr, soc->reg_map->qdma.drx_ptr);
+@@ -2639,14 +2644,14 @@ static void mtk_tx_clean(struct mtk_eth
+       }
+       if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && ring->dma) {
+               dma_free_coherent(eth->dma_dev,
+-                                ring->dma_size * soc->tx.desc_size,
++                                TX_DESC_OFS(eth, ring->dma_size),
+                                 ring->dma, ring->phys);
+               ring->dma = NULL;
+       }
+       if (ring->dma_pdma) {
+               dma_free_coherent(eth->dma_dev,
+-                                ring->dma_size * soc->tx.desc_size,
++                                TX_DESC_OFS(eth, ring->dma_size),
+                                 ring->dma_pdma, ring->phys_pdma);
+               ring->dma_pdma = NULL;
+       }
+@@ -2702,15 +2707,13 @@ static int mtk_rx_alloc(struct mtk_eth *
+       if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM) ||
+           rx_flag != MTK_RX_FLAGS_NORMAL) {
+               ring->dma = dma_alloc_coherent(eth->dma_dev,
+-                              rx_dma_size * eth->soc->rx.desc_size,
++                              RX_DESC_OFS(eth, rx_dma_size),
+                               &ring->phys, GFP_KERNEL);
+       } else {
+               struct mtk_tx_ring *tx_ring = &eth->tx_ring;
+-              ring->dma = tx_ring->dma + tx_ring_size *
+-                          eth->soc->tx.desc_size * (ring_no + 1);
+-              ring->phys = tx_ring->phys + tx_ring_size *
+-                           eth->soc->tx.desc_size * (ring_no + 1);
++              ring->dma = tx_ring->dma + TX_DESC_OFS(eth, tx_ring_size * (ring_no + 1));
++              ring->phys = tx_ring->phys + TX_DESC_OFS(eth, tx_ring_size * (ring_no + 1));
+       }
+       if (!ring->dma)
+@@ -2721,7 +2724,7 @@ static int mtk_rx_alloc(struct mtk_eth *
+               dma_addr_t dma_addr;
+               void *data;
+-              rxd = ring->dma + i * eth->soc->rx.desc_size;
++              rxd = ring->dma + RX_DESC_OFS(eth, i);
+               if (ring->page_pool) {
+                       data = mtk_page_pool_get_buff(ring->page_pool,
+                                                     &dma_addr, GFP_KERNEL);
+@@ -2812,7 +2815,7 @@ static void mtk_rx_clean(struct mtk_eth
+                       if (!ring->data[i])
+                               continue;
+-                      rxd = ring->dma + i * eth->soc->rx.desc_size;
++                      rxd = ring->dma + RX_DESC_OFS(eth, i);
+                       if (!rxd->rxd1)
+                               continue;
+@@ -2829,7 +2832,7 @@ static void mtk_rx_clean(struct mtk_eth
+       if (!in_sram && ring->dma) {
+               dma_free_coherent(eth->dma_dev,
+-                                ring->dma_size * eth->soc->rx.desc_size,
++                                RX_DESC_OFS(eth, ring->dma_size),
+                                 ring->dma, ring->phys);
+               ring->dma = NULL;
+       }
+@@ -3200,7 +3203,7 @@ static void mtk_dma_free(struct mtk_eth
+       if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) {
+               dma_free_coherent(eth->dma_dev,
+-                                MTK_QDMA_RING_SIZE * soc->tx.desc_size,
++                                TX_DESC_OFS(eth, MTK_QDMA_RING_SIZE),
+                                 eth->scratch_ring, eth->phy_scratch_ring);
+               eth->scratch_ring = NULL;
+               eth->phy_scratch_ring = 0;
+@@ -5228,6 +5231,9 @@ static void mtk_remove(struct platform_d
+       mtk_mdio_cleanup(eth);
+ }
++#define DESC_SIZE(struct_name)                                \
++      .desc_shift = const_ilog2(sizeof(struct_name))
++
+ static const struct mtk_soc_data mt2701_data = {
+       .reg_map = &mtk_reg_map,
+       .caps = MT7623_CAPS | MTK_HWLRO,
+@@ -5236,14 +5242,14 @@ static const struct mtk_soc_data mt2701_
+       .required_pctl = true,
+       .version = 1,
+       .tx = {
+-              .desc_size = sizeof(struct mtk_tx_dma),
++              DESC_SIZE(struct mtk_tx_dma),
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+               .dma_len_offset = 16,
+               .dma_size = MTK_DMA_SIZE(2K),
+               .fq_dma_size = MTK_DMA_SIZE(2K),
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma),
++              DESC_SIZE(struct mtk_rx_dma),
+               .irq_done_mask = MTK_RX_DONE_INT,
+               .dma_l4_valid = RX_DMA_L4_VALID,
+               .dma_size = MTK_DMA_SIZE(2K),
+@@ -5264,14 +5270,14 @@ static const struct mtk_soc_data mt7621_
+       .hash_offset = 2,
+       .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+       .tx = {
+-              .desc_size = sizeof(struct mtk_tx_dma),
++              DESC_SIZE(struct mtk_tx_dma),
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+               .dma_len_offset = 16,
+               .dma_size = MTK_DMA_SIZE(2K),
+               .fq_dma_size = MTK_DMA_SIZE(2K),
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma),
++              DESC_SIZE(struct mtk_rx_dma),
+               .irq_done_mask = MTK_RX_DONE_INT,
+               .dma_l4_valid = RX_DMA_L4_VALID,
+               .dma_size = MTK_DMA_SIZE(2K),
+@@ -5294,14 +5300,14 @@ static const struct mtk_soc_data mt7622_
+       .has_accounting = true,
+       .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+       .tx = {
+-              .desc_size = sizeof(struct mtk_tx_dma),
++              DESC_SIZE(struct mtk_tx_dma),
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+               .dma_len_offset = 16,
+               .dma_size = MTK_DMA_SIZE(2K),
+               .fq_dma_size = MTK_DMA_SIZE(2K),
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma),
++              DESC_SIZE(struct mtk_rx_dma),
+               .irq_done_mask = MTK_RX_DONE_INT,
+               .dma_l4_valid = RX_DMA_L4_VALID,
+               .dma_size = MTK_DMA_SIZE(2K),
+@@ -5323,14 +5329,14 @@ static const struct mtk_soc_data mt7623_
+       .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+       .disable_pll_modes = true,
+       .tx = {
+-              .desc_size = sizeof(struct mtk_tx_dma),
++              DESC_SIZE(struct mtk_tx_dma),
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+               .dma_len_offset = 16,
+               .dma_size = MTK_DMA_SIZE(2K),
+               .fq_dma_size = MTK_DMA_SIZE(2K),
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma),
++              DESC_SIZE(struct mtk_rx_dma),
+               .irq_done_mask = MTK_RX_DONE_INT,
+               .dma_l4_valid = RX_DMA_L4_VALID,
+               .dma_size = MTK_DMA_SIZE(2K),
+@@ -5349,14 +5355,14 @@ static const struct mtk_soc_data mt7629_
+       .has_accounting = true,
+       .version = 1,
+       .tx = {
+-              .desc_size = sizeof(struct mtk_tx_dma),
++              DESC_SIZE(struct mtk_tx_dma),
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+               .dma_len_offset = 16,
+               .dma_size = MTK_DMA_SIZE(2K),
+               .fq_dma_size = MTK_DMA_SIZE(2K),
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma),
++              DESC_SIZE(struct mtk_rx_dma),
+               .irq_done_mask = MTK_RX_DONE_INT,
+               .dma_l4_valid = RX_DMA_L4_VALID,
+               .dma_size = MTK_DMA_SIZE(2K),
+@@ -5379,14 +5385,14 @@ static const struct mtk_soc_data mt7981_
+       .has_accounting = true,
+       .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
+       .tx = {
+-              .desc_size = sizeof(struct mtk_tx_dma_v2),
++              DESC_SIZE(struct mtk_tx_dma_v2),
+               .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
+               .dma_len_offset = 8,
+               .dma_size = MTK_DMA_SIZE(2K),
+               .fq_dma_size = MTK_DMA_SIZE(2K),
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma),
++              DESC_SIZE(struct mtk_rx_dma),
+               .irq_done_mask = MTK_RX_DONE_INT,
+               .dma_l4_valid = RX_DMA_L4_VALID_V2,
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+@@ -5409,14 +5415,14 @@ static const struct mtk_soc_data mt7986_
+       .has_accounting = true,
+       .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
+       .tx = {
+-              .desc_size = sizeof(struct mtk_tx_dma_v2),
++              DESC_SIZE(struct mtk_tx_dma_v2),
+               .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
+               .dma_len_offset = 8,
+               .dma_size = MTK_DMA_SIZE(2K),
+               .fq_dma_size = MTK_DMA_SIZE(2K),
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma),
++              DESC_SIZE(struct mtk_rx_dma),
+               .irq_done_mask = MTK_RX_DONE_INT,
+               .dma_l4_valid = RX_DMA_L4_VALID_V2,
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+@@ -5439,14 +5445,14 @@ static const struct mtk_soc_data mt7988_
+       .has_accounting = true,
+       .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE,
+       .tx = {
+-              .desc_size = sizeof(struct mtk_tx_dma_v2),
++              DESC_SIZE(struct mtk_tx_dma_v2),
+               .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
+               .dma_len_offset = 8,
+               .dma_size = MTK_DMA_SIZE(2K),
+               .fq_dma_size = MTK_DMA_SIZE(4K),
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma_v2),
++              DESC_SIZE(struct mtk_rx_dma_v2),
+               .irq_done_mask = MTK_RX_DONE_INT_V2,
+               .dma_l4_valid = RX_DMA_L4_VALID_V2,
+               .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
+@@ -5463,13 +5469,13 @@ static const struct mtk_soc_data rt5350_
+       .required_pctl = false,
+       .version = 1,
+       .tx = {
+-              .desc_size = sizeof(struct mtk_tx_dma),
++              DESC_SIZE(struct mtk_tx_dma),
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+               .dma_len_offset = 16,
+               .dma_size = MTK_DMA_SIZE(2K),
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma),
++              DESC_SIZE(struct mtk_rx_dma),
+               .irq_done_mask = MTK_RX_DONE_INT,
+               .dma_l4_valid = RX_DMA_L4_VALID_PDMA,
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -1160,7 +1160,7 @@ struct mtk_reg_map {
+  * @foe_entry_size            Foe table entry size.
+  * @has_accounting            Bool indicating support for accounting of
+  *                            offloaded flows.
+- * @desc_size                 Tx/Rx DMA descriptor size.
++ * @desc_shift                        Tx/Rx DMA descriptor size (in power-of-2).
+  * @irq_done_mask             Rx irq done register mask.
+  * @dma_l4_valid              Rx DMA valid register mask.
+  * @dma_max_len                       Max DMA tx/rx buffer length.
+@@ -1181,14 +1181,14 @@ struct mtk_soc_data {
+       bool            has_accounting;
+       bool            disable_pll_modes;
+       struct {
+-              u32     desc_size;
++              u32     desc_shift;
+               u32     dma_max_len;
+               u32     dma_len_offset;
+               u32     dma_size;
+               u32     fq_dma_size;
+       } tx;
+       struct {
+-              u32     desc_size;
++              u32     desc_shift;
+               u32     irq_done_mask;
+               u32     dma_l4_valid;
+               u32     dma_max_len;
diff --git a/target/linux/generic/pending-6.12/732-04-net-ethernet-mtk_eth_soc-shrink-struct-mtk_tx_buf.patch b/target/linux/generic/pending-6.12/732-04-net-ethernet-mtk_eth_soc-shrink-struct-mtk_tx_buf.patch
new file mode 100644 (file)
index 0000000..b33b9d3
--- /dev/null
@@ -0,0 +1,124 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Mon, 14 Jul 2025 10:52:59 +0200
+Subject: [PATCH] net: ethernet: mtk_eth_soc: shrink struct mtk_tx_buf
+
+There is no need to track the difference between dma_map_page
+and dma_map_single, since they're unmapped in exactly the same way.
+Also reorder fields in order to avoid padding.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1246,32 +1246,19 @@ static int txd_to_idx(struct mtk_tx_ring
+ static void mtk_tx_unmap(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf,
+                        struct xdp_frame_bulk *bq, bool napi)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) {
+-              if (tx_buf->flags & MTK_TX_FLAGS_SINGLE0) {
+-                      dma_unmap_single(eth->dma_dev,
+-                                       dma_unmap_addr(tx_buf, dma_addr0),
+-                                       dma_unmap_len(tx_buf, dma_len0),
+-                                       DMA_TO_DEVICE);
+-              } else if (tx_buf->flags & MTK_TX_FLAGS_PAGE0) {
+-                      dma_unmap_page(eth->dma_dev,
+-                                     dma_unmap_addr(tx_buf, dma_addr0),
+-                                     dma_unmap_len(tx_buf, dma_len0),
+-                                     DMA_TO_DEVICE);
+-              }
+-      } else {
+-              if (dma_unmap_len(tx_buf, dma_len0)) {
+-                      dma_unmap_page(eth->dma_dev,
+-                                     dma_unmap_addr(tx_buf, dma_addr0),
+-                                     dma_unmap_len(tx_buf, dma_len0),
+-                                     DMA_TO_DEVICE);
+-              }
++      if (dma_unmap_len(tx_buf, dma_len0)) {
++              dma_unmap_page(eth->dma_dev,
++                             dma_unmap_addr(tx_buf, dma_addr0),
++                             dma_unmap_len(tx_buf, dma_len0),
++                             DMA_TO_DEVICE);
++      }
+-              if (dma_unmap_len(tx_buf, dma_len1)) {
+-                      dma_unmap_page(eth->dma_dev,
+-                                     dma_unmap_addr(tx_buf, dma_addr1),
+-                                     dma_unmap_len(tx_buf, dma_len1),
+-                                     DMA_TO_DEVICE);
+-              }
++      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA) &&
++          dma_unmap_len(tx_buf, dma_len1)) {
++              dma_unmap_page(eth->dma_dev,
++                             dma_unmap_addr(tx_buf, dma_addr1),
++                             dma_unmap_len(tx_buf, dma_len1),
++                             DMA_TO_DEVICE);
+       }
+       if (tx_buf->data && tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
+@@ -1293,7 +1280,6 @@ static void mtk_tx_unmap(struct mtk_eth
+                               xdp_return_frame(xdpf);
+               }
+       }
+-      tx_buf->flags = 0;
+       tx_buf->data = NULL;
+ }
+@@ -1458,7 +1444,6 @@ static int mtk_tx_map(struct sk_buff *sk
+       mtk_tx_set_dma_desc(dev, itxd, &txd_info);
+-      itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
+       itx_buf->mac_id = mac->id;
+       setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
+                    k++);
+@@ -1506,7 +1491,6 @@ static int mtk_tx_map(struct sk_buff *sk
+                       if (new_desc)
+                               memset(tx_buf, 0, sizeof(*tx_buf));
+                       tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
+-                      tx_buf->flags |= MTK_TX_FLAGS_PAGE0;
+                       tx_buf->mac_id = mac->id;
+                       setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr,
+@@ -1831,8 +1815,6 @@ static int mtk_xdp_frame_map(struct mtk_
+                                               txd_info->size, DMA_TO_DEVICE);
+               if (unlikely(dma_mapping_error(eth->dma_dev, txd_info->addr)))
+                       return -ENOMEM;
+-
+-              tx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
+       } else {
+               struct page *page = virt_to_head_page(data);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -701,14 +701,6 @@ struct mtk_hw_stats {
+       struct u64_stats_sync   syncp;
+ };
+-enum mtk_tx_flags {
+-      /* PDMA descriptor can point at 1-2 segments. This enum allows us to
+-       * track how memory was allocated so that it can be freed properly.
+-       */
+-      MTK_TX_FLAGS_SINGLE0    = 0x01,
+-      MTK_TX_FLAGS_PAGE0      = 0x02,
+-};
+-
+ /* This enum allows us to identify how the clock is defined on the array of the
+  * clock in the order
+  */
+@@ -881,13 +873,12 @@ enum mtk_tx_buf_type {
+  */
+ struct mtk_tx_buf {
+       enum mtk_tx_buf_type type;
++      u16 mac_id;
+       void *data;
+-      u16 mac_id;
+-      u16 flags;
+       DEFINE_DMA_UNMAP_ADDR(dma_addr0);
+-      DEFINE_DMA_UNMAP_LEN(dma_len0);
+       DEFINE_DMA_UNMAP_ADDR(dma_addr1);
++      DEFINE_DMA_UNMAP_LEN(dma_len0);
+       DEFINE_DMA_UNMAP_LEN(dma_len1);
+ };
diff --git a/target/linux/generic/pending-6.12/732-05-net-ethernet-mtk_eth_soc-add-support-for-sending-fra.patch b/target/linux/generic/pending-6.12/732-05-net-ethernet-mtk_eth_soc-add-support-for-sending-fra.patch
new file mode 100644 (file)
index 0000000..c085328
--- /dev/null
@@ -0,0 +1,509 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Mon, 14 Jul 2025 10:41:27 +0200
+Subject: [PATCH] net: ethernet: mtk_eth_soc: add support for sending
+ fraglist GSO packets
+
+When primarily forwarding traffic, TCP fraglist GRO can be noticeably more
+efficient than regular TCP GRO. In order to avoid the overhead of
+unnecessary segmentation on ethernet tx, add support for sending fraglist
+GRO packets.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -18,6 +18,8 @@
+ #include <linux/if_vlan.h>
+ #include <linux/reset.h>
+ #include <linux/tcp.h>
++#include <linux/ip.h>
++#include <linux/ipv6.h>
+ #include <linux/interrupt.h>
+ #include <linux/pinctrl/devinfo.h>
+ #include <linux/phylink.h>
+@@ -27,6 +29,7 @@
+ #include <net/dsa.h>
+ #include <net/dst_metadata.h>
+ #include <net/gso.h>
++#include <net/checksum.h>
+ #include <net/page_pool/helpers.h>
+ #include "mtk_eth_soc.h"
+@@ -1404,119 +1407,244 @@ static void mtk_tx_set_dma_desc(struct n
+               mtk_tx_set_dma_desc_v1(dev, txd, info);
+ }
++struct mtk_tx_map_state {
++    struct mtk_tx_dma *txd, *txd_pdma;
++    struct mtk_tx_buf *tx_buf;
++    int nbuf;
++    int ndesc;
++};
++
++static void
++mtk_tx_map_set_txd(struct mtk_tx_map_state *state, struct mtk_tx_ring *ring,
++                 const struct mtk_soc_data *soc, struct mtk_tx_dma *txd)
++{
++      state->txd = txd;
++      state->txd_pdma = qdma_to_pdma(ring, txd);
++      state->tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->tx.desc_shift);
++      memset(state->tx_buf, 0, sizeof(*state->tx_buf));
++}
++
++static int
++mtk_tx_map_info(struct mtk_eth *eth, struct mtk_tx_ring *ring,
++              struct net_device *dev, struct mtk_tx_map_state *state,
++              struct mtk_tx_dma_desc_info *txd_info)
++{
++      const struct mtk_soc_data *soc = eth->soc;
++      struct mtk_tx_buf *tx_buf = state->tx_buf;
++      struct mtk_tx_dma *txd = state->txd;
++      struct mtk_mac *mac = netdev_priv(dev);
++
++      if (state->nbuf &&
++          (MTK_HAS_CAPS(soc->caps, MTK_QDMA) || (state->nbuf & 1) == 0)) {
++              txd = mtk_qdma_phys_to_virt(ring, txd->txd2);
++              if (txd == ring->last_free)
++                      return -1;
++
++              mtk_tx_map_set_txd(state, ring, soc, txd);
++              state->ndesc++;
++      }
++
++      mtk_tx_set_dma_desc(dev, txd, txd_info);
++      tx_buf = state->tx_buf;
++      tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
++      tx_buf->mac_id = mac->id;
++
++      setup_tx_buf(eth, tx_buf, state->txd_pdma, txd_info->addr,
++                   txd_info->size, state->nbuf++);
++      return 0;
++}
++
++static void
++mtk_tx_update_ipaddr(struct sk_buff *skb,
++                   struct iphdr *iph, struct tcphdr *th,
++                   __be32 *old_ip, __be32 new_ip)
++{
++      if (*old_ip == new_ip)
++              return;
++
++      inet_proto_csum_replace4(&th->check, skb, *old_ip, new_ip, true);
++      csum_replace4(&iph->check, *old_ip, new_ip);
++      *old_ip = new_ip;
++}
++
++static void
++mtk_tx_update_ip6addr(struct sk_buff *skb, struct ipv6hdr *iph,
++                    struct tcphdr *th, struct in6_addr *old_ip,
++                    const struct in6_addr *new_ip)
++{
++      if (ipv6_addr_equal(old_ip, new_ip))
++              return;
++
++      inet_proto_csum_replace16(&th->check, skb, old_ip->s6_addr32,
++                                new_ip->s6_addr32, true);
++      *old_ip = *new_ip;
++}
++
++static void
++mtk_tx_update_port(struct sk_buff *skb, struct tcphdr *th,
++                 __be16 *old_port, __be16 new_port)
++{
++      if (*old_port == new_port)
++              return;
++
++      inet_proto_csum_replace2(&th->check, skb, *old_port, new_port, false);
++      *old_port = new_port;
++}
++
+ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
+-                    int tx_num, struct mtk_tx_ring *ring, bool gso)
++                    int tx_num, struct mtk_tx_ring *ring, bool gso,
++                    unsigned int header_len)
+ {
+-      struct mtk_tx_dma_desc_info txd_info = {
+-              .size = skb_headlen(skb),
+-              .gso = gso,
+-              .csum = skb->ip_summed == CHECKSUM_PARTIAL,
+-              .vlan = skb_vlan_tag_present(skb),
+-              .qid = skb_get_queue_mapping(skb),
+-              .vlan_tci = skb_vlan_tag_get(skb),
+-              .first = true,
+-              .last = !skb_is_nonlinear(skb),
++      struct mtk_tx_dma_desc_info txd_info;
++      struct mtk_tx_map_state state = {
++              .ndesc = 1,
+       };
+       struct netdev_queue *txq;
+       struct mtk_mac *mac = netdev_priv(dev);
+       struct mtk_eth *eth = mac->hw;
+       const struct mtk_soc_data *soc = eth->soc;
+-      struct mtk_tx_dma *itxd, *txd;
+-      struct mtk_tx_dma *itxd_pdma, *txd_pdma;
+-      struct mtk_tx_buf *itx_buf, *tx_buf;
+-      int i, n_desc = 1;
++      struct mtk_tx_dma *itxd;
++      struct sk_buff *cur_skb, *next_skb;
+       int queue = skb_get_queue_mapping(skb);
+-      int k = 0;
++      int offset = 0;
++      int i, frag_size;
++      bool gso_v4;
+       txq = netdev_get_tx_queue(dev, queue);
+       itxd = ring->next_free;
+-      itxd_pdma = qdma_to_pdma(ring, itxd);
+       if (itxd == ring->last_free)
+               return -ENOMEM;
+-      itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_shift);
+-      memset(itx_buf, 0, sizeof(*itx_buf));
++      cur_skb = skb;
++      next_skb = skb_shinfo(skb)->frag_list;
++      mtk_tx_map_set_txd(&state, ring, soc, itxd);
++      gso_v4 = skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4;
+-      txd_info.addr = dma_map_single(eth->dma_dev, skb->data, txd_info.size,
+-                                     DMA_TO_DEVICE);
+-      if (unlikely(dma_mapping_error(eth->dma_dev, txd_info.addr)))
+-              return -ENOMEM;
++next:
++      txd_info = (struct mtk_tx_dma_desc_info){
++              .gso = gso,
++              .qid = queue,
++              .csum = cur_skb->ip_summed == CHECKSUM_PARTIAL || gso,
++              .vlan = skb_vlan_tag_present(skb),
++              .vlan_tci = skb_vlan_tag_get(skb),
++              .first = true,
++      };
++
++      offset = 0;
++      frag_size = skb_headlen(cur_skb);
++      if (cur_skb != skb) {
++              struct tcphdr *th, *th2;
++
++              if (skb_cow_head(cur_skb, header_len))
++                      goto err_dma;
++
++              memcpy(cur_skb->data - header_len, skb->data,
++                     skb_network_offset(skb));
++
++              th = tcp_hdr(cur_skb);
++              th2 = tcp_hdr(skb);
++              if (gso_v4) {
++                      struct iphdr *iph = ip_hdr(cur_skb);
++                      struct iphdr *iph2 = ip_hdr(skb);
++
++                      mtk_tx_update_ipaddr(skb, iph, th, &iph->saddr,
++                                           iph2->saddr);
++                      mtk_tx_update_ipaddr(skb, iph, th, &iph->daddr,
++                                           iph2->daddr);
++              } else {
++                      struct ipv6hdr *iph = ipv6_hdr(cur_skb);
++                      struct ipv6hdr *iph2 = ipv6_hdr(skb);
+-      mtk_tx_set_dma_desc(dev, itxd, &txd_info);
++                      mtk_tx_update_ip6addr(skb, iph, th, &iph->saddr,
++                                            &iph2->saddr);
++                      mtk_tx_update_ip6addr(skb, iph, th, &iph->daddr,
++                                            &iph2->daddr);
++              }
+-      itx_buf->mac_id = mac->id;
+-      setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
+-                   k++);
+-
+-      /* TX SG offload */
+-      txd = itxd;
+-      txd_pdma = qdma_to_pdma(ring, txd);
+-
+-      for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+-              skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+-              unsigned int offset = 0;
+-              int frag_size = skb_frag_size(frag);
++              mtk_tx_update_port(skb, th, &th->source, th2->source);
++              mtk_tx_update_port(skb, th, &th->dest, th2->dest);
+-              while (frag_size) {
+-                      bool new_desc = true;
++              offset = -header_len;
++              frag_size += header_len;
++      } else if (next_skb) {
++              unsigned int ip_len = skb_pagelen(skb) - skb_network_offset(skb);
++              if (gso_v4) {
++                      struct iphdr *iph = ip_hdr(cur_skb);
++                      __be16 ip_len_val = cpu_to_be16(ip_len);
+-                      if (MTK_HAS_CAPS(soc->caps, MTK_QDMA) ||
+-                          (i & 0x1)) {
+-                              txd = mtk_qdma_phys_to_virt(ring, txd->txd2);
+-                              txd_pdma = qdma_to_pdma(ring, txd);
+-                              if (txd == ring->last_free)
+-                                      goto err_dma;
++                      csum_replace2(&iph->check, iph->tot_len, ip_len_val);
++                      iph->tot_len = ip_len_val;
++              } else {
++                      struct ipv6hdr *iph = ipv6_hdr(cur_skb);
++                      __be16 ip_len_val = cpu_to_be16(ip_len - sizeof(*iph));
+-                              n_desc++;
+-                      } else {
+-                              new_desc = false;
+-                      }
++                      iph->payload_len = ip_len_val;
++              }
++      }
+-                      memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
++      while (frag_size) {
++              txd_info.size = min_t(unsigned int, frag_size,
++                                    soc->tx.dma_max_len);
++              txd_info.addr = dma_map_single(eth->dma_dev, cur_skb->data + offset,
++                                             txd_info.size, DMA_TO_DEVICE);
++              if (unlikely(dma_mapping_error(eth->dma_dev, txd_info.addr)))
++                      goto err_dma;
++
++              frag_size -= txd_info.size;
++              offset += txd_info.size;
++              txd_info.last = !frag_size && !skb_shinfo(cur_skb)->nr_frags;
++              if (mtk_tx_map_info(eth, ring, dev, &state, &txd_info) < 0)
++                      goto err_dma;
++      }
++
++      for (i = 0; i < skb_shinfo(cur_skb)->nr_frags; i++) {
++              skb_frag_t *frag = &skb_shinfo(cur_skb)->frags[i];
++
++              frag_size = skb_frag_size(frag);
++              memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
++              txd_info.qid = queue;
++              offset = 0;
++              while (frag_size) {
+                       txd_info.size = min_t(unsigned int, frag_size,
+                                             soc->tx.dma_max_len);
+-                      txd_info.qid = queue;
+-                      txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 &&
+-                                      !(frag_size - txd_info.size);
+-                      txd_info.addr = skb_frag_dma_map(eth->dma_dev, frag,
+-                                                       offset, txd_info.size,
+-                                                       DMA_TO_DEVICE);
++                      txd_info.addr = skb_frag_dma_map(eth->dma_dev, frag, offset,
++                                                       txd_info.size, DMA_TO_DEVICE);
+                       if (unlikely(dma_mapping_error(eth->dma_dev, txd_info.addr)))
+                               goto err_dma;
+-                      mtk_tx_set_dma_desc(dev, txd, &txd_info);
+-
+-                      tx_buf = mtk_desc_to_tx_buf(ring, txd,
+-                                                  soc->tx.desc_shift);
+-                      if (new_desc)
+-                              memset(tx_buf, 0, sizeof(*tx_buf));
+-                      tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
+-                      tx_buf->mac_id = mac->id;
+-
+-                      setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr,
+-                                   txd_info.size, k++);
+-
+                       frag_size -= txd_info.size;
+                       offset += txd_info.size;
++                      txd_info.last = i == skb_shinfo(cur_skb)->nr_frags - 1 &&
++                                      !frag_size;
++                      if (mtk_tx_map_info(eth, ring, dev, &state, &txd_info) < 0)
++                              goto err_dma;
+               }
+       }
+-      /* store skb to cleanup */
+-      itx_buf->type = MTK_TYPE_SKB;
+-      itx_buf->data = skb;
+-
+       if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
+-              if (k & 0x1)
+-                      txd_pdma->txd2 |= TX_DMA_LS0;
+-              else
+-                      txd_pdma->txd2 |= TX_DMA_LS1;
++              if (state.nbuf & 0x1) {
++                      state.txd_pdma->txd2 |= TX_DMA_LS0;
++                      state.nbuf++;
++              } else {
++                      state.txd_pdma->txd2 |= TX_DMA_LS1;
++              }
+       }
++      if (next_skb) {
++              cur_skb = next_skb;
++              next_skb = cur_skb->next;
++              goto next;
++      }
++
++      /* store skb to cleanup */
++      state.tx_buf->type = MTK_TYPE_SKB;
++      state.tx_buf->data = skb;
++
+       netdev_tx_sent_queue(txq, skb->len);
+       skb_tx_timestamp(skb);
+-      ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2);
+-      atomic_sub(n_desc, &ring->free_count);
++      ring->next_free = mtk_qdma_phys_to_virt(ring, state.txd->txd2);
++      atomic_sub(state.ndesc, &ring->free_count);
+       /* make sure that all changes to the dma ring are flushed before we
+        * continue
+@@ -1525,11 +1653,11 @@ static int mtk_tx_map(struct sk_buff *sk
+       if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
+               if (netif_xmit_stopped(txq) || !netdev_xmit_more())
+-                      mtk_w32(eth, txd->txd2, soc->reg_map->qdma.ctx_ptr);
++                      mtk_w32(eth, state.txd->txd2, soc->reg_map->qdma.ctx_ptr);
+       } else {
+               int next_idx;
+-              next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->tx.desc_shift),
++              next_idx = NEXT_DESP_IDX(txd_to_idx(ring, state.txd, soc->tx.desc_shift),
+                                        ring->dma_size);
+               mtk_w32(eth, next_idx, MT7628_TX_CTX_IDX0);
+       }
+@@ -1538,18 +1666,20 @@ static int mtk_tx_map(struct sk_buff *sk
+ err_dma:
+       do {
+-              tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_shift);
++              struct mtk_tx_dma *itxd_pdma = qdma_to_pdma(ring, itxd);
++              struct mtk_tx_buf *itx_buf;
++
++              itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_shift);
+               /* unmap dma */
+-              mtk_tx_unmap(eth, tx_buf, NULL, false);
++              mtk_tx_unmap(eth, itx_buf, NULL, false);
+               itxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
+               if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA))
+                       itxd_pdma->txd2 = TX_DMA_DESP2_DEF;
+               itxd = mtk_qdma_phys_to_virt(ring, itxd->txd2);
+-              itxd_pdma = qdma_to_pdma(ring, itxd);
+-      } while (itxd != txd);
++      } while (itxd != state.txd);
+       return -ENOMEM;
+ }
+@@ -1569,6 +1699,9 @@ static int mtk_cal_txd_req(struct mtk_et
+               nfrags += skb_shinfo(skb)->nr_frags;
+       }
++      for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next)
++              nfrags += mtk_cal_txd_req(eth, skb) + 1;
++
+       return nfrags;
+ }
+@@ -1609,9 +1742,26 @@ static bool mtk_skb_has_small_frag(struc
+               if (skb_frag_size(&skb_shinfo(skb)->frags[i]) < min_size)
+                       return true;
++      for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next)
++              if (mtk_skb_has_small_frag(skb))
++                      return true;
++
+       return false;
+ }
++static bool mtk_skb_valid_gso(struct mtk_eth *eth, struct sk_buff *skb,
++                            unsigned int header_len)
++{
++      if (mtk_is_netsys_v1(eth) && mtk_skb_has_small_frag(skb))
++              return false;
++
++      if (!(skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST))
++              return true;
++
++      return skb_pagelen(skb) - header_len == skb_shinfo(skb)->gso_size &&
++             skb_headlen(skb) > header_len;
++}
++
+ static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+       struct mtk_mac *mac = netdev_priv(dev);
+@@ -1619,6 +1769,7 @@ static netdev_tx_t mtk_start_xmit(struct
+       struct mtk_tx_ring *ring = &eth->tx_ring;
+       struct net_device_stats *stats = &dev->stats;
+       struct sk_buff *segs, *next;
++      unsigned int header_len = 0;
+       bool gso = false;
+       int tx_num;
+@@ -1640,37 +1791,42 @@ static netdev_tx_t mtk_start_xmit(struct
+               return NETDEV_TX_BUSY;
+       }
+-      if (mtk_is_netsys_v1(eth) &&
+-          skb_is_gso(skb) && mtk_skb_has_small_frag(skb)) {
+-              segs = skb_gso_segment(skb, dev->features & ~NETIF_F_ALL_TSO);
+-              if (IS_ERR(segs))
+-                      goto drop;
+-
+-              if (segs) {
+-                      consume_skb(skb);
+-                      skb = segs;
+-              }
+-      }
+-
+-      /* TSO: fill MSS info in tcp checksum field */
+       if (skb_is_gso(skb)) {
+-              if (skb_cow_head(skb, 0)) {
+-                      netif_warn(eth, tx_err, dev,
+-                                 "GSO expand head fail.\n");
+-                      goto drop;
++              header_len = skb_tcp_all_headers(skb);
++              if (!mtk_skb_valid_gso(eth, skb, header_len)) {
++                      segs = skb_gso_segment(skb, dev->features & ~NETIF_F_ALL_TSO);
++                      if (IS_ERR(segs))
++                              goto drop;
++
++                      if (segs) {
++                              consume_skb(skb);
++                              skb = segs;
++                      }
++                      goto send;
+               }
++              if ((skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST))
++                      goto send;
++
+               if (skb_shinfo(skb)->gso_type &
+                               (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) {
++                      /* TSO: fill MSS info in tcp checksum field */
+                       gso = true;
++                      if (skb_cow_head(skb, 0)) {
++                              netif_warn(eth, tx_err, dev,
++                                         "GSO expand head fail.\n");
++                              goto drop;
++                      }
++
+                       tcp_hdr(skb)->check = htons(skb_shinfo(skb)->gso_size);
+               }
+       }
++send:
+       skb_list_walk_safe(skb, skb, next) {
+               if ((mtk_is_netsys_v1(eth) &&
+                    mtk_skb_has_small_frag(skb) && skb_linearize(skb)) ||
+-                  mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) {
++                  mtk_tx_map(skb, dev, tx_num, ring, gso, header_len) < 0) {
+                               stats->tx_dropped++;
+                               dev_kfree_skb_any(skb);
+               }
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -51,6 +51,8 @@
+                                NETIF_F_HW_VLAN_CTAG_TX | \
+                                NETIF_F_SG | NETIF_F_TSO | \
+                                NETIF_F_TSO6 | \
++                               NETIF_F_FRAGLIST | \
++                               NETIF_F_GSO_FRAGLIST | \
+                                NETIF_F_IPV6_CSUM |\
+                                NETIF_F_HW_TC)
+ #define MTK_HW_FEATURES_MT7628        (NETIF_F_SG | NETIF_F_RXCSUM)
index 36c1d499d33cbc4cb79649064cdbd76bb6ba4aad..0aba4b69b742a1e051e24956a11a7e1626ffa2bd 100644 (file)
@@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2151,7 +2151,7 @@ static int mtk_poll_rx(struct napi_struc
+@@ -2294,7 +2294,7 @@ static int mtk_poll_rx(struct napi_struc
                        if (ret != XDP_PASS)
                                goto skip_rx;
  
@@ -19,7 +19,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                        if (unlikely(!skb)) {
                                page_pool_put_full_page(ring->page_pool,
                                                        page, true);
-@@ -2189,7 +2189,7 @@ static int mtk_poll_rx(struct napi_struc
+@@ -2332,7 +2332,7 @@ static int mtk_poll_rx(struct napi_struc
                        dma_unmap_single(eth->dma_dev, ((u64)trxd.rxd1 | addr64),
                                         ring->buf_size, DMA_FROM_DEVICE);
  
index d9e287326270d572f51628209124668b00022cbc..1efb93226c37023bab48ce2e8d1c89b3aaf3118b 100644 (file)
@@ -15,7 +15,7 @@ Signed-off-by: Chad Monroe <chad@monroe.io>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -279,6 +279,7 @@
+@@ -282,6 +282,7 @@
  #define MTK_WCOMP_EN          BIT(24)
  #define MTK_RESV_BUF          (0x80 << 16)
  #define MTK_MUTLI_CNT         (0x4 << 12)
@@ -25,7 +25,7 @@ Signed-off-by: Chad Monroe <chad@monroe.io>
  /* QDMA Flow Control Register */
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3324,12 +3324,14 @@ static int mtk_start_dma(struct mtk_eth
+@@ -3465,12 +3465,14 @@ static int mtk_start_dma(struct mtk_eth
                       MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
                       MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE;
  
index b03b72b33d5058b8664b8f6651d33e7b7db0e233..faa91b006eecfeef701fb86c5a9232fe69b04a14 100644 (file)
@@ -205,7 +205,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        return mtk_eth_mux_setup(eth, path);
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -22,6 +22,8 @@
+@@ -24,6 +24,8 @@
  #include <linux/pinctrl/devinfo.h>
  #include <linux/phylink.h>
  #include <linux/pcs/pcs-mtk-lynxi.h>
@@ -214,7 +214,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  #include <linux/jhash.h>
  #include <linux/bitfield.h>
  #include <net/dsa.h>
-@@ -514,6 +516,30 @@ static void mtk_setup_bridge_switch(stru
+@@ -522,6 +524,30 @@ static void mtk_setup_bridge_switch(stru
                MTK_GSW_CFG);
  }
  
@@ -245,7 +245,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
                                              phy_interface_t interface)
  {
-@@ -522,6 +548,21 @@ static struct phylink_pcs *mtk_mac_selec
+@@ -530,6 +556,21 @@ static struct phylink_pcs *mtk_mac_selec
        struct mtk_eth *eth = mac->hw;
        unsigned int sid;
  
@@ -267,7 +267,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        if (interface == PHY_INTERFACE_MODE_SGMII ||
            phy_interface_mode_is_8023z(interface)) {
                sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
-@@ -573,7 +614,22 @@ static void mtk_mac_config(struct phylin
+@@ -581,7 +622,22 @@ static void mtk_mac_config(struct phylin
                                        goto init_err;
                        }
                        break;
@@ -290,7 +290,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
                        break;
                default:
                        goto err_phy;
-@@ -620,8 +676,6 @@ static void mtk_mac_config(struct phylin
+@@ -628,8 +684,6 @@ static void mtk_mac_config(struct phylin
                val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id);
                val |= SYSCFG0_GE_MODE(ge_mode, mac->id);
                regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val);
@@ -299,7 +299,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        }
  
        /* SGMII */
-@@ -638,21 +692,40 @@ static void mtk_mac_config(struct phylin
+@@ -646,21 +700,40 @@ static void mtk_mac_config(struct phylin
  
                /* Save the syscfg0 value for mac_finish */
                mac->syscfg0 = val;
@@ -347,7 +347,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        return;
  
  err_phy:
-@@ -665,6 +738,18 @@ init_err:
+@@ -673,6 +746,18 @@ init_err:
                mac->id, phy_modes(state->interface), err);
  }
  
@@ -366,7 +366,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  static int mtk_mac_finish(struct phylink_config *config, unsigned int mode,
                          phy_interface_t interface)
  {
-@@ -673,6 +758,10 @@ static int mtk_mac_finish(struct phylink
+@@ -681,6 +766,10 @@ static int mtk_mac_finish(struct phylink
        struct mtk_eth *eth = mac->hw;
        u32 mcr_cur, mcr_new;
  
@@ -377,7 +377,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        /* Enable SGMII */
        if (interface == PHY_INTERFACE_MODE_SGMII ||
            phy_interface_mode_is_8023z(interface))
-@@ -697,10 +786,14 @@ static void mtk_mac_link_down(struct phy
+@@ -705,10 +794,14 @@ static void mtk_mac_link_down(struct phy
  {
        struct mtk_mac *mac = container_of(config, struct mtk_mac,
                                           phylink_config);
@@ -395,7 +395,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  }
  
  static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
-@@ -772,13 +865,11 @@ static void mtk_set_queue_speed(struct m
+@@ -780,13 +873,11 @@ static void mtk_set_queue_speed(struct m
        mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
  }
  
@@ -413,7 +413,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        u32 mcr;
  
        mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
-@@ -822,9 +913,63 @@ static void mtk_mac_link_up(struct phyli
+@@ -830,9 +921,63 @@ static void mtk_mac_link_up(struct phyli
        mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
  }
  
@@ -477,7 +477,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        .mac_finish = mtk_mac_finish,
        .mac_link_down = mtk_mac_link_down,
        .mac_link_up = mtk_mac_link_up,
-@@ -3432,6 +3577,9 @@ static int mtk_open(struct net_device *d
+@@ -3573,6 +3718,9 @@ static int mtk_open(struct net_device *d
  
        ppe_num = eth->soc->ppe_num;
  
@@ -487,7 +487,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
        if (err) {
                netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
-@@ -3579,6 +3727,9 @@ static int mtk_stop(struct net_device *d
+@@ -3720,6 +3868,9 @@ static int mtk_stop(struct net_device *d
        for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
                mtk_ppe_stop(eth->ppe[i]);
  
@@ -497,7 +497,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        return 0;
  }
  
-@@ -4669,6 +4820,7 @@ static const struct net_device_ops mtk_n
+@@ -4810,6 +4961,7 @@ static const struct net_device_ops mtk_n
  static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
  {
        const __be32 *_id = of_get_property(np, "reg", NULL);
@@ -505,7 +505,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        phy_interface_t phy_mode;
        struct phylink *phylink;
        struct mtk_mac *mac;
-@@ -4707,16 +4859,41 @@ static int mtk_add_mac(struct mtk_eth *e
+@@ -4848,16 +5000,41 @@ static int mtk_add_mac(struct mtk_eth *e
        mac->id = id;
        mac->hw = eth;
        mac->of_node = np;
@@ -555,7 +555,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        }
  
        memset(mac->hwlro_ip, 0, sizeof(mac->hwlro_ip));
-@@ -4799,8 +4976,21 @@ static int mtk_add_mac(struct mtk_eth *e
+@@ -4940,8 +5117,21 @@ static int mtk_add_mac(struct mtk_eth *e
                phy_interface_zero(mac->phylink_config.supported_interfaces);
                __set_bit(PHY_INTERFACE_MODE_INTERNAL,
                          mac->phylink_config.supported_interfaces);
@@ -577,7 +577,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        phylink = phylink_create(&mac->phylink_config,
                                 of_fwnode_handle(mac->of_node),
                                 phy_mode, &mtk_phylink_ops);
-@@ -4851,6 +5041,26 @@ free_netdev:
+@@ -4992,6 +5182,26 @@ free_netdev:
        return err;
  }
  
@@ -604,7 +604,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev)
  {
        struct net_device *dev, *tmp;
-@@ -4997,7 +5207,8 @@ static int mtk_probe(struct platform_dev
+@@ -5138,7 +5348,8 @@ static int mtk_probe(struct platform_dev
                        regmap_write(cci, 0, 3);
        }
  
@@ -614,7 +614,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
                err = mtk_sgmii_init(eth);
  
                if (err)
-@@ -5108,6 +5319,24 @@ static int mtk_probe(struct platform_dev
+@@ -5249,6 +5460,24 @@ static int mtk_probe(struct platform_dev
                }
        }
  
@@ -639,7 +639,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) {
                err = devm_request_irq(eth->dev, eth->irq[0],
                                       mtk_handle_irq, 0,
-@@ -5218,6 +5447,11 @@ static void mtk_remove(struct platform_d
+@@ -5359,6 +5588,11 @@ static void mtk_remove(struct platform_d
                mtk_stop(eth->netdev[i]);
                mac = netdev_priv(eth->netdev[i]);
                phylink_disconnect_phy(mac->phylink);
@@ -661,7 +661,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  #include <linux/rhashtable.h>
  #include <linux/dim.h>
  #include <linux/bitfield.h>
-@@ -524,6 +525,21 @@
+@@ -527,6 +528,21 @@
  #define INTF_MODE_RGMII_1000    (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED)
  #define INTF_MODE_RGMII_10_100  0
  
@@ -683,7 +683,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  /* GPIO port control registers for GMAC 2*/
  #define GPIO_OD33_CTRL8               0x4c0
  #define GPIO_BIAS_CTRL                0xed0
-@@ -549,6 +565,7 @@
+@@ -552,6 +568,7 @@
  #define SYSCFG0_SGMII_GMAC2    ((3 << 8) & SYSCFG0_SGMII_MASK)
  #define SYSCFG0_SGMII_GMAC1_V2 BIT(9)
  #define SYSCFG0_SGMII_GMAC2_V2 BIT(8)
@@ -691,7 +691,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  
  
  /* ethernet subsystem clock register */
-@@ -587,6 +604,11 @@
+@@ -590,6 +607,11 @@
  #define GEPHY_MAC_SEL          BIT(1)
  
  /* Top misc registers */
@@ -703,7 +703,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  #define USB_PHY_SWITCH_REG    0x218
  #define QPHY_SEL_MASK         GENMASK(1, 0)
  #define SGMII_QPHY_SEL                0x2
-@@ -611,6 +633,8 @@
+@@ -614,6 +636,8 @@
  #define MT7628_SDM_RBCNT      (MT7628_SDM_OFFSET + 0x10c)
  #define MT7628_SDM_CS_ERR     (MT7628_SDM_OFFSET + 0x110)
  
@@ -712,7 +712,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  #define MTK_FE_CDM1_FSM               0x220
  #define MTK_FE_CDM2_FSM               0x224
  #define MTK_FE_CDM3_FSM               0x238
-@@ -619,6 +643,11 @@
+@@ -622,6 +646,11 @@
  #define MTK_FE_CDM6_FSM               0x328
  #define MTK_FE_GDM1_FSM               0x228
  #define MTK_FE_GDM2_FSM               0x22C
@@ -724,7 +724,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  
  #define MTK_MAC_FSM(x)                (0x1010C + ((x) * 0x100))
  
-@@ -951,6 +980,8 @@ enum mkt_eth_capabilities {
+@@ -945,6 +974,8 @@ enum mkt_eth_capabilities {
        MTK_RGMII_BIT = 0,
        MTK_TRGMII_BIT,
        MTK_SGMII_BIT,
@@ -733,7 +733,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        MTK_ESW_BIT,
        MTK_GEPHY_BIT,
        MTK_MUX_BIT,
-@@ -971,8 +1002,11 @@ enum mkt_eth_capabilities {
+@@ -965,8 +996,11 @@ enum mkt_eth_capabilities {
        MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
        MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT,
        MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT,
@@ -745,7 +745,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  
        /* PATH BITS */
        MTK_ETH_PATH_GMAC1_RGMII_BIT,
-@@ -980,14 +1014,21 @@ enum mkt_eth_capabilities {
+@@ -974,14 +1008,21 @@ enum mkt_eth_capabilities {
        MTK_ETH_PATH_GMAC1_SGMII_BIT,
        MTK_ETH_PATH_GMAC2_RGMII_BIT,
        MTK_ETH_PATH_GMAC2_SGMII_BIT,
@@ -767,7 +767,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  #define MTK_ESW                       BIT_ULL(MTK_ESW_BIT)
  #define MTK_GEPHY             BIT_ULL(MTK_GEPHY_BIT)
  #define MTK_MUX                       BIT_ULL(MTK_MUX_BIT)
-@@ -1010,10 +1051,16 @@ enum mkt_eth_capabilities {
+@@ -1004,10 +1045,16 @@ enum mkt_eth_capabilities {
        BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
  #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY          \
        BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
@@ -784,7 +784,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  
  /* Supported path present on SoCs */
  #define MTK_ETH_PATH_GMAC1_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
-@@ -1021,8 +1068,13 @@ enum mkt_eth_capabilities {
+@@ -1015,8 +1062,13 @@ enum mkt_eth_capabilities {
  #define MTK_ETH_PATH_GMAC1_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
  #define MTK_ETH_PATH_GMAC2_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
  #define MTK_ETH_PATH_GMAC2_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
@@ -798,7 +798,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  
  #define MTK_GMAC1_RGMII               (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
  #define MTK_GMAC1_TRGMII      (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
-@@ -1030,7 +1082,12 @@ enum mkt_eth_capabilities {
+@@ -1024,7 +1076,12 @@ enum mkt_eth_capabilities {
  #define MTK_GMAC2_RGMII               (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
  #define MTK_GMAC2_SGMII               (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
  #define MTK_GMAC2_GEPHY               (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
@@ -811,7 +811,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  
  /* MUXes present on SoCs */
  /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */
-@@ -1049,10 +1106,20 @@ enum mkt_eth_capabilities {
+@@ -1043,10 +1100,20 @@ enum mkt_eth_capabilities {
        (MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \
        MTK_SHARED_SGMII)
  
@@ -832,7 +832,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  #define MTK_HAS_CAPS(caps, _x)                (((caps) & (_x)) == (_x))
  
  #define MT7621_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
-@@ -1084,8 +1151,12 @@ enum mkt_eth_capabilities {
+@@ -1078,8 +1145,12 @@ enum mkt_eth_capabilities {
                      MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
                      MTK_RSTCTRL_PPE1 | MTK_SRAM)
  
@@ -847,7 +847,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  
  struct mtk_tx_dma_desc_info {
        dma_addr_t      addr;
-@@ -1333,6 +1404,9 @@ struct mtk_mac {
+@@ -1327,6 +1398,9 @@ struct mtk_mac {
        struct device_node              *of_node;
        struct phylink                  *phylink;
        struct phylink_config           phylink_config;
@@ -857,7 +857,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        struct mtk_eth                  *hw;
        struct mtk_hw_stats             *hw_stats;
        __be32                          hwlro_ip[MTK_MAX_LRO_IP_CNT];
-@@ -1456,6 +1530,19 @@ static inline u32 mtk_get_ib2_multicast_
+@@ -1450,6 +1524,19 @@ static inline u32 mtk_get_ib2_multicast_
        return MTK_FOE_IB2_MULTICAST;
  }
  
@@ -877,7 +877,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  /* read the hardware status register */
  void mtk_stats_update_mac(struct mtk_mac *mac);
  
-@@ -1464,8 +1551,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne
+@@ -1458,8 +1545,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne
  u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg);
  
  int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
index 7ec342a20f4d75908037ff43e3e827e19e9ba3eb..b45f7993c91535dc35a406720e07127fe69b6048 100644 (file)
@@ -30,8 +30,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -5482,7 +5482,7 @@ static const struct mtk_soc_data mt2701_
-               .desc_size = sizeof(struct mtk_rx_dma),
+@@ -5626,7 +5626,7 @@ static const struct mtk_soc_data mt2701_
+               DESC_SIZE(struct mtk_rx_dma),
                .irq_done_mask = MTK_RX_DONE_INT,
                .dma_l4_valid = RX_DMA_L4_VALID,
 -              .dma_size = MTK_DMA_SIZE(2K),
@@ -39,8 +39,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
        },
-@@ -5510,7 +5510,7 @@ static const struct mtk_soc_data mt7621_
-               .desc_size = sizeof(struct mtk_rx_dma),
+@@ -5654,7 +5654,7 @@ static const struct mtk_soc_data mt7621_
+               DESC_SIZE(struct mtk_rx_dma),
                .irq_done_mask = MTK_RX_DONE_INT,
                .dma_l4_valid = RX_DMA_L4_VALID,
 -              .dma_size = MTK_DMA_SIZE(2K),
@@ -48,8 +48,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
        },
-@@ -5540,7 +5540,7 @@ static const struct mtk_soc_data mt7622_
-               .desc_size = sizeof(struct mtk_rx_dma),
+@@ -5684,7 +5684,7 @@ static const struct mtk_soc_data mt7622_
+               DESC_SIZE(struct mtk_rx_dma),
                .irq_done_mask = MTK_RX_DONE_INT,
                .dma_l4_valid = RX_DMA_L4_VALID,
 -              .dma_size = MTK_DMA_SIZE(2K),
@@ -57,8 +57,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
        },
-@@ -5569,7 +5569,7 @@ static const struct mtk_soc_data mt7623_
-               .desc_size = sizeof(struct mtk_rx_dma),
+@@ -5713,7 +5713,7 @@ static const struct mtk_soc_data mt7623_
+               DESC_SIZE(struct mtk_rx_dma),
                .irq_done_mask = MTK_RX_DONE_INT,
                .dma_l4_valid = RX_DMA_L4_VALID,
 -              .dma_size = MTK_DMA_SIZE(2K),
@@ -66,8 +66,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
        },
-@@ -5595,7 +5595,7 @@ static const struct mtk_soc_data mt7629_
-               .desc_size = sizeof(struct mtk_rx_dma),
+@@ -5739,7 +5739,7 @@ static const struct mtk_soc_data mt7629_
+               DESC_SIZE(struct mtk_rx_dma),
                .irq_done_mask = MTK_RX_DONE_INT,
                .dma_l4_valid = RX_DMA_L4_VALID,
 -              .dma_size = MTK_DMA_SIZE(2K),
@@ -75,7 +75,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
        },
-@@ -5627,7 +5627,7 @@ static const struct mtk_soc_data mt7981_
+@@ -5771,7 +5771,7 @@ static const struct mtk_soc_data mt7981_
                .dma_l4_valid = RX_DMA_L4_VALID_V2,
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
@@ -84,7 +84,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        },
  };
  
-@@ -5657,7 +5657,7 @@ static const struct mtk_soc_data mt7986_
+@@ -5801,7 +5801,7 @@ static const struct mtk_soc_data mt7986_
                .dma_l4_valid = RX_DMA_L4_VALID_V2,
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
@@ -93,7 +93,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        },
  };
  
-@@ -5710,7 +5710,7 @@ static const struct mtk_soc_data rt5350_
+@@ -5854,7 +5854,7 @@ static const struct mtk_soc_data rt5350_
                .dma_l4_valid = RX_DMA_L4_VALID_PDMA,
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
index 26706de6ad890a197bc2229e597e4841f97fe8ff..63083192e65ca6759f68baf89c10cab611cecdf9 100644 (file)
@@ -25,7 +25,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        help
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4588,6 +4588,7 @@ static int mtk_get_sset_count(struct net
+@@ -4729,6 +4729,7 @@ static int mtk_get_sset_count(struct net
  
  static void mtk_ethtool_pp_stats(struct mtk_eth *eth, u64 *data)
  {
@@ -33,7 +33,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        struct page_pool_stats stats = {};
        int i;
  
-@@ -4600,6 +4601,7 @@ static void mtk_ethtool_pp_stats(struct
+@@ -4741,6 +4742,7 @@ static void mtk_ethtool_pp_stats(struct
                page_pool_get_stats(ring->page_pool, &stats);
        }
        page_pool_ethtool_stats_get(data, &stats);
index 20a6a29449724aeca0b223e650da47e44dbdce67..b72871385b192f5133ef93c45d76689df761a92e 100644 (file)
@@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1778,6 +1778,13 @@ static netdev_tx_t mtk_start_xmit(struct
+@@ -1918,6 +1918,13 @@ static netdev_tx_t mtk_start_xmit(struct
        bool gso = false;
        int tx_num;
  
@@ -26,7 +26,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        /* normally we can rely on the stack not calling this more than once,
         * however we have 2 queues running on the same ring so we need to lock
         * the ring access
-@@ -1841,8 +1848,9 @@ static netdev_tx_t mtk_start_xmit(struct
+@@ -1986,8 +1993,9 @@ send:
  
  drop:
        spin_unlock(&eth->page_lock);
diff --git a/target/linux/generic/pending-6.6/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch b/target/linux/generic/pending-6.6/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch
deleted file mode 100644 (file)
index bd7a1b9..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 28 Oct 2022 12:54:48 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: set NETIF_F_ALL_TSO
-
-Significantly improves performance by avoiding unnecessary segmentation
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -49,8 +49,7 @@
- #define MTK_HW_FEATURES               (NETIF_F_IP_CSUM | \
-                                NETIF_F_RXCSUM | \
-                                NETIF_F_HW_VLAN_CTAG_TX | \
--                               NETIF_F_SG | NETIF_F_TSO | \
--                               NETIF_F_TSO6 | \
-+                               NETIF_F_SG | NETIF_F_ALL_TSO | \
-                                NETIF_F_IPV6_CSUM |\
-                                NETIF_F_HW_TC)
- #define MTK_HW_FEATURES_MT7628        (NETIF_F_SG | NETIF_F_RXCSUM)
diff --git a/target/linux/generic/pending-6.6/732-03-net-ethernet-mtk_eth_soc-optimize-dma-ring-address-i.patch b/target/linux/generic/pending-6.6/732-03-net-ethernet-mtk_eth_soc-optimize-dma-ring-address-i.patch
new file mode 100644 (file)
index 0000000..89720a8
--- /dev/null
@@ -0,0 +1,486 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Tue, 15 Oct 2024 12:52:56 +0200
+Subject: [PATCH] net: ethernet: mtk_eth_soc: optimize dma ring address/index
+ calculation
+
+Since DMA descriptor sizes are all power of 2, we can avoid costly integer
+division in favor or simple shifts.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -43,6 +43,11 @@ MODULE_PARM_DESC(msg_level, "Message lev
+                                 offsetof(struct mtk_hw_stats, xdp_stats.x) / \
+                                 sizeof(u64) }
++#define RX_DESC_OFS(eth, i) \
++      ((i) << (eth)->soc->rx.desc_shift)
++#define TX_DESC_OFS(eth, i) \
++      ((i) << (eth)->soc->tx.desc_shift)
++
+ static const struct mtk_reg_map mtk_reg_map = {
+       .tx_irq_mask            = 0x1a1c,
+       .tx_irq_status          = 0x1a18,
+@@ -1159,14 +1164,14 @@ static int mtk_init_fq_dma(struct mtk_et
+               eth->scratch_ring = eth->sram_base;
+       else
+               eth->scratch_ring = dma_alloc_coherent(eth->dma_dev,
+-                                                     cnt * soc->tx.desc_size,
++                                                     TX_DESC_OFS(eth, cnt),
+                                                      &eth->phy_scratch_ring,
+                                                      GFP_KERNEL);
+       if (unlikely(!eth->scratch_ring))
+               return -ENOMEM;
+-      phy_ring_tail = eth->phy_scratch_ring + soc->tx.desc_size * (cnt - 1);
++      phy_ring_tail = eth->phy_scratch_ring + TX_DESC_OFS(eth, cnt - 1);
+       for (j = 0; j < DIV_ROUND_UP(soc->tx.fq_dma_size, MTK_FQ_DMA_LENGTH); j++) {
+               len = min_t(int, cnt - j * MTK_FQ_DMA_LENGTH, MTK_FQ_DMA_LENGTH);
+@@ -1185,11 +1190,11 @@ static int mtk_init_fq_dma(struct mtk_et
+               for (i = 0; i < len; i++) {
+                       struct mtk_tx_dma_v2 *txd;
+-                      txd = eth->scratch_ring + (j * MTK_FQ_DMA_LENGTH + i) * soc->tx.desc_size;
++                      txd = eth->scratch_ring + TX_DESC_OFS(eth, j * MTK_FQ_DMA_LENGTH + i);
+                       txd->txd1 = dma_addr + i * MTK_QDMA_PAGE_SIZE;
+                       if (j * MTK_FQ_DMA_LENGTH + i < cnt)
+                               txd->txd2 = eth->phy_scratch_ring +
+-                                          (j * MTK_FQ_DMA_LENGTH + i + 1) * soc->tx.desc_size;
++                                          TX_DESC_OFS(eth, j * MTK_FQ_DMA_LENGTH + i + 1);
+                       txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
+                       if (MTK_HAS_CAPS(soc->caps, MTK_36BIT_DMA))
+@@ -1219,9 +1224,9 @@ static void *mtk_qdma_phys_to_virt(struc
+ }
+ static struct mtk_tx_buf *mtk_desc_to_tx_buf(struct mtk_tx_ring *ring,
+-                                           void *txd, u32 txd_size)
++                                           void *txd, u32 txd_shift)
+ {
+-      int idx = (txd - ring->dma) / txd_size;
++      int idx = (txd - ring->dma) >> txd_shift;
+       return &ring->buf[idx];
+ }
+@@ -1232,9 +1237,9 @@ static struct mtk_tx_dma *qdma_to_pdma(s
+       return ring->dma_pdma - (struct mtk_tx_dma *)ring->dma + dma;
+ }
+-static int txd_to_idx(struct mtk_tx_ring *ring, void *dma, u32 txd_size)
++static int txd_to_idx(struct mtk_tx_ring *ring, void *dma, u32 txd_shift)
+ {
+-      return (dma - ring->dma) / txd_size;
++      return (dma - ring->dma) >> txd_shift;
+ }
+ static void mtk_tx_unmap(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf,
+@@ -1442,7 +1447,7 @@ static int mtk_tx_map(struct sk_buff *sk
+       if (itxd == ring->last_free)
+               return -ENOMEM;
+-      itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_size);
++      itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_shift);
+       memset(itx_buf, 0, sizeof(*itx_buf));
+       txd_info.addr = dma_map_single(eth->dma_dev, skb->data, txd_info.size,
+@@ -1496,7 +1501,7 @@ static int mtk_tx_map(struct sk_buff *sk
+                       mtk_tx_set_dma_desc(dev, txd, &txd_info);
+                       tx_buf = mtk_desc_to_tx_buf(ring, txd,
+-                                                  soc->tx.desc_size);
++                                                  soc->tx.desc_shift);
+                       if (new_desc)
+                               memset(tx_buf, 0, sizeof(*tx_buf));
+                       tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
+@@ -1539,7 +1544,7 @@ static int mtk_tx_map(struct sk_buff *sk
+       } else {
+               int next_idx;
+-              next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->tx.desc_size),
++              next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->tx.desc_shift),
+                                        ring->dma_size);
+               mtk_w32(eth, next_idx, MT7628_TX_CTX_IDX0);
+       }
+@@ -1548,7 +1553,7 @@ static int mtk_tx_map(struct sk_buff *sk
+ err_dma:
+       do {
+-              tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_size);
++              tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_shift);
+               /* unmap dma */
+               mtk_tx_unmap(eth, tx_buf, NULL, false);
+@@ -1714,7 +1719,7 @@ static struct mtk_rx_ring *mtk_get_rx_ri
+               ring = &eth->rx_ring[i];
+               idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
+-              rxd = ring->dma + idx * eth->soc->rx.desc_size;
++              rxd = ring->dma + RX_DESC_OFS(eth, idx);
+               if (rxd->rxd2 & RX_DMA_DONE) {
+                       ring->calc_idx_update = true;
+                       return ring;
+@@ -1882,7 +1887,7 @@ static int mtk_xdp_submit_frame(struct m
+       }
+       htxd = txd;
+-      tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->tx.desc_size);
++      tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->tx.desc_shift);
+       memset(tx_buf, 0, sizeof(*tx_buf));
+       htx_buf = tx_buf;
+@@ -1901,7 +1906,7 @@ static int mtk_xdp_submit_frame(struct m
+                               goto unmap;
+                       tx_buf = mtk_desc_to_tx_buf(ring, txd,
+-                                                  soc->tx.desc_size);
++                                                  soc->tx.desc_shift);
+                       memset(tx_buf, 0, sizeof(*tx_buf));
+                       n_desc++;
+               }
+@@ -1939,7 +1944,7 @@ static int mtk_xdp_submit_frame(struct m
+       } else {
+               int idx;
+-              idx = txd_to_idx(ring, txd, soc->tx.desc_size);
++              idx = txd_to_idx(ring, txd, soc->tx.desc_shift);
+               mtk_w32(eth, NEXT_DESP_IDX(idx, ring->dma_size),
+                       MT7628_TX_CTX_IDX0);
+       }
+@@ -1950,7 +1955,7 @@ static int mtk_xdp_submit_frame(struct m
+ unmap:
+       while (htxd != txd) {
+-              tx_buf = mtk_desc_to_tx_buf(ring, htxd, soc->tx.desc_size);
++              tx_buf = mtk_desc_to_tx_buf(ring, htxd, soc->tx.desc_shift);
+               mtk_tx_unmap(eth, tx_buf, NULL, false);
+               htxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
+@@ -2082,7 +2087,7 @@ static int mtk_poll_rx(struct napi_struc
+                       goto rx_done;
+               idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
+-              rxd = ring->dma + idx * eth->soc->rx.desc_size;
++              rxd = ring->dma + RX_DESC_OFS(eth, idx);
+               data = ring->data[idx];
+               if (!mtk_rx_get_desc(eth, &trxd, rxd))
+@@ -2346,7 +2351,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
+                       break;
+               tx_buf = mtk_desc_to_tx_buf(ring, desc,
+-                                          eth->soc->tx.desc_size);
++                                          eth->soc->tx.desc_shift);
+               if (!tx_buf->data)
+                       break;
+@@ -2397,7 +2402,7 @@ static int mtk_poll_tx_pdma(struct mtk_e
+               }
+               mtk_tx_unmap(eth, tx_buf, &bq, true);
+-              desc = ring->dma + cpu * eth->soc->tx.desc_size;
++              desc = ring->dma + TX_DESC_OFS(eth, cpu);
+               ring->last_free = desc;
+               atomic_inc(&ring->free_count);
+@@ -2515,7 +2520,7 @@ static int mtk_tx_alloc(struct mtk_eth *
+ {
+       const struct mtk_soc_data *soc = eth->soc;
+       struct mtk_tx_ring *ring = &eth->tx_ring;
+-      int i, sz = soc->tx.desc_size;
++      int i, sz = TX_DESC_OFS(eth, 1);
+       struct mtk_tx_dma_v2 *txd;
+       int ring_size;
+       u32 ofs, val;
+@@ -2562,7 +2567,7 @@ static int mtk_tx_alloc(struct mtk_eth *
+        * descriptors in ring->dma_pdma.
+        */
+       if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
+-              ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
++              ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, TX_DESC_OFS(eth, ring_size),
+                                                   &ring->phys_pdma, GFP_KERNEL);
+               if (!ring->dma_pdma)
+                       goto no_tx_mem;
+@@ -2577,7 +2582,7 @@ static int mtk_tx_alloc(struct mtk_eth *
+       atomic_set(&ring->free_count, ring_size - 2);
+       ring->next_free = ring->dma;
+       ring->last_free = (void *)txd;
+-      ring->last_free_ptr = (u32)(ring->phys + ((ring_size - 1) * sz));
++      ring->last_free_ptr = (u32)(ring->phys + TX_DESC_OFS(eth, ring_size - 1));
+       ring->thresh = MAX_SKB_FRAGS;
+       /* make sure that all changes to the dma ring are flushed before we
+@@ -2589,7 +2594,7 @@ static int mtk_tx_alloc(struct mtk_eth *
+               mtk_w32(eth, ring->phys, soc->reg_map->qdma.ctx_ptr);
+               mtk_w32(eth, ring->phys, soc->reg_map->qdma.dtx_ptr);
+               mtk_w32(eth,
+-                      ring->phys + ((ring_size - 1) * sz),
++                      ring->phys + TX_DESC_OFS(eth, ring_size - 1),
+                       soc->reg_map->qdma.crx_ptr);
+               mtk_w32(eth, ring->last_free_ptr, soc->reg_map->qdma.drx_ptr);
+@@ -2638,14 +2643,14 @@ static void mtk_tx_clean(struct mtk_eth
+       }
+       if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && ring->dma) {
+               dma_free_coherent(eth->dma_dev,
+-                                ring->dma_size * soc->tx.desc_size,
++                                TX_DESC_OFS(eth, ring->dma_size),
+                                 ring->dma, ring->phys);
+               ring->dma = NULL;
+       }
+       if (ring->dma_pdma) {
+               dma_free_coherent(eth->dma_dev,
+-                                ring->dma_size * soc->tx.desc_size,
++                                TX_DESC_OFS(eth, ring->dma_size),
+                                 ring->dma_pdma, ring->phys_pdma);
+               ring->dma_pdma = NULL;
+       }
+@@ -2701,15 +2706,13 @@ static int mtk_rx_alloc(struct mtk_eth *
+       if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM) ||
+           rx_flag != MTK_RX_FLAGS_NORMAL) {
+               ring->dma = dma_alloc_coherent(eth->dma_dev,
+-                              rx_dma_size * eth->soc->rx.desc_size,
++                              RX_DESC_OFS(eth, rx_dma_size),
+                               &ring->phys, GFP_KERNEL);
+       } else {
+               struct mtk_tx_ring *tx_ring = &eth->tx_ring;
+-              ring->dma = tx_ring->dma + tx_ring_size *
+-                          eth->soc->tx.desc_size * (ring_no + 1);
+-              ring->phys = tx_ring->phys + tx_ring_size *
+-                           eth->soc->tx.desc_size * (ring_no + 1);
++              ring->dma = tx_ring->dma + TX_DESC_OFS(eth, tx_ring_size * (ring_no + 1));
++              ring->phys = tx_ring->phys + TX_DESC_OFS(eth, tx_ring_size * (ring_no + 1));
+       }
+       if (!ring->dma)
+@@ -2720,7 +2723,7 @@ static int mtk_rx_alloc(struct mtk_eth *
+               dma_addr_t dma_addr;
+               void *data;
+-              rxd = ring->dma + i * eth->soc->rx.desc_size;
++              rxd = ring->dma + RX_DESC_OFS(eth, i);
+               if (ring->page_pool) {
+                       data = mtk_page_pool_get_buff(ring->page_pool,
+                                                     &dma_addr, GFP_KERNEL);
+@@ -2811,7 +2814,7 @@ static void mtk_rx_clean(struct mtk_eth
+                       if (!ring->data[i])
+                               continue;
+-                      rxd = ring->dma + i * eth->soc->rx.desc_size;
++                      rxd = ring->dma + RX_DESC_OFS(eth, i);
+                       if (!rxd->rxd1)
+                               continue;
+@@ -2828,7 +2831,7 @@ static void mtk_rx_clean(struct mtk_eth
+       if (!in_sram && ring->dma) {
+               dma_free_coherent(eth->dma_dev,
+-                                ring->dma_size * eth->soc->rx.desc_size,
++                                RX_DESC_OFS(eth, ring->dma_size),
+                                 ring->dma, ring->phys);
+               ring->dma = NULL;
+       }
+@@ -3199,7 +3202,7 @@ static void mtk_dma_free(struct mtk_eth
+       if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) {
+               dma_free_coherent(eth->dma_dev,
+-                                MTK_QDMA_RING_SIZE * soc->tx.desc_size,
++                                TX_DESC_OFS(eth, MTK_QDMA_RING_SIZE),
+                                 eth->scratch_ring, eth->phy_scratch_ring);
+               eth->scratch_ring = NULL;
+               eth->phy_scratch_ring = 0;
+@@ -5220,6 +5223,9 @@ static int mtk_remove(struct platform_de
+       return 0;
+ }
++#define DESC_SIZE(struct_name)                                \
++      .desc_shift = const_ilog2(sizeof(struct_name))
++
+ static const struct mtk_soc_data mt2701_data = {
+       .reg_map = &mtk_reg_map,
+       .caps = MT7623_CAPS | MTK_HWLRO,
+@@ -5228,14 +5234,14 @@ static const struct mtk_soc_data mt2701_
+       .required_pctl = true,
+       .version = 1,
+       .tx = {
+-              .desc_size = sizeof(struct mtk_tx_dma),
++              DESC_SIZE(struct mtk_tx_dma),
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+               .dma_len_offset = 16,
+               .dma_size = MTK_DMA_SIZE(2K),
+               .fq_dma_size = MTK_DMA_SIZE(2K),
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma),
++              DESC_SIZE(struct mtk_rx_dma),
+               .irq_done_mask = MTK_RX_DONE_INT,
+               .dma_l4_valid = RX_DMA_L4_VALID,
+               .dma_size = MTK_DMA_SIZE(2K),
+@@ -5256,14 +5262,14 @@ static const struct mtk_soc_data mt7621_
+       .hash_offset = 2,
+       .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+       .tx = {
+-              .desc_size = sizeof(struct mtk_tx_dma),
++              DESC_SIZE(struct mtk_tx_dma),
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+               .dma_len_offset = 16,
+               .dma_size = MTK_DMA_SIZE(2K),
+               .fq_dma_size = MTK_DMA_SIZE(2K),
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma),
++              DESC_SIZE(struct mtk_rx_dma),
+               .irq_done_mask = MTK_RX_DONE_INT,
+               .dma_l4_valid = RX_DMA_L4_VALID,
+               .dma_size = MTK_DMA_SIZE(2K),
+@@ -5286,14 +5292,14 @@ static const struct mtk_soc_data mt7622_
+       .has_accounting = true,
+       .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+       .tx = {
+-              .desc_size = sizeof(struct mtk_tx_dma),
++              DESC_SIZE(struct mtk_tx_dma),
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+               .dma_len_offset = 16,
+               .dma_size = MTK_DMA_SIZE(2K),
+               .fq_dma_size = MTK_DMA_SIZE(2K),
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma),
++              DESC_SIZE(struct mtk_rx_dma),
+               .irq_done_mask = MTK_RX_DONE_INT,
+               .dma_l4_valid = RX_DMA_L4_VALID,
+               .dma_size = MTK_DMA_SIZE(2K),
+@@ -5315,14 +5321,14 @@ static const struct mtk_soc_data mt7623_
+       .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+       .disable_pll_modes = true,
+       .tx = {
+-              .desc_size = sizeof(struct mtk_tx_dma),
++              DESC_SIZE(struct mtk_tx_dma),
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+               .dma_len_offset = 16,
+               .dma_size = MTK_DMA_SIZE(2K),
+               .fq_dma_size = MTK_DMA_SIZE(2K),
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma),
++              DESC_SIZE(struct mtk_rx_dma),
+               .irq_done_mask = MTK_RX_DONE_INT,
+               .dma_l4_valid = RX_DMA_L4_VALID,
+               .dma_size = MTK_DMA_SIZE(2K),
+@@ -5341,14 +5347,14 @@ static const struct mtk_soc_data mt7629_
+       .has_accounting = true,
+       .version = 1,
+       .tx = {
+-              .desc_size = sizeof(struct mtk_tx_dma),
++              DESC_SIZE(struct mtk_tx_dma),
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+               .dma_len_offset = 16,
+               .dma_size = MTK_DMA_SIZE(2K),
+               .fq_dma_size = MTK_DMA_SIZE(2K),
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma),
++              DESC_SIZE(struct mtk_rx_dma),
+               .irq_done_mask = MTK_RX_DONE_INT,
+               .dma_l4_valid = RX_DMA_L4_VALID,
+               .dma_size = MTK_DMA_SIZE(2K),
+@@ -5371,14 +5377,14 @@ static const struct mtk_soc_data mt7981_
+       .has_accounting = true,
+       .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
+       .tx = {
+-              .desc_size = sizeof(struct mtk_tx_dma_v2),
++              DESC_SIZE(struct mtk_tx_dma_v2),
+               .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
+               .dma_len_offset = 8,
+               .dma_size = MTK_DMA_SIZE(2K),
+               .fq_dma_size = MTK_DMA_SIZE(2K),
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma),
++              DESC_SIZE(struct mtk_rx_dma),
+               .irq_done_mask = MTK_RX_DONE_INT,
+               .dma_l4_valid = RX_DMA_L4_VALID_V2,
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+@@ -5401,14 +5407,14 @@ static const struct mtk_soc_data mt7986_
+       .has_accounting = true,
+       .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
+       .tx = {
+-              .desc_size = sizeof(struct mtk_tx_dma_v2),
++              DESC_SIZE(struct mtk_tx_dma_v2),
+               .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
+               .dma_len_offset = 8,
+               .dma_size = MTK_DMA_SIZE(2K),
+               .fq_dma_size = MTK_DMA_SIZE(2K),
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma),
++              DESC_SIZE(struct mtk_rx_dma),
+               .irq_done_mask = MTK_RX_DONE_INT,
+               .dma_l4_valid = RX_DMA_L4_VALID_V2,
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+@@ -5431,14 +5437,14 @@ static const struct mtk_soc_data mt7988_
+       .has_accounting = true,
+       .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE,
+       .tx = {
+-              .desc_size = sizeof(struct mtk_tx_dma_v2),
++              DESC_SIZE(struct mtk_tx_dma_v2),
+               .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
+               .dma_len_offset = 8,
+               .dma_size = MTK_DMA_SIZE(2K),
+               .fq_dma_size = MTK_DMA_SIZE(4K),
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma_v2),
++              DESC_SIZE(struct mtk_rx_dma_v2),
+               .irq_done_mask = MTK_RX_DONE_INT_V2,
+               .dma_l4_valid = RX_DMA_L4_VALID_V2,
+               .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
+@@ -5455,13 +5461,13 @@ static const struct mtk_soc_data rt5350_
+       .required_pctl = false,
+       .version = 1,
+       .tx = {
+-              .desc_size = sizeof(struct mtk_tx_dma),
++              DESC_SIZE(struct mtk_tx_dma),
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+               .dma_len_offset = 16,
+               .dma_size = MTK_DMA_SIZE(2K),
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma),
++              DESC_SIZE(struct mtk_rx_dma),
+               .irq_done_mask = MTK_RX_DONE_INT,
+               .dma_l4_valid = RX_DMA_L4_VALID_PDMA,
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -1174,7 +1174,7 @@ struct mtk_reg_map {
+  * @foe_entry_size            Foe table entry size.
+  * @has_accounting            Bool indicating support for accounting of
+  *                            offloaded flows.
+- * @desc_size                 Tx/Rx DMA descriptor size.
++ * @desc_shift                        Tx/Rx DMA descriptor size (in power-of-2).
+  * @irq_done_mask             Rx irq done register mask.
+  * @dma_l4_valid              Rx DMA valid register mask.
+  * @dma_max_len                       Max DMA tx/rx buffer length.
+@@ -1195,14 +1195,14 @@ struct mtk_soc_data {
+       bool            has_accounting;
+       bool            disable_pll_modes;
+       struct {
+-              u32     desc_size;
++              u32     desc_shift;
+               u32     dma_max_len;
+               u32     dma_len_offset;
+               u32     dma_size;
+               u32     fq_dma_size;
+       } tx;
+       struct {
+-              u32     desc_size;
++              u32     desc_shift;
+               u32     irq_done_mask;
+               u32     dma_l4_valid;
+               u32     dma_max_len;
diff --git a/target/linux/generic/pending-6.6/732-04-net-ethernet-mtk_eth_soc-shrink-struct-mtk_tx_buf.patch b/target/linux/generic/pending-6.6/732-04-net-ethernet-mtk_eth_soc-shrink-struct-mtk_tx_buf.patch
new file mode 100644 (file)
index 0000000..b14e9bd
--- /dev/null
@@ -0,0 +1,124 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Mon, 14 Jul 2025 10:52:59 +0200
+Subject: [PATCH] net: ethernet: mtk_eth_soc: shrink struct mtk_tx_buf
+
+There is no need to track the difference between dma_map_page
+and dma_map_single, since they're unmapped in exactly the same way.
+Also reorder fields in order to avoid padding.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1245,32 +1245,19 @@ static int txd_to_idx(struct mtk_tx_ring
+ static void mtk_tx_unmap(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf,
+                        struct xdp_frame_bulk *bq, bool napi)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) {
+-              if (tx_buf->flags & MTK_TX_FLAGS_SINGLE0) {
+-                      dma_unmap_single(eth->dma_dev,
+-                                       dma_unmap_addr(tx_buf, dma_addr0),
+-                                       dma_unmap_len(tx_buf, dma_len0),
+-                                       DMA_TO_DEVICE);
+-              } else if (tx_buf->flags & MTK_TX_FLAGS_PAGE0) {
+-                      dma_unmap_page(eth->dma_dev,
+-                                     dma_unmap_addr(tx_buf, dma_addr0),
+-                                     dma_unmap_len(tx_buf, dma_len0),
+-                                     DMA_TO_DEVICE);
+-              }
+-      } else {
+-              if (dma_unmap_len(tx_buf, dma_len0)) {
+-                      dma_unmap_page(eth->dma_dev,
+-                                     dma_unmap_addr(tx_buf, dma_addr0),
+-                                     dma_unmap_len(tx_buf, dma_len0),
+-                                     DMA_TO_DEVICE);
+-              }
++      if (dma_unmap_len(tx_buf, dma_len0)) {
++              dma_unmap_page(eth->dma_dev,
++                             dma_unmap_addr(tx_buf, dma_addr0),
++                             dma_unmap_len(tx_buf, dma_len0),
++                             DMA_TO_DEVICE);
++      }
+-              if (dma_unmap_len(tx_buf, dma_len1)) {
+-                      dma_unmap_page(eth->dma_dev,
+-                                     dma_unmap_addr(tx_buf, dma_addr1),
+-                                     dma_unmap_len(tx_buf, dma_len1),
+-                                     DMA_TO_DEVICE);
+-              }
++      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA) &&
++          dma_unmap_len(tx_buf, dma_len1)) {
++              dma_unmap_page(eth->dma_dev,
++                             dma_unmap_addr(tx_buf, dma_addr1),
++                             dma_unmap_len(tx_buf, dma_len1),
++                             DMA_TO_DEVICE);
+       }
+       if (tx_buf->data && tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
+@@ -1292,7 +1279,6 @@ static void mtk_tx_unmap(struct mtk_eth
+                               xdp_return_frame(xdpf);
+               }
+       }
+-      tx_buf->flags = 0;
+       tx_buf->data = NULL;
+ }
+@@ -1457,7 +1443,6 @@ static int mtk_tx_map(struct sk_buff *sk
+       mtk_tx_set_dma_desc(dev, itxd, &txd_info);
+-      itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
+       itx_buf->mac_id = mac->id;
+       setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
+                    k++);
+@@ -1505,7 +1490,6 @@ static int mtk_tx_map(struct sk_buff *sk
+                       if (new_desc)
+                               memset(tx_buf, 0, sizeof(*tx_buf));
+                       tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
+-                      tx_buf->flags |= MTK_TX_FLAGS_PAGE0;
+                       tx_buf->mac_id = mac->id;
+                       setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr,
+@@ -1830,8 +1814,6 @@ static int mtk_xdp_frame_map(struct mtk_
+                                               txd_info->size, DMA_TO_DEVICE);
+               if (unlikely(dma_mapping_error(eth->dma_dev, txd_info->addr)))
+                       return -ENOMEM;
+-
+-              tx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
+       } else {
+               struct page *page = virt_to_head_page(data);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -701,14 +701,6 @@ struct mtk_hw_stats {
+       struct u64_stats_sync   syncp;
+ };
+-enum mtk_tx_flags {
+-      /* PDMA descriptor can point at 1-2 segments. This enum allows us to
+-       * track how memory was allocated so that it can be freed properly.
+-       */
+-      MTK_TX_FLAGS_SINGLE0    = 0x01,
+-      MTK_TX_FLAGS_PAGE0      = 0x02,
+-};
+-
+ /* This enum allows us to identify how the clock is defined on the array of the
+  * clock in the order
+  */
+@@ -895,13 +887,12 @@ enum mtk_tx_buf_type {
+  */
+ struct mtk_tx_buf {
+       enum mtk_tx_buf_type type;
++      u16 mac_id;
+       void *data;
+-      u16 mac_id;
+-      u16 flags;
+       DEFINE_DMA_UNMAP_ADDR(dma_addr0);
+-      DEFINE_DMA_UNMAP_LEN(dma_len0);
+       DEFINE_DMA_UNMAP_ADDR(dma_addr1);
++      DEFINE_DMA_UNMAP_LEN(dma_len0);
+       DEFINE_DMA_UNMAP_LEN(dma_len1);
+ };
diff --git a/target/linux/generic/pending-6.6/732-05-net-ethernet-mtk_eth_soc-add-support-for-sending-fra.patch b/target/linux/generic/pending-6.6/732-05-net-ethernet-mtk_eth_soc-add-support-for-sending-fra.patch
new file mode 100644 (file)
index 0000000..c36a238
--- /dev/null
@@ -0,0 +1,303 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Mon, 14 Jul 2025 10:41:27 +0200
+Subject: [PATCH] net: ethernet: mtk_eth_soc: add support for sending
+ fraglist GSO packets
+
+When primarily forwarding traffic, TCP fraglist GRO can be noticeably more
+efficient than regular TCP GRO. In order to avoid the overhead of
+unnecessary segmentation on ethernet tx, add support for sending fraglist
+GRO packets.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1403,29 +1403,70 @@ static void mtk_tx_set_dma_desc(struct n
+               mtk_tx_set_dma_desc_v1(dev, txd, info);
+ }
++struct mtk_tx_map_state {
++    struct mtk_tx_dma *txd, *txd_pdma;
++    struct mtk_tx_buf *tx_buf;
++    int nbuf;
++    int ndesc;
++};
++
++static int
++mtk_tx_map_info(struct mtk_eth *eth, struct mtk_tx_ring *ring,
++              struct net_device *dev, struct mtk_tx_map_state *state,
++              struct mtk_tx_dma_desc_info *txd_info)
++{
++      const struct mtk_soc_data *soc = eth->soc;
++      struct mtk_tx_dma *txd_pdma = state->txd_pdma;
++      struct mtk_tx_buf *tx_buf = state->tx_buf;
++      struct mtk_tx_dma *txd = state->txd;
++      struct mtk_mac *mac = netdev_priv(dev);
++
++      if (state->nbuf &&
++          (MTK_HAS_CAPS(soc->caps, MTK_QDMA) || (state->nbuf & 1) == 0)) {
++              txd = state->txd = mtk_qdma_phys_to_virt(ring, txd->txd2);
++              txd_pdma = state->txd_pdma = qdma_to_pdma(ring, txd);
++              if (state->txd == ring->last_free)
++                      return -1;
++
++              tx_buf = mtk_desc_to_tx_buf(ring, state->txd,
++                                          soc->tx.desc_shift);
++              state->tx_buf = tx_buf;
++              memset(tx_buf, 0, sizeof(*tx_buf));
++              state->ndesc++;
++      }
++
++      mtk_tx_set_dma_desc(dev, txd, txd_info);
++      tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
++      tx_buf->mac_id = mac->id;
++
++      setup_tx_buf(eth, tx_buf, txd_pdma, txd_info->addr,
++                   txd_info->size, state->nbuf++);
++      return 0;
++}
++
+ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
+                     int tx_num, struct mtk_tx_ring *ring, bool gso)
+ {
+       struct mtk_tx_dma_desc_info txd_info = {
+-              .size = skb_headlen(skb),
+               .gso = gso,
+-              .csum = skb->ip_summed == CHECKSUM_PARTIAL,
++              .csum = skb->ip_summed == CHECKSUM_PARTIAL || gso,
+               .vlan = skb_vlan_tag_present(skb),
+-              .qid = skb_get_queue_mapping(skb),
+               .vlan_tci = skb_vlan_tag_get(skb),
+               .first = true,
+-              .last = !skb_is_nonlinear(skb),
++      };
++      struct mtk_tx_map_state state = {
++              .ndesc = 1,
+       };
+       struct netdev_queue *txq;
+       struct mtk_mac *mac = netdev_priv(dev);
+       struct mtk_eth *eth = mac->hw;
+       const struct mtk_soc_data *soc = eth->soc;
+-      struct mtk_tx_dma *itxd, *txd;
+-      struct mtk_tx_dma *itxd_pdma, *txd_pdma;
+-      struct mtk_tx_buf *itx_buf, *tx_buf;
+-      int i, n_desc = 1;
++      struct mtk_tx_dma *itxd, *itxd_pdma;
++      struct mtk_tx_buf *itx_buf;
++      struct sk_buff *cur_skb, *next_skb;
+       int queue = skb_get_queue_mapping(skb);
+-      int k = 0;
++      unsigned int offset = 0;
++      int i, frag_size;
+       txq = netdev_get_tx_queue(dev, queue);
+       itxd = ring->next_free;
+@@ -1436,86 +1477,81 @@ static int mtk_tx_map(struct sk_buff *sk
+       itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_shift);
+       memset(itx_buf, 0, sizeof(*itx_buf));
+-      txd_info.addr = dma_map_single(eth->dma_dev, skb->data, txd_info.size,
+-                                     DMA_TO_DEVICE);
+-      if (unlikely(dma_mapping_error(eth->dma_dev, txd_info.addr)))
+-              return -ENOMEM;
+-
+-      mtk_tx_set_dma_desc(dev, itxd, &txd_info);
+-
+-      itx_buf->mac_id = mac->id;
+-      setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
+-                   k++);
+-
+-      /* TX SG offload */
+-      txd = itxd;
+-      txd_pdma = qdma_to_pdma(ring, txd);
+-
+-      for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+-              skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+-              unsigned int offset = 0;
+-              int frag_size = skb_frag_size(frag);
+-
++      cur_skb = skb;
++      next_skb = skb_shinfo(skb)->frag_list;
++      state.txd = itxd;
++      state.txd_pdma = itxd_pdma;
++      state.tx_buf = itx_buf;
++
++next:
++      txd_info.qid = queue;
++      frag_size = skb_headlen(cur_skb);
++
++      while (frag_size) {
++              txd_info.size = min_t(unsigned int, frag_size,
++                                    soc->tx.dma_max_len);
++              txd_info.addr = dma_map_single(eth->dma_dev, cur_skb->data + offset,
++                                             txd_info.size, DMA_TO_DEVICE);
++              if (unlikely(dma_mapping_error(eth->dma_dev, txd_info.addr)))
++                      goto err_dma;
++
++              frag_size -= txd_info.size;
++              offset += txd_info.size;
++              txd_info.last = !skb_is_nonlinear(cur_skb) && !next_skb &&
++                              !frag_size;
++              if (mtk_tx_map_info(eth, ring, dev, &state, &txd_info) < 0)
++                      goto err_dma;
++
++              txd_info.first = false;
++      }
++
++      for (i = 0; i < skb_shinfo(cur_skb)->nr_frags; i++) {
++              skb_frag_t *frag = &skb_shinfo(cur_skb)->frags[i];
++
++              frag_size = skb_frag_size(frag);
++              memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
++              txd_info.qid = queue;
++              offset = 0;
+               while (frag_size) {
+-                      bool new_desc = true;
+-
+-                      if (MTK_HAS_CAPS(soc->caps, MTK_QDMA) ||
+-                          (i & 0x1)) {
+-                              txd = mtk_qdma_phys_to_virt(ring, txd->txd2);
+-                              txd_pdma = qdma_to_pdma(ring, txd);
+-                              if (txd == ring->last_free)
+-                                      goto err_dma;
+-
+-                              n_desc++;
+-                      } else {
+-                              new_desc = false;
+-                      }
+-
+-                      memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
+                       txd_info.size = min_t(unsigned int, frag_size,
+                                             soc->tx.dma_max_len);
+-                      txd_info.qid = queue;
+-                      txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 &&
+-                                      !(frag_size - txd_info.size);
+-                      txd_info.addr = skb_frag_dma_map(eth->dma_dev, frag,
+-                                                       offset, txd_info.size,
+-                                                       DMA_TO_DEVICE);
++                      txd_info.addr = skb_frag_dma_map(eth->dma_dev, frag, offset,
++                                                       txd_info.size, DMA_TO_DEVICE);
+                       if (unlikely(dma_mapping_error(eth->dma_dev, txd_info.addr)))
+                               goto err_dma;
+-                      mtk_tx_set_dma_desc(dev, txd, &txd_info);
+-
+-                      tx_buf = mtk_desc_to_tx_buf(ring, txd,
+-                                                  soc->tx.desc_shift);
+-                      if (new_desc)
+-                              memset(tx_buf, 0, sizeof(*tx_buf));
+-                      tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
+-                      tx_buf->mac_id = mac->id;
+-
+-                      setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr,
+-                                   txd_info.size, k++);
+-
+                       frag_size -= txd_info.size;
+                       offset += txd_info.size;
++                      txd_info.last = i == skb_shinfo(cur_skb)->nr_frags - 1 &&
++                                      !frag_size && !next_skb;
++                      if (mtk_tx_map_info(eth, ring, dev, &state, &txd_info) < 0)
++                              goto err_dma;
+               }
+       }
++      if (next_skb) {
++              cur_skb = next_skb;
++              next_skb = cur_skb->next;
++              memset(&txd_info, 0, sizeof(txd_info));
++              goto next;
++      }
++
+       /* store skb to cleanup */
+       itx_buf->type = MTK_TYPE_SKB;
+       itx_buf->data = skb;
+       if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
+-              if (k & 0x1)
+-                      txd_pdma->txd2 |= TX_DMA_LS0;
++              if (state.nbuf & 0x1)
++                      state.txd_pdma->txd2 |= TX_DMA_LS0;
+               else
+-                      txd_pdma->txd2 |= TX_DMA_LS1;
++                      state.txd_pdma->txd2 |= TX_DMA_LS1;
+       }
+       netdev_tx_sent_queue(txq, skb->len);
+       skb_tx_timestamp(skb);
+-      ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2);
+-      atomic_sub(n_desc, &ring->free_count);
++      ring->next_free = mtk_qdma_phys_to_virt(ring, state.txd->txd2);
++      atomic_sub(state.ndesc, &ring->free_count);
+       /* make sure that all changes to the dma ring are flushed before we
+        * continue
+@@ -1524,11 +1560,11 @@ static int mtk_tx_map(struct sk_buff *sk
+       if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
+               if (netif_xmit_stopped(txq) || !netdev_xmit_more())
+-                      mtk_w32(eth, txd->txd2, soc->reg_map->qdma.ctx_ptr);
++                      mtk_w32(eth, state.txd->txd2, soc->reg_map->qdma.ctx_ptr);
+       } else {
+               int next_idx;
+-              next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->tx.desc_shift),
++              next_idx = NEXT_DESP_IDX(txd_to_idx(ring, state.txd, soc->tx.desc_shift),
+                                        ring->dma_size);
+               mtk_w32(eth, next_idx, MT7628_TX_CTX_IDX0);
+       }
+@@ -1537,10 +1573,10 @@ static int mtk_tx_map(struct sk_buff *sk
+ err_dma:
+       do {
+-              tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_shift);
++              itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_shift);
+               /* unmap dma */
+-              mtk_tx_unmap(eth, tx_buf, NULL, false);
++              mtk_tx_unmap(eth, itx_buf, NULL, false);
+               itxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
+               if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA))
+@@ -1548,7 +1584,7 @@ err_dma:
+               itxd = mtk_qdma_phys_to_virt(ring, itxd->txd2);
+               itxd_pdma = qdma_to_pdma(ring, itxd);
+-      } while (itxd != txd);
++      } while (itxd != state.txd);
+       return -ENOMEM;
+ }
+@@ -1568,6 +1604,9 @@ static int mtk_cal_txd_req(struct mtk_et
+               nfrags += skb_shinfo(skb)->nr_frags;
+       }
++      for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next)
++              nfrags += mtk_cal_txd_req(eth, skb);
++
+       return nfrags;
+ }
+@@ -1608,6 +1647,10 @@ static bool mtk_skb_has_small_frag(struc
+               if (skb_frag_size(&skb_shinfo(skb)->frags[i]) < min_size)
+                       return true;
++      for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next)
++              if (mtk_skb_has_small_frag(skb))
++                      return true;
++
+       return false;
+ }
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -51,6 +51,8 @@
+                                NETIF_F_HW_VLAN_CTAG_TX | \
+                                NETIF_F_SG | NETIF_F_TSO | \
+                                NETIF_F_TSO6 | \
++                               NETIF_F_FRAGLIST | \
++                               NETIF_F_GSO_FRAGLIST | \
+                                NETIF_F_IPV6_CSUM |\
+                                NETIF_F_HW_TC)
+ #define MTK_HW_FEATURES_MT7628        (NETIF_F_SG | NETIF_F_RXCSUM)
index a2a10d141707861c750aca2e8ad77701ccc568f2..b91820b9b1609f134838f9721d4efd9411a031f1 100644 (file)
@@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2150,7 +2150,7 @@ static int mtk_poll_rx(struct napi_struc
+@@ -2180,7 +2180,7 @@ static int mtk_poll_rx(struct napi_struc
                        if (ret != XDP_PASS)
                                goto skip_rx;
  
@@ -19,7 +19,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                        if (unlikely(!skb)) {
                                page_pool_put_full_page(ring->page_pool,
                                                        page, true);
-@@ -2188,7 +2188,7 @@ static int mtk_poll_rx(struct napi_struc
+@@ -2218,7 +2218,7 @@ static int mtk_poll_rx(struct napi_struc
                        dma_unmap_single(eth->dma_dev, ((u64)trxd.rxd1 | addr64),
                                         ring->buf_size, DMA_FROM_DEVICE);
  
index 7274c4a817d6431dd4cac15b869aee24028418f9..ead70343a75ae408f693d6b720427c244a7ae01d 100644 (file)
@@ -15,7 +15,7 @@ Signed-off-by: Chad Monroe <chad@monroe.io>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -279,6 +279,7 @@
+@@ -282,6 +282,7 @@
  #define MTK_WCOMP_EN          BIT(24)
  #define MTK_RESV_BUF          (0x80 << 16)
  #define MTK_MUTLI_CNT         (0x4 << 12)
@@ -25,7 +25,7 @@ Signed-off-by: Chad Monroe <chad@monroe.io>
  /* QDMA Flow Control Register */
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3323,12 +3323,14 @@ static int mtk_start_dma(struct mtk_eth
+@@ -3351,12 +3351,14 @@ static int mtk_start_dma(struct mtk_eth
                       MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
                       MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE;
  
index 392e94dc8a91c1b19025b6641ac96913c0669602..85cb5b06f0ddaec22ce614ac7e63321556cbfa0d 100644 (file)
@@ -214,7 +214,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  #include <linux/jhash.h>
  #include <linux/bitfield.h>
  #include <net/dsa.h>
-@@ -270,12 +272,8 @@ static const char * const mtk_clks_sourc
+@@ -275,12 +277,8 @@ static const char * const mtk_clks_sourc
        "ethwarp_wocpu2",
        "ethwarp_wocpu1",
        "ethwarp_wocpu0",
@@ -227,7 +227,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        "top_eth_gmii_sel",
        "top_eth_refck_50m_sel",
        "top_eth_sys_200m_sel",
-@@ -518,6 +516,30 @@ static void mtk_setup_bridge_switch(stru
+@@ -523,6 +521,30 @@ static void mtk_setup_bridge_switch(stru
                MTK_GSW_CFG);
  }
  
@@ -258,7 +258,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
                                              phy_interface_t interface)
  {
-@@ -526,6 +548,21 @@ static struct phylink_pcs *mtk_mac_selec
+@@ -531,6 +553,21 @@ static struct phylink_pcs *mtk_mac_selec
        struct mtk_eth *eth = mac->hw;
        unsigned int sid;
  
@@ -280,7 +280,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        if (interface == PHY_INTERFACE_MODE_SGMII ||
            phy_interface_mode_is_8023z(interface)) {
                sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
-@@ -577,7 +614,22 @@ static void mtk_mac_config(struct phylin
+@@ -582,7 +619,22 @@ static void mtk_mac_config(struct phylin
                                        goto init_err;
                        }
                        break;
@@ -303,7 +303,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
                        break;
                default:
                        goto err_phy;
-@@ -624,8 +676,6 @@ static void mtk_mac_config(struct phylin
+@@ -629,8 +681,6 @@ static void mtk_mac_config(struct phylin
                val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id);
                val |= SYSCFG0_GE_MODE(ge_mode, mac->id);
                regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val);
@@ -312,7 +312,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        }
  
        /* SGMII */
-@@ -642,21 +692,40 @@ static void mtk_mac_config(struct phylin
+@@ -647,21 +697,40 @@ static void mtk_mac_config(struct phylin
  
                /* Save the syscfg0 value for mac_finish */
                mac->syscfg0 = val;
@@ -360,7 +360,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        return;
  
  err_phy:
-@@ -669,6 +738,18 @@ init_err:
+@@ -674,6 +743,18 @@ init_err:
                mac->id, phy_modes(state->interface), err);
  }
  
@@ -379,7 +379,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  static int mtk_mac_finish(struct phylink_config *config, unsigned int mode,
                          phy_interface_t interface)
  {
-@@ -677,6 +758,10 @@ static int mtk_mac_finish(struct phylink
+@@ -682,6 +763,10 @@ static int mtk_mac_finish(struct phylink
        struct mtk_eth *eth = mac->hw;
        u32 mcr_cur, mcr_new;
  
@@ -390,7 +390,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        /* Enable SGMII */
        if (interface == PHY_INTERFACE_MODE_SGMII ||
            phy_interface_mode_is_8023z(interface))
-@@ -701,10 +786,14 @@ static void mtk_mac_link_down(struct phy
+@@ -706,10 +791,14 @@ static void mtk_mac_link_down(struct phy
  {
        struct mtk_mac *mac = container_of(config, struct mtk_mac,
                                           phylink_config);
@@ -408,7 +408,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  }
  
  static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
-@@ -776,13 +865,11 @@ static void mtk_set_queue_speed(struct m
+@@ -781,13 +870,11 @@ static void mtk_set_queue_speed(struct m
        mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
  }
  
@@ -426,7 +426,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        u32 mcr;
  
        mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
-@@ -826,9 +913,63 @@ static void mtk_mac_link_up(struct phyli
+@@ -831,9 +918,63 @@ static void mtk_mac_link_up(struct phyli
        mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
  }
  
@@ -490,7 +490,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        .mac_finish = mtk_mac_finish,
        .mac_link_down = mtk_mac_link_down,
        .mac_link_up = mtk_mac_link_up,
-@@ -3431,6 +3572,9 @@ static int mtk_open(struct net_device *d
+@@ -3459,6 +3600,9 @@ static int mtk_open(struct net_device *d
  
        ppe_num = eth->soc->ppe_num;
  
@@ -500,7 +500,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
        if (err) {
                netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
-@@ -3581,6 +3725,9 @@ static int mtk_stop(struct net_device *d
+@@ -3609,6 +3753,9 @@ static int mtk_stop(struct net_device *d
        for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
                mtk_ppe_stop(eth->ppe[i]);
  
@@ -510,7 +510,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        return 0;
  }
  
-@@ -4667,6 +4814,7 @@ static const struct net_device_ops mtk_n
+@@ -4695,6 +4842,7 @@ static const struct net_device_ops mtk_n
  static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
  {
        const __be32 *_id = of_get_property(np, "reg", NULL);
@@ -518,7 +518,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        phy_interface_t phy_mode;
        struct phylink *phylink;
        struct mtk_mac *mac;
-@@ -4705,16 +4853,41 @@ static int mtk_add_mac(struct mtk_eth *e
+@@ -4733,16 +4881,41 @@ static int mtk_add_mac(struct mtk_eth *e
        mac->id = id;
        mac->hw = eth;
        mac->of_node = np;
@@ -568,7 +568,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        }
  
        memset(mac->hwlro_ip, 0, sizeof(mac->hwlro_ip));
-@@ -4797,8 +4970,21 @@ static int mtk_add_mac(struct mtk_eth *e
+@@ -4825,8 +4998,21 @@ static int mtk_add_mac(struct mtk_eth *e
                phy_interface_zero(mac->phylink_config.supported_interfaces);
                __set_bit(PHY_INTERFACE_MODE_INTERNAL,
                          mac->phylink_config.supported_interfaces);
@@ -590,7 +590,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        phylink = phylink_create(&mac->phylink_config,
                                 of_fwnode_handle(mac->of_node),
                                 phy_mode, &mtk_phylink_ops);
-@@ -4849,6 +5035,26 @@ free_netdev:
+@@ -4877,6 +5063,26 @@ free_netdev:
        return err;
  }
  
@@ -617,7 +617,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev)
  {
        struct net_device *dev, *tmp;
-@@ -4995,7 +5201,8 @@ static int mtk_probe(struct platform_dev
+@@ -5023,7 +5229,8 @@ static int mtk_probe(struct platform_dev
                        regmap_write(cci, 0, 3);
        }
  
@@ -627,7 +627,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
                err = mtk_sgmii_init(eth);
  
                if (err)
-@@ -5106,6 +5313,24 @@ static int mtk_probe(struct platform_dev
+@@ -5134,6 +5341,24 @@ static int mtk_probe(struct platform_dev
                }
        }
  
@@ -652,7 +652,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) {
                err = devm_request_irq(eth->dev, eth->irq[0],
                                       mtk_handle_irq, 0,
-@@ -5209,6 +5434,11 @@ static int mtk_remove(struct platform_de
+@@ -5237,6 +5462,11 @@ static int mtk_remove(struct platform_de
                mtk_stop(eth->netdev[i]);
                mac = netdev_priv(eth->netdev[i]);
                phylink_disconnect_phy(mac->phylink);
@@ -674,7 +674,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  #include <linux/rhashtable.h>
  #include <linux/dim.h>
  #include <linux/bitfield.h>
-@@ -524,6 +525,21 @@
+@@ -527,6 +528,21 @@
  #define INTF_MODE_RGMII_1000    (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED)
  #define INTF_MODE_RGMII_10_100  0
  
@@ -696,7 +696,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  /* GPIO port control registers for GMAC 2*/
  #define GPIO_OD33_CTRL8               0x4c0
  #define GPIO_BIAS_CTRL                0xed0
-@@ -549,6 +565,7 @@
+@@ -552,6 +568,7 @@
  #define SYSCFG0_SGMII_GMAC2    ((3 << 8) & SYSCFG0_SGMII_MASK)
  #define SYSCFG0_SGMII_GMAC1_V2 BIT(9)
  #define SYSCFG0_SGMII_GMAC2_V2 BIT(8)
@@ -704,7 +704,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  
  
  /* ethernet subsystem clock register */
-@@ -587,6 +604,11 @@
+@@ -590,6 +607,11 @@
  #define GEPHY_MAC_SEL          BIT(1)
  
  /* Top misc registers */
@@ -716,7 +716,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  #define USB_PHY_SWITCH_REG    0x218
  #define QPHY_SEL_MASK         GENMASK(1, 0)
  #define SGMII_QPHY_SEL                0x2
-@@ -611,6 +633,8 @@
+@@ -614,6 +636,8 @@
  #define MT7628_SDM_RBCNT      (MT7628_SDM_OFFSET + 0x10c)
  #define MT7628_SDM_CS_ERR     (MT7628_SDM_OFFSET + 0x110)
  
@@ -725,7 +725,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  #define MTK_FE_CDM1_FSM               0x220
  #define MTK_FE_CDM2_FSM               0x224
  #define MTK_FE_CDM3_FSM               0x238
-@@ -619,6 +643,11 @@
+@@ -622,6 +646,11 @@
  #define MTK_FE_CDM6_FSM               0x328
  #define MTK_FE_GDM1_FSM               0x228
  #define MTK_FE_GDM2_FSM               0x22C
@@ -737,7 +737,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  
  #define MTK_MAC_FSM(x)                (0x1010C + ((x) * 0x100))
  
-@@ -743,12 +772,8 @@ enum mtk_clks_map {
+@@ -738,12 +767,8 @@ enum mtk_clks_map {
        MTK_CLK_ETHWARP_WOCPU2,
        MTK_CLK_ETHWARP_WOCPU1,
        MTK_CLK_ETHWARP_WOCPU0,
@@ -750,7 +750,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        MTK_CLK_TOP_ETH_GMII_SEL,
        MTK_CLK_TOP_ETH_REFCK_50M_SEL,
        MTK_CLK_TOP_ETH_SYS_200M_SEL,
-@@ -819,19 +844,9 @@ enum mtk_clks_map {
+@@ -814,19 +839,9 @@ enum mtk_clks_map {
                                 BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \
                                 BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \
                                 BIT_ULL(MTK_CLK_CRYPTO) | \
@@ -770,7 +770,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
                                 BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \
                                 BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \
                                 BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \
-@@ -965,6 +980,8 @@ enum mkt_eth_capabilities {
+@@ -959,6 +974,8 @@ enum mkt_eth_capabilities {
        MTK_RGMII_BIT = 0,
        MTK_TRGMII_BIT,
        MTK_SGMII_BIT,
@@ -779,7 +779,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        MTK_ESW_BIT,
        MTK_GEPHY_BIT,
        MTK_MUX_BIT,
-@@ -985,8 +1002,11 @@ enum mkt_eth_capabilities {
+@@ -979,8 +996,11 @@ enum mkt_eth_capabilities {
        MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
        MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT,
        MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT,
@@ -791,7 +791,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  
        /* PATH BITS */
        MTK_ETH_PATH_GMAC1_RGMII_BIT,
-@@ -994,14 +1014,21 @@ enum mkt_eth_capabilities {
+@@ -988,14 +1008,21 @@ enum mkt_eth_capabilities {
        MTK_ETH_PATH_GMAC1_SGMII_BIT,
        MTK_ETH_PATH_GMAC2_RGMII_BIT,
        MTK_ETH_PATH_GMAC2_SGMII_BIT,
@@ -813,7 +813,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  #define MTK_ESW                       BIT_ULL(MTK_ESW_BIT)
  #define MTK_GEPHY             BIT_ULL(MTK_GEPHY_BIT)
  #define MTK_MUX                       BIT_ULL(MTK_MUX_BIT)
-@@ -1024,10 +1051,16 @@ enum mkt_eth_capabilities {
+@@ -1018,10 +1045,16 @@ enum mkt_eth_capabilities {
        BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
  #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY          \
        BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
@@ -830,7 +830,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  
  /* Supported path present on SoCs */
  #define MTK_ETH_PATH_GMAC1_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
-@@ -1035,8 +1068,13 @@ enum mkt_eth_capabilities {
+@@ -1029,8 +1062,13 @@ enum mkt_eth_capabilities {
  #define MTK_ETH_PATH_GMAC1_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
  #define MTK_ETH_PATH_GMAC2_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
  #define MTK_ETH_PATH_GMAC2_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
@@ -844,7 +844,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  
  #define MTK_GMAC1_RGMII               (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
  #define MTK_GMAC1_TRGMII      (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
-@@ -1044,7 +1082,12 @@ enum mkt_eth_capabilities {
+@@ -1038,7 +1076,12 @@ enum mkt_eth_capabilities {
  #define MTK_GMAC2_RGMII               (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
  #define MTK_GMAC2_SGMII               (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
  #define MTK_GMAC2_GEPHY               (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
@@ -857,7 +857,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  
  /* MUXes present on SoCs */
  /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */
-@@ -1063,10 +1106,20 @@ enum mkt_eth_capabilities {
+@@ -1057,10 +1100,20 @@ enum mkt_eth_capabilities {
        (MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \
        MTK_SHARED_SGMII)
  
@@ -878,7 +878,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  #define MTK_HAS_CAPS(caps, _x)                (((caps) & (_x)) == (_x))
  
  #define MT7621_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
-@@ -1098,8 +1151,12 @@ enum mkt_eth_capabilities {
+@@ -1092,8 +1145,12 @@ enum mkt_eth_capabilities {
                      MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
                      MTK_RSTCTRL_PPE1 | MTK_SRAM)
  
@@ -893,7 +893,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  
  struct mtk_tx_dma_desc_info {
        dma_addr_t      addr;
-@@ -1346,6 +1403,9 @@ struct mtk_mac {
+@@ -1340,6 +1397,9 @@ struct mtk_mac {
        struct device_node              *of_node;
        struct phylink                  *phylink;
        struct phylink_config           phylink_config;
@@ -903,7 +903,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        struct mtk_eth                  *hw;
        struct mtk_hw_stats             *hw_stats;
        __be32                          hwlro_ip[MTK_MAX_LRO_IP_CNT];
-@@ -1469,6 +1529,19 @@ static inline u32 mtk_get_ib2_multicast_
+@@ -1463,6 +1523,19 @@ static inline u32 mtk_get_ib2_multicast_
        return MTK_FOE_IB2_MULTICAST;
  }
  
@@ -923,7 +923,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  /* read the hardware status register */
  void mtk_stats_update_mac(struct mtk_mac *mac);
  
-@@ -1477,8 +1550,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne
+@@ -1471,8 +1544,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne
  u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg);
  
  int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
index f8b3bb84595f04ee872da17e08985e13e8b2a084..4e4c992d1c434d97c979a5b42cbf27ab1d585495 100644 (file)
@@ -30,8 +30,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -5470,7 +5470,7 @@ static const struct mtk_soc_data mt2701_
-               .desc_size = sizeof(struct mtk_rx_dma),
+@@ -5501,7 +5501,7 @@ static const struct mtk_soc_data mt2701_
+               DESC_SIZE(struct mtk_rx_dma),
                .irq_done_mask = MTK_RX_DONE_INT,
                .dma_l4_valid = RX_DMA_L4_VALID,
 -              .dma_size = MTK_DMA_SIZE(2K),
@@ -39,8 +39,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
        },
-@@ -5498,7 +5498,7 @@ static const struct mtk_soc_data mt7621_
-               .desc_size = sizeof(struct mtk_rx_dma),
+@@ -5529,7 +5529,7 @@ static const struct mtk_soc_data mt7621_
+               DESC_SIZE(struct mtk_rx_dma),
                .irq_done_mask = MTK_RX_DONE_INT,
                .dma_l4_valid = RX_DMA_L4_VALID,
 -              .dma_size = MTK_DMA_SIZE(2K),
@@ -48,8 +48,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
        },
-@@ -5528,7 +5528,7 @@ static const struct mtk_soc_data mt7622_
-               .desc_size = sizeof(struct mtk_rx_dma),
+@@ -5559,7 +5559,7 @@ static const struct mtk_soc_data mt7622_
+               DESC_SIZE(struct mtk_rx_dma),
                .irq_done_mask = MTK_RX_DONE_INT,
                .dma_l4_valid = RX_DMA_L4_VALID,
 -              .dma_size = MTK_DMA_SIZE(2K),
@@ -57,8 +57,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
        },
-@@ -5557,7 +5557,7 @@ static const struct mtk_soc_data mt7623_
-               .desc_size = sizeof(struct mtk_rx_dma),
+@@ -5588,7 +5588,7 @@ static const struct mtk_soc_data mt7623_
+               DESC_SIZE(struct mtk_rx_dma),
                .irq_done_mask = MTK_RX_DONE_INT,
                .dma_l4_valid = RX_DMA_L4_VALID,
 -              .dma_size = MTK_DMA_SIZE(2K),
@@ -66,8 +66,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
        },
-@@ -5583,7 +5583,7 @@ static const struct mtk_soc_data mt7629_
-               .desc_size = sizeof(struct mtk_rx_dma),
+@@ -5614,7 +5614,7 @@ static const struct mtk_soc_data mt7629_
+               DESC_SIZE(struct mtk_rx_dma),
                .irq_done_mask = MTK_RX_DONE_INT,
                .dma_l4_valid = RX_DMA_L4_VALID,
 -              .dma_size = MTK_DMA_SIZE(2K),
@@ -75,7 +75,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
        },
-@@ -5615,7 +5615,7 @@ static const struct mtk_soc_data mt7981_
+@@ -5646,7 +5646,7 @@ static const struct mtk_soc_data mt7981_
                .dma_l4_valid = RX_DMA_L4_VALID_V2,
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
@@ -84,7 +84,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        },
  };
  
-@@ -5645,7 +5645,7 @@ static const struct mtk_soc_data mt7986_
+@@ -5676,7 +5676,7 @@ static const struct mtk_soc_data mt7986_
                .dma_l4_valid = RX_DMA_L4_VALID_V2,
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
@@ -93,7 +93,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        },
  };
  
-@@ -5698,7 +5698,7 @@ static const struct mtk_soc_data rt5350_
+@@ -5729,7 +5729,7 @@ static const struct mtk_soc_data rt5350_
                .dma_l4_valid = RX_DMA_L4_VALID_PDMA,
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
index 349af33524e6c638b893cf40a067bb286ffa1aad..1b46be4b2dba1c5e002bbfa8bf81f38ba449bc8f 100644 (file)
@@ -25,7 +25,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        help
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4582,6 +4582,7 @@ static int mtk_get_sset_count(struct net
+@@ -4610,6 +4610,7 @@ static int mtk_get_sset_count(struct net
  
  static void mtk_ethtool_pp_stats(struct mtk_eth *eth, u64 *data)
  {
@@ -33,7 +33,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        struct page_pool_stats stats = {};
        int i;
  
-@@ -4594,6 +4595,7 @@ static void mtk_ethtool_pp_stats(struct
+@@ -4622,6 +4623,7 @@ static void mtk_ethtool_pp_stats(struct
                page_pool_get_stats(ring->page_pool, &stats);
        }
        page_pool_ethtool_stats_get(data, &stats);
index 7e90a79e5bfe0def004d36902caae9b9ed988eec..ad989c64d5da17de53e41b9dd317bba780fb9699 100644 (file)
@@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1773,6 +1773,13 @@ static netdev_tx_t mtk_start_xmit(struct
+@@ -1805,6 +1805,13 @@ static netdev_tx_t mtk_start_xmit(struct
        bool gso = false;
        int tx_num;
  
@@ -26,7 +26,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        /* normally we can rely on the stack not calling this more than once,
         * however we have 2 queues running on the same ring so we need to lock
         * the ring access
-@@ -1836,8 +1843,9 @@ static netdev_tx_t mtk_start_xmit(struct
+@@ -1868,8 +1875,9 @@ static netdev_tx_t mtk_start_xmit(struct
  
  drop:
        spin_unlock(&eth->page_lock);