a3a205532fc3fcbbb371f8c35114ca24e226a36e
[openwrt/staging/stintel.git] /
1 From d54ef6aea00e7a6ace439baade6ad0aa38ee4b04 Mon Sep 17 00:00:00 2001
2 From: Daniel Golle <daniel@makrotopia.org>
3 Date: Mon, 3 Apr 2023 01:21:57 +0300
4 Subject: [PATCH 287/326] net: phy: realtek: disable SGMII in-band AN for 2.5G
5 PHYs
6
7 MAC drivers don't use SGMII in-band autonegotiation unless told to do so
8 in device tree using 'managed = "in-band-status"'. When using MDIO to
9 access a PHY, in-band-status is unneeded as we have link-status via
10 MDIO. Switch off SGMII in-band autonegotiation using magic values.
11
12 Reported-by: Chen Minqiang <ptpt52@gmail.com>
13 Reported-by: Chukun Pan <amadeus@jmu.edu.cn>
14 Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
15 Tested-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
16 Signed-off-by: Daniel Golle <daniel@makrotopia.org>
17 ---
18 drivers/net/phy/realtek/realtek_main.c | 27 +++++++++++++++++++++++++--
19 1 file changed, 25 insertions(+), 2 deletions(-)
20
21 --- a/drivers/net/phy/realtek/realtek_main.c
22 +++ b/drivers/net/phy/realtek/realtek_main.c
23 @@ -1092,8 +1092,8 @@ static int rtl822x_probe(struct phy_devi
24 static int rtl822x_set_serdes_option_mode(struct phy_device *phydev, bool gen1)
25 {
26 bool has_2500, has_sgmii;
27 + int ret, val;
28 u16 mode;
29 - int ret;
30
31 has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX,
32 phydev->host_interfaces) ||
33 @@ -1135,18 +1135,42 @@ static int rtl822x_set_serdes_option_mod
34 RTL822X_VND1_SERDES_OPTION,
35 RTL822X_VND1_SERDES_OPTION_MODE_MASK,
36 mode);
37 - if (gen1 || ret < 0)
38 + if (ret < 0)
39 + return ret;
40 +
41 + if (!gen1) {
42 + ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6a04, 0x0503);
43 + if (ret < 0)
44 + return ret;
45 +
46 + ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f10, 0xd455);
47 + if (ret < 0)
48 + return ret;
49 +
50 + ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
51 + if (ret < 0)
52 + return ret;
53 + }
54 +
55 + /* Disable SGMII AN */
56 + ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7588, 0x2);
57 + if (ret < 0)
58 + return ret;
59 +
60 + ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7589, 0x71d0);
61 + if (ret < 0)
62 return ret;
63
64 - ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6a04, 0x0503);
65 + ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7587, 0x3);
66 if (ret < 0)
67 return ret;
68
69 - ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f10, 0xd455);
70 + ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, 0x7587,
71 + val, !(val & BIT(0)), 500, 100000, false);
72 if (ret < 0)
73 return ret;
74
75 - return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
76 + return 0;
77 }
78
79 static int rtl822x_config_init(struct phy_device *phydev)