diff options
Diffstat (limited to 'package/boot/uboot-mediatek/patches/101-16-net-mediatek-connect-switch-to-PSE-only-when-startin.patch')
-rw-r--r-- | package/boot/uboot-mediatek/patches/101-16-net-mediatek-connect-switch-to-PSE-only-when-startin.patch | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/package/boot/uboot-mediatek/patches/101-16-net-mediatek-connect-switch-to-PSE-only-when-startin.patch b/package/boot/uboot-mediatek/patches/101-16-net-mediatek-connect-switch-to-PSE-only-when-startin.patch new file mode 100644 index 0000000000..e3e6212742 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/101-16-net-mediatek-connect-switch-to-PSE-only-when-startin.patch @@ -0,0 +1,138 @@ +From a0405999ebecf21ed9f76f1dc9420682cd3feba0 Mon Sep 17 00:00:00 2001 +From: Weijie Gao <weijie.gao@mediatek.com> +Date: Wed, 19 Jul 2023 17:16:54 +0800 +Subject: [PATCH 16/29] net: mediatek: connect switch to PSE only when starting + eth is requested + +So far the switch is initialized in probe stage and is connected to PSE +unconditionally. This will cause all packets being flooded to PSE and may +cause PSE hang before entering linux. + +This patch changes the connection between switch and PSE: +- Still initialize switch in probe stage, but disconnect it with PSE +- Connect switch with PSE on eth start +- Disconnect on eth stop + +Signed-off-by: Weijie Gao <weijie.gao@mediatek.com> +--- + drivers/net/mtk_eth.c | 44 ++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 41 insertions(+), 3 deletions(-) + +--- a/drivers/net/mtk_eth.c ++++ b/drivers/net/mtk_eth.c +@@ -123,8 +123,10 @@ struct mtk_eth_priv { + + enum mtk_switch sw; + int (*switch_init)(struct mtk_eth_priv *priv); ++ void (*switch_mac_control)(struct mtk_eth_priv *priv, bool enable); + u32 mt753x_smi_addr; + u32 mt753x_phy_base; ++ u32 mt753x_pmcr; + + struct gpio_desc rst_gpio; + int mcm; +@@ -613,6 +615,16 @@ static int mt7530_pad_clk_setup(struct m + return 0; + } + ++static void mt7530_mac_control(struct mtk_eth_priv *priv, bool enable) ++{ ++ u32 pmcr = FORCE_MODE; ++ ++ if (enable) ++ pmcr = priv->mt753x_pmcr; ++ ++ mt753x_reg_write(priv, PMCR_REG(6), pmcr); ++} ++ + static int mt7530_setup(struct mtk_eth_priv *priv) + { + u16 phy_addr, phy_val; +@@ -663,11 +675,14 @@ static int mt7530_setup(struct mtk_eth_p + FORCE_DPX | FORCE_LINK; + + /* MT7530 Port6: Forced 1000M/FD, FC disabled */ +- mt753x_reg_write(priv, PMCR_REG(6), val); ++ priv->mt753x_pmcr = val; + + /* MT7530 Port5: Forced link down */ + mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE); + ++ /* Keep MAC link down before starting eth */ ++ mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE); ++ + /* MT7530 Port6: Set to RGMII */ + mt753x_reg_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_M, P6_INTF_MODE_RGMII); + +@@ -823,6 +838,17 @@ static void mt7531_phy_setting(struct mt + } + } + ++static void mt7531_mac_control(struct mtk_eth_priv *priv, bool enable) ++{ ++ u32 pmcr = FORCE_MODE_LNK; ++ ++ if (enable) ++ pmcr = priv->mt753x_pmcr; ++ ++ mt753x_reg_write(priv, PMCR_REG(5), pmcr); ++ mt753x_reg_write(priv, PMCR_REG(6), pmcr); ++} ++ + static int mt7531_setup(struct mtk_eth_priv *priv) + { + u16 phy_addr, phy_val; +@@ -882,8 +908,11 @@ static int mt7531_setup(struct mtk_eth_p + (SPEED_1000M << FORCE_SPD_S) | FORCE_DPX | + FORCE_LINK; + +- mt753x_reg_write(priv, PMCR_REG(5), pmcr); +- mt753x_reg_write(priv, PMCR_REG(6), pmcr); ++ priv->mt753x_pmcr = pmcr; ++ ++ /* Keep MAC link down before starting eth */ ++ mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE_LNK); ++ mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE_LNK); + + /* Turn on PHYs */ + for (i = 0; i < MT753X_NUM_PHYS; i++) { +@@ -1227,6 +1256,9 @@ static int mtk_eth_start(struct udevice + + mtk_eth_fifo_init(priv); + ++ if (priv->switch_mac_control) ++ priv->switch_mac_control(priv, true); ++ + /* Start PHY */ + if (priv->sw == SW_NONE) { + ret = mtk_phy_start(priv); +@@ -1245,6 +1277,9 @@ static void mtk_eth_stop(struct udevice + { + struct mtk_eth_priv *priv = dev_get_priv(dev); + ++ if (priv->switch_mac_control) ++ priv->switch_mac_control(priv, false); ++ + mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, + TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN, 0); + udelay(500); +@@ -1484,16 +1519,19 @@ static int mtk_eth_of_to_plat(struct ude + /* check for switch first, otherwise phy will be used */ + priv->sw = SW_NONE; + priv->switch_init = NULL; ++ priv->switch_mac_control = NULL; + str = dev_read_string(dev, "mediatek,switch"); + + if (str) { + if (!strcmp(str, "mt7530")) { + priv->sw = SW_MT7530; + priv->switch_init = mt7530_setup; ++ priv->switch_mac_control = mt7530_mac_control; + priv->mt753x_smi_addr = MT753X_DFL_SMI_ADDR; + } else if (!strcmp(str, "mt7531")) { + priv->sw = SW_MT7531; + priv->switch_init = mt7531_setup; ++ priv->switch_mac_control = mt7531_mac_control; + priv->mt753x_smi_addr = MT753X_DFL_SMI_ADDR; + } else { + printf("error: unsupported switch\n"); |