f29e690350cb0d3946bc6b3b4bcafa83a6e6cf4b
[openwrt/staging/mans0n.git] / target / linux / generic / pending-6.1 / 721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch
1 From ace6abaa0f9203083fe4c0a6a74da2d96410b625 Mon Sep 17 00:00:00 2001
2 From: Alexander Couzens <lynxis@fe80.eu>
3 Date: Sat, 13 Aug 2022 12:49:33 +0200
4 Subject: [PATCH 01/10] net: phy: realtek: rtl8221: allow to configure SERDES
5 mode
6
7 The rtl8221 supports multiple SERDES modes:
8 - SGMII
9 - 2500base-x
10 - HiSGMII
11
12 Further it supports rate adaption on SERDES links to allow
13 slow ethernet speeds (10/100/1000mbit) to work on 2500base-x/HiSGMII
14 links without reducing the SERDES speed.
15
16 When operating without rate adapters the SERDES link will follow the
17 ethernet speed.
18
19 Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
20 ---
21 drivers/net/phy/realtek.c | 48 +++++++++++++++++++++++++++++++++++++++
22 1 file changed, 48 insertions(+)
23
24 --- a/drivers/net/phy/realtek.c
25 +++ b/drivers/net/phy/realtek.c
26 @@ -53,6 +53,15 @@
27 RTL8201F_ISR_LINK)
28 #define RTL8201F_IER 0x13
29
30 +#define RTL8221B_MMD_SERDES_CTRL MDIO_MMD_VEND1
31 +#define RTL8221B_MMD_PHY_CTRL MDIO_MMD_VEND2
32 +#define RTL8221B_SERDES_OPTION 0x697a
33 +#define RTL8221B_SERDES_OPTION_MODE_MASK GENMASK(5, 0)
34 +#define RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII 0
35 +#define RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII 1
36 +#define RTL8221B_SERDES_OPTION_MODE_2500BASEX 2
37 +#define RTL8221B_SERDES_OPTION_MODE_HISGMII 3
38 +
39 #define RTL8366RB_POWER_SAVE 0x15
40 #define RTL8366RB_POWER_SAVE_ON BIT(12)
41
42 @@ -849,6 +858,48 @@ static irqreturn_t rtl9000a_handle_inter
43 return IRQ_HANDLED;
44 }
45
46 +static int rtl8221b_config_init(struct phy_device *phydev)
47 +{
48 + u16 option_mode;
49 +
50 + switch (phydev->interface) {
51 + case PHY_INTERFACE_MODE_2500BASEX:
52 + if (!phydev->is_c45) {
53 + option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX;
54 + break;
55 + }
56 + fallthrough;
57 + case PHY_INTERFACE_MODE_SGMII:
58 + option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII;
59 + break;
60 + default:
61 + return 0;
62 + }
63 +
64 + phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL,
65 + 0x75f3, 0);
66 +
67 + phy_modify_mmd_changed(phydev, RTL8221B_MMD_SERDES_CTRL,
68 + RTL8221B_SERDES_OPTION,
69 + RTL8221B_SERDES_OPTION_MODE_MASK, option_mode);
70 + switch (option_mode) {
71 + case RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII:
72 + case RTL8221B_SERDES_OPTION_MODE_2500BASEX:
73 + phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503);
74 + phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd455);
75 + phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020);
76 + break;
77 + case RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII:
78 + case RTL8221B_SERDES_OPTION_MODE_HISGMII:
79 + phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503);
80 + phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd433);
81 + phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020);
82 + break;
83 + }
84 +
85 + return 0;
86 +}
87 +
88 static struct phy_driver realtek_drvs[] = {
89 {
90 PHY_ID_MATCH_EXACT(0x00008201),
91 @@ -1001,6 +1052,7 @@ static struct phy_driver realtek_drvs[]
92 PHY_ID_MATCH_EXACT(0x001cc849),
93 .name = "RTL8221B-VB-CG 2.5Gbps PHY",
94 .get_features = rtl822x_get_features,
95 + .config_init = rtl8221b_config_init,
96 .config_aneg = rtl822x_config_aneg,
97 .read_status = rtl822x_read_status,
98 .suspend = genphy_suspend,
99 @@ -1012,6 +1064,7 @@ static struct phy_driver realtek_drvs[]
100 .name = "RTL8221B-VM-CG 2.5Gbps PHY",
101 .get_features = rtl822x_get_features,
102 .config_aneg = rtl822x_config_aneg,
103 + .config_init = rtl8221b_config_init,
104 .read_status = rtl822x_read_status,
105 .suspend = genphy_suspend,
106 .resume = rtlgen_resume,