aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mediatek/patches-5.15/731-net-phy-hack-mxl-gpy-disable-sgmii-an.patch
blob: 2e39ca3c26aad294216f6eb182b3a53f3dc9df0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
--- a/drivers/net/phy/mxl-gpy.c
+++ b/drivers/net/phy/mxl-gpy.c
@@ -126,6 +126,12 @@ static int gpy_config_init(struct phy_de
 	if (ret < 0)
 		return ret;
 
+	/* Disable SGMII auto-negotiation */
+	ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
+			     VSPEC1_SGMII_CTRL_ANEN, 0);
+	if (ret < 0)
+		return ret;
+
 	return gpy_led_write(phydev);
 }
 
@@ -151,65 +157,6 @@ static int gpy_probe(struct phy_device *
 	return 0;
 }
 
-static bool gpy_sgmii_need_reaneg(struct phy_device *phydev)
-{
-	int fw_ver, fw_type, fw_minor;
-	size_t i;
-
-	fw_ver = phy_read(phydev, PHY_FWV);
-	if (fw_ver < 0)
-		return true;
-
-	fw_type = FIELD_GET(PHY_FWV_TYPE_MASK, fw_ver);
-	fw_minor = FIELD_GET(PHY_FWV_MINOR_MASK, fw_ver);
-
-	for (i = 0; i < ARRAY_SIZE(ver_need_sgmii_reaneg); i++) {
-		if (fw_type != ver_need_sgmii_reaneg[i].type)
-			continue;
-		if (fw_minor < ver_need_sgmii_reaneg[i].minor)
-			return true;
-		break;
-	}
-
-	return false;
-}
-
-static bool gpy_2500basex_chk(struct phy_device *phydev)
-{
-	int ret;
-
-	ret = phy_read(phydev, PHY_MIISTAT);
-	if (ret < 0) {
-		phydev_err(phydev, "Error: MDIO register access failed: %d\n",
-			   ret);
-		return false;
-	}
-
-	if (!(ret & PHY_MIISTAT_LS) ||
-	    FIELD_GET(PHY_MIISTAT_SPD_MASK, ret) != PHY_MIISTAT_SPD_2500)
-		return false;
-
-	phydev->speed = SPEED_2500;
-	phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-	phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
-		       VSPEC1_SGMII_CTRL_ANEN, 0);
-	return true;
-}
-
-static bool gpy_sgmii_aneg_en(struct phy_device *phydev)
-{
-	int ret;
-
-	ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL);
-	if (ret < 0) {
-		phydev_err(phydev, "Error: MMD register access failed: %d\n",
-			   ret);
-		return true;
-	}
-
-	return (ret & VSPEC1_SGMII_CTRL_ANEN) ? true : false;
-}
-
 static int gpy_config_aneg(struct phy_device *phydev)
 {
 	bool changed = false;
@@ -248,53 +195,11 @@ static int gpy_config_aneg(struct phy_de
 	    phydev->interface == PHY_INTERFACE_MODE_INTERNAL)
 		return 0;
 
-	/* No need to trigger re-ANEG if link speed is 2.5G or SGMII ANEG is
-	 * disabled.
-	 */
-	if (!gpy_sgmii_need_reaneg(phydev) || gpy_2500basex_chk(phydev) ||
-	    !gpy_sgmii_aneg_en(phydev))
-		return 0;
-
-	/* There is a design constraint in GPY2xx device where SGMII AN is
-	 * only triggered when there is change of speed. If, PHY link
-	 * partner`s speed is still same even after PHY TPI is down and up
-	 * again, SGMII AN is not triggered and hence no new in-band message
-	 * from GPY to MAC side SGMII.
-	 * This could cause an issue during power up, when PHY is up prior to
-	 * MAC. At this condition, once MAC side SGMII is up, MAC side SGMII
-	 * wouldn`t receive new in-band message from GPY with correct link
-	 * status, speed and duplex info.
-	 *
-	 * 1) If PHY is already up and TPI link status is still down (such as
-	 *    hard reboot), TPI link status is polled for 4 seconds before
-	 *    retriggerring SGMII AN.
-	 * 2) If PHY is already up and TPI link status is also up (such as soft
-	 *    reboot), polling of TPI link status is not needed and SGMII AN is
-	 *    immediately retriggered.
-	 * 3) Other conditions such as PHY is down, speed change etc, skip
-	 *    retriggering SGMII AN. Note: in case of speed change, GPY FW will
-	 *    initiate SGMII AN.
-	 */
-
-	if (phydev->state != PHY_UP)
-		return 0;
-
-	ret = phy_read_poll_timeout(phydev, MII_BMSR, ret, ret & BMSR_LSTATUS,
-				    20000, 4000000, false);
-	if (ret == -ETIMEDOUT)
-		return 0;
-	else if (ret < 0)
-		return ret;
-
-	/* Trigger SGMII AN. */
-	return phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
-			      VSPEC1_SGMII_CTRL_ANRS, VSPEC1_SGMII_CTRL_ANRS);
+	return 0;
 }
 
 static void gpy_update_interface(struct phy_device *phydev)
 {
-	int ret;
-
 	/* Interface mode is fixed for USXGMII and integrated PHY */
 	if (phydev->interface == PHY_INTERFACE_MODE_USXGMII ||
 	    phydev->interface == PHY_INTERFACE_MODE_INTERNAL)
@@ -306,29 +211,11 @@ static void gpy_update_interface(struct
 	switch (phydev->speed) {
 	case SPEED_2500:
 		phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-		ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
-				     VSPEC1_SGMII_CTRL_ANEN, 0);
-		if (ret < 0)
-			phydev_err(phydev,
-				   "Error: Disable of SGMII ANEG failed: %d\n",
-				   ret);
 		break;
 	case SPEED_1000:
 	case SPEED_100:
 	case SPEED_10:
 		phydev->interface = PHY_INTERFACE_MODE_SGMII;
-		if (gpy_sgmii_aneg_en(phydev))
-			break;
-		/* Enable and restart SGMII ANEG for 10/100/1000Mbps link speed
-		 * if ANEG is disabled (in 2500-BaseX mode).
-		 */
-		ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
-				     VSPEC1_SGMII_ANEN_ANRS,
-				     VSPEC1_SGMII_ANEN_ANRS);
-		if (ret < 0)
-			phydev_err(phydev,
-				   "Error: Enable of SGMII ANEG failed: %d\n",
-				   ret);
 		break;
 	}
 }