From: Felix Fietkau Date: Mon, 14 Jul 2025 09:55:10 +0000 (+0200) Subject: kernel: improve mtk_eth_soc performance X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=19e977293591febe91fb1340e50dcb6b3d881732;p=openwrt%2Fstaging%2Fstintel.git kernel: improve mtk_eth_soc performance - shrink data structures - avoid unnecessary divisions - support GSO fraglist on tx Reapply with fixed patch Signed-off-by: Felix Fietkau --- diff --git a/target/linux/generic/hack-6.12/730-net-ethernet-mtk_eth_soc-add-hw-dump-for-forced-rese.patch b/target/linux/generic/hack-6.12/730-net-ethernet-mtk_eth_soc-add-hw-dump-for-forced-rese.patch index ffc21ee2ff..2244531b6c 100644 --- a/target/linux/generic/hack-6.12/730-net-ethernet-mtk_eth_soc-add-hw-dump-for-forced-rese.patch +++ b/target/linux/generic/hack-6.12/730-net-ethernet-mtk_eth_soc-add-hw-dump-for-forced-rese.patch @@ -13,7 +13,7 @@ Signed-off-by: Bo-Cun Chen --- 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 .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 .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 .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 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, ð->state); @@ -105,7 +105,7 @@ Signed-off-by: Bo-Cun Chen /* 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/hack-6.6/730-net-ethernet-mtk_eth_soc-add-hw-dump-for-forced-rese.patch b/target/linux/generic/hack-6.6/730-net-ethernet-mtk_eth_soc-add-hw-dump-for-forced-rese.patch index 25d824bce6..f6d6574ded 100644 --- a/target/linux/generic/hack-6.6/730-net-ethernet-mtk_eth_soc-add-hw-dump-for-forced-rese.patch +++ b/target/linux/generic/hack-6.6/730-net-ethernet-mtk_eth_soc-add-hw-dump-for-forced-rese.patch @@ -13,7 +13,7 @@ Signed-off-by: Bo-Cun Chen --- 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 .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 .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 .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 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, ð->state); @@ -105,7 +105,7 @@ Signed-off-by: Bo-Cun Chen /* 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 index bd7a1b96f2..0000000000 --- a/target/linux/generic/pending-6.12/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch +++ /dev/null @@ -1,21 +0,0 @@ -From: Felix Fietkau -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 ---- - ---- 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 index 0000000000..c7cf3299c0 --- /dev/null +++ b/target/linux/generic/pending-6.12/732-03-net-ethernet-mtk_eth_soc-optimize-dma-ring-address-i.patch @@ -0,0 +1,486 @@ +From: Felix Fietkau +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 +--- + +--- 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), + ð->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 = ð->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 = ð->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 = ð->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 index 0000000000..b33b9d3f0e --- /dev/null +++ b/target/linux/generic/pending-6.12/732-04-net-ethernet-mtk_eth_soc-shrink-struct-mtk_tx_buf.patch @@ -0,0 +1,124 @@ +From: Felix Fietkau +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 +--- + +--- 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 index 0000000000..c085328a56 --- /dev/null +++ b/target/linux/generic/pending-6.12/732-05-net-ethernet-mtk_eth_soc-add-support-for-sending-fra.patch @@ -0,0 +1,509 @@ +From: Felix Fietkau +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 +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -18,6 +18,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -27,6 +29,7 @@ + #include + #include + #include ++#include + #include + + #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 = ð->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) diff --git a/target/linux/generic/pending-6.12/733-01-net-ethernet-mtk_eth_soc-use-napi_build_skb.patch b/target/linux/generic/pending-6.12/733-01-net-ethernet-mtk_eth_soc-use-napi_build_skb.patch index 36c1d499d3..0aba4b69b7 100644 --- a/target/linux/generic/pending-6.12/733-01-net-ethernet-mtk_eth_soc-use-napi_build_skb.patch +++ b/target/linux/generic/pending-6.12/733-01-net-ethernet-mtk_eth_soc-use-napi_build_skb.patch @@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau --- 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 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); diff --git a/target/linux/generic/pending-6.12/734-net-ethernet-mediatek-enlarge-DMA-reserve-buffer.patch b/target/linux/generic/pending-6.12/734-net-ethernet-mediatek-enlarge-DMA-reserve-buffer.patch index d9e2873262..1efb93226c 100644 --- a/target/linux/generic/pending-6.12/734-net-ethernet-mediatek-enlarge-DMA-reserve-buffer.patch +++ b/target/linux/generic/pending-6.12/734-net-ethernet-mediatek-enlarge-DMA-reserve-buffer.patch @@ -15,7 +15,7 @@ Signed-off-by: Chad Monroe --- 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 /* 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; diff --git a/target/linux/generic/pending-6.12/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch b/target/linux/generic/pending-6.12/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch index b03b72b33d..faa91b006e 100644 --- a/target/linux/generic/pending-6.12/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch +++ b/target/linux/generic/pending-6.12/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch @@ -205,7 +205,7 @@ Signed-off-by: Daniel Golle 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 #include #include @@ -214,7 +214,7 @@ Signed-off-by: Daniel Golle #include #include #include -@@ -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 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 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 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 } /* 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 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 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 /* 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 } 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 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 .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 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 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 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 } 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 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 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 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 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 #include #include #include -@@ -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 /* 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 /* 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 #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 #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 #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 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 /* 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 #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 /* 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 #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 /* 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 #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 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 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 /* 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); diff --git a/target/linux/generic/pending-6.12/738-01-net-ethernet-mtk_eth_soc-reduce-rx-ring-size-for-older.patch b/target/linux/generic/pending-6.12/738-01-net-ethernet-mtk_eth_soc-reduce-rx-ring-size-for-older.patch index 7ec342a20f..b45f7993c9 100644 --- a/target/linux/generic/pending-6.12/738-01-net-ethernet-mtk_eth_soc-reduce-rx-ring-size-for-older.patch +++ b/target/linux/generic/pending-6.12/738-01-net-ethernet-mtk_eth_soc-reduce-rx-ring-size-for-older.patch @@ -30,8 +30,8 @@ Signed-off-by: Felix Fietkau --- 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 .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 .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 .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 .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 .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 }, }; -@@ -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 }, }; -@@ -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, diff --git a/target/linux/generic/pending-6.12/738-02-net-ethernet-mtk_eth_soc-do-not-enable-page-pool-sta.patch b/target/linux/generic/pending-6.12/738-02-net-ethernet-mtk_eth_soc-do-not-enable-page-pool-sta.patch index 26706de6ad..63083192e6 100644 --- a/target/linux/generic/pending-6.12/738-02-net-ethernet-mtk_eth_soc-do-not-enable-page-pool-sta.patch +++ b/target/linux/generic/pending-6.12/738-02-net-ethernet-mtk_eth_soc-do-not-enable-page-pool-sta.patch @@ -25,7 +25,7 @@ Signed-off-by: Felix Fietkau 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 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); diff --git a/target/linux/generic/pending-6.12/742-net-ethernet-mtk_eth_soc-fix-tx-vlan-tag-for-llc-pac.patch b/target/linux/generic/pending-6.12/742-net-ethernet-mtk_eth_soc-fix-tx-vlan-tag-for-llc-pac.patch index 20a6a29449..b72871385b 100644 --- a/target/linux/generic/pending-6.12/742-net-ethernet-mtk_eth_soc-fix-tx-vlan-tag-for-llc-pac.patch +++ b/target/linux/generic/pending-6.12/742-net-ethernet-mtk_eth_soc-fix-tx-vlan-tag-for-llc-pac.patch @@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau --- 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 /* 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(ð->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 index bd7a1b96f2..0000000000 --- a/target/linux/generic/pending-6.6/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch +++ /dev/null @@ -1,21 +0,0 @@ -From: Felix Fietkau -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 ---- - ---- 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 index 0000000000..89720a87a8 --- /dev/null +++ b/target/linux/generic/pending-6.6/732-03-net-ethernet-mtk_eth_soc-optimize-dma-ring-address-i.patch @@ -0,0 +1,486 @@ +From: Felix Fietkau +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 +--- + +--- 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), + ð->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 = ð->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 = ð->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 = ð->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 index 0000000000..b14e9bd2a4 --- /dev/null +++ b/target/linux/generic/pending-6.6/732-04-net-ethernet-mtk_eth_soc-shrink-struct-mtk_tx_buf.patch @@ -0,0 +1,124 @@ +From: Felix Fietkau +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 +--- + +--- 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 index 0000000000..c36a238b67 --- /dev/null +++ b/target/linux/generic/pending-6.6/732-05-net-ethernet-mtk_eth_soc-add-support-for-sending-fra.patch @@ -0,0 +1,303 @@ +From: Felix Fietkau +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 +--- + +--- 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) diff --git a/target/linux/generic/pending-6.6/733-01-net-ethernet-mtk_eth_soc-use-napi_build_skb.patch b/target/linux/generic/pending-6.6/733-01-net-ethernet-mtk_eth_soc-use-napi_build_skb.patch index a2a10d1417..b91820b9b1 100644 --- a/target/linux/generic/pending-6.6/733-01-net-ethernet-mtk_eth_soc-use-napi_build_skb.patch +++ b/target/linux/generic/pending-6.6/733-01-net-ethernet-mtk_eth_soc-use-napi_build_skb.patch @@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau --- 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 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); diff --git a/target/linux/generic/pending-6.6/734-net-ethernet-mediatek-enlarge-DMA-reserve-buffer.patch b/target/linux/generic/pending-6.6/734-net-ethernet-mediatek-enlarge-DMA-reserve-buffer.patch index 7274c4a817..ead70343a7 100644 --- a/target/linux/generic/pending-6.6/734-net-ethernet-mediatek-enlarge-DMA-reserve-buffer.patch +++ b/target/linux/generic/pending-6.6/734-net-ethernet-mediatek-enlarge-DMA-reserve-buffer.patch @@ -15,7 +15,7 @@ Signed-off-by: Chad Monroe --- 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 /* 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; diff --git a/target/linux/generic/pending-6.6/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch b/target/linux/generic/pending-6.6/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch index 392e94dc8a..85cb5b06f0 100644 --- a/target/linux/generic/pending-6.6/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch +++ b/target/linux/generic/pending-6.6/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch @@ -214,7 +214,7 @@ Signed-off-by: Daniel Golle #include #include #include -@@ -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 "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 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 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 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 } /* 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 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 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 /* 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 } 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 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 .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 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 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 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 } 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 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 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 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 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 #include #include #include -@@ -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 /* 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 /* 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 #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 #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 #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 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 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 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 /* 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 #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 /* 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 #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 /* 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 #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 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 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 /* 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); diff --git a/target/linux/generic/pending-6.6/738-01-net-ethernet-mtk_eth_soc-reduce-rx-ring-size-for-older.patch b/target/linux/generic/pending-6.6/738-01-net-ethernet-mtk_eth_soc-reduce-rx-ring-size-for-older.patch index f8b3bb8459..4e4c992d1c 100644 --- a/target/linux/generic/pending-6.6/738-01-net-ethernet-mtk_eth_soc-reduce-rx-ring-size-for-older.patch +++ b/target/linux/generic/pending-6.6/738-01-net-ethernet-mtk_eth_soc-reduce-rx-ring-size-for-older.patch @@ -30,8 +30,8 @@ Signed-off-by: Felix Fietkau --- 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 .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 .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 .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 .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 .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 }, }; -@@ -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 }, }; -@@ -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, diff --git a/target/linux/generic/pending-6.6/738-02-net-ethernet-mtk_eth_soc-do-not-enable-page-pool-sta.patch b/target/linux/generic/pending-6.6/738-02-net-ethernet-mtk_eth_soc-do-not-enable-page-pool-sta.patch index 349af33524..1b46be4b2d 100644 --- a/target/linux/generic/pending-6.6/738-02-net-ethernet-mtk_eth_soc-do-not-enable-page-pool-sta.patch +++ b/target/linux/generic/pending-6.6/738-02-net-ethernet-mtk_eth_soc-do-not-enable-page-pool-sta.patch @@ -25,7 +25,7 @@ Signed-off-by: Felix Fietkau 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 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); diff --git a/target/linux/generic/pending-6.6/742-net-ethernet-mtk_eth_soc-fix-tx-vlan-tag-for-llc-pac.patch b/target/linux/generic/pending-6.6/742-net-ethernet-mtk_eth_soc-fix-tx-vlan-tag-for-llc-pac.patch index 7e90a79e5b..ad989c64d5 100644 --- a/target/linux/generic/pending-6.6/742-net-ethernet-mtk_eth_soc-fix-tx-vlan-tag-for-llc-pac.patch +++ b/target/linux/generic/pending-6.6/742-net-ethernet-mtk_eth_soc-fix-tx-vlan-tag-for-llc-pac.patch @@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau --- 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 /* 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(ð->page_lock);