From: Felix Fietkau Date: Tue, 27 Dec 2022 18:08:27 +0000 (+0100) Subject: kernel: mediatek: improve ethernet fix for dealing with small fragments X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=78c51de847102541795d7c93b05ae8321fcd50e7;p=openwrt%2Fstaging%2Fjow.git kernel: mediatek: improve ethernet fix for dealing with small fragments Replace the workaround on MT7986 with a proper fix. Software workaround is still needed on older chips. Signed-off-by: Felix Fietkau --- diff --git a/target/linux/generic/pending-5.15/732-10-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch b/target/linux/generic/pending-5.15/732-10-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch index ba86686eeb..86ce481c2e 100644 --- a/target/linux/generic/pending-5.15/732-10-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch +++ b/target/linux/generic/pending-5.15/732-10-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch @@ -1,12 +1,15 @@ From: Felix Fietkau Date: Thu, 3 Nov 2022 12:38:49 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: work around issue with - sending small fragments +Subject: [PATCH] net: ethernet: mtk_eth_soc: work around issue with sending + small fragments -When frames are sent with very small fragments, the DMA engine appears to -lock up and transmit attempts time out. Fix this by detecting the presence -of small fragments and use skb_gso_segment + skb_linearize to deal with -them +When lots of frames are sent with a number of very small fragments, an +internal FIFO can overflow, causing the DMA engine to lock up lock up and +transmit attempts time out. + +Fix this on MT7986 by increasing the reserved FIFO space. +Fix this on older chips by detecting the presence of small fragments and use +skb_gso_segment + skb_linearize to deal with them. Signed-off-by: Felix Fietkau --- @@ -42,11 +45,12 @@ Signed-off-by: Felix Fietkau bool gso = false; int tx_num; -@@ -1423,6 +1439,17 @@ static netdev_tx_t mtk_start_xmit(struct +@@ -1423,6 +1439,18 @@ static netdev_tx_t mtk_start_xmit(struct return NETDEV_TX_BUSY; } -+ if (skb_is_gso(skb) && mtk_skb_has_small_frag(skb)) { ++ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) && ++ 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; @@ -60,19 +64,31 @@ Signed-off-by: Felix Fietkau /* TSO: fill MSS info in tcp checksum field */ if (skb_is_gso(skb)) { if (skb_cow_head(skb, 0)) { -@@ -1438,8 +1465,13 @@ static netdev_tx_t mtk_start_xmit(struct +@@ -1438,8 +1466,14 @@ static netdev_tx_t mtk_start_xmit(struct } } - if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) - goto drop; -+ skb_list_walk_safe(skb, skb, next) { -+ if ((mtk_skb_has_small_frag(skb) && skb_linearize(skb)) || -+ mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) { -+ stats->tx_dropped++; -+ dev_kfree_skb_any(skb); ++ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ skb_list_walk_safe(skb, skb, next) { ++ if ((mtk_skb_has_small_frag(skb) && skb_linearize(skb)) || ++ mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) { ++ stats->tx_dropped++; ++ dev_kfree_skb_any(skb); ++ } + } -+ } if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) netif_tx_stop_all_queues(dev); +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -246,7 +246,7 @@ + #define MTK_CHK_DDONE_EN BIT(28) + #define MTK_DMAD_WR_WDONE BIT(26) + #define MTK_WCOMP_EN BIT(24) +-#define MTK_RESV_BUF (0x40 << 16) ++#define MTK_RESV_BUF (0x80 << 16) + #define MTK_MUTLI_CNT (0x4 << 12) + #define MTK_LEAKY_BUCKET_EN BIT(11) + diff --git a/target/linux/generic/pending-5.15/732-14-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch b/target/linux/generic/pending-5.15/732-14-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch index c3a879e5ab..0d575b84a0 100644 --- a/target/linux/generic/pending-5.15/732-14-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch +++ b/target/linux/generic/pending-5.15/732-14-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch @@ -17,7 +17,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1993,29 +1993,16 @@ static int mtk_poll_rx(struct napi_struc +@@ -1995,29 +1995,16 @@ static int mtk_poll_rx(struct napi_struc if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) mtk_ppe_check_skb(eth->ppe[0], skb, hash); @@ -50,7 +50,7 @@ Signed-off-by: Felix Fietkau } skb_record_rx_queue(skb, 0); -@@ -2832,29 +2819,11 @@ static netdev_features_t mtk_fix_feature +@@ -2834,29 +2821,11 @@ static netdev_features_t mtk_fix_feature static int mtk_set_features(struct net_device *dev, netdev_features_t features) { @@ -80,7 +80,7 @@ Signed-off-by: Felix Fietkau return 0; } -@@ -3153,30 +3122,6 @@ static int mtk_open(struct net_device *d +@@ -3155,30 +3124,6 @@ static int mtk_open(struct net_device *d struct mtk_eth *eth = mac->hw; int i, err; @@ -111,7 +111,7 @@ Signed-off-by: Felix Fietkau err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0); if (err) { netdev_err(dev, "%s: could not attach PHY: %d\n", __func__, -@@ -3217,6 +3162,35 @@ static int mtk_open(struct net_device *d +@@ -3219,6 +3164,35 @@ static int mtk_open(struct net_device *d phylink_start(mac->phylink); netif_tx_start_all_queues(dev); @@ -147,7 +147,7 @@ Signed-off-by: Felix Fietkau return 0; } -@@ -3510,10 +3484,9 @@ static int mtk_hw_init(struct mtk_eth *e +@@ -3512,10 +3486,9 @@ static int mtk_hw_init(struct mtk_eth *e if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { val = mtk_r32(eth, MTK_CDMP_IG_CTRL); mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); @@ -160,7 +160,7 @@ Signed-off-by: Felix Fietkau /* set interrupt delays based on current Net DIM sample */ mtk_dim_rx(ð->rx_dim.work); -@@ -4134,7 +4107,7 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -4136,7 +4109,7 @@ static int mtk_add_mac(struct mtk_eth *e eth->netdev[id]->hw_features |= NETIF_F_LRO; eth->netdev[id]->vlan_features = eth->soc->hw_features &