mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 14:23:38 +00:00
kernel: fix mtk_eth_soc throughput regressions on gigabit PHY ports
Fixes issues on MT7621 and MT7623 switch ports, and PHY ports on all SoC Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
4c48c9a80f
commit
17f02fb364
@ -0,0 +1,31 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Fri, 24 Mar 2023 14:56:58 +0100
|
||||||
|
Subject: [PATCH] net: ethernet: mtk_eth_soc: fix tx throughput regression with
|
||||||
|
direct 1G links
|
||||||
|
|
||||||
|
Using the QDMA tx scheduler to throttle tx to line speed works fine for
|
||||||
|
switch ports, but apparently caused a regression on non-switch ports.
|
||||||
|
|
||||||
|
Based on a number of tests, it seems that this throttling can be safely
|
||||||
|
dropped without re-introducing the issues on switch ports that the
|
||||||
|
tx scheduling changes resolved.
|
||||||
|
|
||||||
|
Link: https://lore.kernel.org/netdev/trinity-92c3826f-c2c8-40af-8339-bc6d0d3ffea4-1678213958520@3c-app-gmx-bs16/
|
||||||
|
Fixes: f63959c7eec3 ("net: ethernet: mtk_eth_soc: implement multi-queue support for per-port queues")
|
||||||
|
Reported-by: Frank Wunderlich <frank-w@public-files.de>
|
||||||
|
Reported-by: Daniel Golle <daniel@makrotopia.org>
|
||||||
|
Tested-by: Daniel Golle <daniel@makrotopia.org>
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||||
|
@@ -676,8 +676,6 @@ static void mtk_mac_link_up(struct phyli
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- mtk_set_queue_speed(mac->hw, mac->id, speed);
|
||||||
|
-
|
||||||
|
/* Configure duplex */
|
||||||
|
if (duplex == DUPLEX_FULL)
|
||||||
|
mcr |= MAC_MCR_FORCE_DPX;
|
@ -34,7 +34,7 @@
|
|||||||
mtk_eth_path_name(path), __func__, updated);
|
mtk_eth_path_name(path), __func__, updated);
|
||||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||||
@@ -4757,6 +4757,26 @@ static const struct mtk_soc_data mt7629_
|
@@ -4755,6 +4755,26 @@ static const struct mtk_soc_data mt7629_
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -61,7 +61,7 @@
|
|||||||
static const struct mtk_soc_data mt7986_data = {
|
static const struct mtk_soc_data mt7986_data = {
|
||||||
.reg_map = &mt7986_reg_map,
|
.reg_map = &mt7986_reg_map,
|
||||||
.ana_rgc3 = 0x128,
|
.ana_rgc3 = 0x128,
|
||||||
@@ -4799,6 +4819,7 @@ const struct of_device_id of_mtk_match[]
|
@@ -4797,6 +4817,7 @@ const struct of_device_id of_mtk_match[]
|
||||||
{ .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
|
{ .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
|
||||||
{ .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
|
{ .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
|
||||||
{ .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
|
{ .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
|
||||||
|
@ -21,7 +21,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|||||||
|
|
||||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||||
@@ -704,8 +704,10 @@ static const struct phylink_mac_ops mtk_
|
@@ -702,8 +702,10 @@ static const struct phylink_mac_ops mtk_
|
||||||
|
|
||||||
static int mtk_mdio_init(struct mtk_eth *eth)
|
static int mtk_mdio_init(struct mtk_eth *eth)
|
||||||
{
|
{
|
||||||
@ -32,7 +32,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|||||||
|
|
||||||
mii_np = of_get_child_by_name(eth->dev->of_node, "mdio-bus");
|
mii_np = of_get_child_by_name(eth->dev->of_node, "mdio-bus");
|
||||||
if (!mii_np) {
|
if (!mii_np) {
|
||||||
@@ -731,6 +733,25 @@ static int mtk_mdio_init(struct mtk_eth
|
@@ -729,6 +731,25 @@ static int mtk_mdio_init(struct mtk_eth
|
||||||
eth->mii_bus->parent = eth->dev;
|
eth->mii_bus->parent = eth->dev;
|
||||||
|
|
||||||
snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%pOFn", mii_np);
|
snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%pOFn", mii_np);
|
||||||
|
@ -60,7 +60,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -3979,8 +3980,17 @@ static int mtk_unreg_dev(struct mtk_eth
|
@@ -3977,8 +3978,17 @@ static int mtk_unreg_dev(struct mtk_eth
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|||||||
mtk_unreg_dev(eth);
|
mtk_unreg_dev(eth);
|
||||||
mtk_free_dev(eth);
|
mtk_free_dev(eth);
|
||||||
cancel_work_sync(ð->pending_work);
|
cancel_work_sync(ð->pending_work);
|
||||||
@@ -4410,6 +4420,36 @@ void mtk_eth_set_dma_device(struct mtk_e
|
@@ -4408,6 +4418,36 @@ void mtk_eth_set_dma_device(struct mtk_e
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|||||||
static int mtk_probe(struct platform_device *pdev)
|
static int mtk_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct resource *res = NULL;
|
struct resource *res = NULL;
|
||||||
@@ -4473,13 +4513,7 @@ static int mtk_probe(struct platform_dev
|
@@ -4471,13 +4511,7 @@ static int mtk_probe(struct platform_dev
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) {
|
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) {
|
||||||
@ -130,7 +130,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
@@ -4490,14 +4524,17 @@ static int mtk_probe(struct platform_dev
|
@@ -4488,14 +4522,17 @@ static int mtk_probe(struct platform_dev
|
||||||
"mediatek,pctl");
|
"mediatek,pctl");
|
||||||
if (IS_ERR(eth->pctl)) {
|
if (IS_ERR(eth->pctl)) {
|
||||||
dev_err(&pdev->dev, "no pctl regmap found\n");
|
dev_err(&pdev->dev, "no pctl regmap found\n");
|
||||||
@ -151,7 +151,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (eth->soc->offload_version) {
|
if (eth->soc->offload_version) {
|
||||||
@@ -4657,6 +4694,8 @@ err_deinit_hw:
|
@@ -4655,6 +4692,8 @@ err_deinit_hw:
|
||||||
mtk_hw_deinit(eth);
|
mtk_hw_deinit(eth);
|
||||||
err_wed_exit:
|
err_wed_exit:
|
||||||
mtk_wed_exit();
|
mtk_wed_exit();
|
||||||
|
@ -16,7 +16,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
|
|
||||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||||
@@ -1425,12 +1425,28 @@ static void mtk_wake_queue(struct mtk_et
|
@@ -1423,12 +1423,28 @@ static void mtk_wake_queue(struct mtk_et
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
bool gso = false;
|
bool gso = false;
|
||||||
int tx_num;
|
int tx_num;
|
||||||
|
|
||||||
@@ -1452,6 +1468,18 @@ static netdev_tx_t mtk_start_xmit(struct
|
@@ -1450,6 +1466,18 @@ static netdev_tx_t mtk_start_xmit(struct
|
||||||
return NETDEV_TX_BUSY;
|
return NETDEV_TX_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
/* TSO: fill MSS info in tcp checksum field */
|
/* TSO: fill MSS info in tcp checksum field */
|
||||||
if (skb_is_gso(skb)) {
|
if (skb_is_gso(skb)) {
|
||||||
if (skb_cow_head(skb, 0)) {
|
if (skb_cow_head(skb, 0)) {
|
||||||
@@ -1467,8 +1495,14 @@ static netdev_tx_t mtk_start_xmit(struct
|
@@ -1465,8 +1493,14 @@ static netdev_tx_t mtk_start_xmit(struct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Wed, 29 Mar 2023 16:02:54 +0200
|
||||||
|
Subject: [PATCH] net: ethernet: mtk_eth_soc: fix remaining throughput
|
||||||
|
regression
|
||||||
|
|
||||||
|
Based on further tests, it seems that the QDMA shaper is not able to
|
||||||
|
perform shaping close to the MAC link rate without throughput loss.
|
||||||
|
This cannot be compensated by increasing the shaping rate, so it seems
|
||||||
|
to be an internal limit.
|
||||||
|
|
||||||
|
Fix the remaining throughput regression by detecting that condition and
|
||||||
|
limiting shaping to ports with lower link speed.
|
||||||
|
|
||||||
|
This patch intentionally ignores link speed gain from TRGMII, because
|
||||||
|
even on such links, shaping to 1000 Mbit/s incurs some throughput
|
||||||
|
degradation.
|
||||||
|
|
||||||
|
Fixes: f63959c7eec3 ("net: ethernet: mtk_eth_soc: implement multi-queue support for per-port queues")
|
||||||
|
Reported-by: Frank Wunderlich <frank-w@public-files.de>
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||||
|
@@ -667,6 +667,7 @@ static void mtk_mac_link_up(struct phyli
|
||||||
|
MAC_MCR_FORCE_RX_FC);
|
||||||
|
|
||||||
|
/* Configure speed */
|
||||||
|
+ mac->speed = speed;
|
||||||
|
switch (speed) {
|
||||||
|
case SPEED_2500:
|
||||||
|
case SPEED_1000:
|
||||||
|
@@ -3145,6 +3146,9 @@ found:
|
||||||
|
if (dp->index >= MTK_QDMA_NUM_QUEUES)
|
||||||
|
return NOTIFY_DONE;
|
||||||
|
|
||||||
|
+ if (mac->speed > 0 && mac->speed <= s.base.speed)
|
||||||
|
+ s.base.speed = 0;
|
||||||
|
+
|
||||||
|
mtk_set_queue_speed(eth, dp->index + 3, s.base.speed);
|
||||||
|
|
||||||
|
return NOTIFY_DONE;
|
@ -103,7 +103,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
|||||||
|
|
||||||
ret = mtk_mdio_busy_wait(eth);
|
ret = mtk_mdio_busy_wait(eth);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@@ -730,6 +773,7 @@ static int mtk_mdio_init(struct mtk_eth
|
@@ -729,6 +772,7 @@ static int mtk_mdio_init(struct mtk_eth
|
||||||
eth->mii_bus->name = "mdio";
|
eth->mii_bus->name = "mdio";
|
||||||
eth->mii_bus->read = mtk_mdio_read;
|
eth->mii_bus->read = mtk_mdio_read;
|
||||||
eth->mii_bus->write = mtk_mdio_write;
|
eth->mii_bus->write = mtk_mdio_write;
|
||||||
|
Loading…
Reference in New Issue
Block a user