123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- From a0405999ebecf21ed9f76f1dc9420682cd3feba0 Mon Sep 17 00:00:00 2001
- From: Weijie Gao <[email protected]>
- 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 <[email protected]>
- ---
- 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");
|