e3e6212742b6f5726a561ade713f6c12c3dbaef4
[openwrt/staging/blocktrron.git] /
1 From a0405999ebecf21ed9f76f1dc9420682cd3feba0 Mon Sep 17 00:00:00 2001
2 From: Weijie Gao <weijie.gao@mediatek.com>
3 Date: Wed, 19 Jul 2023 17:16:54 +0800
4 Subject: [PATCH 16/29] net: mediatek: connect switch to PSE only when starting
5 eth is requested
6
7 So far the switch is initialized in probe stage and is connected to PSE
8 unconditionally. This will cause all packets being flooded to PSE and may
9 cause PSE hang before entering linux.
10
11 This patch changes the connection between switch and PSE:
12 - Still initialize switch in probe stage, but disconnect it with PSE
13 - Connect switch with PSE on eth start
14 - Disconnect on eth stop
15
16 Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
17 ---
18 drivers/net/mtk_eth.c | 44 ++++++++++++++++++++++++++++++++++++++++---
19 1 file changed, 41 insertions(+), 3 deletions(-)
20
21 --- a/drivers/net/mtk_eth.c
22 +++ b/drivers/net/mtk_eth.c
23 @@ -123,8 +123,10 @@ struct mtk_eth_priv {
24
25 enum mtk_switch sw;
26 int (*switch_init)(struct mtk_eth_priv *priv);
27 + void (*switch_mac_control)(struct mtk_eth_priv *priv, bool enable);
28 u32 mt753x_smi_addr;
29 u32 mt753x_phy_base;
30 + u32 mt753x_pmcr;
31
32 struct gpio_desc rst_gpio;
33 int mcm;
34 @@ -613,6 +615,16 @@ static int mt7530_pad_clk_setup(struct m
35 return 0;
36 }
37
38 +static void mt7530_mac_control(struct mtk_eth_priv *priv, bool enable)
39 +{
40 + u32 pmcr = FORCE_MODE;
41 +
42 + if (enable)
43 + pmcr = priv->mt753x_pmcr;
44 +
45 + mt753x_reg_write(priv, PMCR_REG(6), pmcr);
46 +}
47 +
48 static int mt7530_setup(struct mtk_eth_priv *priv)
49 {
50 u16 phy_addr, phy_val;
51 @@ -663,11 +675,14 @@ static int mt7530_setup(struct mtk_eth_p
52 FORCE_DPX | FORCE_LINK;
53
54 /* MT7530 Port6: Forced 1000M/FD, FC disabled */
55 - mt753x_reg_write(priv, PMCR_REG(6), val);
56 + priv->mt753x_pmcr = val;
57
58 /* MT7530 Port5: Forced link down */
59 mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE);
60
61 + /* Keep MAC link down before starting eth */
62 + mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE);
63 +
64 /* MT7530 Port6: Set to RGMII */
65 mt753x_reg_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_M, P6_INTF_MODE_RGMII);
66
67 @@ -823,6 +838,17 @@ static void mt7531_phy_setting(struct mt
68 }
69 }
70
71 +static void mt7531_mac_control(struct mtk_eth_priv *priv, bool enable)
72 +{
73 + u32 pmcr = FORCE_MODE_LNK;
74 +
75 + if (enable)
76 + pmcr = priv->mt753x_pmcr;
77 +
78 + mt753x_reg_write(priv, PMCR_REG(5), pmcr);
79 + mt753x_reg_write(priv, PMCR_REG(6), pmcr);
80 +}
81 +
82 static int mt7531_setup(struct mtk_eth_priv *priv)
83 {
84 u16 phy_addr, phy_val;
85 @@ -882,8 +908,11 @@ static int mt7531_setup(struct mtk_eth_p
86 (SPEED_1000M << FORCE_SPD_S) | FORCE_DPX |
87 FORCE_LINK;
88
89 - mt753x_reg_write(priv, PMCR_REG(5), pmcr);
90 - mt753x_reg_write(priv, PMCR_REG(6), pmcr);
91 + priv->mt753x_pmcr = pmcr;
92 +
93 + /* Keep MAC link down before starting eth */
94 + mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE_LNK);
95 + mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE_LNK);
96
97 /* Turn on PHYs */
98 for (i = 0; i < MT753X_NUM_PHYS; i++) {
99 @@ -1227,6 +1256,9 @@ static int mtk_eth_start(struct udevice
100
101 mtk_eth_fifo_init(priv);
102
103 + if (priv->switch_mac_control)
104 + priv->switch_mac_control(priv, true);
105 +
106 /* Start PHY */
107 if (priv->sw == SW_NONE) {
108 ret = mtk_phy_start(priv);
109 @@ -1245,6 +1277,9 @@ static void mtk_eth_stop(struct udevice
110 {
111 struct mtk_eth_priv *priv = dev_get_priv(dev);
112
113 + if (priv->switch_mac_control)
114 + priv->switch_mac_control(priv, false);
115 +
116 mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG,
117 TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN, 0);
118 udelay(500);
119 @@ -1484,16 +1519,19 @@ static int mtk_eth_of_to_plat(struct ude
120 /* check for switch first, otherwise phy will be used */
121 priv->sw = SW_NONE;
122 priv->switch_init = NULL;
123 + priv->switch_mac_control = NULL;
124 str = dev_read_string(dev, "mediatek,switch");
125
126 if (str) {
127 if (!strcmp(str, "mt7530")) {
128 priv->sw = SW_MT7530;
129 priv->switch_init = mt7530_setup;
130 + priv->switch_mac_control = mt7530_mac_control;
131 priv->mt753x_smi_addr = MT753X_DFL_SMI_ADDR;
132 } else if (!strcmp(str, "mt7531")) {
133 priv->sw = SW_MT7531;
134 priv->switch_init = mt7531_setup;
135 + priv->switch_mac_control = mt7531_mac_control;
136 priv->mt753x_smi_addr = MT753X_DFL_SMI_ADDR;
137 } else {
138 printf("error: unsupported switch\n");