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